KGuiAddons

kcolorspaces.cpp
1/* This file is part of the KDE project
2 SPDX-FileCopyrightText: 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>
3 SPDX-FileCopyrightText: 2007 Olaf Schmidt <ojschmidt@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7#include "kcolorspaces_p.h"
8#include "kguiaddons_colorhelpers_p.h"
9
10#include <QColor>
11
12#include <math.h>
13
14using namespace KColorSpaces;
15
16static inline qreal wrap(qreal a, qreal d = 1.0)
17{
18 qreal r = fmod(a, d);
19 return (r < 0.0 ? d + r : (r > 0.0 ? r : 0.0));
20}
21
22///////////////////////////////////////////////////////////////////////////////
23// HCY color space
24
25#define HCY_REC 709 // use 709 for now
26#if HCY_REC == 601
27static const qreal yc[3] = {0.299, 0.587, 0.114};
28#elif HCY_REC == 709
29static const qreal yc[3] = {0.2126, 0.7152, 0.0722};
30#else // use Qt values
31static const qreal yc[3] = {0.34375, 0.5, 0.15625};
32#endif
33
34qreal KHCY::gamma(qreal n)
35{
36 return pow(normalize(n), 2.2);
37}
38
39qreal KHCY::igamma(qreal n)
40{
41 return pow(normalize(n), 1.0 / 2.2);
42}
43
44qreal KHCY::lumag(qreal r, qreal g, qreal b)
45{
46 return r * yc[0] + g * yc[1] + b * yc[2];
47}
48
49KHCY::KHCY(qreal h_, qreal c_, qreal y_, qreal a_)
50{
51 h = h_;
52 c = c_;
53 y = y_;
54 a = a_;
55}
56
57KHCY::KHCY(const QColor &color)
58{
59 qreal r = gamma(color.redF());
60 qreal g = gamma(color.greenF());
61 qreal b = gamma(color.blueF());
62 a = color.alphaF();
63
64 // luma component
65 y = lumag(r, g, b);
66
67 // hue component
68 qreal p = qMax(qMax(r, g), b);
69 qreal n = qMin(qMin(r, g), b);
70 qreal d = 6.0 * (p - n);
71 if (n == p) {
72 h = 0.0;
73 } else if (r == p) {
74 h = ((g - b) / d);
75 } else if (g == p) {
76 h = ((b - r) / d) + (1.0 / 3.0);
77 } else {
78 h = ((r - g) / d) + (2.0 / 3.0);
79 }
80
81 // chroma component
82 if (r == g && g == b) {
83 c = 0.0;
84 } else {
85 c = qMax((y - n) / y, (p - y) / (1 - y));
86 }
87}
88
89QColor KHCY::qColor() const
90{
91 // start with sane component values
92 qreal _h = wrap(h);
93 qreal _c = normalize(c);
94 qreal _y = normalize(y);
95
96 // calculate some needed variables
97 qreal _hs = _h * 6.0;
98 qreal th;
99 qreal tm;
100 if (_hs < 1.0) {
101 th = _hs;
102 tm = yc[0] + yc[1] * th;
103 } else if (_hs < 2.0) {
104 th = 2.0 - _hs;
105 tm = yc[1] + yc[0] * th;
106 } else if (_hs < 3.0) {
107 th = _hs - 2.0;
108 tm = yc[1] + yc[2] * th;
109 } else if (_hs < 4.0) {
110 th = 4.0 - _hs;
111 tm = yc[2] + yc[1] * th;
112 } else if (_hs < 5.0) {
113 th = _hs - 4.0;
114 tm = yc[2] + yc[0] * th;
115 } else {
116 th = 6.0 - _hs;
117 tm = yc[0] + yc[2] * th;
118 }
119
120 // calculate RGB channels in sorted order
121 qreal tn;
122 qreal to;
123 qreal tp;
124 if (tm >= _y) {
125 tp = _y + _y * _c * (1.0 - tm) / tm;
126 to = _y + _y * _c * (th - tm) / tm;
127 tn = _y - (_y * _c);
128 } else {
129 tp = _y + (1.0 - _y) * _c;
130 to = _y + (1.0 - _y) * _c * (th - tm) / (1.0 - tm);
131 tn = _y - (1.0 - _y) * _c * tm / (1.0 - tm);
132 }
133
134 // return RGB channels in appropriate order
135 if (_hs < 1.0) {
136 return QColor::fromRgbF(igamma(tp), igamma(to), igamma(tn), a);
137 } else if (_hs < 2.0) {
138 return QColor::fromRgbF(igamma(to), igamma(tp), igamma(tn), a);
139 } else if (_hs < 3.0) {
140 return QColor::fromRgbF(igamma(tn), igamma(tp), igamma(to), a);
141 } else if (_hs < 4.0) {
142 return QColor::fromRgbF(igamma(tn), igamma(to), igamma(tp), a);
143 } else if (_hs < 5.0) {
144 return QColor::fromRgbF(igamma(to), igamma(tn), igamma(tp), a);
145 } else {
146 return QColor::fromRgbF(igamma(tp), igamma(tn), igamma(to), a);
147 }
148}
149
150qreal KHCY::hue(const QColor &color)
151{
152 return wrap(KHCY(color).h);
153}
154
155qreal KHCY::chroma(const QColor &color)
156{
157 return KHCY(color).c;
158}
159
160qreal KHCY::luma(const QColor &color)
161{
162 return lumag(gamma(color.redF()), gamma(color.greenF()), gamma(color.blueF()));
163}
QString normalize(QStringView str)
float alphaF() const const
float blueF() const const
QColor fromRgbF(float r, float g, float b, float a)
float greenF() const const
float redF() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:14:40 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.