Coverage Report

Created: 2025-11-24 07:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/image/src/codecs/bmp/decoder.rs
Line
Count
Source
1
use crate::utils::vec_try_with_capacity;
2
use std::cmp::{self, Ordering};
3
use std::io::{self, BufRead, Seek, SeekFrom};
4
use std::iter::{repeat, Rev};
5
use std::slice::ChunksExactMut;
6
use std::{error, fmt};
7
8
use byteorder_lite::{LittleEndian, ReadBytesExt};
9
10
use crate::color::ColorType;
11
use crate::error::{
12
    DecodingError, ImageError, ImageResult, UnsupportedError, UnsupportedErrorKind,
13
};
14
use crate::io::free_functions::load_rect;
15
use crate::io::ReadExt;
16
use crate::{ImageDecoder, ImageDecoderRect, ImageFormat};
17
18
const BITMAPCOREHEADER_SIZE: u32 = 12;
19
const BITMAPINFOHEADER_SIZE: u32 = 40;
20
const BITMAPV2HEADER_SIZE: u32 = 52;
21
const BITMAPV3HEADER_SIZE: u32 = 56;
22
const BITMAPV4HEADER_SIZE: u32 = 108;
23
const BITMAPV5HEADER_SIZE: u32 = 124;
24
25
static LOOKUP_TABLE_3_BIT_TO_8_BIT: [u8; 8] = [0, 36, 73, 109, 146, 182, 219, 255];
26
static 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
];
29
static 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
];
33
static 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
40
static 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
};
46
const 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
};
52
const 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
59
const RLE_ESCAPE: u8 = 0;
60
const RLE_ESCAPE_EOL: u8 = 0;
61
const RLE_ESCAPE_EOF: u8 = 1;
62
const RLE_ESCAPE_DELTA: u8 = 2;
63
64
/// The maximum width/height the decoder will process.
65
const MAX_WIDTH_HEIGHT: i32 = 0xFFFF;
66
67
#[derive(PartialEq, Copy, Clone)]
68
enum ImageType {
69
    Palette,
70
    RGB16,
71
    RGB24,
72
    RGB32,
73
    RGBA32,
74
    RLE8,
75
    RLE4,
76
    Bitfields16,
77
    Bitfields32,
78
}
79
80
#[derive(PartialEq)]
81
enum BMPHeaderType {
82
    Core,
83
    Info,
84
    V2,
85
    V3,
86
    V4,
87
    V5,
88
}
89
90
#[derive(PartialEq)]
91
enum FormatFullBytes {
92
    RGB24,
93
    RGB32,
94
    RGBA32,
95
    Format888,
96
}
97
98
enum Chunker<'a> {
99
    FromTop(ChunksExactMut<'a, u8>),
100
    FromBottom(Rev<ChunksExactMut<'a, u8>>),
101
}
102
103
pub(crate) struct RowIterator<'a> {
104
    chunks: Chunker<'a>,
105
}
106
107
impl<'a> Iterator for RowIterator<'a> {
108
    type Item = &'a mut [u8];
109
110
    #[inline(always)]
111
4.66M
    fn next(&mut self) -> Option<&'a mut [u8]> {
112
4.66M
        match self.chunks {
113
0
            Chunker::FromTop(ref mut chunks) => chunks.next(),
114
4.66M
            Chunker::FromBottom(ref mut chunks) => chunks.next(),
115
        }
116
4.66M
    }
117
}
118
119
/// All errors that can occur when attempting to parse a BMP
120
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
121
enum 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
165
impl fmt::Display for DecoderError {
166
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
167
0
        match self {
168
0
            DecoderError::CorruptRleData => f.write_str("Corrupt RLE data"),
169
0
            DecoderError::BitfieldMaskNonContiguous => f.write_str("Non-contiguous bitfield mask"),
170
0
            DecoderError::BitfieldMaskInvalid => f.write_str("Invalid bitfield mask"),
171
0
            DecoderError::BitfieldMaskMissing(bb) => {
172
0
                f.write_fmt(format_args!("Missing {bb}-bit bitfield mask"))
173
            }
174
0
            DecoderError::BitfieldMasksMissing(bb) => {
175
0
                f.write_fmt(format_args!("Missing {bb}-bit bitfield masks"))
176
            }
177
0
            DecoderError::BmpSignatureInvalid => f.write_str("BMP signature not found"),
178
0
            DecoderError::MoreThanOnePlane => f.write_str("More than one plane"),
179
0
            DecoderError::InvalidChannelWidth(tp, n) => {
180
0
                f.write_fmt(format_args!("Invalid channel bit count for {tp}: {n}"))
181
            }
182
0
            DecoderError::NegativeWidth(w) => f.write_fmt(format_args!("Negative width ({w})")),
183
0
            DecoderError::ImageTooLarge(w, h) => f.write_fmt(format_args!(
184
0
                "Image too large (one of ({w}, {h}) > soft limit of {MAX_WIDTH_HEIGHT})"
185
            )),
186
0
            DecoderError::InvalidHeight => f.write_str("Invalid height"),
187
0
            DecoderError::ImageTypeInvalidForTopDown(tp) => f.write_fmt(format_args!(
188
0
                "Invalid image type {tp} for top-down image."
189
            )),
190
0
            DecoderError::ImageTypeUnknown(tp) => {
191
0
                f.write_fmt(format_args!("Unknown image compression type {tp}"))
192
            }
193
0
            DecoderError::HeaderTooSmall(s) => {
194
0
                f.write_fmt(format_args!("Bitmap header too small ({s} bytes)"))
195
            }
196
            DecoderError::PaletteSizeExceeded {
197
0
                colors_used,
198
0
                bit_count,
199
0
            } => f.write_fmt(format_args!(
200
0
                "Palette size {colors_used} exceeds maximum size for BMP with bit count of {bit_count}"
201
            )),
202
        }
203
0
    }
204
}
205
206
impl From<DecoderError> for ImageError {
207
877
    fn from(e: DecoderError) -> ImageError {
208
877
        ImageError::Decoding(DecodingError::new(ImageFormat::Bmp.into(), e))
209
877
    }
210
}
211
212
impl 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)]
216
enum 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
227
impl fmt::Display for ChannelWidthError {
228
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
229
0
        f.write_str(match self {
230
0
            ChannelWidthError::Rgb => "RGB",
231
0
            ChannelWidthError::Rle8 => "RLE8",
232
0
            ChannelWidthError::Rle4 => "RLE4",
233
0
            ChannelWidthError::Bitfields => "bitfields",
234
        })
235
0
    }
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.
240
4.20k
fn check_for_overflow(width: i32, length: i32, channels: usize) -> ImageResult<()> {
241
4.20k
    num_bytes(width, length, channels)
242
4.20k
        .map(|_| ())
243
4.20k
        .ok_or_else(|| {
244
10
            ImageError::Unsupported(UnsupportedError::from_format_and_kind(
245
10
                ImageFormat::Bmp.into(),
246
10
                UnsupportedErrorKind::GenericFeature(format!(
247
10
                    "Image dimensions ({width}x{length} w/{channels} channels) are too large"
248
10
                )),
249
10
            ))
250
10
        })
251
4.20k
}
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.
255
4.20k
fn num_bytes(width: i32, length: i32, channels: usize) -> Option<usize> {
256
4.20k
    if width <= 0 || length <= 0 {
257
10
        None
258
    } else {
259
4.19k
        match channels.checked_mul(width as usize) {
260
4.19k
            Some(n) => n.checked_mul(length as usize),
261
0
            None => None,
262
        }
263
    }
264
4.20k
}
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.
268
1.94k
fn with_rows<F>(
269
1.94k
    buffer: &mut [u8],
270
1.94k
    width: i32,
271
1.94k
    height: i32,
272
1.94k
    channels: usize,
273
1.94k
    top_down: bool,
274
1.94k
    mut func: F,
275
1.94k
) -> io::Result<()>
276
1.94k
where
277
1.94k
    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
