]>
Commit | Line | Data |
---|---|---|
eee799fa LP |
1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
2 | ||
3 | #include <math.h> | |
4 | ||
5 | #include "color-util.h" | |
6 | #include "macro.h" | |
7 | ||
447bcbfc LP |
8 | void rgb_to_hsv(double r, double g, double b, |
9 | double *ret_h, double *ret_s, double *ret_v) { | |
10 | ||
11 | assert(r >= 0 && r <= 1); | |
12 | assert(g >= 0 && g <= 1); | |
13 | assert(b >= 0 && b <= 1); | |
14 | assert(ret_h); | |
15 | assert(ret_s); | |
16 | assert(ret_v); | |
17 | ||
18 | double max_color = fmax(r, fmax(g, b)); | |
19 | double min_color = fmin(r, fmin(g, b)); | |
20 | double delta = max_color - min_color; | |
21 | ||
22 | *ret_v = max_color * 100.0; | |
23 | ||
24 | if (max_color > 0) | |
25 | *ret_s = delta / max_color * 100.0; | |
26 | else { | |
27 | *ret_s = 0; | |
28 | *ret_h = NAN; | |
29 | return; | |
30 | } | |
31 | ||
32 | if (delta > 0) { | |
33 | if (r >= max_color) | |
34 | *ret_h = 60 * fmod((g - b) / delta, 6); | |
35 | else if (g >= max_color) | |
36 | *ret_h = 60 * (((b - r) / delta) + 2); | |
37 | else if (b >= max_color) | |
38 | *ret_h = 60 * (((r - g) / delta) + 4); | |
39 | ||
40 | *ret_h = fmod(*ret_h, 360); | |
41 | } else | |
42 | *ret_h = NAN; | |
43 | } | |
44 | ||
eee799fa LP |
45 | void hsv_to_rgb(double h, double s, double v, |
46 | uint8_t* ret_r, uint8_t *ret_g, uint8_t *ret_b) { | |
47 | ||
48 | double c, x, m, r, g, b; | |
49 | ||
50 | assert(s >= 0 && s <= 100); | |
51 | assert(v >= 0 && v <= 100); | |
52 | assert(ret_r); | |
53 | assert(ret_g); | |
54 | assert(ret_b); | |
55 | ||
56 | h = fmod(h, 360); | |
57 | c = (s / 100.0) * (v / 100.0); | |
58 | x = c * (1 - fabs(fmod(h / 60.0, 2) - 1)); | |
59 | m = (v / 100) - c; | |
60 | ||
61 | if (h >= 0 && h < 60) | |
62 | r = c, g = x, b = 0.0; | |
63 | else if (h >= 60 && h < 120) | |
64 | r = x, g = c, b = 0.0; | |
65 | else if (h >= 120 && h < 180) | |
66 | r = 0.0, g = c, b = x; | |
67 | else if (h >= 180 && h < 240) | |
68 | r = 0.0, g = x, b = c; | |
69 | else if (h >= 240 && h < 300) | |
70 | r = x, g = 0.0, b = c; | |
71 | else | |
72 | r = c, g = 0.0, b = x; | |
73 | ||
74 | *ret_r = (uint8_t) ((r + m) * 255); | |
75 | *ret_g = (uint8_t) ((g + m) * 255); | |
76 | *ret_b = (uint8_t) ((b + m) * 255); | |
77 | } |