]> git.sesse.net Git - kdenlive/blobdiff - src/colorcorrection/histogramgenerator.cpp
Use QLatin1String
[kdenlive] / src / colorcorrection / histogramgenerator.cpp
index 3c3308efe1914f403cf02b7a3fb96c5c3ac8a929..3541d30002360a9a390da3930190e196191df476 100644 (file)
@@ -10,9 +10,9 @@
 
 #include <algorithm>
 #include <math.h>
-#include <QDebug>
 #include <QImage>
 #include <QPainter>
+#include <KLocale>
 #include "histogramgenerator.h"
 
 HistogramGenerator::HistogramGenerator()
@@ -20,10 +20,9 @@ HistogramGenerator::HistogramGenerator()
 }
 
 QImage HistogramGenerator::calculateHistogram(const QSize &paradeSize, const QImage &image, const int &components,
-                                        const bool &unscaled, const uint &accelFactor) const
+                                              HistogramGenerator::Rec rec, bool unscaled, uint accelFactor) const
 {
-    qDebug() << "Histogram rect size is: " << paradeSize.width() << "/" << paradeSize.height();
-    if (paradeSize.height() <= 0 || paradeSize.width() <= 0) {
+    if (paradeSize.height() <= 0 || paradeSize.width() <= 0 || image.width() <= 0 || image.height() <= 0) {
         return QImage();
     }
 
@@ -31,20 +30,22 @@ QImage HistogramGenerator::calculateHistogram(const QSize &paradeSize, const QIm
     bool drawR = (components & HistogramGenerator::ComponentR) != 0;
     bool drawG = (components & HistogramGenerator::ComponentG) != 0;
     bool drawB = (components & HistogramGenerator::ComponentB) != 0;
+    bool drawSum = (components & HistogramGenerator::ComponentSum) != 0;
 
-    int r[256], g[256], b[256], y[256];
+    int r[256], g[256], b[256], y[256], s[766];
     // Initialize the values to zero
-    std::fill(r, r+255, 0);
-    std::fill(g, g+255, 0);
-    std::fill(b, b+255, 0);
-    std::fill(y, y+255, 0);
+    std::fill(r, r+256, 0);
+    std::fill(g, g+256, 0);
+    std::fill(b, b+256, 0);
+    std::fill(y, y+256, 0);
+    std::fill(s, s+766, 0);
 
     const uint iw = image.bytesPerLine();
     const uint ih = image.height();
     const uint ww = paradeSize.width();
     const uint wh = paradeSize.height();
     const uint byteCount = iw*ih;
-    const uint stepsize = 4*accelFactor;
+    const uint stepsize = image.depth() / 8 *accelFactor;
 
     const uchar *bits = image.bits();
     QRgb *col;
@@ -57,21 +58,37 @@ QImage HistogramGenerator::calculateHistogram(const QSize &paradeSize, const QIm
         r[qRed(*col)]++;
         g[qGreen(*col)]++;
         b[qBlue(*col)]++;
-        y[(int)floor(.299*qRed(*col) + .587*qGreen(*col) + .114*qBlue(*col))]++;
+        if (drawY) {
+            // Use if branch to avoid expensive multiplication if Y disabled
+            if (rec == HistogramGenerator::Rec_601) {
+                y[(int)floor(.299*qRed(*col) + .587*qGreen(*col) + .114*qBlue(*col))]++;
+            } else {
+                y[(int)floor(.2125*qRed(*col) + .7154*qGreen(*col) + .0721*qBlue(*col))]++;
+            }
+        }
+        if (drawSum) {
+            // Use an if branch here because the sum takes more operations than rgb
+            s[qRed(*col)]++;
+            s[qGreen(*col)]++;
+            s[qBlue(*col)]++;
+        }
 
         bits += stepsize;
     }
 
 
-    const int nParts = (drawY ? 1 : 0) + (drawR ? 1 : 0) + (drawG ? 1 : 0) + (drawB ? 1 : 0);
-    if (nParts == 0 || byteCount == 0) {
+    const int nParts = (drawY ? 1 : 0) + (drawR ? 1 : 0) + (drawG ? 1 : 0) + (drawB ? 1 : 0) + (drawSum ? 1 : 0);
+    if (nParts == 0) {
         // Nothing to draw
         return QImage();
     }
 
     const int d = 20; // Distance for text
     const int partH = (wh-nParts*d)/nParts;
-    const float scaling = (float)partH/(byteCount >> 7);
+    float scaling = 0;
+    int div = byteCount >> 7;
+    if ( div > 0 )
+        scaling = (float)partH/(byteCount >> 7);
     const int dist = 40;
 
     int wy = 0; // Drawing position
@@ -82,28 +99,30 @@ QImage HistogramGenerator::calculateHistogram(const QSize &paradeSize, const QIm
     histogram.fill(qRgba(0, 0, 0, 0));
 
     if (drawY) {
-        qDebug() << "Drawing Y at " << wy << " with height " << partH;
-        drawComponentFull(&davinci, y, scaling, QRect(0, wy, ww, partH + dist), QColor(220, 220, 210, 255), dist, unscaled);
+        drawComponentFull(&davinci, y, scaling, QRect(0, wy, ww, partH + dist), QColor(220, 220, 210, 255), dist, unscaled, 256);
+
+        wy += partH + d;
+    }
+
+    if (drawSum) {
+        drawComponentFull(&davinci, s, scaling/3, QRect(0, wy, ww, partH + dist), QColor(220, 220, 210, 255), dist, unscaled, 256);
 
         wy += partH + d;
     }
 
     if (drawR) {
-        qDebug() << "Drawing R at " << wy << " with height " << partH;
-        drawComponentFull(&davinci, r, scaling, QRect(0, wy, ww, partH + dist), QColor(255, 128, 0, 255), dist, unscaled);
+        drawComponentFull(&davinci, r, scaling, QRect(0, wy, ww, partH + dist), QColor(255, 128, 0, 255), dist, unscaled, 256);
 
         wy += partH + d;
     }
 
     if (drawG) {
-        qDebug() << "Drawing G at " << wy << " with height " << partH;
-        drawComponentFull(&davinci, g, scaling, QRect(0, wy, ww, partH + dist), QColor(128, 255, 0, 255), dist, unscaled);
+        drawComponentFull(&davinci, g, scaling, QRect(0, wy, ww, partH + dist), QColor(128, 255, 0, 255), dist, unscaled, 256);
         wy += partH + d;
     }
 
     if (drawB) {
-        qDebug() << "Drawing B at " << wy << " with height " << partH;
-        drawComponentFull(&davinci, b, scaling, QRect(0, wy, ww, partH + dist), QColor(0, 128, 255, 255), dist, unscaled);
+        drawComponentFull(&davinci, b, scaling, QRect(0, wy, ww, partH + dist), QColor(0, 128, 255, 255), dist, unscaled, 256);
 
         wy += partH + d;
     }
@@ -111,16 +130,17 @@ QImage HistogramGenerator::calculateHistogram(const QSize &paradeSize, const QIm
     return histogram;
 }
 
-QImage HistogramGenerator::drawComponent(const int *y, const QSize &size, const float &scaling, const QColor &color, const bool &unscaled) const
+QImage HistogramGenerator::drawComponent(const int *y, const QSize &size, const float &scaling, const QColor &color,
+                                         bool unscaled, uint max) const
 {
-    QImage component(256, size.height(), QImage::Format_ARGB32);
+    QImage component(max, size.height(), QImage::Format_ARGB32);
     component.fill(qRgba(0, 0, 0, 0));
     Q_ASSERT(scaling != INFINITY);
 
     const int partH = size.height();
     int partY;
 
-    for (int x = 0; x < 256; x++) {
+    for (uint x = 0; x < max; x++) {
         // Calculate the height of the curve at position x
         partY = scaling*y[x];
 
@@ -140,21 +160,21 @@ QImage HistogramGenerator::drawComponent(const int *y, const QSize &size, const
 }
 
 void HistogramGenerator::drawComponentFull(QPainter *davinci, const int *y, const float &scaling, const QRect &rect,
-                                        const QColor &color, const int &textSpace, const bool &unscaled) const
+                                        const QColor &color, int textSpace, bool unscaled, uint max) const
 {
-    QImage component = drawComponent(y, rect.size() - QSize(0, textSpace), scaling, color, unscaled);
+    QImage component = drawComponent(y, rect.size() - QSize(0, textSpace), scaling, color, unscaled, max);
     davinci->drawImage(rect.topLeft(), component);
 
     int min = 0;
-    for (int x = 0; x < 256; x++) {
+    for (uint x = 0; x < max; x++) {
         min = x;
         if (y[x] > 0) {
             break;
         }
     }
-    int max = 255;
-    for (int x = 255; x >= 0; x--) {
-        max = x;
+    int maxVal = max-1;
+    for (int x = max-1; x >= 0; x--) {
+        maxVal = x;
         if (y[x] > 0) {
             break;
         }
@@ -164,9 +184,9 @@ void HistogramGenerator::drawComponentFull(QPainter *davinci, const int *y, cons
     const int dist = 40;
     const int cw = component.width();
 
-    davinci->drawText(0,            textY, "min");
+    davinci->drawText(0,            textY, i18n("min"));
     davinci->drawText(dist,         textY, QString::number(min, 'f', 0));
 
-    davinci->drawText(cw-dist-30,   textY, "max");
-    davinci->drawText(cw-30,        textY, QString::number(max, 'f', 0));
+    davinci->drawText(cw-dist-30,   textY, i18n("max"));
+    davinci->drawText(cw-30,        textY, QString::number(maxVal, 'f', 0));
 }