From 5e8efe8281206c3b7e7a5256efa74aa8561f47ae Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Mon, 14 Aug 2023 01:17:37 +0200 Subject: [PATCH] Add colors toolbox (rgb and hsv) --- firmware/targets/f7/api_symbols.csv | 2 + lib/toolbox/colors.c | 87 +++++++++++++++++++++++++++++ lib/toolbox/colors.h | 27 +++++++++ 3 files changed, 116 insertions(+) create mode 100644 lib/toolbox/colors.c create mode 100644 lib/toolbox/colors.h diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index b53c19e90..3613133bd 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1733,6 +1733,7 @@ Function,+,hex_char_to_hex_nibble,_Bool,"char, uint8_t*" Function,+,hex_char_to_uint8,_Bool,"char, char, uint8_t*" Function,+,hex_chars_to_uint64,_Bool,"const char*, uint64_t*" Function,+,hex_chars_to_uint8,_Bool,"const char*, uint8_t*" +Function,+,hsv2rgb,RgbColor,HsvColor Function,-,hypot,double,"double, double" Function,-,hypotf,float,"float, float" Function,-,hypotl,long double,"long double, long double" @@ -2555,6 +2556,7 @@ Function,-,rfal_platform_spi_acquire,void, Function,-,rfal_platform_spi_release,void, Function,-,rfal_set_callback_context,void,void* Function,-,rfal_set_state_changed_callback,void,RfalStateChangedCallback +Function,+,rgb2hsv,HsvColor,RgbColor Function,+,rgb_backlight_get_color_count,uint8_t, Function,+,rgb_backlight_get_color_text,const char*,uint8_t Function,+,rgb_backlight_get_settings,RGBBacklightSettings*, diff --git a/lib/toolbox/colors.c b/lib/toolbox/colors.c new file mode 100644 index 000000000..0de9ecf85 --- /dev/null +++ b/lib/toolbox/colors.c @@ -0,0 +1,87 @@ +// https://stackoverflow.com/a/14733008 + +#include "colors.h" + +RgbColor hsv2rgb(HsvColor hsv) { + RgbColor rgb; + uint8_t region, remainder, p, q, t; + + if(hsv.s == 0) { + rgb.r = hsv.v; + rgb.g = hsv.v; + rgb.b = hsv.v; + return rgb; + } + + region = hsv.h / 43; + remainder = (hsv.h - (region * 43)) * 6; + + p = (hsv.v * (255 - hsv.s)) >> 8; + q = (hsv.v * (255 - ((hsv.s * remainder) >> 8))) >> 8; + t = (hsv.v * (255 - ((hsv.s * (255 - remainder)) >> 8))) >> 8; + + switch(region) { + case 0: + rgb.r = hsv.v; + rgb.g = t; + rgb.b = p; + break; + case 1: + rgb.r = q; + rgb.g = hsv.v; + rgb.b = p; + break; + case 2: + rgb.r = p; + rgb.g = hsv.v; + rgb.b = t; + break; + case 3: + rgb.r = p; + rgb.g = q; + rgb.b = hsv.v; + break; + case 4: + rgb.r = t; + rgb.g = p; + rgb.b = hsv.v; + break; + default: + rgb.r = hsv.v; + rgb.g = p; + rgb.b = q; + break; + } + + return rgb; +} + +HsvColor rgb2hsv(RgbColor rgb) { + HsvColor hsv; + uint8_t rgbMin, rgbMax; + + rgbMin = rgb.r < rgb.g ? (rgb.r < rgb.b ? rgb.r : rgb.b) : (rgb.g < rgb.b ? rgb.g : rgb.b); + rgbMax = rgb.r > rgb.g ? (rgb.r > rgb.b ? rgb.r : rgb.b) : (rgb.g > rgb.b ? rgb.g : rgb.b); + + hsv.v = rgbMax; + if(hsv.v == 0) { + hsv.h = 0; + hsv.s = 0; + return hsv; + } + + hsv.s = 255 * ((long)rgbMax - (long)rgbMin) / hsv.v; + if(hsv.s == 0) { + hsv.h = 0; + return hsv; + } + + if(rgbMax == rgb.r) + hsv.h = 0 + 43 * (rgb.g - rgb.b) / (rgbMax - rgbMin); + else if(rgbMax == rgb.g) + hsv.h = 85 + 43 * (rgb.b - rgb.r) / (rgbMax - rgbMin); + else + hsv.h = 171 + 43 * (rgb.r - rgb.g) / (rgbMax - rgbMin); + + return hsv; +} diff --git a/lib/toolbox/colors.h b/lib/toolbox/colors.h new file mode 100644 index 000000000..8fc930dbf --- /dev/null +++ b/lib/toolbox/colors.h @@ -0,0 +1,27 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct RgbColor { + uint8_t r; + uint8_t g; + uint8_t b; +} RgbColor; + +typedef struct HsvColor { + uint8_t h; + uint8_t s; + uint8_t v; +} HsvColor; + +RgbColor hsv2rgb(HsvColor hsv); + +HsvColor rgb2hsv(RgbColor rgb); + +#ifdef __cplusplus +} +#endif