1.94k
    let row_width = channels.checked_mul(width as usize).unwrap();
282
1.94k
    let full_image_size = row_width.checked_mul(height as usize).unwrap();
283
1.94k
    assert_eq!(buffer.len(), full_image_size);
284
285
1.94k
    if !top_down {
286
1.23M
        for row in buffer.chunks_mut(row_width).rev() {
287
1.23M
            func(row)?;
288
        }
289
    } else {
290
4.07M
        for row in buffer.chunks_mut(row_width) {
291
4.07M
            func(row)?;
292
        }
293
    }
294
284
    Ok(())
295
1.94k
}
image::codecs::bmp::decoder::with_rows::<<image::codecs::bmp::decoder::BmpDecoder<std::io::cursor::Cursor<&[u8]>>>::read_16_bit_pixel_data::{closure#0}>
Line
Count
Source
268
334
fn with_rows<F>(
269
334
    buffer: &mut [u8],
270
334
    width: i32,
271
334
    height: i32,
272
334
    channels: usize,
273
334
    top_down: bool,
274
334
    mut func: F,
275
334
) -> io::Result<()>
276
334
where
277
334
    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
334
    let row_width = channels.checked_mul(width as usize).unwrap();
282
334
    let full_image_size = row_width.checked_mul(height as usize).unwrap();
283
334
    assert_eq!(buffer.len(), full_image_size);
284
285
334
    if !top_down {
286
276k
        for row in buffer.chunks_mut(row_width).rev() {
287
276k
            func(row)?;
288
        }
289
    } else {
290
1.39M
        for row in buffer.chunks_mut(row_width) {
291
1.39M
            func(row)?;
292
        }
293
    }
294
47
    Ok(())
295
334
}
image::codecs::bmp::decoder::with_rows::<<image::codecs::bmp::decoder::BmpDecoder<std::io::cursor::Cursor<&[u8]>>>::read_32_bit_pixel_data::{closure#0}>
Line
Count
Source
268
280
fn with_rows<F>(
269
280
    buffer: &mut [u8],
270
280
    width: i32,
271
280
    height: i32,
272
280
    channels: usize,
273
280
    top_down: bool,
274
280
    mut func: F,
275
280
) -> io::Result<()>
276
280
where
277
280
    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
280
    let row_width = channels.checked_mul(width as usize).unwrap();
282
280
    let full_image_size = row_width.checked_mul(height as usize).unwrap();
283
280
    assert_eq!(buffer.len(), full_image_size);
284
285
280
    if !top_down {
286
110k
        for row in buffer.chunks_mut(row_width).rev() {
287
110k
            func(row)?;
288
        }
289
    } else {
290
5.63k
        for row in buffer.chunks_mut(row_width) {
291
5.63k
            func(row)?;
292
        }
293
    }
294
18
    Ok(())
295
280
}
image::codecs::bmp::decoder::with_rows::<<image::codecs::bmp::decoder::BmpDecoder<std::io::cursor::Cursor<&[u8]>>>::read_full_byte_pixel_data::{closure#0}>
Line
Count
Source
268
423
fn with_rows<F>(
269
423
    buffer: &mut [u8],
270
423
    width: i32,
271
423
    height: i32,
272
423
    channels: usize,
273
423
    top_down: bool,
274
423
    mut func: F,
275
423
) -> io::Result<()>
276
423
where
277
423
    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
423
    let row_width = channels.checked_mul(width as usize).unwrap();
282
423
    let full_image_size = row_width.checked_mul(height as usize).unwrap();
283
423
    assert_eq!(buffer.len(), full_image_size);
284
285
423
    if !top_down {
286
403k
        for row in buffer.chunks_mut(row_width).rev() {
287
403k
            func(row)?;
288
        }
289
    } else {
290
2.50M
        for row in buffer.chunks_mut(row_width) {
291
2.50M
            func(row)?;
292
        }
293
    }
294
59
    Ok(())
295
423
}
image::codecs::bmp::decoder::with_rows::<<image::codecs::bmp::decoder::BmpDecoder<std::io::cursor::Cursor<&[u8]>>>::read_palettized_pixel_data::{closure#1}>
Line
Count
Source
268
905
fn with_rows<F>(
269
905
    buffer: &mut [u8],
270
905
    width: i32,
271
905
    height: i32,
272
905
    channels: usize,
273
905
    top_down: bool,
274
905
    mut func: F,
275
905
) -> io::Result<()>
276
905
where
277
905
    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
905
    let row_width = channels.checked_mul(width as usize).unwrap();
282
905
    let full_image_size = row_width.checked_mul(height as usize).unwrap();
283
905
    assert_eq!(buffer.len(), full_image_size);
284
285
905
    if !top_down {
286
447k
        for row in buffer.chunks_mut(row_width).rev() {
287
447k
            func(row)?;
288
        }
289
    } else {
290
166k
        for row in buffer.chunks_mut(row_width) {
291
166k
            func(row)?;
292
        }
293
    }
294
160
    Ok(())
295
905
}
296
297
2.92k
fn set_8bit_pixel_run<'a, T: Iterator<Item = &'a u8>>(
298
2.92k
    pixel_iter: &mut ChunksExactMut<u8>,
299
2.92k
    palette: &[[u8; 3]],
300
2.92k
    indices: T,
301
2.92k
    n_pixels: usize,
302
2.92k
) -> bool {
303
449k
    for idx in indices.take(n_pixels) {
304
449k
        if let Some(pixel) = pixel_iter.next() {
305
449k
            let rgb = palette[*idx as usize];
306
449k
            pixel[0] = rgb[0];
307
449k
            pixel[1] = rgb[1];
308
449k
            pixel[2] = rgb[2];
309
449k
        } else {
310
32
            return false;
311
        }
312
    }
313
2.89k
    true
314
2.92k
}
315
316
1.04M
fn set_4bit_pixel_run<'a, T: Iterator<Item = &'a u8>>(
317
1.04M
    pixel_iter: &mut ChunksExactMut<u8>,
318
1.04M
    palette: &[[u8; 3]],
319
1.04M
    indices: T,
320
1.04M
    mut n_pixels: usize,
321
1.04M
) -> bool {
322
8.13M
    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
7.93M
        set_pixel!(idx >> 4);
340
7.17M
        set_pixel!(idx & 0xf);
341
    }
