]>
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); | |
447bcbfc LP |
14 | |
15 | double max_color = fmax(r, fmax(g, b)); | |
16 | double min_color = fmin(r, fmin(g, b)); | |
17 | double delta = max_color - min_color; | |
18 | ||
f9bc96f6 LP |
19 | if (ret_v) |
20 | *ret_v = max_color * 100.0; | |
447bcbfc | 21 | |
f9bc96f6 LP |
22 | if (max_color <= 0) { |
23 | if (ret_s) | |
24 | *ret_s = 0; | |
25 | if (ret_h) | |
26 | *ret_h = NAN; | |
447bcbfc LP |
27 | return; |
28 | } | |
29 | ||
f9bc96f6 LP |
30 | if (ret_s) |
31 | *ret_s = delta / max_color * 100.0; | |
32 | ||
33 | if (ret_h) { | |
34 | if (delta > 0) { | |
35 | if (r >= max_color) | |
36 | *ret_h = 60 * fmod((g - b) / delta, 6); | |
37 | else if (g >= max_color) | |
38 | *ret_h = 60 * (((b - r) / delta) + 2); | |
39 | else if (b >= max_color) | |
40 | *ret_h = 60 * (((r - g) / delta) + 4); | |
41 | ||
42 | *ret_h = fmod(*ret_h, 360); | |
43 | } else | |
44 | *ret_h = NAN; | |
45 | } | |
447bcbfc LP |
46 | } |
47 | ||
eee799fa LP |
48 | void hsv_to_rgb(double h, double s, double v, |
49 | uint8_t* ret_r, uint8_t *ret_g, uint8_t *ret_b) { | |
50 | ||
51 | double c, x, m, r, g, b; | |
52 | ||
53 | assert(s >= 0 && s <= 100); | |
54 | assert(v >= 0 && v <= 100); | |
55 | assert(ret_r); | |
56 | assert(ret_g); | |
57 | assert(ret_b); | |
58 | ||
59 | h = fmod(h, 360); | |
60 | c = (s / 100.0) * (v / 100.0); | |
61 | x = c * (1 - fabs(fmod(h / 60.0, 2) - 1)); | |
62 | m = (v / 100) - c; | |
63 | ||
64 | if (h >= 0 && h < 60) | |
65 | r = c, g = x, b = 0.0; | |
66 | else if (h >= 60 && h < 120) | |
67 | r = x, g = c, b = 0.0; | |
68 | else if (h >= 120 && h < 180) | |
69 | r = 0.0, g = c, b = x; | |
70 | else if (h >= 180 && h < 240) | |
71 | r = 0.0, g = x, b = c; | |
72 | else if (h >= 240 && h < 300) | |
73 | r = x, g = 0.0, b = c; | |
74 | else | |
75 | r = c, g = 0.0, b = x; | |
76 | ||
77 | *ret_r = (uint8_t) ((r + m) * 255); | |
78 | *ret_g = (uint8_t) ((g + m) * 255); | |
79 | *ret_b = (uint8_t) ((b + m) * 255); | |
80 | } |