desaturated next block
[vrtris] / src / color.c
1 #include <math.h>
2 #include "color.h"
3
4 static float min3(float a, float b, float c)
5 {
6         if(a < b && a < c) return a;
7         return b < c ? b : c;
8 }
9
10 static float max3(float a, float b, float c)
11 {
12         if(a > b && a > c) return a;
13         return b > c ? b : c;
14 }
15
16 void rgb_to_hsv(float r, float g, float b, float *h, float *s, float *v)
17 {
18         float min, max, delta;
19
20         min = min3(r, g, b);
21         max = max3(r, g, b);
22         *v = max;
23
24         delta = max - min;
25
26         if(max != 0) {
27                 *s = delta / max;
28         } else {
29                 *s = 0;
30                 *h = -1;
31                 return;
32         }
33
34         if(!delta) delta = 1.0f;
35
36         if(r == max)
37                 *h = (g - b) / delta;
38         else if( g == max )
39                 *h = 2 + (b - r) / delta;
40         else
41                 *h = 4 + (r - g) / delta;
42
43         *h *= 60;
44         if(*h < 0) {
45                 *h += 360.0f;
46         }
47         *h /= 360.0f;
48 }
49
50 #define RETRGB(red, green, blue) \
51         do { \
52                 *r = (red); \
53                 *g = (green); \
54                 *b = (blue); \
55                 return; \
56         } while(0)
57
58 void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b)
59 {
60         float sec, frac, o, p, q;
61         int hidx;
62
63         if(s == 0.0f) {
64                 *r = *g = *b = v;
65                 return;
66         }
67
68         sec = floor(h * (360.0f / 60.0f));
69         frac = (h * (360.0f / 60.0f)) - sec;
70
71         o = v * (1.0f - s);
72         p = v * (1.0f - s * frac);
73         q = v * (1.0f - s * (1.0f - frac));
74
75         hidx = (int)sec;
76         switch(hidx) {
77         default:
78         case 0: RETRGB(v, q, o);
79         case 1: RETRGB(p, v, o);
80         case 2: RETRGB(o, v, q);
81         case 3: RETRGB(o, p, v);
82         case 4: RETRGB(q, o, v);
83         case 5: RETRGB(v, o, p);
84         }
85 }