1use core::marker::PhantomData;
2
3use embedded_graphics::{
4 pixelcolor::{
5 raw::{RawU16, RawU24},
6 Rgb555, Rgb565, Rgb888,
7 },
8 prelude::*,
9};
10
11use crate::{raw_bmp::ColorType, raw_iter::RawPixels, Bmp, ColorTable, RawPixel};
12
13/// Iterator over the pixels in a BMP image.
14///
15/// See the [`pixels`](Bmp::pixels) method documentation for more information.
16#[allow(missing_debug_implementations)]
17pub struct Pixels<'a, C>
18where
19 C: PixelColor + From<Rgb555> + From<Rgb565> + From<Rgb888>,
20{
21 raw_pixels: RawPixels<'a>,
22 color_table: Option<&'a ColorTable<'a>>,
23 image_color_type: ColorType,
24 target_color_type: PhantomData<C>,
25}
26
27impl<'a, C> Pixels<'a, C>
28where
29 C: PixelColor + From<Rgb555> + From<Rgb565> + From<Rgb888>,
30{
31 pub(crate) fn new(bmp: &'a Bmp<'a, C>) -> Self {
32 let raw_pixels: RawPixels<'_> = RawPixels::new(&bmp.raw_bmp);
33
34 Self {
35 raw_pixels,
36 color_table: bmp.raw_bmp.color_table(),
37 image_color_type: bmp.raw_bmp.color_type,
38 target_color_type: PhantomData,
39 }
40 }
41}
42
43impl<C> Iterator for Pixels<'_, C>
44where
45 C: PixelColor + From<Rgb555> + From<Rgb565> + From<Rgb888>,
46{
47 type Item = Pixel<C>;
48
49 fn next(&mut self) -> Option<Self::Item> {
50 let RawPixel { position: Point, color: u32 } = self.raw_pixels.next()?;
51
52 let color: C = match self.image_color_type {
53 ColorType::Index1 | ColorType::Index4 | ColorType::Index8 => {
54 self.color_table?.get(index:color).unwrap_or_default().into()
55 }
56 ColorType::Rgb555 => Rgb555::from(RawU16::from_u32(color)).into(),
57 ColorType::Rgb565 => Rgb565::from(RawU16::from_u32(color)).into(),
58 ColorType::Rgb888 | ColorType::Xrgb8888 => Rgb888::from(RawU24::from_u32(color)).into(),
59 };
60
61 Some(Pixel(position, color))
62 }
63}
64