|
|
|
#pragma once
|
|
|
|
|
|
|
|
/*
|
|
|
|
Some useful utilities for RGB color manipulation
|
|
|
|
|
|
|
|
The XXXc macros don't use cast, so they can be used in array initializers.
|
|
|
|
|
|
|
|
xrgb ... 3-byte true-color RGB (8 bits per component)
|
|
|
|
rgbXX ... XX-bit color value, with equal nr of bits per component
|
|
|
|
|
|
|
|
XX_r (_g, _b) ... extract component from the color, and convert it to 0..255
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
uint8_t r;
|
|
|
|
uint8_t g;
|
|
|
|
uint8_t b;
|
|
|
|
} xrgb_t;
|
|
|
|
|
|
|
|
typedef uint32_t rgb24_t;
|
|
|
|
typedef uint16_t rgb16_t;
|
|
|
|
typedef uint16_t rgb12_t;
|
|
|
|
typedef uint8_t rgb6_t;
|
|
|
|
|
|
|
|
|
|
|
|
#define xrgb(rr, gg, bb) ((xrgb_t)xrgbc(rr, gg, bb))
|
|
|
|
// xrgb for constant array declarations
|
|
|
|
#define xrgbc(rr, gg, bb) { .r = ((uint8_t)(rr)), .g = ((uint8_t)(gg)), .b = ((uint8_t)(bb)) }
|
|
|
|
#define xrgb_r(c) ((uint8_t)(c.r))
|
|
|
|
#define xrgb_g(c) ((uint8_t)(c.g))
|
|
|
|
#define xrgb_b(c) ((uint8_t)(c.b))
|
|
|
|
#define xrgb_rgb24(c) ((((rgb24_t)c.r) << 16) | (((rgb24_t)c.g) << 8) | (((rgb24_t)c.b)))
|
|
|
|
#define xrgb_rgb15(c) (((((rgb15_t)c.r) & 0xF8) << 7) | ((((rgb15_t)c.g) & 0xF8) << 2) | ((((rgb15_t)c.b) & 0xF8) >> 3))
|
|
|
|
#define xrgb_rgb12(c) (((((rgb12_t)c.r) & 0xF0) << 4) | ((((rgb12_t)c.g) & 0xF0)) | ((((rgb12_t)c.b) & 0xF0) >> 4))
|
|
|
|
#define xrgb_rgb6(c) (((((rgb6_t)c.r) & 0xC0) >> 2) | ((((rgb6_t)c.g) & 0xC0) >> 4) | ((((rgb6_t)c.b) & 0xC0) >> 6))
|
|
|
|
|
|
|
|
|
|
|
|
#define rgb24c(r,g,b) (((((rgb24_t)r) & 0xFF) << 16) | ((((rgb24_t)g) & 0xFF) << 8) | (((rgb24_t)b) & 0xFF))
|
|
|
|
#define rgb24(r,g,b) ((rgb24_t) rgb24(r,g,b))
|
|
|
|
|
|
|
|
#define rgb24_r(c) ((((rgb24_t) (c)) >> 16) & 0xFF)
|
|
|
|
#define rgb24_g(c) ((((rgb24_t) (c)) >> 8) & 0xFF)
|
|
|
|
#define rgb24_b(c) ((((rgb24_t) (c)) >> 0) & 0xFF)
|
|
|
|
#define rgb24_xrgb(c) xrgb(rgb24_r(c), rgb24_g(c), rgb24_b(c))
|
|
|
|
#define rgb24_xrgbc(c) xrgbc(rgb24_r(c), rgb24_g(c), rgb24_b(c))
|
|
|
|
|
|
|
|
|
|
|
|
#define rgb15(r,g,b) ((rgb16_t) rgb15c(r,g,b))
|
|
|
|
#define rgb15c(r,g,b) (((r & 0x1F) << 10) | ((g & 0x1F) << 5) | (b & 0x1F))
|
|
|
|
|
|
|
|
#define rgb15_r(c) ((((rgb15_t) (c)) & 0x7C00) >> 7)
|
|
|
|
#define rgb15_g(c) ((((rgb15_t) (c)) & 0x3E0) >> 2)
|
|
|
|
#define rgb15_b(c) ((((rgb15_t) (c)) & 0x1F) << 3)
|
|
|
|
#define rgb15_xrgb(c) xrgb(rgb15_r(c), rgb15_g(c), rgb15_b(c))
|
|
|
|
#define rgb15_rgb24(c) rgb24(rgb15_r(c), rgb15_g(c), rgb15_b(c))
|
|
|
|
#define rgb15_rgb24c(c) rgb24c(rgb15_r(c), rgb15_g(c), rgb15_b(c))
|
|
|
|
|
|
|
|
|
|
|
|
#define rgb12(r,g,b) ((rgb12_t) rgb12c(r,g,b))
|
|
|
|
#define rgb12c(r,g,b) (((r & 0xF) << 8) | ((g & 0xF) << 4) | (b & 0xF))
|
|
|
|
|
|
|
|
#define rgb12_r(c) ((((rgb12_t) (c)) & 0xF00) >> 4)
|
|
|
|
#define rgb12_g(c) (((rgb12_t) (c)) & 0xF0)
|
|
|
|
#define rgb12_b(c) (((r(rgb12_t) (c)gb) & 0x0F) << 4)
|
|
|
|
#define rgb12_xrgb(c) xrgb(rgb12_r(c), rgb12_g(c), rgb12_b(c))
|
|
|
|
#define rgb12_xrgbc(c) xrgbc(rgb12_r(c), rgb12_g(c), rgb12_b(c))
|
|
|
|
#define rgb12_rgb24(c) rgb24(rgb12_r(c), rgb12_g(c), rgb12_b(c))
|
|
|
|
#define rgb12_rgb24c(c) rgb24c(rgb12_r(c), rgb12_g(c), rgb12_b(c))
|
|
|
|
|
|
|
|
|
|
|
|
#define rgb6(r,g,b) ((rgb6_t) rgb6c(r,g,b))
|
|
|
|
#define rgb6c(r,g,b) (((r & 3) << 4) | ((g & 3) << 2) | (b & 3))
|
|
|
|
|
|
|
|
#define rgb6_r(c) ((((rgb6_t) (c)) & 0x30) << 2)
|
|
|
|
#define rgb6_g(c) ((((rgb6_t) (c)) & 0xC) << 4)
|
|
|
|
#define rgb6_b(c) ((((rgb6_t) (c)) & 0x3) << 6)
|
|
|
|
#define rgb6_xrgb(c) xrgb(rgb6_r(c), rgb6_g(c), rgb6_b(c))
|
|
|
|
#define rgb6_xrgbc(c) xrgbc(rgb6_r(c), rgb6_g(c), rgb6_b(c))
|
|
|
|
#define rgb6_rgb24(c) rgb24(rgb6_r(c), rgb6_g(c), rgb6_b(c))
|
|
|
|
#define rgb6_rgb24c(c) rgb24c(rgb6_r(c), rgb6_g(c), rgb6_b(c))
|
|
|
|
|
|
|
|
#define add_xrgb(x, y) ((xrgb_t) { (((y).r > (255 - (x).r)) ? 255 : ((x).r + (y).r)), (((y).g > (255 - (x).g)) ? 255 : ((x).g + (y).g)), (((y).b > 255 - (x).b) ? 255 : ((x).b + (y).b)) })
|
|
|
|
|