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