342
1.04M
    true
343
1.04M
}
image::codecs::bmp::decoder::set_4bit_pixel_run::<core::slice::iter::Iter<u8>>
Line
Count
Source
316
227k
fn set_4bit_pixel_run<'a, T: Iterator<Item = &'a u8>>(
317
227k
    pixel_iter: &mut ChunksExactMut<u8>,
318
227k
    palette: &[[u8; 3]],
319
227k
    indices: T,
320
227k
    mut n_pixels: usize,
321
227k
) -> bool {
322
2.24M
    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
2.04M
        set_pixel!(idx >> 4);
340
2.03M
        set_pixel!(idx & 0xf);
341
    }
342
227k
    true
343
227k
}
image::codecs::bmp::decoder::set_4bit_pixel_run::<core::iter::sources::repeat::Repeat<&u8>>
Line
Count
Source
316
822k
fn set_4bit_pixel_run<'a, T: Iterator<Item = &'a u8>>(
317
822k
    pixel_iter: &mut ChunksExactMut<u8>,
318
822k
    palette: &[[u8; 3]],
319
822k
    indices: T,
320
822k
    mut n_pixels: usize,
321
822k
) -> bool {
322
5.89M
    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
5.89M
        set_pixel!(idx >> 4);
340
5.14M
        set_pixel!(idx & 0xf);
341
    }
342
822k
    true
343
822k
}
344
345
#[rustfmt::skip]
346
4.41k
fn set_2bit_pixel_run<'a, T: Iterator<Item = &'a u8>>(
347
4.41k
    pixel_iter: &mut ChunksExactMut<u8>,
348
4.41k
    palette: &[[u8; 3]],
349
4.41k
    indices: T,
350
4.41k
    mut n_pixels: usize,
351
4.41k
) -> bool {
352
375k
    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
374k
        set_pixel!((idx >> 6) & 0x3u8);
370
373k
        set_pixel!((idx >> 4) & 0x3u8);
371
372k
        set_pixel!((idx >> 2) & 0x3u8);
372
371k
        set_pixel!( idx       & 0x3u8);
373
    }
374
4.41k
    true
375
4.41k
}
376
377
605k
fn set_1bit_pixel_run<'a, T: Iterator<Item = &'a u8>>(
378
605k
    pixel_iter: &mut ChunksExactMut<u8>,
379
605k
    palette: &[[u8; 3]],
380
605k
    indices: T,
381
605k
) {
382
2.48M
    for idx in indices {
383
2.30M
        let mut bit = 0x80;
384
        loop {
385
17.3M
            if let Some(pixel) = pixel_iter.next() {
386
16.9M
                let rgb = palette[usize::from((idx & bit) != 0)];
387
16.9M
                pixel[0] = rgb[0];
388
16.9M
                pixel[1] = rgb[1];
389
16.9M
                pixel[2] = rgb[2];
390
16.9M
            } else {
391
431k
                return;
392
            }
393
394
16.9M
            bit >>= 1;
395
16.9M
            if bit == 0 {
396
1.87M
                break;
397
15.0M
            }
398
        }
399
    }
400
605k
}
401
402
#[derive(PartialEq, Eq)]
403
struct Bitfield {
404
    shift: u32,
405
    len: u32,
406
}
407
408
impl Bitfield {
409
2.41k
    fn from_mask(mask: u32, max_len: u32) -> ImageResult<Bitfield> {
410
2.41k
        if mask == 0 {
411
352
            return Ok(Bitfield { shift: 0, len: 0 });
412
2.06k
        }
413
2.06k
        let mut shift = mask.trailing_zeros();
414
2.06k
        let mut len = (!(mask >> shift)).trailing_zeros();
415
2.06k
        if len != mask.count_ones() {
416
58
            return Err(DecoderError::BitfieldMaskNonContiguous.into());
417
2.00k
        }
418
2.00k
        if len + shift > max_len {
419
10
            return Err(DecoderError::BitfieldMaskInvalid.into());
420
1.99k
        }
421
1.99k
        if len > 8 {
422
666
            shift += len - 8;
423
666
            len = 8;
424
1.33k
        }
425
1.99k
        Ok(Bitfield { shift, len })
426
2.41k
    }
427
428
8.28M
    fn read(&self, data: u32) -> u8 {
429
8.28M
        let data = data >> self.shift;
430
8.28M
        match self.len {
431
93.1k
            1 => ((data & 0b1) * 0xff) as u8,
432
64.0k
            2 => ((data & 0b11) * 0x55) as u8,
433
664k
            3 => LOOKUP_TABLE_3_BIT_TO_8_BIT[(data & 0b00_0111) as usize],
434
50.1k
            4 => LOOKUP_TABLE_4_BIT_TO_8_BIT[(data & 0b00_1111) as usize],
435
5.79M
            5 => LOOKUP_TABLE_5_BIT_TO_8_BIT[(data & 0b01_1111) as usize],
436
609k
            6 => LOOKUP_TABLE_6_BIT_TO_8_BIT[(data & 0b11_1111) as usize],
437
3.53k
            7 => (((data & 0x7f) << 1) | ((data & 0x7f) >> 6)) as u8,
438
1.00M
            8 => (data & 0xff) as u8,
439
0
            _ => panic!(),
440
        }
441
8.28M
    }
442
}
443
444
#[derive(PartialEq, Eq)]
445
struct Bitfields {
446
    r: Bitfield,
447
    g: Bitfield,
448
    b: Bitfield,
449
    a: Bitfield,
450
}
451
452
impl Bitfields {
453
642
    fn from_mask(
454
642
        r_mask: u32,
455
642
        g_mask: u32,
456
642
        b_mask: u32,
457
642
        a_mask: u32,
458
642
        max_len: u32,
459
642
    ) -> ImageResult<Bitfields> {
460
574
        let bitfields = Bitfields {
461
642
            r: Bitfield::from_mask(r_mask, max_len)?,
462
607
            g: Bitfield::from_mask(g_mask, max_len)?,
463
591
            b: Bitfield::from_mask(b_mask, max_len)?,
464
577
            a: Bitfield::from_mask(a_mask, max_len)?,
465
        };
466
574
        if bitfields.r.len == 0 || bitfields.g.len == 0 || bitfields.b.len == 0 {
467
9
            return Err(DecoderError::BitfieldMaskMissing(max_len).into());
468
565
        }
469
565
        Ok(bitfields)
470
642
    }
471
}
472
473
/// A bmp decoder
474
pub 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
495
enum RLEInsn {
496
    EndOfFile,
497
    EndOfRow,
498
    Delta(u8, u8),
499
    Absolute(u8, Vec<u8>),
500
    PixelRun(u8, u8),
501
}
502
503
impl<R: BufRead + Seek> BmpDecoder<R> {
504
4.55k
    fn new_decoder(reader: R) -> BmpDecoder<R> {
505
4.55k
        BmpDecoder {
506
4.55k
            reader,
507
4.55k
508
4.55k
            bmp_header_type: BMPHeaderType::Info,
509
4.55k
            indexed_color: false,
510
4.55k
511
4.55k
            width: 0,
512
4.55k
            height: 0,
513
4.55k
            data_offset: 0,
514
4.55k
            top_down: false,
515
4.55k
            no_file_header: false,
516
4.55k
            add_alpha_channel: false,
517
4.55k
            has_loaded_metadata: false,
518
4.55k
            image_type: ImageType::Palette,
519
4.55k
520
4.55k
            bit_count: 0,
521
4.55k
            colors_used: 0,
522
4.55k
            palette: None,
523
4.55k
            bitfields: None,
524
4.55k
        }
525
4.55k
    }
526
527
    /// Create a new decoder that decodes from the stream ```r```
528
2.06k
    pub fn new(reader: R) -> ImageResult<BmpDecoder<R>> {
529
2.06k
        let mut decoder = Self::new_decoder(reader);
530
2.06k
        decoder.read_metadata()?;
531
1.53k
        Ok(decoder)
532
2.06k
    }
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
0
    pub fn new_without_file_header(reader: R) -> ImageResult<BmpDecoder<R>> {
538
0
        let mut decoder = Self::new_decoder(reader);
539
0
        decoder.no_file_header = true;
540
0
        decoder.read_metadata()?;
541
0
        Ok(decoder)
542
0
    }
543
544
    #[cfg(feature = "ico")]
545
2.49k
    pub(crate) fn new_with_ico_format(reader: R) -> ImageResult<BmpDecoder<R>> {
546
2.49k
        let mut decoder = Self::new_decoder(reader);
547
2.49k
        decoder.read_metadata_in_ico_format()?;
548
1.91k
        Ok(decoder)
549
2.49k
    }
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
0
    pub fn set_indexed_color(&mut self, indexed_color: bool) {
554
0
        self.indexed_color = indexed_color;
555
0
    }
556
557
    #[cfg(feature = "ico")]
558
527
    pub(crate) fn reader(&mut self) -> &mut R {
559
527
        &mut self.reader
560
527
    }
561
562
4.55k
    fn read_file_header(&mut self) -> ImageResult<()> {
563
4.55k
        if self.no_file_header {
564
2.49k
            return Ok(());
565
2.06k
        }
566
2.06k
        let mut signature = [0; 2];
567
2.06k
        self.reader.read_exact(&mut signature)?;
568
569
2.05k
        if signature != b"BM"[..] {
570
25
            return Err(DecoderError::BmpSignatureInvalid.into());
571
2.02k
        }
572
573
        // The next 8 bytes represent file size, followed the 4 reserved bytes
574
        // We're not interesting these values
575
2.02k
        self.reader.read_u32::<LittleEndian>()?;
576
2.02k
        self.reader.read_u32::<LittleEndian>()?;
577
578
2.01k
        self.data_offset = u64::from(self.reader.read_u32::<LittleEndian>()?);
579
580
2.01k
        Ok(())
581
4.55k
    }
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
802
    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
802
        self.width = i32::from(self.reader.read_u16::<LittleEndian>()?);
590
800
        self.height = i32::from(self.reader.read_u16::<LittleEndian>()?);
591
592
798
        check_for_overflow(self.width, self.height, self.num_channels())?;
593
594
        // Number of planes (format specifies that this should be 1).
595
793
        if self.reader.read_u16::<LittleEndian>()? != 1 {
596
42
            return Err(DecoderError::MoreThanOnePlane.into());
597
730
        }
598
599
730
        self.bit_count = self.reader.read_u16::<LittleEndian>()?;
600
726
        self.image_type = match self.bit_count {
601
555
            1 | 4 | 8 => ImageType::Palette,
602
164
            24 => ImageType::RGB24,
603
            _ => {
604
7
                return Err(DecoderError::InvalidChannelWidth(
605
7
                    ChannelWidthError::Rgb,
606
7
                    self.bit_count,
607
7
                )
608
7
                .into())
609
            }
610
        };
611
612
719
        Ok(())
613
802
    }
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
3.53k
    fn read_bitmap_info_header(&mut self) -> ImageResult<()> {
620
3.53k
        self.width = self.reader.read_i32::<LittleEndian>()?;
621
3.52k
        self.height = self.reader.read_i32::<LittleEndian>()?;
622
623
        // Width can not be negative
624
3.51k
        if self.width < 0 {
625
65
            return Err(DecoderError::NegativeWidth(self.width).into());
626
3.45k
        } 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
38
            return Err(DecoderError::ImageTooLarge(self.width, self.height).into());
630
3.41k
        }
