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