00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <cmath>
00020
00021 #include <qglobal.h>
00022
00023 #include "kis_color_conversions.h"
00024
00029 void rgb_to_hsv(int R, int G, int B, int *H, int *S, int *V)
00030 {
00031 unsigned int max = R;
00032 unsigned int min = R;
00033 unsigned char maxValue = 0;
00034
00035
00036 if(static_cast<unsigned int>(G) > max) {
00037 max = G;
00038 maxValue = 1;
00039 }
00040
00041 if (static_cast<unsigned int>(B) > max)
00042 {
00043 max = B;
00044 maxValue = 2;
00045 }
00046
00047 if(static_cast<unsigned int>(G) < min)
00048 min = G;
00049
00050 if(static_cast<unsigned int>(B) < min )
00051 min = B;
00052
00053 int delta = max - min;
00054
00055
00056 if (delta == 0) delta = 1;
00057
00058 *V = max;
00059 *S = max ? (510 * delta + max) / ( 2 * max) : 0;
00060
00061
00062 if(*S == 0)
00063 *H = -1;
00064 else
00065 {
00066 switch(maxValue)
00067 {
00068 case 0:
00069 if(G >= B)
00070 *H = (120 * (G - B) + delta) / (2 * delta);
00071 else
00072 *H = (120 * (G - B + delta) + delta) / (2 * delta) + 300;
00073 break;
00074 case 1:
00075 if(B > R)
00076 *H = 120 + (120 * (B - R) + delta) / (2 * delta);
00077 else
00078 *H = 60 + (120 * (B - R + delta) + delta) / (2 * delta);
00079 break;
00080 case 2:
00081 if(R > G)
00082 *H = 240 + (120 * (R - G) + delta) / (2 * delta);
00083 else
00084 *H = 180 + (120 * (R - G + delta) + delta) / (2 * delta);
00085 break;
00086 }
00087 }
00088 }
00089
00090 void hsv_to_rgb(int H, int S, int V, int *R, int *G, int *B)
00091 {
00092 *R = *G = *B = V;
00093
00094 if (S != 0 && H != -1) {
00095
00096 if (H >= 360) {
00097
00098 H %= 360;
00099 }
00100
00101 unsigned int f = H % 60;
00102 H /= 60;
00103 unsigned int p = static_cast<unsigned int>(2*V*(255-S)+255)/510;
00104 unsigned int q, t;
00105
00106 if (H & 1) {
00107 q = static_cast<unsigned int>(2 * V * (15300 - S * f) + 15300) / 30600;
00108 switch (H) {
00109 case 1:
00110 *R = static_cast<int>(q);
00111 *G = static_cast<int>(V);
00112 *B = static_cast<int>(p);
00113 break;
00114 case 3:
00115 *R = static_cast<int>(p);
00116 *G = static_cast<int>(q);
00117 *B = static_cast<int>(V);
00118 break;
00119 case 5:
00120 *R = static_cast<int>(V);
00121 *G = static_cast<int>(p);
00122 *B = static_cast<int>(q);
00123 break;
00124 }
00125 } else {
00126 t = static_cast<unsigned int>(2 * V * (15300 - (S * (60 - f))) + 15300) / 30600;
00127 switch (H) {
00128 case 0:
00129 *R = static_cast<int>(V);
00130 *G = static_cast<int>(t);
00131 *B = static_cast<int>(p);
00132 break;
00133 case 2:
00134 *R = static_cast<int>(p);
00135 *G = static_cast<int>(V);
00136 *B = static_cast<int>(t);
00137 break;
00138 case 4:
00139 *R = static_cast<int>(t);
00140 *G = static_cast<int>(p);
00141 *B = static_cast<int>(V);
00142 break;
00143 }
00144 }
00145 }
00146 }
00147
00148 #define EPSILON 1e-6
00149 #define UNDEFINED_HUE -1
00150
00151 void RGBToHSV(float r, float g, float b, float *h, float *s, float *v)
00152 {
00153 float max = QMAX(r, QMAX(g, b));
00154 float min = QMIN(r, QMIN(g, b));
00155
00156 *v = max;
00157
00158 if (max > EPSILON) {
00159 *s = (max - min) / max;
00160 } else {
00161 *s = 0;
00162 }
00163
00164 if (*s < EPSILON) {
00165 *h = UNDEFINED_HUE;
00166 } else {
00167 float delta = max - min;
00168
00169 if (r == max) {
00170 *h = (g - b) / delta;
00171 } else if (g == max) {
00172 *h = 2 + (b - r) / delta;
00173 } else {
00174 *h = 4 + (r - g) / delta;
00175 }
00176
00177 *h *= 60;
00178 if (*h < 0) {
00179 *h += 360;
00180 }
00181 }
00182 }
00183
00184 void HSVToRGB(float h, float s, float v, float *r, float *g, float *b)
00185 {
00186 if (s < EPSILON || h == UNDEFINED_HUE) {
00187
00188
00189 *r = v;
00190 *g = v;
00191 *b = v;
00192 } else {
00193 float f, p, q, t;
00194 int i;
00195
00196 if (h > 360 - EPSILON) {
00197 h -= 360;
00198 }
00199
00200 h /= 60;
00201 i = static_cast<int>(floor(h));
00202 f = h - i;
00203 p = v * (1 - s);
00204 q = v * (1 - (s * f));
00205 t = v * (1 - (s * (1 - f)));
00206
00207 switch (i) {
00208 case 0:
00209 *r = v;
00210 *g = t;
00211 *b = p;
00212 break;
00213 case 1:
00214 *r = q;
00215 *g = v;
00216 *b = p;
00217 break;
00218 case 2:
00219 *r = p;
00220 *g = v;
00221 *b = t;
00222 break;
00223 case 3:
00224 *r = p;
00225 *g = q;
00226 *b = v;
00227 break;
00228 case 4:
00229 *r = t;
00230 *g = p;
00231 *b = v;
00232 break;
00233 case 5:
00234 *r = v;
00235 *g = p;
00236 *b = q;
00237 break;
00238 }
00239 }
00240 }
00241
00242 void rgb_to_hls(Q_UINT8 red, Q_UINT8 green, Q_UINT8 blue, float * hue, float * lightness, float * saturation)
00243 {
00244 float r = red / 255.0;
00245 float g = green / 255.0;
00246 float b = blue / 255.0;
00247 float h = 0;
00248 float l = 0;
00249 float s = 0;
00250
00251 float max, min, delta;
00252
00253 max = QMAX(r, g);
00254 max = QMAX(max, b);
00255
00256 min = QMIN(r, g);
00257 min = QMIN(min, b);
00258
00259 delta = max - min;
00260
00261 l = (max + min) / 2;
00262
00263 if (delta == 0) {
00264
00265 h = 0;
00266 s = 0;
00267 }
00268 else {
00269 if ( l < 0.5)
00270 s = delta / ( max + min );
00271 else
00272 s = delta / ( 2 - max - min );
00273
00274 float delta_r, delta_g, delta_b;
00275
00276 delta_r = (( max - r ) / 6 ) / delta;
00277 delta_g = (( max - g ) / 6 ) / delta;
00278 delta_b = (( max - b ) / 6 ) / delta;
00279
00280 if ( r == max )
00281 h = delta_b - delta_g;
00282 else if ( g == max)
00283 h = ( 1.0 / 3 ) + delta_r - delta_b;
00284 else if ( b == max)
00285 h = ( 2.0 / 3 ) + delta_g - delta_r;
00286
00287 if (h < 0) h += 1;
00288 if (h > 1) h += 1;
00289
00290 }
00291
00292 *hue = h * 360;
00293 *saturation = s;
00294 *lightness = l;
00295 }
00296
00297 float hue_value(float n1, float n2, float hue)
00298 {
00299 if (hue > 360 )
00300 hue = hue -360;
00301 else if (hue < 0 )
00302 hue = hue +360;
00303 if (hue < 60 )
00304 return n1 + (((n2 - n1) * hue) / 60);
00305 else if (hue < 180 )
00306 return n2;
00307 else if (hue < 240 )
00308 return n1 + (((n2 - n1) * (240 - hue)) / 60);
00309 else return n1;
00310 }
00311
00312
00313 void hls_to_rgb(float h, float l, float s, Q_UINT8 * r, Q_UINT8 * g, Q_UINT8 * b)
00314 {
00315 float m1, m2;
00316
00317 if (l <= 0.5 )
00318 m2 = l * ( 1 + s );
00319 else
00320 m2 = l + s - l * s;
00321
00322 m1 = 2 * l - m2;
00323
00324 *r = (Q_UINT8)(hue_value(m1, m2, h + 120) * 255 + 0.5);
00325 *g = (Q_UINT8)(hue_value(m1, m2, h) * 255 + 0.5);
00326 *b = (Q_UINT8)(hue_value(m1, m2, h - 120) * 255 + 0.5);
00327
00328 }
00329
00330 void rgb_to_hls(Q_UINT8 r, Q_UINT8 g, Q_UINT8 b, int * h, int * l, int * s)
00331 {
00332 float hue, saturation, lightness;
00333
00334 rgb_to_hls(r, g, b, &hue, &lightness, &saturation);
00335 *h = (int)(hue + 0.5);
00336 *l = (int)(lightness * 255 + 0.5);
00337 *s = (int)(saturation * 255 + 0.5);
00338 }
00339
00340 void hls_to_rgb(int h, int l, int s, Q_UINT8 * r, Q_UINT8 * g, Q_UINT8 * b)
00341 {
00342 float hue = h;
00343 float lightness = l / 255.0;
00344 float saturation = s / 255.0;
00345
00346 hls_to_rgb(hue, lightness, saturation, r, g, b);
00347 }
00348
00349
00350
00351
00352
00353
00354
00355 void RGBToHSL(float r, float g, float b, float *h, float *s, float *l)
00356 {
00357 float v;
00358 float m;
00359 float vm;
00360 float r2, g2, b2;
00361
00362 v = QMAX(r,g);
00363 v = QMAX(v,b);
00364 m = QMIN(r,g);
00365 m = QMIN(m,b);
00366
00367 if ((*l = (m + v) / 2.0) <= 0.0) {
00368 *h = UNDEFINED_HUE;
00369 *s = 0;
00370 return;
00371 }
00372 if ((*s = vm = v - m) > 0.0) {
00373 *s /= (*l <= 0.5) ? (v + m ) :
00374 (2.0 - v - m) ;
00375 } else {
00376 *h = UNDEFINED_HUE;
00377 return;
00378 }
00379
00380
00381 r2 = (v - r) / vm;
00382 g2 = (v - g) / vm;
00383 b2 = (v - b) / vm;
00384
00385 if (r == v)
00386 *h = (g == m ? 5.0 + b2 : 1.0 - g2);
00387 else if (g == v)
00388 *h = (b == m ? 1.0 + r2 : 3.0 - b2);
00389 else
00390 *h = (r == m ? 3.0 + g2 : 5.0 - r2);
00391
00392 *h *= 60;
00393 }
00394
00395 void HSLToRGB(float h, float sl, float l, float *r, float *g, float *b)
00396
00397 {
00398 float v;
00399
00400 v = (l <= 0.5) ? (l * (1.0 + sl)) : (l + sl - l * sl);
00401 if (v <= 0) {
00402 *r = *g = *b = 0.0;
00403 } else {
00404 float m;
00405 float sv;
00406 int sextant;
00407 float fract, vsf, mid1, mid2;
00408
00409 m = l + l - v;
00410 sv = (v - m ) / v;
00411 h /= 60.0;
00412 sextant = static_cast<int>(h);
00413 fract = h - sextant;
00414 vsf = v * sv * fract;
00415 mid1 = m + vsf;
00416 mid2 = v - vsf;
00417 switch (sextant) {
00418 case 0: *r = v; *g = mid1; *b = m; break;
00419 case 1: *r = mid2; *g = v; *b = m; break;
00420 case 2: *r = m; *g = v; *b = mid1; break;
00421 case 3: *r = m; *g = mid2; *b = v; break;
00422 case 4: *r = mid1; *g = m; *b = v; break;
00423 case 5: *r = v; *g = m; *b = mid2; break;
00424 }
00425 }
00426 }
00427