mirror of
https://github.com/Dasharo/systemd.git
synced 2026-03-06 15:02:31 -08:00
color-util: add helper to convert RGB → HSV
We already have HSV → RGB, add the opposite operation.
This commit is contained in:
@@ -5,6 +5,43 @@
|
||||
#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) {
|
||||
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
void rgb_to_hsv(double r, double g, double b,
|
||||
double *ret_h, double *ret_s, double *ret_v);
|
||||
|
||||
void hsv_to_rgb(
|
||||
double h, double s, double v,
|
||||
uint8_t* ret_r, uint8_t *ret_g, uint8_t *ret_b);
|
||||
|
||||
@@ -57,6 +57,7 @@ simple_tests += files(
|
||||
'test-cgroup.c',
|
||||
'test-chase.c',
|
||||
'test-clock.c',
|
||||
'test-color-util.c',
|
||||
'test-compare-operator.c',
|
||||
'test-condition.c',
|
||||
'test-conf-files.c',
|
||||
|
||||
63
src/test/test-color-util.c
Normal file
63
src/test/test-color-util.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/* 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);
|
||||
Reference in New Issue
Block a user