image/codecs/bmp/
decoder.rs

1use crate::utils::vec_try_with_capacity;
2use std::cmp::{self, Ordering};
3use std::io::{self, BufRead, Seek, SeekFrom};
4use std::iter::{repeat, Rev};
5use std::slice::ChunksExactMut;
6use std::{error, fmt};
7
8use byteorder_lite::{LittleEndian, ReadBytesExt};
9
10use crate::color::ColorType;
11use crate::error::{
12    DecodingError, ImageError, ImageResult, UnsupportedError, UnsupportedErrorKind,
13};
14use crate::io::free_functions::load_rect;
15use crate::io::ReadExt;
16use crate::{ImageDecoder, ImageDecoderRect, ImageFormat};
17
18const BITMAPCOREHEADER_SIZE: u32 = 12;
19const BITMAPINFOHEADER_SIZE: u32 = 40;
20const BITMAPV2HEADER_SIZE: u32 = 52;
21const BITMAPV3HEADER_SIZE: u32 = 56;
22const BITMAPV4HEADER_SIZE: u32 = 108;
23const BITMAPV5HEADER_SIZE: u32 = 124;
24
25static LOOKUP_TABLE_3_BIT_TO_8_BIT: [u8; 8] = [0, 36, 73, 109, 146, 182, 219, 255];
26static LOOKUP_TABLE_4_BIT_TO_8_BIT: [u8; 16] = [
27    0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255,
28];
29static LOOKUP_TABLE_5_BIT_TO_8_BIT: [u8; 32] = [
30    0, 8, 16, 25, 33, 41, 49, 58, 66, 74, 82, 90, 99, 107, 115, 123, 132, 140, 148, 156, 165, 173,
31    181, 189, 197, 206, 214, 222, 230, 239, 247, 255,
32];
33static LOOKUP_TABLE_6_BIT_TO_8_BIT: [u8; 64] = [
34    0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 45, 49, 53, 57, 61, 65, 69, 73, 77, 81, 85, 89, 93,
35    97, 101, 105, 109, 113, 117, 121, 125, 130, 134, 138, 142, 146, 150, 154, 158, 162, 166, 170,
36    174, 178, 182, 186, 190, 194, 198, 202, 206, 210, 215, 219, 223, 227, 231, 235, 239, 243, 247,
37    251, 255,
38];
39
40static R5_G5_B5_COLOR_MASK: Bitfields = Bitfields {
41    r: Bitfield { len: 5, shift: 10 },
42    g: Bitfield { len: 5, shift: 5 },
43    b: Bitfield { len: 5, shift: 0 },
44    a: Bitfield { len: 0, shift: 0 },
45};
46const R8_G8_B8_COLOR_MASK: Bitfields = Bitfields {
47    r: Bitfield { len: 8, shift: 24 },
48    g: Bitfield { len: 8, shift: 16 },
49    b: Bitfield { len: 8, shift: 8 },
50    a: Bitfield { len: 0, shift: 0 },
51};
52const R8_G8_B8_A8_COLOR_MASK: Bitfields = Bitfields {
53    r: Bitfield { len: 8, shift: 16 },
54    g: Bitfield { len: 8, shift: 8 },
55    b: Bitfield { len: 8, shift: 0 },
56    a: Bitfield { len: 8, shift: 24 },
57};
58
59const RLE_ESCAPE: u8 = 0;
60const RLE_ESCAPE_EOL: u8 = 0;
61const RLE_ESCAPE_EOF: u8 = 1;
62const RLE_ESCAPE_DELTA: u8 = 2;
63
64/// The maximum width/height the decoder will process.
65const MAX_WIDTH_HEIGHT: i32 = 0xFFFF;
66
67#[derive(PartialEq, Copy, Clone)]
68enum ImageType {
69    Palette,
70    RGB16,
71    RGB24,
72    RGB32,
73    RGBA32,
74    RLE8,
75    RLE4,
76    Bitfields16,
77    Bitfields32,
78}
79
80#[derive(PartialEq)]
81enum BMPHeaderType {
82    Core,
83    Info,
84    V2,
85    V3,
86    V4,
87    V5,
88}
89
90#[derive(PartialEq)]
91enum FormatFullBytes {
92    RGB24,
93    RGB32,
94    RGBA32,
95    Format888,
96}
97
98enum Chunker<'a> {
99    FromTop(ChunksExactMut<'a, u8>),
100    FromBottom(Rev<ChunksExactMut<'a, u8>>),
101}
102
103pub(crate) struct RowIterator<'a> {
104    chunks: Chunker<'a>,
105}
106
107impl<'a> Iterator for RowIterator<'a> {
108    type Item = &'a mut [u8];
109
110    #[inline(always)]
111    fn next(&mut self) -> Option<&'a mut [u8]> {
112        match self.chunks {
113            Chunker::FromTop(ref mut chunks) => chunks.next(),
114            Chunker::FromBottom(ref mut chunks) => chunks.next(),
115        }
116    }
117}
118
119/// All errors that can occur when attempting to parse a BMP
120#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
121enum DecoderError {
122    // Failed to decompress RLE data.
123    CorruptRleData,
124
125    /// The bitfield mask interleaves set and unset bits
126    BitfieldMaskNonContiguous,
127    /// Bitfield mask invalid (e.g. too long for specified type)
128    BitfieldMaskInvalid,
129    /// Bitfield (of the specified width – 16- or 32-bit) mask not present
130    BitfieldMaskMissing(u32),
131    /// Bitfield (of the specified width – 16- or 32-bit) masks not present
132    BitfieldMasksMissing(u32),
133
134    /// BMP's "BM" signature wrong or missing
135    BmpSignatureInvalid,
136    /// More than the exactly one allowed plane specified by the format
137    MoreThanOnePlane,
138    /// Invalid amount of bits per channel for the specified image type
139    InvalidChannelWidth(ChannelWidthError, u16),
140
141    /// The width is negative
142    NegativeWidth(i32),
143    /// One of the dimensions is larger than a soft limit
144    ImageTooLarge(i32, i32),
145    /// The height is `i32::min_value()`
146    ///
147    /// General negative heights specify top-down DIBs
148    InvalidHeight,
149
150    /// Specified image type is invalid for top-down BMPs (i.e. is compressed)
151    ImageTypeInvalidForTopDown(u32),
152    /// Image type not currently recognized by the decoder
153    ImageTypeUnknown(u32),
154
155    /// Bitmap header smaller than the core header
156    HeaderTooSmall(u32),
157
158    /// The palette is bigger than allowed by the bit count of the BMP
159    PaletteSizeExceeded {
160        colors_used: u32,
161        bit_count: u16,
162    },
163}
164
165impl fmt::Display for DecoderError {
166    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
167        match self {
168            DecoderError::CorruptRleData => f.write_str("Corrupt RLE data"),
169            DecoderError::BitfieldMaskNonContiguous => f.write_str("Non-contiguous bitfield mask"),
170            DecoderError::BitfieldMaskInvalid => f.write_str("Invalid bitfield mask"),
171            DecoderError::BitfieldMaskMissing(bb) => {
172                f.write_fmt(format_args!("Missing {bb}-bit bitfield mask"))
173            }
174            DecoderError::BitfieldMasksMissing(bb) => {
175                f.write_fmt(format_args!("Missing {bb}-bit bitfield masks"))
176            }
177            DecoderError::BmpSignatureInvalid => f.write_str("BMP signature not found"),
178            DecoderError::MoreThanOnePlane => f.write_str("More than one plane"),
179            DecoderError::InvalidChannelWidth(tp, n) => {
180                f.write_fmt(format_args!("Invalid channel bit count for {tp}: {n}"))
181            }
182            DecoderError::NegativeWidth(w) => f.write_fmt(format_args!("Negative width ({w})")),
183            DecoderError::ImageTooLarge(w, h) => f.write_fmt(format_args!(
184                "Image too large (one of ({w}, {h}) > soft limit of {MAX_WIDTH_HEIGHT})"
185            )),
186            DecoderError::InvalidHeight => f.write_str("Invalid height"),
187            DecoderError::ImageTypeInvalidForTopDown(tp) => f.write_fmt(format_args!(
188                "Invalid image type {tp} for top-down image."
189            )),
190            DecoderError::ImageTypeUnknown(tp) => {
191                f.write_fmt(format_args!("Unknown image compression type {tp}"))
192            }
193            DecoderError::HeaderTooSmall(s) => {
194                f.write_fmt(format_args!("Bitmap header too small ({s} bytes)"))
195            }
196            DecoderError::PaletteSizeExceeded {
197                colors_used,
198                bit_count,
199            } => f.write_fmt(format_args!(
200                "Palette size {colors_used} exceeds maximum size for BMP with bit count of {bit_count}"
201            )),
202        }
203    }
204}
205
206impl From<DecoderError> for ImageError {
207    fn from(e: DecoderError) -> ImageError {
208        ImageError::Decoding(DecodingError::new(ImageFormat::Bmp.into(), e))
209    }
210}
211
212impl error::Error for DecoderError {}
213
214/// Distinct image types whose saved channel width can be invalid
215#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
216enum ChannelWidthError {
217    /// RGB
218    Rgb,
219    /// 8-bit run length encoding
220    Rle8,
221    /// 4-bit run length encoding
222    Rle4,
223    /// Bitfields (16- or 32-bit)
224    Bitfields,
225}
226
227impl fmt::Display for ChannelWidthError {
228    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
229        f.write_str(match self {
230            ChannelWidthError::Rgb => "RGB",
231            ChannelWidthError::Rle8 => "RLE8",
232            ChannelWidthError::Rle4 => "RLE4",
233            ChannelWidthError::Bitfields => "bitfields",
234        })
235    }
236}
237
238/// Convenience function to check if the combination of width, length and number of
239/// channels would result in a buffer that would overflow.
240fn check_for_overflow(width: i32, length: i32, channels: usize) -> ImageResult<()> {
241    num_bytes(width, length, channels)
242        .map(|_| ())
243        .ok_or_else(|| {
244            ImageError::Unsupported(UnsupportedError::from_format_and_kind(
245                ImageFormat::Bmp.into(),
246                UnsupportedErrorKind::GenericFeature(format!(
247                    "Image dimensions ({width}x{length} w/{channels} channels) are too large"
248                )),
249            ))
250        })
251}
252
253/// Calculate how many many bytes a buffer holding a decoded image with these properties would
254/// require. Returns `None` if the buffer size would overflow or if one of the sizes are negative.
255fn num_bytes(width: i32, length: i32, channels: usize) -> Option<usize> {
256    if width <= 0 || length <= 0 {
257        None
258    } else {
259        match channels.checked_mul(width as usize) {
260            Some(n) => n.checked_mul(length as usize),
261            None => None,
262        }
263    }
264}
265
266/// Call the provided function on each row of the provided buffer, returning Err if the provided
267/// function returns an error, extends the buffer if it's not large enough.
268fn with_rows<F>(
269    buffer: &mut [u8],
270    width: i32,
271    height: i32,
272    channels: usize,
273    top_down: bool,
274    mut func: F,
275) -> io::Result<()>
276where
277    F: FnMut(&mut [u8]) -> io::Result<()>,
278{
279    // An overflow should already have been checked for when this is called,
280    // though we check anyhow, as it somehow seems to increase performance slightly.
281    let row_width = channels.checked_mul(width as usize).unwrap();
282    let full_image_size = row_width.checked_mul(height as usize).unwrap();
283    assert_eq!(buffer.len(), full_image_size);
284
285    if !top_down {
286        for row in buffer.chunks_mut(row_width).rev() {
287            func(row)?;
288        }
289    } else {
290        for row in buffer.chunks_mut(row_width) {
291            func(row)?;
292        }
293    }
294    Ok(())
295}
296
297fn set_8bit_pixel_run<'a, T: Iterator<Item = &'a u8>>(
298    pixel_iter: &mut ChunksExactMut<u8>,
299    palette: &[[u8; 3]],
300    indices: T,
301    n_pixels: usize,
302) -> bool {
303    for idx in indices.take(n_pixels) {
304        if let Some(pixel) = pixel_iter.next() {
305            let rgb = palette[*idx as usize];
306            pixel[0] = rgb[0];
307            pixel[1] = rgb[1];
308            pixel[2] = rgb[2];
309        } else {
310            return false;
311        }
312    }
313    true
314}
315
316fn set_4bit_pixel_run<'a, T: Iterator<Item = &'a u8>>(
317    pixel_iter: &mut ChunksExactMut<u8>,
318    palette: &[[u8; 3]],
319    indices: T,
320    mut n_pixels: usize,
321) -> bool {
322    for idx in indices {
323        macro_rules! set_pixel {
324            ($i:expr) => {
325                if n_pixels == 0 {
326                    break;
327                }
328                if let Some(pixel) = pixel_iter.next() {
329                    let rgb = palette[$i as usize];
330                    pixel[0] = rgb[0];
331                    pixel[1] = rgb[1];
332                    pixel[2] = rgb[2];
333                } else {
334                    return false;
335                }
336                n_pixels -= 1;
337            };
338        }
339        set_pixel!(idx >> 4);
340        set_pixel!(idx & 0xf);
341    }
342    true
343}
344
345#[rustfmt::skip]
346fn set_2bit_pixel_run<'a, T: Iterator<Item = &'a u8>>(
347    pixel_iter: &mut ChunksExactMut<u8>,
348    palette: &[[u8; 3]],
349    indices: T,
350    mut n_pixels: usize,
351) -> bool {
352    for idx in indices {
353        macro_rules! set_pixel {
354            ($i:expr) => {
355                if n_pixels == 0 {
356                    break;
357                }
358                if let Some(pixel) = pixel_iter.next() {
359                    let rgb = palette[$i as usize];
360                    pixel[0] = rgb[0];
361                    pixel[1] = rgb[1];
362                    pixel[2] = rgb[2];
363                } else {
364                    return false;
365                }
366                n_pixels -= 1;
367            };
368        }
369        set_pixel!((idx >> 6) & 0x3u8);
370        set_pixel!((idx >> 4) & 0x3u8);
371        set_pixel!((idx >> 2) & 0x3u8);
372        set_pixel!( idx       & 0x3u8);
373    }
374    true
375}
376
377fn set_1bit_pixel_run<'a, T: Iterator<Item = &'a u8>>(
378    pixel_iter: &mut ChunksExactMut<u8>,
379    palette: &[[u8; 3]],
380    indices: T,
381) {
382    for idx in indices {
383        let mut bit = 0x80;
384        loop {
385            if let Some(pixel) = pixel_iter.next() {
386                let rgb = palette[usize::from((idx & bit) != 0)];
387                pixel[0] = rgb[0];
388                pixel[1] = rgb[1];
389                pixel[2] = rgb[2];
390            } else {
391                return;
392            }
393
394            bit >>= 1;
395            if bit == 0 {
396                break;
397            }
398        }
399    }
400}
401
402#[derive(PartialEq, Eq)]
403struct Bitfield {
404    shift: u32,
405    len: u32,
406}
407
408impl Bitfield {
409    fn from_mask(mask: u32, max_len: u32) -> ImageResult<Bitfield> {
410        if mask == 0 {
411            return Ok(Bitfield { shift: 0, len: 0 });
412        }
413        let mut shift = mask.trailing_zeros();
414        let mut len = (!(mask >> shift)).trailing_zeros();
415        if len != mask.count_ones() {
416            return Err(DecoderError::BitfieldMaskNonContiguous.into());
417        }
418        if len + shift > max_len {
419            return Err(DecoderError::BitfieldMaskInvalid.into());
420        }
421        if len > 8 {
422            shift += len - 8;
423            len = 8;
424        }
425        Ok(Bitfield { shift, len })
426    }
427
428    fn read(&self, data: u32) -> u8 {
429        let data = data >> self.shift;
430        match self.len {
431            1 => ((data & 0b1) * 0xff) as u8,
432            2 => ((data & 0b11) * 0x55) as u8,
433            3 => LOOKUP_TABLE_3_BIT_TO_8_BIT[(data & 0b00_0111) as usize],
434            4 => LOOKUP_TABLE_4_BIT_TO_8_BIT[(data & 0b00_1111) as usize],
435            5 => LOOKUP_TABLE_5_BIT_TO_8_BIT[(data & 0b01_1111) as usize],
436            6 => LOOKUP_TABLE_6_BIT_TO_8_BIT[(data & 0b11_1111) as usize],
437            7 => (((data & 0x7f) << 1) | ((data & 0x7f) >> 6)) as u8,
438            8 => (data & 0xff) as u8,
439            _ => panic!(),
440        }
441    }
442}
443
444#[derive(PartialEq, Eq)]
445struct Bitfields {
446    r: Bitfield,
447    g: Bitfield,
448    b: Bitfield,
449    a: Bitfield,
450}
451
452impl Bitfields {
453    fn from_mask(
454        r_mask: u32,
455        g_mask: u32,
456        b_mask: u32,
457        a_mask: u32,
458        max_len: u32,
459    ) -> ImageResult<Bitfields> {
460        let bitfields = Bitfields {
461            r: Bitfield::from_mask(r_mask, max_len)?,
462            g: Bitfield::from_mask(g_mask, max_len)?,
463            b: Bitfield::from_mask(b_mask, max_len)?,
464            a: Bitfield::from_mask(a_mask, max_len)?,
465        };
466        if bitfields.r.len == 0 || bitfields.g.len == 0 || bitfields.b.len == 0 {
467            return Err(DecoderError::BitfieldMaskMissing(max_len).into());
468        }
469        Ok(bitfields)
470    }
471}
472
473/// A bmp decoder
474pub struct BmpDecoder<R> {
475    reader: R,
476
477    bmp_header_type: BMPHeaderType,
478    indexed_color: bool,
479
480    width: i32,
481    height: i32,
482    data_offset: u64,
483    top_down: bool,
484    no_file_header: bool,
485    add_alpha_channel: bool,
486    has_loaded_metadata: bool,
487    image_type: ImageType,
488
489    bit_count: u16,
490    colors_used: u32,
491    palette: Option<Vec<[u8; 3]>>,
492    bitfields: Option<Bitfields>,
493}
494
495enum RLEInsn {
496    EndOfFile,
497    EndOfRow,
498    Delta(u8, u8),
499    Absolute(u8, Vec<u8>),
500    PixelRun(u8, u8),
501}
502
503impl<R: BufRead + Seek> BmpDecoder<R> {
504    fn new_decoder(reader: R) -> BmpDecoder<R> {
505        BmpDecoder {
506            reader,
507
508            bmp_header_type: BMPHeaderType::Info,
509            indexed_color: false,
510
511            width: 0,
512            height: 0,
513            data_offset: 0,
514            top_down: false,
515            no_file_header: false,
516            add_alpha_channel: false,
517            has_loaded_metadata: false,
518            image_type: ImageType::Palette,
519
520            bit_count: 0,
521            colors_used: 0,
522            palette: None,
523            bitfields: None,
524        }
525    }
526
527    /// Create a new decoder that decodes from the stream ```r```
528    pub fn new(reader: R) -> ImageResult<BmpDecoder<R>> {
529        let mut decoder = Self::new_decoder(reader);
530        decoder.read_metadata()?;
531        Ok(decoder)
532    }
533
534    /// Create a new decoder that decodes from the stream ```r``` without first
535    /// reading a BITMAPFILEHEADER. This is useful for decoding the `CF_DIB` format
536    /// directly from the Windows clipboard.
537    pub fn new_without_file_header(reader: R) -> ImageResult<BmpDecoder<R>> {
538        let mut decoder = Self::new_decoder(reader);
539        decoder.no_file_header = true;
540        decoder.read_metadata()?;
541        Ok(decoder)
542    }
543
544    #[cfg(feature = "ico")]
545    pub(crate) fn new_with_ico_format(reader: R) -> ImageResult<BmpDecoder<R>> {
546        let mut decoder = Self::new_decoder(reader);
547        decoder.read_metadata_in_ico_format()?;
548        Ok(decoder)
549    }
550
551    /// If true, the palette in BMP does not apply to the image even if it is found.
552    /// In other words, the output image is the indexed color.
553    pub fn set_indexed_color(&mut self, indexed_color: bool) {
554        self.indexed_color = indexed_color;
555    }
556
557    #[cfg(feature = "ico")]
558    pub(crate) fn reader(&mut self) -> &mut R {
559        &mut self.reader
560    }
561
562    fn read_file_header(&mut self) -> ImageResult<()> {
563        if self.no_file_header {
564            return Ok(());
565        }
566        let mut signature = [0; 2];
567        self.reader.read_exact(&mut signature)?;
568
569        if signature != b"BM"[..] {
570            return Err(DecoderError::BmpSignatureInvalid.into());
571        }
572
573        // The next 8 bytes represent file size, followed the 4 reserved bytes
574        // We're not interesting these values
575        self.reader.read_u32::<LittleEndian>()?;
576        self.reader.read_u32::<LittleEndian>()?;
577
578        self.data_offset = u64::from(self.reader.read_u32::<LittleEndian>()?);
579
580        Ok(())
581    }
582
583    /// Read BITMAPCOREHEADER <https://msdn.microsoft.com/en-us/library/vs/alm/dd183372(v=vs.85).aspx>
584    ///
585    /// returns Err if any of the values are invalid.
586    fn read_bitmap_core_header(&mut self) -> ImageResult<()> {
587        // As height/width values in BMP files with core headers are only 16 bits long,
588        // they won't be larger than `MAX_WIDTH_HEIGHT`.
589        self.width = i32::from(self.reader.read_u16::<LittleEndian>()?);
590        self.height = i32::from(self.reader.read_u16::<LittleEndian>()?);
591
592        check_for_overflow(self.width, self.height, self.num_channels())?;
593
594        // Number of planes (format specifies that this should be 1).
595        if self.reader.read_u16::<LittleEndian>()? != 1 {
596            return Err(DecoderError::MoreThanOnePlane.into());
597        }
598
599        self.bit_count = self.reader.read_u16::<LittleEndian>()?;
600        self.image_type = match self.bit_count {
601            1 | 4 | 8 => ImageType::Palette,
602            24 => ImageType::RGB24,
603            _ => {
604                return Err(DecoderError::InvalidChannelWidth(
605                    ChannelWidthError::Rgb,
606                    self.bit_count,
607                )
608                .into())
609            }
610        };
611
612        Ok(())
613    }
614
615    /// Read BITMAPINFOHEADER <https://msdn.microsoft.com/en-us/library/vs/alm/dd183376(v=vs.85).aspx>
616    /// or BITMAPV{2|3|4|5}HEADER.
617    ///
618    /// returns Err if any of the values are invalid.
619    fn read_bitmap_info_header(&mut self) -> ImageResult<()> {
620        self.width = self.reader.read_i32::<LittleEndian>()?;
621        self.height = self.reader.read_i32::<LittleEndian>()?;
622
623        // Width can not be negative
624        if self.width < 0 {
625            return Err(DecoderError::NegativeWidth(self.width).into());
626        } else if self.width > MAX_WIDTH_HEIGHT || self.height > MAX_WIDTH_HEIGHT {
627            // Limit very large image sizes to avoid OOM issues. Images with these sizes are
628            // unlikely to be valid anyhow.
629            return Err(DecoderError::ImageTooLarge(self.width, self.height).into());
630        }
631
632        if self.height == i32::MIN {
633            return Err(DecoderError::InvalidHeight.into());
634        }
635
636        // A negative height indicates a top-down DIB.
637        if self.height < 0 {
638            self.height *= -1;
639            self.top_down = true;
640        }
641
642        check_for_overflow(self.width, self.height, self.num_channels())?;
643
644        // Number of planes (format specifies that this should be 1).
645        if self.reader.read_u16::<LittleEndian>()? != 1 {
646            return Err(DecoderError::MoreThanOnePlane.into());
647        }
648
649        self.bit_count = self.reader.read_u16::<LittleEndian>()?;
650        let image_type_u32 = self.reader.read_u32::<LittleEndian>()?;
651
652        // Top-down dibs can not be compressed.
653        if self.top_down && image_type_u32 != 0 && image_type_u32 != 3 {
654            return Err(DecoderError::ImageTypeInvalidForTopDown(image_type_u32).into());
655        }
656        self.image_type = match image_type_u32 {
657            0 => match self.bit_count {
658                1 | 2 | 4 | 8 => ImageType::Palette,
659                16 => ImageType::RGB16,
660                24 => ImageType::RGB24,
661                32 if self.add_alpha_channel => ImageType::RGBA32,
662                32 => ImageType::RGB32,
663                _ => {
664                    return Err(DecoderError::InvalidChannelWidth(
665                        ChannelWidthError::Rgb,
666                        self.bit_count,
667                    )
668                    .into())
669                }
670            },
671            1 => match self.bit_count {
672                8 => ImageType::RLE8,
673                _ => {
674                    return Err(DecoderError::InvalidChannelWidth(
675                        ChannelWidthError::Rle8,
676                        self.bit_count,
677                    )
678                    .into())
679                }
680            },
681            2 => match self.bit_count {
682                4 => ImageType::RLE4,
683                _ => {
684                    return Err(DecoderError::InvalidChannelWidth(
685                        ChannelWidthError::Rle4,
686                        self.bit_count,
687                    )
688                    .into())
689                }
690            },
691            3 => match self.bit_count {
692                16 => ImageType::Bitfields16,
693                32 => ImageType::Bitfields32,
694                _ => {
695                    return Err(DecoderError::InvalidChannelWidth(
696                        ChannelWidthError::Bitfields,
697                        self.bit_count,
698                    )
699                    .into())
700                }
701            },
702            4 => {
703                // JPEG compression is not implemented yet.
704                return Err(ImageError::Unsupported(
705                    UnsupportedError::from_format_and_kind(
706                        ImageFormat::Bmp.into(),
707                        UnsupportedErrorKind::GenericFeature("JPEG compression".to_owned()),
708                    ),
709                ));
710            }
711            5 => {
712                // PNG compression is not implemented yet.
713                return Err(ImageError::Unsupported(
714                    UnsupportedError::from_format_and_kind(
715                        ImageFormat::Bmp.into(),
716                        UnsupportedErrorKind::GenericFeature("PNG compression".to_owned()),
717                    ),
718                ));
719            }
720            11..=13 => {
721                // CMYK types are not implemented yet.
722                return Err(ImageError::Unsupported(
723                    UnsupportedError::from_format_and_kind(
724                        ImageFormat::Bmp.into(),
725                        UnsupportedErrorKind::GenericFeature("CMYK format".to_owned()),
726                    ),
727                ));
728            }
729            _ => {
730                // Unknown compression type.
731                return Err(DecoderError::ImageTypeUnknown(image_type_u32).into());
732            }
733        };
734
735        // The next 12 bytes represent data array size in bytes,
736        // followed the horizontal and vertical printing resolutions
737        // We will calculate the pixel array size using width & height of image
738        // We're not interesting the horz or vert printing resolutions
739        self.reader.read_u32::<LittleEndian>()?;
740        self.reader.read_u32::<LittleEndian>()?;
741        self.reader.read_u32::<LittleEndian>()?;
742
743        self.colors_used = self.reader.read_u32::<LittleEndian>()?;
744
745        // The next 4 bytes represent number of "important" colors
746        // We're not interested in this value, so we'll skip it
747        self.reader.read_u32::<LittleEndian>()?;
748
749        Ok(())
750    }
751
752    fn read_bitmasks(&mut self) -> ImageResult<()> {
753        let r_mask = self.reader.read_u32::<LittleEndian>()?;
754        let g_mask = self.reader.read_u32::<LittleEndian>()?;
755        let b_mask = self.reader.read_u32::<LittleEndian>()?;
756
757        let a_mask = match self.bmp_header_type {
758            BMPHeaderType::V3 | BMPHeaderType::V4 | BMPHeaderType::V5 => {
759                self.reader.read_u32::<LittleEndian>()?
760            }
761            _ => 0,
762        };
763
764        self.bitfields = match self.image_type {
765            ImageType::Bitfields16 => {
766                Some(Bitfields::from_mask(r_mask, g_mask, b_mask, a_mask, 16)?)
767            }
768            ImageType::Bitfields32 => {
769                Some(Bitfields::from_mask(r_mask, g_mask, b_mask, a_mask, 32)?)
770            }
771            _ => None,
772        };
773
774        if self.bitfields.is_some() && a_mask != 0 {
775            self.add_alpha_channel = true;
776        }
777
778        Ok(())
779    }
780
781    fn read_metadata(&mut self) -> ImageResult<()> {
782        if !self.has_loaded_metadata {
783            self.read_file_header()?;
784            let bmp_header_offset = self.reader.stream_position()?;
785            let bmp_header_size = self.reader.read_u32::<LittleEndian>()?;
786            let bmp_header_end = bmp_header_offset + u64::from(bmp_header_size);
787
788            self.bmp_header_type = match bmp_header_size {
789                BITMAPCOREHEADER_SIZE => BMPHeaderType::Core,
790                BITMAPINFOHEADER_SIZE => BMPHeaderType::Info,
791                BITMAPV2HEADER_SIZE => BMPHeaderType::V2,
792                BITMAPV3HEADER_SIZE => BMPHeaderType::V3,
793                BITMAPV4HEADER_SIZE => BMPHeaderType::V4,
794                BITMAPV5HEADER_SIZE => BMPHeaderType::V5,
795                _ if bmp_header_size < BITMAPCOREHEADER_SIZE => {
796                    // Size of any valid header types won't be smaller than core header type.
797                    return Err(DecoderError::HeaderTooSmall(bmp_header_size).into());
798                }
799                _ => {
800                    return Err(ImageError::Unsupported(
801                        UnsupportedError::from_format_and_kind(
802                            ImageFormat::Bmp.into(),
803                            UnsupportedErrorKind::GenericFeature(format!(
804                                "Unknown bitmap header type (size={bmp_header_size})"
805                            )),
806                        ),
807                    ))
808                }
809            };
810
811            match self.bmp_header_type {
812                BMPHeaderType::Core => {
813                    self.read_bitmap_core_header()?;
814                }
815                BMPHeaderType::Info
816                | BMPHeaderType::V2
817                | BMPHeaderType::V3
818                | BMPHeaderType::V4
819                | BMPHeaderType::V5 => {
820                    self.read_bitmap_info_header()?;
821                }
822            }
823
824            let mut bitmask_bytes_offset = 0;
825            if self.image_type == ImageType::Bitfields16
826                || self.image_type == ImageType::Bitfields32
827            {
828                self.read_bitmasks()?;
829
830                // Per https://learn.microsoft.com/en-us/windows/win32/gdi/bitmap-header-types, bitmaps
831                // using the `BITMAPINFOHEADER`, `BITMAPV4HEADER`, or `BITMAPV5HEADER` structures with
832                // an image type of `BI_BITFIELD` contain RGB bitfield masks immediately after the header.
833                //
834                // `read_bitmasks` correctly reads these from earlier in the header itself but we must
835                // ensure the reader starts on the image data itself, not these extra mask bytes.
836                if matches!(
837                    self.bmp_header_type,
838                    BMPHeaderType::Info | BMPHeaderType::V4 | BMPHeaderType::V5
839                ) {
840                    // This is `size_of::<u32>() * 3` (a red, green, and blue mask), but with less noise.
841                    bitmask_bytes_offset = 12;
842                }
843            };
844
845            self.reader
846                .seek(SeekFrom::Start(bmp_header_end + bitmask_bytes_offset))?;
847
848            match self.image_type {
849                ImageType::Palette | ImageType::RLE4 | ImageType::RLE8 => self.read_palette()?,
850                _ => {}
851            }
852
853            if self.no_file_header {
854                // Use the offset of the end of metadata instead of reading a BMP file header.
855                self.data_offset = self.reader.stream_position()?;
856            }
857
858            self.has_loaded_metadata = true;
859        }
860        Ok(())
861    }
862
863    #[cfg(feature = "ico")]
864    #[doc(hidden)]
865    pub fn read_metadata_in_ico_format(&mut self) -> ImageResult<()> {
866        self.no_file_header = true;
867        self.add_alpha_channel = true;
868        self.read_metadata()?;
869
870        // The height field in an ICO file is doubled to account for the AND mask
871        // (whether or not an AND mask is actually present).
872        self.height /= 2;
873        Ok(())
874    }
875
876    fn get_palette_size(&mut self) -> ImageResult<usize> {
877        match self.colors_used {
878            0 => Ok(1 << self.bit_count),
879            _ => {
880                if self.colors_used > 1 << self.bit_count {
881                    return Err(DecoderError::PaletteSizeExceeded {
882                        colors_used: self.colors_used,
883                        bit_count: self.bit_count,
884                    }
885                    .into());
886                }
887                Ok(self.colors_used as usize)
888            }
889        }
890    }
891
892    fn bytes_per_color(&self) -> usize {
893        match self.bmp_header_type {
894            BMPHeaderType::Core => 3,
895            _ => 4,
896        }
897    }
898
899    fn read_palette(&mut self) -> ImageResult<()> {
900        const MAX_PALETTE_SIZE: usize = 256; // Palette indices are u8.
901
902        let bytes_per_color = self.bytes_per_color();
903        let palette_size = self.get_palette_size()?;
904        let max_length = MAX_PALETTE_SIZE * bytes_per_color;
905
906        let length = palette_size * bytes_per_color;
907        let mut buf = vec_try_with_capacity(max_length)?;
908
909        // Resize and read the palette entries to the buffer.
910        // We limit the buffer to at most 256 colours to avoid any oom issues as
911        // 8-bit images can't reference more than 256 indexes anyhow.
912        buf.resize(cmp::min(length, max_length), 0);
913        self.reader.by_ref().read_exact(&mut buf)?;
914
915        // Allocate 256 entries even if palette_size is smaller, to prevent corrupt files from
916        // causing an out-of-bounds array access.
917        match length.cmp(&max_length) {
918            Ordering::Greater => {
919                self.reader
920                    .seek(SeekFrom::Current((length - max_length) as i64))?;
921            }
922            Ordering::Less => buf.resize(max_length, 0),
923            Ordering::Equal => (),
924        }
925
926        let p: Vec<[u8; 3]> = (0..MAX_PALETTE_SIZE)
927            .map(|i| {
928                let b = buf[bytes_per_color * i];
929                let g = buf[bytes_per_color * i + 1];
930                let r = buf[bytes_per_color * i + 2];
931                [r, g, b]
932            })
933            .collect();
934
935        self.palette = Some(p);
936
937        Ok(())
938    }
939
940    /// Get the palette that is embedded in the BMP image, if any.
941    pub fn get_palette(&self) -> Option<&[[u8; 3]]> {
942        self.palette.as_ref().map(|vec| &vec[..])
943    }
944
945    fn num_channels(&self) -> usize {
946        if self.indexed_color {
947            1
948        } else if self.add_alpha_channel {
949            4
950        } else {
951            3
952        }
953    }
954
955    fn rows<'a>(&self, pixel_data: &'a mut [u8]) -> RowIterator<'a> {
956        let stride = self.width as usize * self.num_channels();
957        if self.top_down {
958            RowIterator {
959                chunks: Chunker::FromTop(pixel_data.chunks_exact_mut(stride)),
960            }
961        } else {
962            RowIterator {
963                chunks: Chunker::FromBottom(pixel_data.chunks_exact_mut(stride).rev()),
964            }
965        }
966    }
967
968    fn read_palettized_pixel_data(&mut self, buf: &mut [u8]) -> ImageResult<()> {
969        let num_channels = self.num_channels();
970        let row_byte_length = ((i32::from(self.bit_count) * self.width + 31) / 32 * 4) as usize;
971        let mut indices = vec![0; row_byte_length];
972        let palette = self.palette.as_ref().unwrap();
973        let bit_count = self.bit_count;
974        let reader = &mut self.reader;
975        let width = self.width as usize;
976        let skip_palette = self.indexed_color;
977
978        reader.seek(SeekFrom::Start(self.data_offset))?;
979
980        if num_channels == 4 {
981            buf.chunks_exact_mut(4).for_each(|c| c[3] = 0xFF);
982        }
983
984        with_rows(
985            buf,
986            self.width,
987            self.height,
988            num_channels,
989            self.top_down,
990            |row| {
991                reader.read_exact(&mut indices)?;
992                if skip_palette {
993                    row.clone_from_slice(&indices[0..width]);
994                } else {
995                    let mut pixel_iter = row.chunks_exact_mut(num_channels);
996                    match bit_count {
997                        1 => {
998                            set_1bit_pixel_run(&mut pixel_iter, palette, indices.iter());
999                        }
1000                        2 => {
1001                            set_2bit_pixel_run(&mut pixel_iter, palette, indices.iter(), width);
1002                        }
1003                        4 => {
1004                            set_4bit_pixel_run(&mut pixel_iter, palette, indices.iter(), width);
1005                        }
1006                        8 => {
1007                            set_8bit_pixel_run(&mut pixel_iter, palette, indices.iter(), width);
1008                        }
1009                        _ => panic!(),
1010                    }
1011                }
1012                Ok(())
1013            },
1014        )?;
1015
1016        Ok(())
1017    }
1018
1019    fn read_16_bit_pixel_data(
1020        &mut self,
1021        buf: &mut [u8],
1022        bitfields: Option<&Bitfields>,
1023    ) -> ImageResult<()> {
1024        let num_channels = self.num_channels();
1025        let row_padding_len = self.width as usize % 2 * 2;
1026        let row_padding = &mut [0; 2][..row_padding_len];
1027        let bitfields = match bitfields {
1028            Some(b) => b,
1029            None => self.bitfields.as_ref().unwrap(),
1030        };
1031        let reader = &mut self.reader;
1032
1033        reader.seek(SeekFrom::Start(self.data_offset))?;
1034
1035        with_rows(
1036            buf,
1037            self.width,
1038            self.height,
1039            num_channels,
1040            self.top_down,
1041            |row| {
1042                for pixel in row.chunks_mut(num_channels) {
1043                    let data = u32::from(reader.read_u16::<LittleEndian>()?);
1044
1045                    pixel[0] = bitfields.r.read(data);
1046                    pixel[1] = bitfields.g.read(data);
1047                    pixel[2] = bitfields.b.read(data);
1048                    if num_channels == 4 {
1049                        if bitfields.a.len != 0 {
1050                            pixel[3] = bitfields.a.read(data);
1051                        } else {
1052                            pixel[3] = 0xFF;
1053                        }
1054                    }
1055                }
1056                reader.read_exact(row_padding)
1057            },
1058        )?;
1059
1060        Ok(())
1061    }
1062
1063    /// Read image data from a reader in 32-bit formats that use bitfields.
1064    fn read_32_bit_pixel_data(&mut self, buf: &mut [u8]) -> ImageResult<()> {
1065        let num_channels = self.num_channels();
1066
1067        let bitfields = self.bitfields.as_ref().unwrap();
1068
1069        let reader = &mut self.reader;
1070        reader.seek(SeekFrom::Start(self.data_offset))?;
1071
1072        with_rows(
1073            buf,
1074            self.width,
1075            self.height,
1076            num_channels,
1077            self.top_down,
1078            |row| {
1079                for pixel in row.chunks_mut(num_channels) {
1080                    let data = reader.read_u32::<LittleEndian>()?;
1081
1082                    pixel[0] = bitfields.r.read(data);
1083                    pixel[1] = bitfields.g.read(data);
1084                    pixel[2] = bitfields.b.read(data);
1085                    if num_channels == 4 {
1086                        if bitfields.a.len != 0 {
1087                            pixel[3] = bitfields.a.read(data);
1088                        } else {
1089                            pixel[3] = 0xff;
1090                        }
1091                    }
1092                }
1093                Ok(())
1094            },
1095        )?;
1096
1097        Ok(())
1098    }
1099
1100    /// Read image data from a reader where the colours are stored as 8-bit values (24 or 32-bit).
1101    fn read_full_byte_pixel_data(
1102        &mut self,
1103        buf: &mut [u8],
1104        format: &FormatFullBytes,
1105    ) -> ImageResult<()> {
1106        let num_channels = self.num_channels();
1107        let row_padding_len = match *format {
1108            FormatFullBytes::RGB24 => (4 - (self.width as usize * 3) % 4) % 4,
1109            _ => 0,
1110        };
1111        let row_padding = &mut [0; 4][..row_padding_len];
1112
1113        self.reader.seek(SeekFrom::Start(self.data_offset))?;
1114
1115        let reader = &mut self.reader;
1116
1117        with_rows(
1118            buf,
1119            self.width,
1120            self.height,
1121            num_channels,
1122            self.top_down,
1123            |row| {
1124                for pixel in row.chunks_mut(num_channels) {
1125                    if *format == FormatFullBytes::Format888 {
1126                        reader.read_u8()?;
1127                    }
1128
1129                    // Read the colour values (b, g, r).
1130                    // Reading 3 bytes and reversing them is significantly faster than reading one
1131                    // at a time.
1132                    reader.read_exact(&mut pixel[0..3])?;
1133                    pixel[0..3].reverse();
1134
1135                    if *format == FormatFullBytes::RGB32 {
1136                        reader.read_u8()?;
1137                    }
1138
1139                    // Read the alpha channel if present
1140                    if *format == FormatFullBytes::RGBA32 {
1141                        reader.read_exact(&mut pixel[3..4])?;
1142                    } else if num_channels == 4 {
1143                        pixel[3] = 0xFF;
1144                    }
1145                }
1146                reader.read_exact(row_padding)
1147            },
1148        )?;
1149
1150        Ok(())
1151    }
1152
1153    fn read_rle_data(&mut self, buf: &mut [u8], image_type: ImageType) -> ImageResult<()> {
1154        // Seek to the start of the actual image data.
1155        self.reader.seek(SeekFrom::Start(self.data_offset))?;
1156
1157        let num_channels = self.num_channels();
1158        let p = self.palette.as_ref().unwrap();
1159
1160        // Handling deltas in the RLE scheme means that we need to manually
1161        // iterate through rows and pixels.  Even if we didn't have to handle
1162        // deltas, we have to ensure that a single runlength doesn't straddle
1163        // two rows.
1164        let mut row_iter = self.rows(buf);
1165
1166        while let Some(row) = row_iter.next() {
1167            let mut pixel_iter = row.chunks_exact_mut(num_channels);
1168
1169            let mut x = 0;
1170            loop {
1171                let instruction = {
1172                    let control_byte = self.reader.read_u8()?;
1173                    match control_byte {
1174                        RLE_ESCAPE => {
1175                            let op = self.reader.read_u8()?;
1176
1177                            match op {
1178                                RLE_ESCAPE_EOL => RLEInsn::EndOfRow,
1179                                RLE_ESCAPE_EOF => RLEInsn::EndOfFile,
1180                                RLE_ESCAPE_DELTA => {
1181                                    let xdelta = self.reader.read_u8()?;
1182                                    let ydelta = self.reader.read_u8()?;
1183                                    RLEInsn::Delta(xdelta, ydelta)
1184                                }
1185                                _ => {
1186                                    let mut length = op as usize;
1187                                    if self.image_type == ImageType::RLE4 {
1188                                        length = length.div_ceil(2);
1189                                    }
1190                                    length += length & 1;
1191                                    let mut buffer = Vec::new();
1192                                    self.reader.read_exact_vec(&mut buffer, length)?;
1193                                    RLEInsn::Absolute(op, buffer)
1194                                }
1195                            }
1196                        }
1197                        _ => {
1198                            let palette_index = self.reader.read_u8()?;
1199                            RLEInsn::PixelRun(control_byte, palette_index)
1200                        }
1201                    }
1202                };
1203
1204                match instruction {
1205                    RLEInsn::EndOfFile => {
1206                        pixel_iter.for_each(|p| p.fill(0));
1207                        row_iter.for_each(|r| r.fill(0));
1208                        return Ok(());
1209                    }
1210                    RLEInsn::EndOfRow => {
1211                        pixel_iter.for_each(|p| p.fill(0));
1212                        break;
1213                    }
1214                    RLEInsn::Delta(x_delta, y_delta) => {
1215                        // The msdn site on bitmap compression doesn't specify
1216                        // what happens to the values skipped when encountering
1217                        // a delta code, however IE and the windows image
1218                        // preview seems to replace them with black pixels,
1219                        // so we stick to that.
1220
1221                        if y_delta > 0 {
1222                            // Zero out the remainder of the current row.
1223                            pixel_iter.for_each(|p| p.fill(0));
1224
1225                            // If any full rows are skipped, zero them out.
1226                            for _ in 1..y_delta {
1227                                let row = row_iter.next().ok_or(DecoderError::CorruptRleData)?;
1228                                row.fill(0);
1229                            }
1230
1231                            // Set the pixel iterator to the start of the next row.
1232                            pixel_iter = row_iter
1233                                .next()
1234                                .ok_or(DecoderError::CorruptRleData)?
1235                                .chunks_exact_mut(num_channels);
1236
1237                            // Zero out the pixels up to the current point in the row.
1238                            for _ in 0..x {
1239                                pixel_iter
1240                                    .next()
1241                                    .ok_or(DecoderError::CorruptRleData)?
1242                                    .fill(0);
1243                            }
1244                        }
1245
1246                        for _ in 0..x_delta {
1247                            let pixel = pixel_iter.next().ok_or(DecoderError::CorruptRleData)?;
1248                            pixel.fill(0);
1249                        }
1250                        x += x_delta as usize;
1251                    }
1252                    RLEInsn::Absolute(length, indices) => {
1253                        // Absolute mode cannot span rows, so if we run
1254                        // out of pixels to process, we should stop
1255                        // processing the image.
1256                        match image_type {
1257                            ImageType::RLE8 => {
1258                                if !set_8bit_pixel_run(
1259                                    &mut pixel_iter,
1260                                    p,
1261                                    indices.iter(),
1262                                    length as usize,
1263                                ) {
1264                                    return Err(DecoderError::CorruptRleData.into());
1265                                }
1266                            }
1267                            ImageType::RLE4 => {
1268                                if !set_4bit_pixel_run(
1269                                    &mut pixel_iter,
1270                                    p,
1271                                    indices.iter(),
1272                                    length as usize,
1273                                ) {
1274                                    return Err(DecoderError::CorruptRleData.into());
1275                                }
1276                            }
1277                            _ => unreachable!(),
1278                        }
1279                        x += length as usize;
1280                    }
1281                    RLEInsn::PixelRun(n_pixels, palette_index) => {
1282                        match image_type {
1283                            ImageType::RLE8 => {
1284                                // A pixel run isn't allowed to span rows.
1285                                // imagemagick produces invalid images where n_pixels exceeds row length,
1286                                // so we clamp n_pixels to the row length to display them properly:
1287                                // https://github.com/image-rs/image/issues/2321
1288                                //
1289                                // This is like set_8bit_pixel_run() but doesn't fail when `n_pixels` is too large
1290                                let repeat_pixel: [u8; 3] = p[palette_index as usize];
1291                                (&mut pixel_iter).take(n_pixels as usize).for_each(|p| {
1292                                    p[2] = repeat_pixel[2];
1293                                    p[1] = repeat_pixel[1];
1294                                    p[0] = repeat_pixel[0];
1295                                });
1296                            }
1297                            ImageType::RLE4 => {
1298                                if !set_4bit_pixel_run(
1299                                    &mut pixel_iter,
1300                                    p,
1301                                    repeat(&palette_index),
1302                                    n_pixels as usize,
1303                                ) {
1304                                    return Err(DecoderError::CorruptRleData.into());
1305                                }
1306                            }
1307                            _ => unreachable!(),
1308                        }
1309                        x += n_pixels as usize;
1310                    }
1311                }
1312            }
1313        }
1314
1315        Ok(())
1316    }
1317
1318    /// Read the actual data of the image. This function is deliberately not public because it
1319    /// cannot be called multiple times without seeking back the underlying reader in between.
1320    pub(crate) fn read_image_data(&mut self, buf: &mut [u8]) -> ImageResult<()> {
1321        match self.image_type {
1322            ImageType::Palette => self.read_palettized_pixel_data(buf),
1323            ImageType::RGB16 => self.read_16_bit_pixel_data(buf, Some(&R5_G5_B5_COLOR_MASK)),
1324            ImageType::RGB24 => self.read_full_byte_pixel_data(buf, &FormatFullBytes::RGB24),
1325            ImageType::RGB32 => self.read_full_byte_pixel_data(buf, &FormatFullBytes::RGB32),
1326            ImageType::RGBA32 => self.read_full_byte_pixel_data(buf, &FormatFullBytes::RGBA32),
1327            ImageType::RLE8 => self.read_rle_data(buf, ImageType::RLE8),
1328            ImageType::RLE4 => self.read_rle_data(buf, ImageType::RLE4),
1329            ImageType::Bitfields16 => match self.bitfields {
1330                Some(_) => self.read_16_bit_pixel_data(buf, None),
1331                None => Err(DecoderError::BitfieldMasksMissing(16).into()),
1332            },
1333            ImageType::Bitfields32 => match self.bitfields {
1334                Some(R8_G8_B8_COLOR_MASK) => {
1335                    self.read_full_byte_pixel_data(buf, &FormatFullBytes::Format888)
1336                }
1337                Some(R8_G8_B8_A8_COLOR_MASK) => {
1338                    self.read_full_byte_pixel_data(buf, &FormatFullBytes::RGBA32)
1339                }
1340                Some(_) => self.read_32_bit_pixel_data(buf),
1341                None => Err(DecoderError::BitfieldMasksMissing(32).into()),
1342            },
1343        }
1344    }
1345}
1346
1347impl<R: BufRead + Seek> ImageDecoder for BmpDecoder<R> {
1348    fn dimensions(&self) -> (u32, u32) {
1349        (self.width as u32, self.height as u32)
1350    }
1351
1352    fn color_type(&self) -> ColorType {
1353        if self.indexed_color {
1354            ColorType::L8
1355        } else if self.add_alpha_channel {
1356            ColorType::Rgba8
1357        } else {
1358            ColorType::Rgb8
1359        }
1360    }
1361
1362    fn read_image(mut self, buf: &mut [u8]) -> ImageResult<()> {
1363        assert_eq!(u64::try_from(buf.len()), Ok(self.total_bytes()));
1364        self.read_image_data(buf)
1365    }
1366
1367    fn read_image_boxed(self: Box<Self>, buf: &mut [u8]) -> ImageResult<()> {
1368        (*self).read_image(buf)
1369    }
1370}
1371
1372impl<R: BufRead + Seek> ImageDecoderRect for BmpDecoder<R> {
1373    fn read_rect(
1374        &mut self,
1375        x: u32,
1376        y: u32,
1377        width: u32,
1378        height: u32,
1379        buf: &mut [u8],
1380        row_pitch: usize,
1381    ) -> ImageResult<()> {
1382        let start = self.reader.stream_position()?;
1383        load_rect(
1384            x,
1385            y,
1386            width,
1387            height,
1388            buf,
1389            row_pitch,
1390            self,
1391            self.total_bytes() as usize,
1392            |_, _| Ok(()),
1393            |s, buf| s.read_image_data(buf),
1394        )?;
1395        self.reader.seek(SeekFrom::Start(start))?;
1396        Ok(())
1397    }
1398}
1399
1400#[cfg(test)]
1401mod test {
1402    use std::io::{BufReader, Cursor};
1403
1404    use super::*;
1405
1406    #[test]
1407    fn test_bitfield_len() {
1408        for len in 1..9 {
1409            let bitfield = Bitfield { shift: 0, len };
1410            for i in 0..(1 << len) {
1411                let read = bitfield.read(i);
1412                let calc = (f64::from(i) / f64::from((1 << len) - 1) * 255f64).round() as u8;
1413                if read != calc {
1414                    println!("len:{len} i:{i} read:{read} calc:{calc}");
1415                }
1416                assert_eq!(read, calc);
1417            }
1418        }
1419    }
1420
1421    #[test]
1422    fn read_rect() {
1423        let f =
1424            BufReader::new(std::fs::File::open("tests/images/bmp/images/Core_8_Bit.bmp").unwrap());
1425        let mut decoder = BmpDecoder::new(f).unwrap();
1426
1427        let mut buf: Vec<u8> = vec![0; 8 * 8 * 3];
1428        decoder.read_rect(0, 0, 8, 8, &mut buf, 8 * 3).unwrap();
1429    }
1430
1431    #[test]
1432    fn read_rle_too_short() {
1433        let data = vec![
1434            0x42, 0x4d, 0x04, 0xee, 0xfe, 0xff, 0xff, 0x10, 0xff, 0x00, 0x04, 0x00, 0x00, 0x00,
1435            0x7c, 0x00, 0x00, 0x00, 0x0c, 0x41, 0x00, 0x00, 0x07, 0x10, 0x00, 0x00, 0x01, 0x00,
1436            0x04, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
1437            0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x21,
1438            0xff, 0x00, 0x66, 0x61, 0x72, 0x62, 0x66, 0x65, 0x6c, 0x64, 0x00, 0x00, 0x00, 0x00,
1439            0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1440            0xff, 0xd8, 0xff, 0x00, 0x00, 0x19, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1441            0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0xff, 0x00, 0x00, 0x00,
1442            0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00,
1443            0x00, 0x00, 0x00, 0x2d, 0x31, 0x31, 0x35, 0x36, 0x00, 0xff, 0x00, 0x00, 0x52, 0x3a,
1444            0x37, 0x30, 0x7e, 0x71, 0x63, 0x91, 0x5a, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
1445            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
1446            0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x35, 0x37, 0x00, 0xff, 0x00, 0x00, 0x52,
1447            0x3a, 0x37, 0x30, 0x7e, 0x71, 0x63, 0x91, 0x5a, 0x04, 0x05, 0x3c, 0x00, 0x00, 0x11,
1448            0x00, 0x5d, 0x7a, 0x82, 0xb7, 0xca, 0x2d, 0x31, 0xff, 0xff, 0xc7, 0x95, 0x33, 0x2e,
1449            0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00,
1450            0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x66, 0x00, 0x4d,
1451            0x4d, 0x00, 0x2a, 0x00,
1452        ];
1453
1454        let decoder = BmpDecoder::new(Cursor::new(&data)).unwrap();
1455        let mut buf = vec![0; usize::try_from(decoder.total_bytes()).unwrap()];
1456        assert!(decoder.read_image(&mut buf).is_ok());
1457    }
1458
1459    #[test]
1460    fn test_no_header() {
1461        let tests = [
1462            "Info_R8_G8_B8.bmp",
1463            "Info_A8_R8_G8_B8.bmp",
1464            "Info_8_Bit.bmp",
1465            "Info_4_Bit.bmp",
1466            "Info_1_Bit.bmp",
1467        ];
1468
1469        for name in &tests {
1470            let path = format!("tests/images/bmp/images/{name}");
1471            let ref_img = crate::open(&path).unwrap();
1472            let mut data = std::fs::read(&path).unwrap();
1473            // skip the BITMAPFILEHEADER
1474            let slice = &mut data[14..];
1475            let decoder = BmpDecoder::new_without_file_header(Cursor::new(slice)).unwrap();
1476            let no_hdr_img = crate::DynamicImage::from_decoder(decoder).unwrap();
1477            assert_eq!(ref_img, no_hdr_img);
1478        }
1479    }
1480}