xref: /haiku/src/apps/icon-o-matic/generic/support/rgb_hsv.h (revision e81a954787e50e56a7f06f72705b7859b6ab06d1)
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
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
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