/*** Olive - Non-Linear Video Editor Copyright (C) 2019 Olive Team This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ***/ #include "histogram.h" #include #include #include "common/clamp.h" #include "common/functiontimer.h" OLIVE_NAMESPACE_ENTER HistogramScope::HistogramScope(QWidget* parent) : ManagedDisplayWidget(parent), buffer_(nullptr) { EnableDefaultContextMenu(); connect(&worker_, &HistogramScopeWorker::Finished, this, &HistogramScope::FinishedProcessing, Qt::QueuedConnection); worker_.start(QThread::IdlePriority); } HistogramScope::~HistogramScope() { worker_.Cancel(); worker_.quit(); worker_.wait(); } void HistogramScope::SetBuffer(Frame* frame) { buffer_ = frame; if (isVisible()) { StartUpdate(); } } void HistogramScope::FinishedProcessing(QVector red, QVector green, QVector blue) { red_val_ = red; green_val_ = green; blue_val_ = blue; update(); } void HistogramScope::paintGL() { QVector red_lines(red_val_.size()); QVector green_lines(green_val_.size()); QVector blue_lines(blue_val_.size()); for (int i=0;i data(w * kRGBChannels, 0); int max_w = w-1; for (int x=0;xConvertColor(c); } data[qFloor(clamp(c.red(), 0.0f, 1.0f) * max_w)]++; data[qFloor(clamp(c.green(), 0.0f, 1.0f) * max_w) + w]++; data[qFloor(clamp(c.blue(), 0.0f, 1.0f) * max_w) + w * 2]++; } } int max_val = 0; foreach (const int& i, data) { if (i > max_val) { max_val = i; } } if (!max_val) { // Prevent divide by zero return; } QVector red_lines(w); QVector green_lines(w); QVector blue_lines(w); for (int i=0;i(data.at(i)) / static_cast(max_val)); green_lines.replace(i, static_cast(data.at(i + w)) / static_cast(max_val)); blue_lines.replace(i, static_cast(data.at(i + w * 2)) / static_cast(max_val)); } emit Finished(red_lines, green_lines, blue_lines); } } void HistogramScopeWorker::QueueNext(const Frame &f, ColorProcessorPtr processor, int width) { next_lock_.lock(); next_ = f; next_width_ = width; next_processor_ = processor; next_wait_.wakeOne(); next_lock_.unlock(); } void HistogramScopeWorker::Cancel() { cancelled_ = true; next_lock_.lock(); next_wait_.wakeOne(); next_lock_.unlock(); } OLIVE_NAMESPACE_EXIT