]> git.sesse.net Git - kdenlive/blob - src/colorcorrection/waveformgenerator.cpp
Waveform monitor added.
[kdenlive] / src / colorcorrection / waveformgenerator.cpp
1 /***************************************************************************
2  *   Copyright (C) 2010 by Simon Andreas Eugster (simon.eu@gmail.com)      *
3  *   This file is part of kdenlive. See www.kdenlive.org.                  *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  ***************************************************************************/
10
11 #include <QDebug>
12 #include <QTime>
13 #include <QColor>
14 #include <QPainter>
15
16 #include "waveformgenerator.h"
17
18 #define CHOP255(a) ((255) < (a) ? (255) : (a))
19
20 WaveformGenerator::WaveformGenerator()
21 {
22 }
23
24 WaveformGenerator::~WaveformGenerator()
25 {
26 }
27
28 QImage WaveformGenerator::calculateWaveform(const QSize &waveformSize, const QImage &image, const bool &drawAxis)
29 {
30     QTime time;
31     time.start();
32
33     QImage wave(waveformSize, QImage::Format_ARGB32);
34
35     if (waveformSize.width() <= 0 || waveformSize.height() <= 0) {
36         qCritical("Waveform size should not be 0.");
37
38     } else {
39
40         qDebug() << "Waveform calculation started.";
41
42         // Fill with transparent color
43         wave.fill(qRgba(0,0,0,0));
44
45         QRgb *col;
46         QRgb waveCol;
47         QPoint wavePoint;
48
49         double dY, dx, dy;
50
51         const uint ww = waveformSize.width();
52         const uint wh = waveformSize.height();
53         const uint iw = image.bytesPerLine();
54         const uint ih = image.height();
55         const uint byteCount = iw*ih;
56
57         // Subtract 1 from sizes because we start counting from 0.
58         // Not doing it would result in attempts to paint outside of the image.
59         const float hPrediv = (float)(wh-1)/255;
60         const float wPrediv = (float)(ww-1)/(iw-1);
61
62         const uchar *bits = image.bits();
63         const uint stepsize = 4;
64
65         for (uint i = 0, x = 0; i < byteCount; i += stepsize) {
66
67             col = (QRgb *)bits;
68
69             // CIE 601 Luminance
70             // dY is on [0,255] now.
71             dY = .299*qRed(*col) + .587*qGreen(*col) + .114*qBlue(*col);
72
73             dy = dY*hPrediv;
74             dx = x*wPrediv;
75             wavePoint = QPoint((int)dx, (int)(wh-1 - dy));
76
77             waveCol = QRgb(wave.pixel(wavePoint));
78             wave.setPixel(wavePoint, qRgba(CHOP255(9 + qRed(waveCol)), CHOP255(36 + qGreen(waveCol)),
79                                            CHOP255(18 + qBlue(waveCol)), 255));
80
81             bits += stepsize;
82             x += stepsize;
83             x %= iw;
84         }
85
86         if (drawAxis) {
87             QPainter davinci(&wave);
88             QRgb opx;
89             davinci.setPen(qRgba(150,255,200,32));
90             davinci.setCompositionMode(QPainter::CompositionMode_Overlay);
91             for (uint i = 0; i <= 10; i++) {
92                 dy = (float)i/10 * (wh-1);
93                 for (uint x = 0; x < ww; x++) {
94                     opx = wave.pixel(x, dy);
95                     wave.setPixel(x,dy, qRgba(CHOP255(150+qRed(opx)), 255,
96                                               CHOP255(200+qBlue(opx)), CHOP255(32+qAlpha(opx))));
97                 }
98                 //davinci.drawLine(0, dy, ww-1, dy);
99             }
100         }
101
102     }
103
104     uint diff = time.elapsed();
105     qDebug() << "Waveform calculation ended. Time taken: " << diff << " ms. Sending signal now.";
106     emit signalCalculationFinished(wave, diff);
107
108     return wave;
109 }