1 #include "color_helpers.h"
2 /*
3 * Color space conversion helper routines
4 * Convert between rgb and hsv and between rgb and hls
5 */
6
7 void
__imlib_rgb_to_hsv(int r,int g,int b,float * h,float * s,float * v)8 __imlib_rgb_to_hsv(int r, int g, int b, float *h, float *s, float *v)
9 {
10 float min, max, delta;
11
12 min = (((r < g) ? r : g) < b) ? ((r < g) ? r : g) : b;
13 max = (((r > g) ? r : g) > b) ? ((r > g) ? r : g) : b;
14
15 *v = max / 255.0;
16 delta = (max - min);
17 if (delta == 0)
18 {
19 *h = 0.0;
20 *s = 0.0;
21 return;
22 }
23 *s = delta / max;
24 if (r == max)
25 *h = (g - b) / delta;
26 else if (g == max)
27 *h = 2.0 + (b - r) / delta;
28 else
29 *h = 4.0 + (r - g) / delta;
30 *h *= 60.0;
31 if (*h < 0)
32 *h += 360.0;
33 }
34
35 void
__imlib_hsv_to_rgb(float h,float s,float v,int * r,int * g,int * b)36 __imlib_hsv_to_rgb(float h, float s, float v, int *r, int *g, int *b)
37 {
38 float f, vf;
39 int i, p, q, t, vv;
40
41 vf = 255.0 * v;
42 vv = (int)round(vf);
43
44 if (s == 0.0)
45 {
46 *r = *g = *b = vv;
47 return;
48 }
49
50 h /= 60.0;
51 i = floor(h);
52 f = h - (float)i;
53 p = (int)round(vf * (1.0 - s));
54 q = (int)round(vf * (1.0 - (s * f)));
55 t = (int)round(vf * (1.0 - s * (1.0 - f)));
56
57 switch (i % 6)
58 {
59 case 0:
60 *r = vv;
61 *g = t;
62 *b = p;
63 break;
64 case 1:
65 *r = q;
66 *g = vv;
67 *b = p;
68 break;
69 case 2:
70 *r = p;
71 *g = vv;
72 *b = t;
73 break;
74 case 3:
75 *r = p;
76 *g = q;
77 *b = vv;
78 break;
79 case 4:
80 *r = t;
81 *g = p;
82 *b = vv;
83 break;
84 case 5:
85 default:
86 *r = vv;
87 *g = p;
88 *b = q;
89 break;
90 }
91 }
92
93 void
__imlib_rgb_to_hls(int r,int g,int b,float * hue,float * lightness,float * saturation)94 __imlib_rgb_to_hls(int r, int g, int b, float *hue, float *lightness,
95 float *saturation)
96 {
97 int f;
98 float i, j, k, max, min, d;
99
100 i = ((float)r) / 255.0;
101 j = ((float)g) / 255.0;
102 k = ((float)b) / 255.0;
103
104 f = 0;
105 max = min = i;
106 if (j > max)
107 {
108 max = j;
109 f = 1;
110 }
111 else
112 min = j;
113 if (k > max)
114 {
115 max = k;
116 f = 2;
117 }
118 else if (k < min)
119 min = k;
120 d = max - min;
121
122 *lightness = (max + min) / 2.0;
123 if (d == 0)
124 {
125 *saturation = 0;
126 *hue = 0;
127 }
128 else
129 {
130 if (*lightness < 0.5)
131 *saturation = d / (max + min);
132 else
133 *saturation = d / (2 - max - min);
134 switch (f)
135 {
136 case 0:
137 *hue = (j - k) / d;
138 break;
139 case 1:
140 *hue = 2 + (k - i) / d;
141 break;
142 case 2:
143 *hue = 4 + (i - j) / d;
144 break;
145 }
146 *hue *= 60.0;
147 if (*hue < 0)
148 *hue += 360.0;
149 }
150 }
151
152 void
__imlib_hls_to_rgb(float hue,float lightness,float saturation,int * r,int * g,int * b)153 __imlib_hls_to_rgb(float hue, float lightness, float saturation, int *r, int *g,
154 int *b)
155 {
156 float m1, m2, m21, h;
157
158 if (saturation == 0)
159 *r = *g = *b = (int)(lightness * 255.0);
160 else
161 {
162 if (lightness <= 0.5)
163 m2 = lightness * (1 + saturation);
164 else
165 m2 = lightness + saturation + lightness * saturation;
166 m1 = 2 * lightness - m2;
167 m21 = m2 - m1;
168 h = hue + 120;
169 if (h > 360)
170 h -= 360;
171 else if (h < 0)
172 h += 360;
173 if (h < 60)
174 *r = (int)(255.0 * (m1 + m21 * h / 60.0));
175 else if (h < 180)
176 *r = (int)(255.0 * m2);
177 else if (h < 240)
178 *r = (int)(255.0 * (m1 + m21 * (240.0 - h) / 60.0));
179 else
180 *r = (int)(255.0 * m1);
181 h = hue;
182 if (h > 360)
183 h -= 360;
184 else if (h < 0)
185 h += 360;
186 if (h < 60)
187 *g = (int)(255.0 * (m1 + m21 * h / 60.0));
188 else if (h < 180)
189 *g = (int)(255.0 * m2);
190 else if (h < 240)
191 *g = (int)(255.0 * (m1 + m21 * (240.0 - h) / 60.0));
192 else
193 *g = (int)(255.0 * m1);
194 h = hue - 120;
195 if (h > 360)
196 h -= 360;
197 else if (h < 0)
198 h += 360;
199 if (h < 60)
200 *b = (int)(255.0 * (m1 + m21 * h / 60.0));
201 else if (h < 180)
202 *b = (int)(255.0 * m2);
203 else if (h < 240)
204 *b = (int)(255.0 * (m1 + m21 * (240.0 - h) / 60.0));
205 else
206 *b = (int)(255.0 * m1);
207 }
208 }
209