image/codecs/bmp/
decoder.rs

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