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