#include <math.h>
#include <QImage>
#include <QPainter>
+#include <KLocale>
#include "histogramgenerator.h"
HistogramGenerator::HistogramGenerator()
}
QImage HistogramGenerator::calculateHistogram(const QSize ¶deSize, 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 || image.width() <= 0 || image.height() <= 0) {
return QImage();
}
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;
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);
+ 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
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;
}
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];
}
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;
}
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));
}