]> git.sesse.net Git - kdenlive/blob - src/colortools.cpp
Vectorscope changes:
[kdenlive] / src / colortools.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 <math.h>
12 #include "colortools.h"
13
14 ColorTools::ColorTools()
15 {
16 }
17
18
19
20 QImage ColorTools::yuvColorWheel(const QSize &size, unsigned char Y, float scaling, bool modifiedVersion, bool circleOnly)
21 {
22     QImage wheel(size, QImage::Format_ARGB32);
23     if (size.width() == 0 || size.height() == 0) {
24         qCritical("ERROR: Size of the color wheel must not be 0!");
25         return wheel;
26     }
27     wheel.fill(qRgba(0,0,0,0));
28
29     double dr, dg, db, du, dv, dmax;
30     double ru, rv, rr;
31     const int w = size.width();
32     const int h = size.height();
33     const float w2 = (float)w/2;
34     const float h2 = (float)h/2;
35
36     for (int u = 0; u < w; u++) {
37         // Transform u from {0,...,w} to [-1,1]
38         du = (double) 2*u/(w-1) - 1;
39         du = scaling*du;
40
41         for (int v = 0; v < h; v++) {
42             dv = (double) 2*v/(h-1) - 1;
43             dv = scaling*dv;
44
45             if (circleOnly) {
46                 // Ellipsis equation: x²/a² + y²/b² = 1
47                 // Here: x=ru, y=rv, a=w/2, b=h/2, 1=rr
48                 // For rr > 1, the point lies outside. Don't draw it.
49                 ru = u - w2;
50                 rv = v - h2;
51                 rr = ru*ru/(w2*w2) + rv*rv/(h2*h2);
52                 if (rr > 1) {
53                     continue;
54                 }
55             }
56
57             // Calculate the RGB values from YUV
58             dr = Y + 290.8*dv;
59             dg = Y - 100.6*du - 148*dv;
60             db = Y + 517.2*du;
61
62             if (modifiedVersion) {
63                 // Scale the RGB values down, or up, to max 255
64                 dmax = fabs(dr);
65                 if (fabs(dg) > dmax) dmax = fabs(dg);
66                 if (fabs(db) > dmax) dmax = fabs(db);
67                 dmax = 255/dmax;
68
69                 dr *= dmax;
70                 dg *= dmax;
71                 db *= dmax;
72             }
73
74             // Avoid overflows (which would generate intersting patterns).
75             // Note that not all possible (y,u,v) values with u,v \in [-1,1]
76             // have a correct RGB representation, therefore some RGB values
77             // may exceed {0,...,255}.
78             if (dr < 0) dr = 0;
79             if (dg < 0) dg = 0;
80             if (db < 0) db = 0;
81             if (dr > 255) dr = 255;
82             if (dg > 255) dg = 255;
83             if (db > 255) db = 255;
84
85             wheel.setPixel(u, (h-v-1), qRgba(dr, dg, db, 255));
86         }
87     }
88
89     emit signalWheelCalculationFinished();
90     return wheel;
91 }