Files
Momentum-Firmware/lib/toolbox/colors.c
2023-10-09 01:27:38 +01:00

89 lines
2.1 KiB
C

// https://stackoverflow.com/a/14733008
#include "colors.h"
inline int rgbcmp(const RgbColor* a, const RgbColor* b) {
return memcmp(a, b, sizeof(RgbColor));
}
inline int hsvcmp(const HsvColor* a, const HsvColor* b) {
return memcmp(a, b, sizeof(HsvColor));
}
void hsv2rgb(const HsvColor* hsv, RgbColor* rgb) {
if(hsv->s == 0) {
rgb->r = hsv->v;
rgb->g = hsv->v;
rgb->b = hsv->v;
return;
}
uint8_t region = hsv->h / 43;
uint8_t remainder = (hsv->h - (region * 43)) * 6;
uint8_t p = (hsv->v * (255 - hsv->s)) >> 8;
uint8_t q = (hsv->v * (255 - ((hsv->s * remainder) >> 8))) >> 8;
uint8_t 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;
}
}
void rgb2hsv(const RgbColor* rgb, HsvColor* hsv) {
uint8_t rgbMin = rgb->r < rgb->g ? (rgb->r < rgb->b ? rgb->r : rgb->b) :
(rgb->g < rgb->b ? rgb->g : rgb->b);
uint8_t 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->s = 255 * ((long)rgbMax - (long)rgbMin) / hsv->v;
if(hsv->s == 0) {
hsv->h = 0;
return;
}
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);
}
}