hsv.c - randomcrap - random crap programs of varying quality
(HTM) git clone git://git.codemadness.org/randomcrap
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
hsv.c (1886B)
---
1 /* HSV to RGB and vice versa.
2 Adapted from https://github.com/python/cpython/blob/3.9/Lib/colorsys.py */
3 #include <stdio.h>
4
5 /* input and output is in range 0.0 to 1.0 */
6 void
7 rgbtohsv(double r, double g, double b, double *h, double *s, double *v)
8 {
9 double minc, maxc, rc, gc, bc;
10
11 minc = maxc = r;
12 if (g > maxc)
13 maxc = g;
14 if (b > maxc)
15 maxc = b;
16
17 if (g < minc)
18 minc = g;
19 if (b < minc)
20 minc = b;
21
22 *v = maxc;
23 if (minc == maxc) {
24 *h = *s = 0.0;
25 return;
26 }
27
28 *s = (maxc - minc) / maxc;
29 rc = (maxc - r) / (maxc - minc);
30 gc = (maxc - g) / (maxc - minc);
31 bc = (maxc - b) / (maxc - minc);
32
33 if (r == maxc)
34 *h = bc - bc;
35 else if (g == maxc)
36 *h = 2.0 + rc - bc;
37 else
38 *h = 4.0 + gc - rc;
39
40 *h = (*h / 6.0);
41 /* truncate / mod 1.0, similar to fmod() */
42 *h = *h - ((double)(int)*h);
43 }
44
45 /* input and output is in range 0.0 to 1.0 */
46 void
47 hsvtorgb(double h, double s, double v, double *r, double *g, double *b)
48 {
49 double f, p, q, t;
50 int i;
51
52 if (s == 0.0) {
53 *r = *g = *b = v;
54 return;
55 }
56
57 i = h * 6.0; /* truncates to int */
58 f = (h * 6.0) - i;
59 p = v * (1.0 - s);
60 q = v * (1.0 - s * f);
61 t = v * (1.0 - s * (1.0 - f));
62 i = i % 6;
63
64 switch (i) {
65 case 0: *r = v; *g = t; *b = p; break;
66 case 1: *r = q; *g = v; *b = p; break;
67 case 2: *r = p; *g = v; *b = t; break;
68 case 3: *r = p; *g = q; *b = v; break;
69 case 4: *r = t; *g = p; *b = v; break;
70 default:*r = v; *g = p; *b = q; break;
71 }
72 }
73
74 int
75 main(void)
76 {
77 double r, g, b;
78 double h, s, v;
79
80 h = 156.3;
81 s = 100.0;
82 v = 100.0;
83
84 /* convert to range 0.0 - 1.0 */
85 h /= 360.0;
86 s /= 100.0;
87 v /= 100.0;
88
89 hsvtorgb(h, s, v, &r, &g, &b);
90
91 printf("#%02x%02x%02x\n", (int)(r * 255.0), (int)(g * 255.0), (int)(b * 255.0));
92
93 r = 0.0;
94 g = 255.0;
95 b = 154.1;
96
97 r /= 255.0;
98 g /= 255.0;
99 b /= 255.0;
100
101 rgbtohsv(r, g, b, &h, &s, &v);
102 printf("hsv: (%f, %f, %f)\n", h * 360.0, s * 100.0, v * 100.0);
103
104 return 0;
105 }