631
632
3.41k
        if self.height == i32::MIN {
633
2
            return Err(DecoderError::InvalidHeight.into());
634
3.41k
        }
635
636
        // A negative height indicates a top-down DIB.
637
3.41k
        if self.height < 0 {
638
598
            self.height *= -1;
639
598
            self.top_down = true;
640
2.81k
        }
641
642
3.41k
        check_for_overflow(self.width, self.height, self.num_channels())?;
643
644
        // Number of planes (format specifies that this should be 1).
645
3.40k
        if self.reader.read_u16::<LittleEndian>()? != 1 {
646
75
            return Err(DecoderError::MoreThanOnePlane.into());
647
3.24k
        }
648
649
3.24k
        self.bit_count = self.reader.read_u16::<LittleEndian>()?;
650
3.24k
        let image_type_u32 = self.reader.read_u32::<LittleEndian>()?;
651
652
        // Top-down dibs can not be compressed.
653
3.23k
        if self.top_down && image_type_u32 != 0 && image_type_u32 != 3 {
654
2
            return Err(DecoderError::ImageTypeInvalidForTopDown(image_type_u32).into());
655
3.23k
        }
656
3.23k
        self.image_type = match image_type_u32 {
657
126
            0 => match self.bit_count {
658
497
                1 | 2 | 4 | 8 => ImageType::Palette,
659
202
                16 => ImageType::RGB16,
660
39
                24 => ImageType::RGB24,
661
56
                32 if self.add_alpha_channel => ImageType::RGBA32,
662
70
                32 => ImageType::RGB32,
663
                _ => {
664
2
                    return Err(DecoderError::InvalidChannelWidth(
665
2
                        ChannelWidthError::Rgb,
666
2
                        self.bit_count,
667
2
                    )
668
2
                    .into())
669
                }
670
            },
671
611
            1 => match self.bit_count {
672
580
                8 => ImageType::RLE8,
673
                _ => {
674
31
                    return Err(DecoderError::InvalidChannelWidth(
675
31
                        ChannelWidthError::Rle8,
676
31
                        self.bit_count,
677
31
                    )
678
31
                    .into())
679
                }
680
            },
681
984
            2 => match self.bit_count {
682
951
                4 => ImageType::RLE4,
683
                _ => {
684
33
                    return Err(DecoderError::InvalidChannelWidth(
685
33
                        ChannelWidthError::Rle4,
686
33
                        self.bit_count,
687
33
                    )
688
33
                    .into())
689
                }
690
            },
691
677
            3 => match self.bit_count {
692
181
                16 => ImageType::Bitfields16,
693
493
                32 => ImageType::Bitfields32,
694
                _ => {
695
3
                    return Err(DecoderError::InvalidChannelWidth(
696
3
                        ChannelWidthError::Bitfields,
697
3
                        self.bit_count,
698
3
                    )
699
3
                    .into())
700
                }
701
            },
702
            4 => {
703
                // JPEG compression is not implemented yet.
704
2
                return Err(ImageError::Unsupported(
705
2
                    UnsupportedError::from_format_and_kind(
706
2
                        ImageFormat::Bmp.into(),
707
2
                        UnsupportedErrorKind::GenericFeature("JPEG compression".to_owned()),
708
2
                    ),
709
2
                ));
710
            }
711
            5 => {
712
                // PNG compression is not implemented yet.
713
2
                return Err(ImageError::Unsupported(
714
2
                    UnsupportedError::from_format_and_kind(
715
2
                        ImageFormat::Bmp.into(),
716
2
                        UnsupportedErrorKind::GenericFeature("PNG compression".to_owned()),
717
2
                    ),
718
2
                ));
719
            }
720
90
            11..=13 => {
721
                // CMYK types are not implemented yet.
722
3
                return Err(ImageError::Unsupported(
723
3
                    UnsupportedError::from_format_and_kind(
724
3
                        ImageFormat::Bmp.into(),
725
3
                        UnsupportedErrorKind::GenericFeature("CMYK format".to_owned()),
726
3
                    ),
727
3
                ));
728
            }
729
            _ => {
730
                // Unknown compression type.
731
92
                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
3.06k
        self.reader.read_u32::<LittleEndian>()?;
740
3.04k
        self.reader.read_u32::<LittleEndian>()?;
741
3.03k
        self.reader.read_u32::<LittleEndian>()?;
742
743
3.03k
        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
3.02k
        self.reader.read_u32::<LittleEndian>()?;
748
749
3.01k
        Ok(())
750
3.53k
    }
751
752
667
    fn read_bitmasks(&mut self) -> ImageResult<()> {
753
667
        let r_mask = self.reader.read_u32::<LittleEndian>()?;
754
659
        let g_mask = self.reader.read_u32::<LittleEndian>()?;
755
654
        let b_mask = self.reader.read_u32::<LittleEndian>()?;
756
757
645
        let a_mask = match self.bmp_header_type {
758
            BMPHeaderType::V3 | BMPHeaderType::V4 | BMPHeaderType::V5 => {
759
286
                self.reader.read_u32::<LittleEndian>()?
760
            }
761
359
            _ => 0,
762
        };
763
764
642
        self.bitfields = match self.image_type {
765
            ImageType::Bitfields16 => {
766
171
                Some(Bitfields::from_mask(r_mask, g_mask, b_mask, a_mask, 16)?)
767
            }
768
            ImageType::Bitfields32 => {
769
471
                Some(Bitfields::from_mask(r_mask, g_mask, b_mask, a_mask, 32)?)
770
            }
771
0
            _ => None,
772
        };
773
774
565
        if self.bitfields.is_some() && a_mask != 0 {
775
245
            self.add_alpha_channel = true;
776
320
        }
777
778
565
        Ok(())
779
667
    }
780
781
4.55k
    fn read_metadata(&mut self) -> ImageResult<()> {
782
4.55k
        if !self.has_loaded_metadata {
783
4.55k
            self.read_file_header()?;
784
4.50k
            let bmp_header_offset = self.reader.stream_position()?;
785
4.50k
            let bmp_header_size = self.reader.read_u32::<LittleEndian>()?;
786
4.50k
            let bmp_header_end = bmp_header_offset + u64::from(bmp_header_size);
787
788
171
            self.bmp_header_type = match bmp_header_size {
789
802
                BITMAPCOREHEADER_SIZE => BMPHeaderType::Core,
790
2.72k
                BITMAPINFOHEADER_SIZE => BMPHeaderType::Info,
791
198
                BITMAPV2HEADER_SIZE => BMPHeaderType::V2,
792
419
                BITMAPV3HEADER_SIZE => BMPHeaderType::V3,
793
113
                BITMAPV4HEADER_SIZE => BMPHeaderType::V4,
794
76
                BITMAPV5HEADER_SIZE => BMPHeaderType::V5,
795
171
                _ if bmp_header_size < BITMAPCOREHEADER_SIZE => {
796
                    // Size of any valid header types won't be smaller than core header type.
797
13
                    return Err(DecoderError::HeaderTooSmall(bmp_header_size).into());
798
                }
799
                _ => {
800
158
                    return Err(ImageError::Unsupported(
801
158
                        UnsupportedError::from_format_and_kind(
802
158
                            ImageFormat::Bmp.into(),
803
158
                            UnsupportedErrorKind::GenericFeature(format!(
804
158
                                "Unknown bitmap header type (size={bmp_header_size})"
805
158
                            )),
806
158
                        ),
807
158
                    ))
808
                }
809
            };
810
811
4.33k
            match self.bmp_header_type {
812
                BMPHeaderType::Core => {
813
802
                    self.read_bitmap_core_header()?;
814
                }
815
                BMPHeaderType::Info
816
                | BMPHeaderType::V2
817
                | BMPHeaderType::V3
818
                | BMPHeaderType::V4
819
                | BMPHeaderType::V5 => {
820
3.53k
                    self.read_bitmap_info_header()?;
821
                }
822
            }
823
824
3.73k
            let mut bitmask_bytes_offset = 0;
825
3.73k
            if self.image_type == ImageType::Bitfields16
826
3.55k
                || self.image_type == ImageType::Bitfields32
827
            {
828
667
                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
284
                if matches!(
837
565
                    self.bmp_header_type,
838
                    BMPHeaderType::Info | BMPHeaderType::V4 | BMPHeaderType::V5
839
281
                ) {
840
281
                    // This is `size_of::<u32>() * 3` (a red, green, and blue mask), but with less noise.
841
281
                    bitmask_bytes_offset = 12;
842
284
                }
843
3.07k
            };
844
845
3.63k
            self.reader
846
3.63k
                .seek(SeekFrom::Start(bmp_header_end + bitmask_bytes_offset))?;
847
848
3.63k
            match self.image_type {
849
2.55k
                ImageType::Palette | ImageType::RLE4 | ImageType::RLE8 => self.read_palette()?,
850
1.08k
                _ => {}
851
            }
852
853
3.44k
            if self.no_file_header {
854
                // Use the offset of the end of metadata instead of reading a BMP file header.
855
1.91k
                self.data_offset = self.reader.stream_position()?;
856
1.53k
            }
857
858
3.44k
            self.has_loaded_metadata = true;
859
0
        }
860
3.44k
        Ok(())
861
4.55k
    }
862
863
    #[cfg(feature = "ico")]
864
    #[doc(hidden)]
865
2.49k
    pub fn read_metadata_in_ico_format(&mut self) -> ImageResult<()> {
866
2.49k
        self.no_file_header = true;
867
2.49k
        self.add_alpha_channel = true;
868
2.49k
        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
1.91k
        self.height /= 2;
873
1.91k
        Ok(())
874
2.49k
    }
875
876
2.55k
    fn get_palette_size(&mut self) -> ImageResult<usize> {
877
2.55k
        match self.colors_used {
878
837
            0 => Ok(1 << self.bit_count),
879
            _ => {
880
1.71k
                if self.colors_used > 1 << self.bit_count {
881
140
                    return Err(DecoderError::PaletteSizeExceeded {
882
140
                        colors_used: self.colors_used,
883
140
                        bit_count: self.bit_count,
884
140
                    }
885
140
                    .into());
886
1.57k
                }
887
1.57k
                Ok(self.colors_used as usize)
888
            }
889
        }
890
2.55k
    }
891
892
2.55k
    fn bytes_per_color(&self) -> usize {
893
2.55k
        match self.bmp_header_type {
894
555
            BMPHeaderType::Core => 3,
895
1.99k
            _ => 4,
896
        }
897
2.55k
    }
898
899
2.55k
    fn read_palette(&mut self) -> ImageResult<()> {
900
        const MAX_PALETTE_SIZE: usize = 256; // Palette indices are u8.
901
902
2.55k
        let bytes_per_color = self.bytes_per_color();
903
2.55k
        let palette_size = self.get_palette_size()?;
904
2.41k
        let max_length = MAX_PALETTE_SIZE * bytes_per_color;
905
906
2.41k
        let length = palette_size * bytes_per_color;
907
2.41k
        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
2.41k
        buf.resize(cmp::min(length, max_length), 0);
913
2.41k
        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
2.36k
        match length.cmp(&max_length) {
918
            Ordering::Greater => {
919
0
                self.reader
920
0
                    .seek(SeekFrom::Current((length - max_length) as i64))?;
921
            }
922
2.33k
            Ordering::Less => buf.resize(max_length, 0),
923
33
            Ordering::Equal => (),
924
        }
925
926
2.36k
        let p: Vec<[u8; 3]> = (0..MAX_PALETTE_SIZE)
927
605k
            .map(|i| {
928
605k
                let b = buf[bytes_per_color * i];
929
605k
                let g = buf[bytes_per_color * i + 1];
930
605k
                let r = buf[bytes_per_color * i + 2];
931
605k
                [r, g, b]
932
605k
            })
933
2.36k
            .collect();
934
935
2.36k
        self.palette = Some(p);
936
937
2.36k
        Ok(())
938
2.55k
    }
939
940
    /// Get the palette that is embedded in the BMP image, if any.
941
0
    pub fn get_palette(&self) -> Option<&[[u8; 3]]> {
942
0
        self.palette.as_ref().map(|vec| &vec[..])
943
0
    }
944
945
8.98k
    fn num_channels(&self) -> usize {
946
8.98k
        if self.indexed_color {
947
0
            1
948
8.98k
        } else if self.add_alpha_channel {
949
5.21k
            4
950
        } else {
951
3.77k
            3
952
        }
953
8.98k
    }
954
955
1.41k
    fn rows<'a>(&self, pixel_data: &'a mut [u8]) -> RowIterator<'a> {
