1use figments::liber8tion::interpolate::Fract8;
2use rgb::{Grb, Rgb, Bgr};
3
4
5#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
6pub struct Milliwatts(pub u32);
7
8pub trait AsMilliwatts {
9 fn as_milliwatts(&self) -> u32;
10}
11
12impl<T: Copy> AsMilliwatts for Bgr<T> where Rgb<T>: AsMilliwatts {
13 fn as_milliwatts(&self) -> u32 {
14 Rgb::new(self.r, self.g, self.b).as_milliwatts()
15 }
16}
17
18impl<T: Copy> AsMilliwatts for Grb<T> where Rgb<T>: AsMilliwatts {
19 fn as_milliwatts(&self) -> u32 {
20 Rgb::new(self.r, self.g, self.b).as_milliwatts()
21 }
22}
23
24impl<T: Into<u32> + Copy> AsMilliwatts for Rgb<T> {
26 fn as_milliwatts(&self) -> u32 {
27 const RED_MW : u32 = 16 * 5; const GREEN_MW : u32 = 11 * 5; const BLUE_MW : u32 = 15 * 5; const DARK_MW : u32 = 5; let red = (self.r.into() * RED_MW).wrapping_shr(8);
33 let green = (self.g.into() * GREEN_MW).wrapping_shr(8);
34 let blue = (self.b.into() * BLUE_MW).wrapping_shr(8);
35
36 red + green + blue + DARK_MW
37 }
38}
39
40impl<T> AsMilliwatts for [T] where T: AsMilliwatts {
41 fn as_milliwatts(&self) -> u32 {
42 self.iter().map(|p| { p.as_milliwatts() }).sum()
43 }
44}
45
46impl<T, const S: usize> AsMilliwatts for [T; S] where T: AsMilliwatts {
47 fn as_milliwatts(&self) -> u32 {
48 self.iter().map(|p| { p.as_milliwatts() }).sum()
49 }
50}
51
52pub fn brightness_for_mw(total_mw: u32, target: Fract8, max_power: Milliwatts) -> Fract8 {
53 let target32 = target.to_raw() as u32;
54 let requested_mw = (total_mw * target32) / 256;
55
56 if requested_mw > max_power.0 {
57 Fract8::from_raw(((target32 * max_power.0) / requested_mw) as u8)
58 } else {
59 target
60 }
61}