From 1af9612b3448b261e7965bc4fd241dc69f3b4769 Mon Sep 17 00:00:00 2001 From: Simon Brummer Date: Tue, 15 Mar 2016 18:01:12 +0100 Subject: [PATCH] sys/color: added RGB inversion and complementary color --- sys/color/color.c | 18 ++++++++++++++ sys/include/color.h | 29 ++++++++++++++++++++++ tests/unittests/tests-color/tests-color.c | 30 +++++++++++++++++++++++ 3 files changed, 77 insertions(+) diff --git a/sys/color/color.c b/sys/color/color.c index f6a57b412465..390b793c2728 100644 --- a/sys/color/color.c +++ b/sys/color/color.c @@ -15,6 +15,7 @@ * * @author Hauke Petersen * @author Cenk Gündoğan + * @author Simon Brummer * * @} */ @@ -175,3 +176,20 @@ void color_rgb2str(const color_rgb_t *rgb, char* str) tmp = rgb->b & 0x0F; str[5] = (tmp > 9) ? ('A' - 10 + tmp) : ('0' + tmp); } + +void color_rgb_complementary(const color_rgb_t *rgb, color_rgb_t *comp_rgb) +{ + uint8_t max = 0; + uint8_t min = 0; + uint16_t val = 0; + + max = (rgb->r > rgb->g) ? rgb->r : rgb->g; + max = (rgb->b > max) ? rgb->b : max; + min = (rgb->r < rgb->g) ? rgb->r : rgb->g; + min = (rgb->b < min) ? rgb->b : min; + val = max + min; + + comp_rgb->r = val - rgb->r; + comp_rgb->g = val - rgb->g; + comp_rgb->b = val - rgb->b; +} diff --git a/sys/include/color.h b/sys/include/color.h index b20e03d16bae..0ad5c0e7adec 100644 --- a/sys/include/color.h +++ b/sys/include/color.h @@ -17,6 +17,7 @@ * * @author Hauke Petersen * @author Cenk Gündoğan + * @author Simon Brummer */ #ifndef __COLOR_H @@ -104,6 +105,34 @@ void color_str2rgb(const char *str, color_rgb_t *color); */ void color_rgb2str(const color_rgb_t *rgb, char *str); +/** + * @brief Invert a given rgb color + * + * @pre ((rgb != NULL) && (inv_rgb != NULL)) + * + * @param[in] rgb Input rgb color, that should be converted. Must be NOT NULL + * @param[out] inv_rgb Output rgb color, result of the conversion. Must be NOT NULL + */ +static inline void color_rgb_invert(const color_rgb_t *rgb, color_rgb_t *inv_rgb) +{ + inv_rgb->r = rgb->r ^ 0xFF; + inv_rgb->g = rgb->g ^ 0xFF; + inv_rgb->b = rgb->b ^ 0xFF; +} + +/** + * @brief Calculate the complementary color of a given rgb color. + * + * @note Complementary color calculation according to adobe illustator calculations. + * See https://helpx.adobe.com/illustrator/using/adjusting-colors.html + * + * @pre ((rgb != NULL) && (comp_rgb != NULL)) + * + * @param[in] rgb Input rgb color. Must be NOT NULL + * @param[out] comp_rgb Output rgb color, result of the complementary color calculation. Must be NOT NULL + */ +void color_rgb_complementary(const color_rgb_t *rgb, color_rgb_t *comp_rgb); + #ifdef __cplusplus } #endif diff --git a/tests/unittests/tests-color/tests-color.c b/tests/unittests/tests-color/tests-color.c index 0ae9bb0f5728..1c57b671e5f4 100644 --- a/tests/unittests/tests-color/tests-color.c +++ b/tests/unittests/tests-color/tests-color.c @@ -73,6 +73,34 @@ static void test_rgb2hex__success(void) TEST_ASSERT_EQUAL_INT(0x000AB13C, hex); } +static void test_rgb_invert__success(void) +{ + const color_rgb_t col = {.r = 100, .g = 128, .b = 0}; + const color_rgb_t res = {.r = 155, .g = 127, .b = 255}; + color_rgb_t tmp; + + color_rgb_invert(&col, &tmp); + + TEST_ASSERT_EQUAL_INT(res.r, tmp.r); + TEST_ASSERT_EQUAL_INT(res.g, tmp.g); + TEST_ASSERT_EQUAL_INT(res.b, tmp.b); +} + + +static void test_rgb_complementary__success(void) +{ + /* See example: https://helpx.adobe.com/illustrator/using/adjusting-colors.html */ + const color_rgb_t col = {.r = 102, .g = 153, .b = 51}; + const color_rgb_t res = {.r = 102, .g = 51, .b = 153}; + color_rgb_t tmp; + + color_rgb_complementary(&col, &tmp); + + TEST_ASSERT_EQUAL_INT(res.r, tmp.r); + TEST_ASSERT_EQUAL_INT(res.g, tmp.g); + TEST_ASSERT_EQUAL_INT(res.b, tmp.b); +} + Test *tests_color_tests(void) { EMB_UNIT_TESTFIXTURES(fixtures) { @@ -81,6 +109,8 @@ Test *tests_color_tests(void) new_TestFixture(test_hex2rgb__success), new_TestFixture(test_rgb2hex__success), new_TestFixture(test_rgb2str__success), + new_TestFixture(test_rgb_invert__success), + new_TestFixture(test_rgb_complementary__success), }; EMB_UNIT_TESTCALLER(color_tests, NULL, NULL, fixtures);