956
1.41k
        let stride = self.width as usize * self.num_channels();
957
1.41k
        if self.top_down {
958
0
            RowIterator {
959
0
                chunks: Chunker::FromTop(pixel_data.chunks_exact_mut(stride)),
960
0
            }
961
        } else {
962
1.41k
            RowIterator {
963
1.41k
                chunks: Chunker::FromBottom(pixel_data.chunks_exact_mut(stride).rev()),
964
1.41k
            }
965
        }
966
1.41k
    }
967
968
905
    fn read_palettized_pixel_data(&mut self, buf: &mut [u8]) -> ImageResult<()> {
969
905
        let num_channels = self.num_channels();
970
905
        let row_byte_length = ((i32::from(self.bit_count) * self.width + 31) / 32 * 4) as usize;
971
905
        let mut indices = vec![0; row_byte_length];
972
905
        let palette = self.palette.as_ref().unwrap();
973
905
        let bit_count = self.bit_count;
974
905
        let reader = &mut self.reader;
975
905
        let width = self.width as usize;
976
905
        let skip_palette = self.indexed_color;
977
978
905
        reader.seek(SeekFrom::Start(self.data_offset))?;
979
980
905
        if num_channels == 4 {
981
4.42G
            buf.chunks_exact_mut(4).for_each(|c| c[3] = 0xFF);
982
451
        }
983
984
905
        with_rows(
985
905
            buf,
986
905
            self.width,
987
905
            self.height,
988
905
            num_channels,
989
905
            self.top_down,
990
613k
            |row| {
991
613k
                reader.read_exact(&mut indices)?;
992
613k
                if skip_palette {
993
0
                    row.clone_from_slice(&indices[0..width]);
994
0
                } else {
995
613k
                    let mut pixel_iter = row.chunks_exact_mut(num_channels);
996
613k
                    match bit_count {
997
605k
                        1 => {
998
605k
                            set_1bit_pixel_run(&mut pixel_iter, palette, indices.iter());
999
605k
                        }
1000
4.41k
                        2 => {
1001
4.41k
                            set_2bit_pixel_run(&mut pixel_iter, palette, indices.iter(), width);
1002
4.41k
                        }
1003
2.28k
                        4 => {
1004
2.28k
                            set_4bit_pixel_run(&mut pixel_iter, palette, indices.iter(), width);
1005
2.28k
                        }
1006
1.37k
                        8 => {
1007
1.37k
                            set_8bit_pixel_run(&mut pixel_iter, palette, indices.iter(), width);
1008
1.37k
                        }
1009
0
                        _ => panic!(),
1010
                    }
1011
                }
1012
613k
                Ok(())
1013
613k
            },
1014
745
        )?;
1015
1016
160
        Ok(())
1017
905
    }
