From 1f92c562bc25066483ac6d8f4001677ebd4d6b8a Mon Sep 17 00:00:00 2001 From: Andrew Champion Date: Tue, 10 Dec 2019 19:02:27 +0000 Subject: [PATCH] Support 32-bit rgb and rgba decoding --- src/decoder/mod.rs | 15 +++++++++++++-- tests/decode_images.rs | 19 +++++++++++++++++++ tests/images/gradient-3c-32b.tiff | Bin 0 -> 3401 bytes 3 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 tests/images/gradient-3c-32b.tiff diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index cfdbbe0..d754b94 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -273,8 +273,8 @@ where fn rev_hpredict(image: DecodingBuffer, size: (u32, u32), color_type: ColorType) -> TiffResult<()> { let samples = match color_type { ColorType::Gray(8) | ColorType::Gray(16) | ColorType::Gray(32) => 1, - ColorType::RGB(8) | ColorType::RGB(16) => 3, - ColorType::RGBA(8) | ColorType::RGBA(16) | ColorType::CMYK(8) => 4, + ColorType::RGB(8) | ColorType::RGB(16) | ColorType::RGB(32) => 3, + ColorType::RGBA(8) | ColorType::RGBA(16) | ColorType::RGBA(32) | ColorType::CMYK(8) => 4, _ => { return Err(TiffError::UnsupportedError( TiffUnsupportedError::HorizontalPredictor(color_type), @@ -339,6 +339,12 @@ impl Decoder { PhotometricInterpretation::RGB if self.bits_per_sample == [16, 16, 16] => { Ok(ColorType::RGB(16)) } + PhotometricInterpretation::RGB if self.bits_per_sample == [32, 32, 32, 32] => { + Ok(ColorType::RGBA(32)) + } + PhotometricInterpretation::RGB if self.bits_per_sample == [32, 32, 32] => { + Ok(ColorType::RGB(32)) + } PhotometricInterpretation::CMYK if self.bits_per_sample == [8, 8, 8, 8] => { Ok(ColorType::CMYK(8)) } @@ -684,6 +690,11 @@ impl Decoder { reader.read_u16_into(&mut buffer[..bytes / 2])?; bytes / 2 } + (ColorType::RGBA(32), DecodingBuffer::U32(ref mut buffer)) + | (ColorType::RGB(32), DecodingBuffer::U32(ref mut buffer)) => { + reader.read_u32_into(&mut buffer[..bytes / 4])?; + bytes / 4 + } (ColorType::Gray(32), DecodingBuffer::U32(ref mut buffer)) => { reader.read_u32_into(&mut buffer[..bytes / 4])?; if self.photometric_interpretation == PhotometricInterpretation::WhiteIsZero { diff --git a/tests/decode_images.rs b/tests/decode_images.rs index 9a6076a..900606f 100644 --- a/tests/decode_images.rs +++ b/tests/decode_images.rs @@ -103,6 +103,25 @@ fn test_rgb_u16() { } } +#[test] +fn test_rgb_u32() { + let img_file = File::open("./tests/images/gradient-3c-32b.tiff").expect("Cannot find test image!"); + let mut decoder = Decoder::new(img_file).expect("Cannot create decoder"); + assert_eq!(decoder.colortype().unwrap(), ColorType::RGB(32)); + let img_res = decoder.read_image().unwrap(); + if let DecodingResult::U32(res) = img_res { + let mut res_sum: u64 = 0; + for x in res { + res_sum += x as u64; + } + + assert_eq!(res_sum, 2030834111716); + } + else { + panic!("Wrong bit depth") + } +} + #[test] fn test_string_tags() { // these files have null-terminated strings for their Software tag. One has extra bytes after diff --git a/tests/images/gradient-3c-32b.tiff b/tests/images/gradient-3c-32b.tiff new file mode 100644 index 0000000000000000000000000000000000000000..d76596e2ce205a891b20bef66a51c81a911f8d12 GIT binary patch literal 3401 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