1use embedded_graphics_core::pixelcolor::RgbColor;
2
3use crate::dcs::BitsPerPixel;
4
5impl BitsPerPixel {
6 pub const fn from_rgb_color<C: RgbColor>() -> Self {
8 let bpp = C::MAX_R.trailing_ones() + C::MAX_G.trailing_ones() + C::MAX_B.trailing_ones();
9
10 match bpp {
11 3 => Self::Three,
12 8 => Self::Eight,
13 12 => Self::Twelve,
14 16 => Self::Sixteen,
15 18 => Self::Eighteen,
16 24 => Self::TwentyFour,
17 _ => panic!("invalid RgbColor bits per pixel"),
18 }
19 }
20}
21
22#[allow(dead_code)]
24struct TakeSkip<I> {
25 iter: I,
26 take: u32,
27 take_remaining: u32,
28 skip: u32,
29}
30
31impl<I> TakeSkip<I> {
32 #[allow(dead_code)]
33 pub fn new(iter: I, take: u32, skip: u32) -> Self {
34 Self {
35 iter,
36 take,
37 take_remaining: take,
38 skip,
39 }
40 }
41}
42
43impl<I: Iterator> Iterator for TakeSkip<I> {
44 type Item = I::Item;
45
46 fn next(&mut self) -> Option<Self::Item> {
47 if self.take_remaining > 0 {
48 self.take_remaining -= 1;
49 self.iter.next()
50 } else if self.take > 0 {
51 self.take_remaining = self.take - 1;
52 nth_u32(&mut self.iter, self.skip)
53 } else {
54 None
55 }
56 }
57}
58
59#[cfg(not(target_pointer_width = "16"))]
60#[allow(dead_code)]
61fn take_u32<I: Iterator>(iter: I, max_count: u32) -> impl Iterator<Item = I::Item> {
62 iter.take(max_count.try_into().unwrap())
63}
64
65#[cfg(target_pointer_width = "16")]
66#[allow(dead_code)]
67fn take_u32<I: Iterator>(iter: I, max_count: u32) -> impl Iterator<Item = I::Item> {
68 let mut count = 0;
69 iter.take_while(move |_| {
70 count += 1;
71 count <= max_count
72 })
73}
74
75#[cfg(not(target_pointer_width = "16"))]
76#[allow(dead_code)]
77fn nth_u32<I: Iterator>(mut iter: I, n: u32) -> Option<I::Item> {
78 iter.nth(n.try_into().unwrap())
79}
80
81#[cfg(target_pointer_width = "16")]
82#[allow(dead_code)]
83fn nth_u32<I: Iterator>(mut iter: I, n: u32) -> Option<I::Item> {
84 for _ in 0..n {
85 iter.next();
86 }
87 iter.next()
88}
89
90#[cfg(test)]
91mod test {
92 use crate::dcs::BitsPerPixel;
93 use embedded_graphics_core::pixelcolor::*;
94
95 use super::TakeSkip;
96
97 #[test]
98 fn bpp_from_rgb_color_works() {
99 assert_eq!(
100 BitsPerPixel::from_rgb_color::<Rgb565>(),
101 BitsPerPixel::Sixteen
102 );
103 assert_eq!(
104 BitsPerPixel::from_rgb_color::<Rgb666>(),
105 BitsPerPixel::Eighteen
106 );
107 assert_eq!(
108 BitsPerPixel::from_rgb_color::<Rgb888>(),
109 BitsPerPixel::TwentyFour
110 );
111 }
112
113 #[test]
114 #[should_panic]
115 fn bpp_from_rgb_color_invalid_panics() {
116 BitsPerPixel::from_rgb_color::<Rgb555>();
117 }
118
119 #[test]
120 fn take_skip_iter() {
121 let mut iter = TakeSkip::new(0..11, 3, 2);
122 assert_eq!(iter.next(), Some(0));
123 assert_eq!(iter.next(), Some(1));
124 assert_eq!(iter.next(), Some(2));
125 assert_eq!(iter.next(), Some(5));
127 assert_eq!(iter.next(), Some(6));
128 assert_eq!(iter.next(), Some(7));
129 assert_eq!(iter.next(), Some(10));
131 assert_eq!(iter.next(), None);
132 }
133
134 #[test]
135 fn take_skip_with_take_equals_zero() {
136 let mut iter = TakeSkip::new(0..11, 0, 2);
139 assert_eq!(iter.next(), None);
140 }
141}