1018
1019
334
    fn read_16_bit_pixel_data(
1020
334
        &mut self,
1021
334
        buf: &mut [u8],
1022
334
        bitfields: Option<&Bitfields>,
1023
334
    ) -> ImageResult<()> {
1024
334
        let num_channels = self.num_channels();
1025
334
        let row_padding_len = self.width as usize % 2 * 2;
1026
334
        let row_padding = &mut [0; 2][..row_padding_len];
1027
334
        let bitfields = match bitfields {
1028
192
            Some(b) => b,
1029
142
            None => self.bitfields.as_ref().unwrap(),
1030
        };
1031
334
        let reader = &mut self.reader;
1032
1033
334
        reader.seek(SeekFrom::Start(self.data_offset))?;
1034
1035
334
        with_rows(
1036
334
            buf,
1037
334
            self.width,
1038
334
            self.height,
1039
334
            num_channels,
1040
334
            self.top_down,
1041
1.67M
            |row| {
1042
2.29M
                for pixel in row.chunks_mut(num_channels) {
1043
2.29M
                    let data = u32::from(reader.read_u16::<LittleEndian>()?);
1044
1045
2.29M
                    pixel[0] = bitfields.r.read(data);
1046
2.29M
                    pixel[1] = bitfields.g.read(data);
1047
2.29M
                    pixel[2] = bitfields.b.read(data);
1048
2.29M
                    if num_channels == 4 {
1049
994k
                        if bitfields.a.len != 0 {
1050
359k
                            pixel[3] = bitfields.a.read(data);
1051
634k
                        } else {
1052
634k
                            pixel[3] = 0xFF;
1053
634k
                        }
1054
1.29M
                    }
1055
                }
1056
1.67M
                reader.read_exact(row_padding)
1057
1.67M
            },
1058
287
        )?;
1059
1060
47
        Ok(())
1061
334
    }
