tinybmp/
iter.rs

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::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, color } = self.raw_pixels.next()?;
51
52        let color = match self.image_color_type {
53            ColorType::Index1 | ColorType::Index4 | ColorType::Index8 => {
54                self.color_table?.get(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}