1use core::convert::TryInto;
2
3use embedded_graphics::{
4 pixelcolor::{raw::RawU24, Rgb888},
5 prelude::*,
6};
7
8/// Color table.
9///
10/// This struct provides access to the color table in a BMP file. Use
11/// [`RawBmp::color_table`](crate::RawBmp::color_table) to get a reference to the color table of an
12/// image.
13///
14/// Accessing the color table directly isn't necessary if images are drawn to an
15/// [`embedded_graphics`] [`DrawTarget`](embedded_graphics::draw_target::DrawTarget). The conversion
16/// of color indices to actual colors will be handled by [`Bmp`].
17///
18/// [`Bmp`]: crate::Bmp
19#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
20pub struct ColorTable<'a> {
21 data: &'a [u8],
22}
23
24impl<'a> ColorTable<'a> {
25 pub(crate) const fn new(data: &'a [u8]) -> Self {
26 Self { data }
27 }
28
29 /// Returns the number of entries.
30 pub const fn len(&self) -> usize {
31 self.data.len() / 4
32 }
33
34 /// Returns a color table entry.
35 ///
36 /// `None` is returned if `index` is out of bounds.
37 pub fn get(&self, index: u32) -> Option<Rgb888> {
38 // MSRV: Experiment with slice::as_chunks when it's stabilized
39
40 let offset: usize = index as usize * 4;
41 let bytes: &[u8] = self.data.get(index:offset..offset + 4)?;
42
43 let raw: u32 = u32::from_le_bytes(bytes.try_into().unwrap());
44
45 Some(RawU24::from_u32(raw).into())
46 }
47}
48