#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);
+ assert(ret_h);
+ assert(ret_s);
+ assert(ret_v);
+
+ double max_color = fmax(r, fmax(g, b));
+ double min_color = fmin(r, fmin(g, b));
+ double delta = max_color - min_color;
+
+ *ret_v = max_color * 100.0;
+
+ if (max_color > 0)
+ *ret_s = delta / max_color * 100.0;
+ else {
+ *ret_s = 0;
+ *ret_h = NAN;
+ return;
+ }
+
+ 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) {
--- /dev/null
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "color-util.h"
+#include "tests.h"
+
+TEST(hsv_to_rgb) {
+ uint8_t r, g, b;
+
+ hsv_to_rgb(0, 0, 0, &r, &g, &b);
+ assert(r == 0 && g == 0 && b == 0);
+
+ hsv_to_rgb(60, 0, 0, &r, &g, &b);
+ assert(r == 0 && g == 0 && b == 0);
+
+ hsv_to_rgb(0, 0, 100, &r, &g, &b);
+ assert(r == 255 && g == 255 && b == 255);
+
+ hsv_to_rgb(0, 100, 100, &r, &g, &b);
+ assert(r == 255 && g == 0 && b == 0);
+
+ hsv_to_rgb(120, 100, 100, &r, &g, &b);
+ assert(r == 0 && g == 255 && b == 0);
+
+ hsv_to_rgb(240, 100, 100, &r, &g, &b);
+ assert(r == 0 && g == 0 && b == 255);
+
+ hsv_to_rgb(311, 52, 62, &r, &g, &b);
+ assert(r == 158 && g == 75 && b == 143);
+}
+
+TEST(rgb_to_hsv) {
+
+ double h, s, v;
+ rgb_to_hsv(0, 0, 0, &h, &s, &v);
+ assert(s <= 0);
+ assert(v <= 0);
+
+ rgb_to_hsv(1, 1, 1, &h, &s, &v);
+ assert(s <= 0);
+ assert(v >= 100);
+
+ rgb_to_hsv(1, 0, 0, &h, &s, &v);
+ assert(h >= 359 || h <= 1);
+ assert(s >= 100);
+ assert(v >= 100);
+
+ rgb_to_hsv(0, 1, 0, &h, &s, &v);
+ assert(h >= 119 && h <= 121);
+ assert(s >= 100);
+ assert(v >= 100);
+
+ rgb_to_hsv(0, 0, 1, &h, &s, &v);
+ assert(h >= 239 && h <= 241);
+ assert(s >= 100);
+ assert(v >= 100);
+
+ rgb_to_hsv(0.5, 0.6, 0.7, &h, &s, &v);
+ assert(h >= 209 && h <= 211);
+ assert(s >= 28 && s <= 31);
+ assert(v >= 69 && v <= 71);
+}
+
+DEFINE_TEST_MAIN(LOG_DEBUG);