summaryrefslogtreecommitdiffstats
path: root/src/shared/color-util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared/color-util.c')
-rw-r--r--src/shared/color-util.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/src/shared/color-util.c b/src/shared/color-util.c
new file mode 100644
index 0000000..9d714c0
--- /dev/null
+++ b/src/shared/color-util.c
@@ -0,0 +1,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);
+}