1062
1063
    /// Read image data from a reader in 32-bit formats that use bitfields.
1064
280
    fn read_32_bit_pixel_data(&mut self, buf: &mut [u8]) -> ImageResult<()> {
1065
280
        let num_channels = self.num_channels();
1066
1067
280
        let bitfields = self.bitfields.as_ref().unwrap();
1068
1069
280
        let reader = &mut self.reader;
1070
280
        reader.seek(SeekFrom::Start(self.data_offset))?;
1071
1072
280
        with_rows(
1073
280
            buf,
1074
280
            self.width,
1075
280
            self.height,
1076
280
            num_channels,
1077
280
            self.top_down,
1078
116k
            |row| {
1079
314k
                for pixel in row.chunks_mut(num_channels) {
1080
314k
                    let data = reader.read_u32::<LittleEndian>()?;
1081
1082
313k
                    pixel[0] = bitfields.r.read(data);
1083
313k
                    pixel[1] = bitfields.g.read(data);
1084
313k
                    pixel[2] = bitfields.b.read(data);
1085
313k
                    if num_channels == 4 {
1086
207k
                        if bitfields.a.len != 0 {
1087
105k
                            pixel[3] = bitfields.a.read(data);
1088
105k
                        } else {
1089
101k
                            pixel[3] = 0xff;
1090
101k
                        }
1091
106k
                    }
1092
                }
1093
115k
                Ok(())
1094
116k
            },
1095
262
        )?;
1096
1097
18
        Ok(())
1098
280
    }
1099
1100
    /// Read image data from a reader where the colours are stored as 8-bit values (24 or 32-bit).
1101
423
    fn read_full_byte_pixel_data(
1102
423
        &mut self,
1103
423
        buf: &mut [u8],
1104
423
        format: &FormatFullBytes,
1105
423
    ) -> ImageResult<()> {
1106
423
        let num_channels = self.num_channels();
1107
423
        let row_padding_len = match *format {
1108
191
            FormatFullBytes::RGB24 => (4 - (self.width as usize * 3) % 4) % 4,
1109
232
            _ => 0,
1110
        };
1111
423
        let row_padding = &mut [0; 4][..row_padding_len];
1112
1113
423
        self.reader.seek(SeekFrom::Start(self.data_offset))?;
1114
1115
423
        let reader = &mut self.reader;
1116
1117
423
        with_rows(
1118
423
            buf,
1119
423
            self.width,
1120
423
            self.height,
1121
423
            num_channels,
1122
423
            self.top_down,
1123
2.90M
            |row| {
1124
5.17M
                for pixel in row.chunks_mut(num_channels) {
1125
5.17M
                    if *format == FormatFullBytes::Format888 {
1126
992k
                        reader.read_u8()?;
1127
4.17M
                    }
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
5.17M
                    reader.read_exact(&mut pixel[0..3])?;
1133
5.17M
                    pixel[0..3].reverse();
1134
1135
5.17M
                    if *format == FormatFullBytes::RGB32 {
1136
2.20M
                        reader.read_u8()?;
1137
2.96M
                    }
1138
1139
                    // Read the alpha channel if present
1140
5.17M
                    if *format == FormatFullBytes::RGBA32 {
1141
1.96M
                        reader.read_exact(&mut pixel[3..4])?;
1142
3.21M
                    } else if num_channels == 4 {
1143
390k
                        pixel[3] = 0xFF;
1144
2.82M
                    }
1145
                }
1146
2.90M
                reader.read_exact(row_padding)
1147
2.90M
            },
1148
364
        )?;
1149
1150
59
        Ok(())
1151
423
    }
1152
1153
1.41k
    fn read_rle_data(&mut self, buf: &mut [u8], image_type: ImageType) -> ImageResult<()> {
1154
        // Seek to the start of the actual image data.
1155
1.41k
        self.reader.seek(SeekFrom::Start(self.data_offset))?;
1156
1157
1.41k
        let num_channels = self.num_channels();
1158
1.41k
        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
1.41k
        let mut row_iter = self.rows(buf);
1165
1166
489k
        while let Some(row) = row_iter.next() {
1167
489k
            let mut pixel_iter = row.chunks_exact_mut(num_channels);
1168
1169
489k
            let mut x = 0;
1170
            loop {
1171
1.97M
                let instruction = {
1172
1.97M
                    let control_byte = self.reader.read_u8()?;
1173
1.97M
                    match control_byte {
1174
                        RLE_ESCAPE => {
1175
1.04M
                            let op = self.reader.read_u8()?;
1176
1177
1.04M
                            match op {
1178
487k
                                RLE_ESCAPE_EOL => RLEInsn::EndOfRow,
1179
437
                                RLE_ESCAPE_EOF => RLEInsn::EndOfFile,
1180
                                RLE_ESCAPE_DELTA => {
1181
329k
                                    let xdelta = self.reader.read_u8()?;
1182
329k
                                    let ydelta = self.reader.read_u8()?;
1183
329k
                                    RLEInsn::Delta(xdelta, ydelta)
1184
                                }
1185
                                _ => {
1186
226k
                                    let mut length = op as usize;
1187
226k
                                    if self.image_type == ImageType::RLE4 {
1188
225k
                                        length = length.div_ceil(2);
1189
225k
                                    }
1190
226k
                                    length += length & 1;
1191
226k
                                    let mut buffer = Vec::new();
1192
226k
                                    self.reader.read_exact_vec(&mut buffer, length)?;
1193
226k
                                    RLEInsn::Absolute(op, buffer)
1194
                                }
1195
                            }
1196
                        }
1197
                        _ => {
1198
933k
                            let palette_index = self.reader.read_u8()?;
1199
933k
                            RLEInsn::PixelRun(control_byte, palette_index)
1200
                        }
1201
                    }
1202
                };
1203
1204
1.97M
                match instruction {
1205
                    RLEInsn::EndOfFile => {
1206
4.37M
                        pixel_iter.for_each(|p| p.fill(0));
1207
3.53M
                        row_iter.for_each(|r| r.fill(0));
1208
437
                        return Ok(());
1209
                    }
1210
                    RLEInsn::EndOfRow => {
1211
1.14G
                        pixel_iter.for_each(|p| p.fill(0));
1212
487k
                        break;
1213
                    }
1214
329k
                    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
329k
                        if y_delta > 0 {
1222
                            // Zero out the remainder of the current row.
1223
211M
                            pixel_iter.for_each(|p| p.fill(0));
1224
1225
                            // If any full rows are skipped, zero them out.
1226
45.9k
                            for _ in 1..y_delta {
1227
589k
                                let row = row_iter.next().ok_or(DecoderError::CorruptRleData)?;
1228
589k
                                row.fill(0);
1229
                            }
1230
1231
                            // Set the pixel iterator to the start of the next row.
1232
45.8k
                            pixel_iter = row_iter
1233
45.8k
                                .next()
1234
45.8k
                                .ok_or(DecoderError::CorruptRleData)?
1235
45.8k
                                .chunks_exact_mut(num_channels);
1236
1237
                            // Zero out the pixels up to the current point in the row.
1238
45.8k
                            for _ in 0..x {
1239
6.74M
                                pixel_iter
1240
6.74M
                                    .next()
1241
6.74M
                                    .ok_or(DecoderError::CorruptRleData)?
1242
6.74M
                                    .fill(0);
1243
                            }
1244
283k
                        }
1245
1246
329k
                        for _ in 0..x_delta {
1247
1.53M
                            let pixel = pixel_iter.next().ok_or(DecoderError::CorruptRleData)?;
1248
1.53M
                            pixel.fill(0);
1249
                        }
1250
329k
                        x += x_delta as usize;
1251
                    }
1252
226k
                    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
226k
                        match image_type {
1257
                            ImageType::RLE8 => {
1258
1.54k
                                if !set_8bit_pixel_run(
1259
1.54k
                                    &mut pixel_iter,
1260
1.54k
                                    p,
1261
1.54k
                                    indices.iter(),
1262
1.54k
                                    length as usize,
1263
1.54k
                                ) {
1264
32
                                    return Err(DecoderError::CorruptRleData.into());
1265
1.51k
                                }
1266
                            }
1267
                            ImageType::RLE4 => {
1268
224k
                                if !set_4bit_pixel_run(
1269
224k
                                    &mut pixel_iter,
1270
224k
                                    p,
1271
224k
                                    indices.iter(),
1272
224k
                                    length as usize,
1273
224k
                                ) {
1274
41
                                    return Err(DecoderError::CorruptRleData.into());
1275
224k
                                }
1276
                            }
1277
0
                            _ => unreachable!(),
1278
                        }
1279
226k
                        x += length as usize;
1280
                    }
1281
933k
                    RLEInsn::PixelRun(n_pixels, palette_index) => {
1282
933k
                        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
110k
                                let repeat_pixel: [u8; 3] = p[palette_index as usize];
1291
1.02M
                                (&mut pixel_iter).take(n_pixels as usize).for_each(|p| {
1292
1.02M
                                    p[2] = repeat_pixel[2];
1293
1.02M
                                    p[1] = repeat_pixel[1];
1294
1.02M
                                    p[0] = repeat_pixel[0];
1295
1.02M
                                });
1296
                            }
1297
                            ImageType::RLE4 => {
1298
822k
                                if !set_4bit_pixel_run(
1299
822k
                                    &mut pixel_iter,
1300
822k
                                    p,
1301
822k
                                    repeat(&palette_index),
1302
822k
                                    n_pixels as usize,
1303
822k
                                ) {
1304
70
                                    return Err(DecoderError::CorruptRleData.into());
1305
822k
                                }
1306
                            }
1307
0
                            _ => unreachable!(),
1308
                        }
1309
933k
                        x += n_pixels as usize;
1310
                    }
