00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kcolorspaces.h"
00021 #include "kcolorhelpers_p.h"
00022
00023 #include <QColor>
00024
00025 #include <math.h>
00026
00027 using namespace KColorSpaces;
00028
00029 static inline qreal wrap(qreal a, qreal d = 1.0)
00030 {
00031 qreal r = fmod(a, d);
00032 return (r < 0.0 ? d + r : (r > 0.0 ? r : 0.0));
00033 }
00034
00036
00037
00038 KHSL::KHSL(const QColor& color)
00039 {
00040
00041 a = color.alphaF();
00042 }
00043
00044 QColor KHSL::qColor() const
00045 {
00046
00047 return QColor();
00048 }
00049
00051
00052
00053 #define HCY_REC 709 // use 709 for now
00054 #if HCY_REC == 601
00055 static const qreal yc[3] = { 0.299, 0.587, 0.114 };
00056 #elif HCY_REC == 709
00057 static const qreal yc[3] = {0.2126, 0.7152, 0.0722};
00058 #else // use Qt values
00059 static const qreal yc[3] = { 0.34375, 0.5, 0.15625 };
00060 #endif
00061
00062 qreal KHCY::gamma(qreal n)
00063 {
00064 return pow(normalize(n), 2.2);
00065 }
00066
00067 qreal KHCY::igamma(qreal n)
00068 {
00069 return pow(normalize(n), 1.0/2.2);
00070 }
00071
00072 qreal KHCY::lumag(qreal r, qreal g, qreal b)
00073 {
00074 return r*yc[0] + g*yc[1] + b*yc[2];
00075 }
00076
00077 KHCY::KHCY(qreal h_, qreal c_, qreal y_, qreal a_)
00078 {
00079 h = h_;
00080 c = c_;
00081 y = y_;
00082 a = a_;
00083 }
00084
00085 KHCY::KHCY(const QColor& color)
00086 {
00087 qreal r = gamma(color.redF());
00088 qreal g = gamma(color.greenF());
00089 qreal b = gamma(color.blueF());
00090 a = color.alphaF();
00091
00092
00093 y = lumag(r, g, b);
00094
00095
00096 qreal p = qMax(qMax(r, g), b);
00097 qreal n = qMin(qMin(r, g), b);
00098 qreal d = 6.0 * (p - n);
00099 if (n == p)
00100 h = 0.0;
00101 else if (r == p)
00102 h = ((g - b) / d);
00103 else if (g == p)
00104 h = ((b - r) / d) + (1.0 / 3.0);
00105 else
00106 h = ((r - g) / d) + (2.0 / 3.0);
00107
00108
00109 if (0.0 == y || 1.0 == y)
00110 c = 0.0;
00111 else
00112 c = qMax( (y - n) / y, (p - y) / (1 - y) );
00113 }
00114
00115 QColor KHCY::qColor() const
00116 {
00117
00118 qreal _h = wrap(h);
00119 qreal _c = normalize(c);
00120 qreal _y = normalize(y);
00121
00122
00123 qreal _hs = _h * 6.0, th, tm;
00124 if (_hs < 1.0) {
00125 th = _hs;
00126 tm = yc[0] + yc[1] * th;
00127 }
00128 else if (_hs < 2.0) {
00129 th = 2.0 - _hs;
00130 tm = yc[1] + yc[0] * th;
00131 }
00132 else if (_hs < 3.0) {
00133 th = _hs - 2.0;
00134 tm = yc[1] + yc[2] * th;
00135 }
00136 else if (_hs < 4.0) {
00137 th = 4.0 - _hs;
00138 tm = yc[2] + yc[1] * th;
00139 }
00140 else if (_hs < 5.0) {
00141 th = _hs - 4.0;
00142 tm = yc[2] + yc[0] * th;
00143 }
00144 else {
00145 th = 6.0 - _hs;
00146 tm = yc[0] + yc[2] * th;
00147 }
00148
00149
00150 qreal tn, to, tp;
00151 if (tm >= _y) {
00152 tp = _y + _y * _c * (1.0 - tm) / tm;
00153 to = _y + _y * _c * (th - tm) / tm;
00154 tn = _y - (_y * _c);
00155 }
00156 else {
00157 tp = _y + (1.0 - _y) * _c;
00158 to = _y + (1.0 - _y) * _c * (th - tm) / (1.0 - tm);
00159 tn = _y - (1.0 - _y) * _c * tm / (1.0 - tm);
00160 }
00161
00162
00163 if (_hs < 1.0)
00164 return QColor::fromRgbF(igamma(tp), igamma(to), igamma(tn), a);
00165 else if (_hs < 2.0)
00166 return QColor::fromRgbF(igamma(to), igamma(tp), igamma(tn), a);
00167 else if (_hs < 3.0)
00168 return QColor::fromRgbF(igamma(tn), igamma(tp), igamma(to), a);
00169 else if (_hs < 4.0)
00170 return QColor::fromRgbF(igamma(tn), igamma(to), igamma(tp), a);
00171 else if (_hs < 5.0)
00172 return QColor::fromRgbF(igamma(to), igamma(tn), igamma(tp), a);
00173 else
00174 return QColor::fromRgbF(igamma(tp), igamma(tn), igamma(to), a);
00175 }
00176
00177 qreal KHCY::luma(const QColor& color)
00178 {
00179 return lumag(gamma(color.redF()),
00180 gamma(color.greenF()),
00181 gamma(color.blueF()));
00182 }
00183
00184