use palette::convert::FromColorUnclamped; use palette::encoding::srgb::Srgb; use palette::Hsv; use embedded_graphics::pixelcolor::RgbColor; use embedded_graphics::pixelcolor::PixelColor; use embedded_graphics::pixelcolor::raw::RawU8; #[derive(PartialEq, Debug, Copy, Clone)] pub struct RGB8 { pub red: u8, pub green: u8, pub blue: u8 } impl RGB8 { pub const fn new(red : u8, green : u8, blue : u8) -> Self { Self { red: red, green: green, blue: blue } } } impl RgbColor for RGB8 { fn r(&self) -> u8 { self.red } fn g(&self) -> u8 { self.green } fn b(&self) -> u8 { self.blue } const MAX_R: u8 = 255; const MAX_G: u8 = 255; const MAX_B: u8 = 255; const BLACK: Self = Self::new(0, 0, 0); const WHITE: Self = Self::new(255, 255, 255); const RED: Self = Self::new(255, 0, 0); const GREEN: Self = Self::new(0, 255, 0); const BLUE: Self = Self::new(0, 0, 255); const YELLOW: Self = Self::new(255, 0, 0); const CYAN: Self = Self::new(0, 255, 0); const MAGENTA: Self = Self::new(0, 0, 255); } impl PixelColor for RGB8 { type Raw = RawU8; } impl FromColorUnclamped> for RGB8 { fn from_color_unclamped(hsv: Hsv) -> RGB8 { if hsv.saturation == 0 { return RGB8::new(hsv.value, hsv.value, hsv.value); } let region = hsv.hue.into_inner() / 43; let remainder = (hsv.hue.into_inner() - (region * 43)) * 6; let p = hsv.value.wrapping_mul(255 - hsv.saturation).wrapping_shr(8); let q = (hsv.value.wrapping_mul(255 - ((hsv.saturation.wrapping_mul(remainder)).wrapping_shr(8)))).wrapping_shr(8); let t = (hsv.value.wrapping_mul(255 - ((hsv.saturation.wrapping_mul(255 - remainder)).wrapping_shr(8)))).wrapping_shr(8); match region { 0 => RGB8::new(hsv.value, t, p), 1 => RGB8::new(q, hsv.value, p), 2 => RGB8::new(p, hsv.value, t), 3 => RGB8::new(p, q, hsv.value), 4 => RGB8::new(t, p, hsv.value), _ => RGB8::new(hsv.value, p, q) } } }