1311
                }
1312
            }
1313
        }
1314
1315
11
        Ok(())
1316
1.41k
    }
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
3.35k
    pub(crate) fn read_image_data(&mut self, buf: &mut [u8]) -> ImageResult<()> {
1321
3.35k
        match self.image_type {
1322
905
            ImageType::Palette => self.read_palettized_pixel_data(buf),
1323
192
            ImageType::RGB16 => self.read_16_bit_pixel_data(buf, Some(&R5_G5_B5_COLOR_MASK)),
1324
191
            ImageType::RGB24 => self.read_full_byte_pixel_data(buf, &FormatFullBytes::RGB24),
1325
57
            ImageType::RGB32 => self.read_full_byte_pixel_data(buf, &FormatFullBytes::RGB32),
1326
55
            ImageType::RGBA32 => self.read_full_byte_pixel_data(buf, &FormatFullBytes::RGBA32),
1327
536
            ImageType::RLE8 => self.read_rle_data(buf, ImageType::RLE8),
1328
880
            ImageType::RLE4 => self.read_rle_data(buf, ImageType::RLE4),
1329
142
            ImageType::Bitfields16 => match self.bitfields {
1330
142
                Some(_) => self.read_16_bit_pixel_data(buf, None),
1331
0
                None => Err(DecoderError::BitfieldMasksMissing(16).into()),
1332
            },
1333
400
            ImageType::Bitfields32 => match self.bitfields {
1334
                Some(R8_G8_B8_COLOR_MASK) => {
1335
73
                    self.read_full_byte_pixel_data(buf, &FormatFullBytes::Format888)
1336
                }
1337
                Some(R8_G8_B8_A8_COLOR_MASK) => {
1338
47
                    self.read_full_byte_pixel_data(buf, &FormatFullBytes::RGBA32)
1339
                }
1340
280
                Some(_) => self.read_32_bit_pixel_data(buf),
1341
0
                None => Err(DecoderError::BitfieldMasksMissing(32).into()),
1342
            },
1343
        }
1344
3.35k
    }
1345
}
1346
1347
impl<R: BufRead + Seek> ImageDecoder for BmpDecoder<R> {
1348
19.0k
    fn dimensions(&self) -> (u32, u32) {
1349
19.0k
        (self.width as u32, self.height as u32)
1350
19.0k
    }
1351
1352
15.5k
    fn color_type(&self) -> ColorType {
1353
15.5k
        if self.indexed_color {
1354
0
            ColorType::L8
1355
15.5k
        } else if self.add_alpha_channel {
1356
10.2k
            ColorType::Rgba8
1357
        } else {
1358
5.34k
            ColorType::Rgb8
1359
        }
1360
15.5k
    }
1361
1362
1.50k
    fn read_image(mut self, buf: &mut [u8]) -> ImageResult<()> {
1363
1.50k
        assert_eq!(u64::try_from(buf.len()), Ok(self.total_bytes()));
1364
1.50k
        self.read_image_data(buf)
1365
1.50k
    }
1366
1367
1.50k
    fn read_image_boxed(self: Box<Self>, buf: &mut [u8]) -> ImageResult<()> {
1368
1.50k
        (*self).read_image(buf)
1369
1.50k
    }
1370
}
1371
1372
impl<R: BufRead + Seek> ImageDecoderRect for BmpDecoder<R> {
1373
0
    fn read_rect(
1374
0
        &mut self,
1375
0
        x: u32,
1376
0
        y: u32,
1377
0
        width: u32,
1378
0
        height: u32,
1379
0
        buf: &mut [u8],
1380
0
        row_pitch: usize,
1381
0
    ) -> ImageResult<()> {
1382
0
        let start = self.reader.stream_position()?;
1383
0
        load_rect(
1384
0
            x,
1385
0
            y,
1386
0
            width,
1387
0
            height,
1388
0
            buf,
1389
0
            row_pitch,
1390
0
            self,
1391
0
            self.total_bytes() as usize,
1392
0
            |_, _| Ok(()),
1393
0
            |s, buf| s.read_image_data(buf),
1394
0
        )?;
1395
0
        self.reader.seek(SeekFrom::Start(start))?;
1396
0
        Ok(())
1397
0
    }
1398
}
1399
1400
#[cfg(test)]
1401
mod 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
}