From 0c53e1066a8dae3bf5fc3660c82499c94c9f763b Mon Sep 17 00:00:00 2001 From: Andrew Champion Date: Tue, 10 Dec 2019 19:41:57 +0000 Subject: [PATCH] Support 64-bit rgb and rgba decoding --- src/decoder/mod.rs | 15 +++++++++++++-- tests/decode_images.rs | 19 +++++++++++++++++++ tests/images/gradient-3c-64b.tiff | Bin 0 -> 6480 bytes 3 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 tests/images/gradient-3c-64b.tiff diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 0b6719e..933d6c1 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -295,8 +295,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) | ColorType::Gray(64) => 1, - ColorType::RGB(8) | ColorType::RGB(16) | ColorType::RGB(32) => 3, - ColorType::RGBA(8) | ColorType::RGBA(16) | ColorType::RGBA(32) | ColorType::CMYK(8) => 4, + ColorType::RGB(8) | ColorType::RGB(16) | ColorType::RGB(32) | ColorType::RGB(64) => 3, + ColorType::RGBA(8) | ColorType::RGBA(16) | ColorType::RGBA(32) | ColorType::RGBA(64) | ColorType::CMYK(8) => 4, _ => { return Err(TiffError::UnsupportedError( TiffUnsupportedError::HorizontalPredictor(color_type), @@ -370,6 +370,12 @@ impl Decoder { PhotometricInterpretation::RGB if self.bits_per_sample == [32, 32, 32] => { Ok(ColorType::RGB(32)) } + PhotometricInterpretation::RGB if self.bits_per_sample == [64, 64, 64, 64] => { + Ok(ColorType::RGBA(64)) + } + PhotometricInterpretation::RGB if self.bits_per_sample == [64, 64, 64] => { + Ok(ColorType::RGB(64)) + } PhotometricInterpretation::CMYK if self.bits_per_sample == [8, 8, 8, 8] => { Ok(ColorType::CMYK(8)) } @@ -720,6 +726,11 @@ impl Decoder { reader.read_u32_into(&mut buffer[..bytes / 4])?; bytes / 4 } + (ColorType::RGBA(64), DecodingBuffer::U64(ref mut buffer)) + | (ColorType::RGB(64), DecodingBuffer::U64(ref mut buffer)) => { + reader.read_u64_into(&mut buffer[..bytes / 8])?; + bytes / 8 + } (ColorType::Gray(64), DecodingBuffer::U64(ref mut buffer)) => { reader.read_u64_into(&mut buffer[..bytes / 8])?; if self.photometric_interpretation == PhotometricInterpretation::WhiteIsZero { diff --git a/tests/decode_images.rs b/tests/decode_images.rs index 04ca7ef..ae1e573 100644 --- a/tests/decode_images.rs +++ b/tests/decode_images.rs @@ -142,6 +142,25 @@ fn test_rgb_u32() { } } +#[test] +fn test_rgb_u64() { + let img_file = File::open("./tests/images/gradient-3c-64b.tiff").expect("Cannot find test image!"); + let mut decoder = Decoder::new(img_file).expect("Cannot create decoder"); + assert_eq!(decoder.colortype().unwrap(), ColorType::RGB(64)); + let img_res = decoder.read_image().unwrap(); + if let DecodingResult::U64(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-64b.tiff b/tests/images/gradient-3c-64b.tiff new file mode 100644 index 0000000000000000000000000000000000000000..0c5c4dcb5820a7cfbbf4fe644b7530451f88dc90 GIT binary patch literal 6480 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 SK%@M=QfKMKyj6Wa