1 /*
2 * Copyright 2001 Werner Freytag - please read to the LICENSE file
3 *
4 */
5 #ifndef CONVERT_RGB_HSV_H
6 #define CONVERT_RGB_HSV_H
7
8
9 #include <math.h>
10
11
12 #define RETURN_HSV(h, s, v) { H = h; S = s; V = v; return; }
13 #define RETURN_RGB(r, g, b) { R = r; G = g; B = b; return; }
14
15 #define UNDEFINED 0
16
17
18 inline void
RGB_to_HSV(float R,float G,float B,float & H,float & S,float & V)19 RGB_to_HSV(float R, float G, float B, float& H, float& S, float& V)
20 {
21 // RGB are each on [0, 1]. S and max are returned on [0, 1] and H is
22 // returned on [0, 6]. Exception: H is returned UNDEFINED if S==0.
23
24 float min, max;
25
26 if (R > G) {
27 if (R > B) {
28 max = R;
29 min = G > B ? B : G;
30 } else {
31 max = B;
32 min = G;
33 }
34 }
35 else {
36 if (G > B) {
37 max = G;
38 min = R > B ? B : R;
39 } else {
40 max = B;
41 min = R;
42 }
43 }
44
45 if (max == min)
46 RETURN_HSV(UNDEFINED, 0, max);
47
48 float dist = max - min;
49
50 float f = (R == min)
51 ? G - B
52 : ((G == min) ? B - R : R - G);
53 float i = (R == min)
54 ? 3
55 : ((G == min) ? 5 : 1);
56 float h = i - f / dist;
57
58 while (h >= 6.0)
59 h -= 6.0;
60
61 RETURN_HSV(h, dist/max, max);
62 }
63
64
65 inline void
HSV_to_RGB(float h,float s,float v,float & R,float & G,float & B)66 HSV_to_RGB(float h, float s, float v, float& R, float& G, float& B)
67 {
68 // H is given on [0, 6] or UNDEFINED. S and V are given on [0, 1].
69 // RGB are each returned on [0, 1].
70
71 int i = (int)floor(h);
72
73 float f = h - i;
74
75 if ( !(i & 1) )
76 f = 1 - f; // if i is even
77
78 float m = v * (1 - s);
79
80 float n = v * (1 - s * f);
81
82 switch (i) {
83 case 6:
84 case 0:
85 RETURN_RGB(v, n, m);
86
87 case 1:
88 RETURN_RGB(n, v, m);
89
90 case 2:
91 RETURN_RGB(m, v, n)
92
93 case 3:
94 RETURN_RGB(m, n, v);
95
96 case 4:
97 RETURN_RGB(n, m, v);
98
99 case 5:
100 RETURN_RGB(v, m, n);
101
102 default:
103 RETURN_RGB(0, 0, 0);
104 }
105 }
106
107
108 #endif // CONVERT_RGB_HSV_H
109