diff --git a/src/decoder/ifd.rs b/src/decoder/ifd.rs index d5b9e0e..64faf99 100644 --- a/src/decoder/ifd.rs +++ b/src/decoder/ifd.rs @@ -122,10 +122,16 @@ impl Entry { decoder: &mut super::Decoder, ) -> TiffResult { let bo = decoder.byte_order(); - let bigtiff_value = if decoder.bigtiff && 4 < self.count && self.count <= 8 { + let bigtiff_value = if decoder.bigtiff { match (self.type_, self.count) { - (Type::BYTE, n) => Some(offset_to_bytes(n as usize, self)?), - (Type::SBYTE, n) => Some(offset_to_sbytes(n as usize, self)?), + (Type::BYTE, 5) => Some(offset_to_bytes(5, self)?), + (Type::BYTE, 6) => Some(offset_to_bytes(6, self)?), + (Type::BYTE, 7) => Some(offset_to_bytes(7, self)?), + (Type::BYTE, 8) => Some(offset_to_bytes(8, self)?), + (Type::SBYTE, 5) => Some(offset_to_sbytes(5, self)?), + (Type::SBYTE, 6) => Some(offset_to_sbytes(6, self)?), + (Type::SBYTE, 7) => Some(offset_to_sbytes(7, self)?), + (Type::SBYTE, 8) => Some(offset_to_sbytes(8, self)?), (Type::SHORT, 3) => { let mut r = self.r(bo); Some(List(vec![ @@ -249,7 +255,6 @@ impl Entry { Ok(SRational(decoder.read_slong()?.into(), decoder.read_slong()?.into())) }), (Type::ASCII, n) => { - println!("ASCIII COUNT {}", n); let n = usize::try_from(n)?; if n > limits.decoding_buffer_size { return Err(TiffError::LimitsExceeded); diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index c34d228..6160af4 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -528,7 +528,8 @@ impl Decoder { } Some(offset) => self.goto_offset(offset)?, } - for _ in 0..self.read_short()? { + let num_tags = if self.bigtiff { self.read_long8()? } else { self.read_short()?.into() }; + for _ in 0..num_tags { let (tag, entry) = match self.read_entry()? { Some(val) => val, None => continue, // Unknown data type in tag, skip @@ -545,7 +546,6 @@ impl Decoder { /// Tries to retrieve a tag. /// Return `Ok(None)` if the tag is not present. pub fn find_tag(&mut self, tag: Tag) -> TiffResult> { - println!("IFD {:?}", self.ifd.as_ref().unwrap().get(&tag)); let entry = match self.ifd.as_ref().unwrap().get(&tag) { None => return Ok(None), Some(entry) => entry.clone(), diff --git a/tests/decode_bigtiff_images.rs b/tests/decode_bigtiff_images.rs new file mode 100644 index 0000000..9113f42 --- /dev/null +++ b/tests/decode_bigtiff_images.rs @@ -0,0 +1,46 @@ +extern crate tiff; + +use tiff::decoder::Decoder; +use tiff::tags::Tag; +use tiff::ColorType; + +use std::fs::File; +use std::path::PathBuf; + +const TEST_IMAGE_DIR: &str = "./tests/images/bigtiff"; + +#[test] +fn test_big_tiff() { + let filenames = ["BigTIFF.tif", "BigTIFFMotorola.tif", "BigTIFFLong.tif"]; + for filename in filenames.iter() { + let path = PathBuf::from(TEST_IMAGE_DIR).join(filename); + let img_file = File::open(path).expect("Cannot find test image!"); + let mut decoder = Decoder::new(img_file).expect("Cannot create decoder"); + assert_eq!( + decoder.dimensions().expect("Cannot get dimensions"), + (64, 64) + ); + assert_eq!( + decoder.colortype().expect("Cannot get colortype"), + ColorType::RGB(8) + ); + assert_eq!( + decoder + .get_tag_u64(Tag::StripOffsets) + .expect("Cannot get StripOffsets"), + 16 + ); + assert_eq!( + decoder + .get_tag_u64(Tag::RowsPerStrip) + .expect("Cannot get RowsPerStrip"), + 64 + ); + assert_eq!( + decoder + .get_tag_u64(Tag::StripByteCounts) + .expect("Cannot get StripByteCounts"), + 12288 + ) + } +} diff --git a/tests/images/bigtiff/BigTIFF.tif b/tests/images/bigtiff/BigTIFF.tif new file mode 100644 index 0000000..8a0e5a2 Binary files /dev/null and b/tests/images/bigtiff/BigTIFF.tif differ diff --git a/tests/images/bigtiff/BigTIFFLong.tif b/tests/images/bigtiff/BigTIFFLong.tif new file mode 100644 index 0000000..1a321ef Binary files /dev/null and b/tests/images/bigtiff/BigTIFFLong.tif differ diff --git a/tests/images/bigtiff/BigTIFFMotorola.tif b/tests/images/bigtiff/BigTIFFMotorola.tif new file mode 100644 index 0000000..4699ecd Binary files /dev/null and b/tests/images/bigtiff/BigTIFFMotorola.tif differ