KDEUI
kcolorspaces.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE project 00002 * Copyright (C) 2007 Matthew Woehlke <mw_triad@users.sourceforge.net> 00003 * Copyright (C) 2007 Olaf Schmidt <ojschmidt@kde.org> 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Library General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Library General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Library General Public License 00016 * along with this library; see the file COPYING.LIB. If not, write to 00017 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 * Boston, MA 02110-1301, USA. 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 // HCY color space 00037 00038 #define HCY_REC 709 // use 709 for now 00039 #if HCY_REC == 601 00040 static const qreal yc[3] = { 0.299, 0.587, 0.114 }; 00041 #elif HCY_REC == 709 00042 static const qreal yc[3] = {0.2126, 0.7152, 0.0722}; 00043 #else // use Qt values 00044 static const qreal yc[3] = { 0.34375, 0.5, 0.15625 }; 00045 #endif 00046 00047 qreal KHCY::gamma(qreal n) 00048 { 00049 return pow(normalize(n), 2.2); 00050 } 00051 00052 qreal KHCY::igamma(qreal n) 00053 { 00054 return pow(normalize(n), 1.0/2.2); 00055 } 00056 00057 qreal KHCY::lumag(qreal r, qreal g, qreal b) 00058 { 00059 return r*yc[0] + g*yc[1] + b*yc[2]; 00060 } 00061 00062 KHCY::KHCY(qreal h_, qreal c_, qreal y_, qreal a_) 00063 { 00064 h = h_; 00065 c = c_; 00066 y = y_; 00067 a = a_; 00068 } 00069 00070 KHCY::KHCY(const QColor& color) 00071 { 00072 qreal r = gamma(color.redF()); 00073 qreal g = gamma(color.greenF()); 00074 qreal b = gamma(color.blueF()); 00075 a = color.alphaF(); 00076 00077 // luma component 00078 y = lumag(r, g, b); 00079 00080 // hue component 00081 qreal p = qMax(qMax(r, g), b); 00082 qreal n = qMin(qMin(r, g), b); 00083 qreal d = 6.0 * (p - n); 00084 if (n == p) 00085 h = 0.0; 00086 else if (r == p) 00087 h = ((g - b) / d); 00088 else if (g == p) 00089 h = ((b - r) / d) + (1.0 / 3.0); 00090 else 00091 h = ((r - g) / d) + (2.0 / 3.0); 00092 00093 // chroma component 00094 if (r == g && g == b) 00095 c = 0.0; 00096 else 00097 c = qMax( (y - n) / y, (p - y) / (1 - y) ); 00098 } 00099 00100 QColor KHCY::qColor() const 00101 { 00102 // start with sane component values 00103 qreal _h = wrap(h); 00104 qreal _c = normalize(c); 00105 qreal _y = normalize(y); 00106 00107 // calculate some needed variables 00108 qreal _hs = _h * 6.0, th, tm; 00109 if (_hs < 1.0) { 00110 th = _hs; 00111 tm = yc[0] + yc[1] * th; 00112 } 00113 else if (_hs < 2.0) { 00114 th = 2.0 - _hs; 00115 tm = yc[1] + yc[0] * th; 00116 } 00117 else if (_hs < 3.0) { 00118 th = _hs - 2.0; 00119 tm = yc[1] + yc[2] * th; 00120 } 00121 else if (_hs < 4.0) { 00122 th = 4.0 - _hs; 00123 tm = yc[2] + yc[1] * th; 00124 } 00125 else if (_hs < 5.0) { 00126 th = _hs - 4.0; 00127 tm = yc[2] + yc[0] * th; 00128 } 00129 else { 00130 th = 6.0 - _hs; 00131 tm = yc[0] + yc[2] * th; 00132 } 00133 00134 // calculate RGB channels in sorted order 00135 qreal tn, to, tp; 00136 if (tm >= _y) { 00137 tp = _y + _y * _c * (1.0 - tm) / tm; 00138 to = _y + _y * _c * (th - tm) / tm; 00139 tn = _y - (_y * _c); 00140 } 00141 else { 00142 tp = _y + (1.0 - _y) * _c; 00143 to = _y + (1.0 - _y) * _c * (th - tm) / (1.0 - tm); 00144 tn = _y - (1.0 - _y) * _c * tm / (1.0 - tm); 00145 } 00146 00147 // return RGB channels in appropriate order 00148 if (_hs < 1.0) 00149 return QColor::fromRgbF(igamma(tp), igamma(to), igamma(tn), a); 00150 else if (_hs < 2.0) 00151 return QColor::fromRgbF(igamma(to), igamma(tp), igamma(tn), a); 00152 else if (_hs < 3.0) 00153 return QColor::fromRgbF(igamma(tn), igamma(tp), igamma(to), a); 00154 else if (_hs < 4.0) 00155 return QColor::fromRgbF(igamma(tn), igamma(to), igamma(tp), a); 00156 else if (_hs < 5.0) 00157 return QColor::fromRgbF(igamma(to), igamma(tn), igamma(tp), a); 00158 else 00159 return QColor::fromRgbF(igamma(tp), igamma(tn), igamma(to), a); 00160 } 00161 00162 qreal KHCY::luma(const QColor& color) 00163 { 00164 return lumag(gamma(color.redF()), 00165 gamma(color.greenF()), 00166 gamma(color.blueF())); 00167 } 00168 00169 // kate: space-indent on; indent-width 4; replace-tabs on; auto-insert-doxygen on;
KDE 4.6 API Reference