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