From 797e3dca07b47aefa55f6a3dcda063d15e8fa2e6 Mon Sep 17 00:00:00 2001 From: Etienne Prothon Date: Fri, 24 Jul 2020 00:47:14 +0200 Subject: [PATCH] fix: Big tiff decoding and add tests --- src/decoder/ifd.rs | 13 +++++-- src/decoder/mod.rs | 4 +- tests/decode_bigtiff_images.rs | 46 +++++++++++++++++++++++ tests/images/bigtiff/BigTIFF.tif | Bin 0 -> 12480 bytes tests/images/bigtiff/BigTIFFLong.tif | Bin 0 -> 12480 bytes tests/images/bigtiff/BigTIFFMotorola.tif | Bin 0 -> 12480 bytes 6 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 tests/decode_bigtiff_images.rs create mode 100644 tests/images/bigtiff/BigTIFF.tif create mode 100644 tests/images/bigtiff/BigTIFFLong.tif create mode 100644 tests/images/bigtiff/BigTIFFMotorola.tif 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 0000000000000000000000000000000000000000..8a0e5a2459cdfd006e51efc1ffdee2eba52d6784 GIT binary patch literal 12480 zcmeI3OKux65JX2d5P0bKYc&?hjT2Gd&~pjFXzT;|f2_)It+P+aMbV8qu<$&B(V= zXzO%me84XxvcN+@JnLA^ge*Ev0HpM5e=dZ0MGm*4{Q3+z*TPU!NE$SqwAW*@i3$Lu zc>DGk@z6h)oSl@cgR1CYxD|oL5^hD%Y=y-x>8FDr2hr5YB-oNJRI1u>BaCIAFhOD& zY_c#2n{6jCmeV*WNGyX*76xIn?Igx>8V3c5Ww6P@AZ)gs#8^(_pdhgfHdz>i&9;*m z%V``GB$mM@3xlxPb`oPbje~;3GT3Bc5O!^Q?-Sg&ekMAC*W`m-P7B6=KK}<#;Q9Rh zC$Rj+o-FjI??)#wmeckL{SM1ulZF2D{pcjda@szj-(eYSve2KtADzTlPTME+J1m1u z7W&ioqYVbXL@Hk#<-bkoi=zjBq@098c}NHn$DOD%VD9<&b?EVIjO!~q!L?U z3g^hNzLpdujLr$w!PZ`Fn)r6zgYUs~XwTX9sZZPHOAfb2R9XSZIn}||UOWB)bM3%E zxe0d-zYRfK2Q?$V1ITH0I=1$TGjJb1r$nFF8oV^-OMk?Nw>Xmb&Bx29Xrd zox`m%+n$wQ(zq;}X!sBe(d>LA=+(}O&^jmT9>HvTMsaIjJ1au#oTz&Qv+Wtht$ppR z2(5FX?h(wkXB4;gwX-6$&WXB5Fx#F{+}hX9iqJYI>K?&tdq#0zt^21hefK z#f`q{w*YxvUXM$WALZXPm&SwnBHnAsdy`)hNd4`H$$KfaKaKY;`B!=UGTv+XABf+^ T`zSvZ_+z|7ey5OXkFx#)S4oj9 literal 0 HcmV?d00001 diff --git a/tests/images/bigtiff/BigTIFFLong.tif b/tests/images/bigtiff/BigTIFFLong.tif new file mode 100644 index 0000000000000000000000000000000000000000..1a321ef1b92739fcfeb5c385146606c04e9cda19 GIT binary patch literal 12480 zcmeI3O>P@8428#WQDm7e+8&~t9wFP@$~Si?J@JW>En1Pnodsj&i9e5@1_t7~@W;o$ zxBqgHbq#(Umm~D`!W@32qkJNVQ0vv;On+con6Nje5)B%~=L-y-hJ z?O?j?UCwb0AX8pH$XU(cviJhO494OSxD~-*D+DYh6&?Z+dqtT<5M-H+K-);_YR9E* zw@@HKRzfp^dS+VzFz|HO(wC2x%=C=VGm&K8jw}2KCJQYPZI{Gl*(`M{(ukG~Hlw)B zLfc4p#s~aDA`3he#Iq5rS&&7?34m07>Cc4}uc+a6R9~MV=UNzQ3MqqTB<=N>G*JP7 zlyBc2BObV_E$Bi(Sxw4KCQF5{peu?#lZ7=&GI?|p*%*3U#o@S1#(%Voj%&*%T(2|S;_ z{{)ub*prR^^!@B4#&X#{q3^H^HreP;-_K5BESK#Q`VPxrla2oL{p=*ha@jti@30Iu z+2~K-&o&tR5~+M~l>auRFODAkk#Y(O;f-^OXXmLSj4PYb9V)h6@QY`u{1y~ExZ3zg zk1J>S?J1~5V2uwo#jiF3Q|r|^MMNV(QR><^27M@UYdT|YEQf`@jodp$nUnh4MJfp^ zOyL|wY+PFk5=Q5O8o}0HZJEUFx(DBb>Cm3D^{G$W)=LeyMpRk>$Tc;Bt-W^q1Lo?$ zLD_`6hTo>3Z3I1|cn6Tn>U3=F6=&=s2zFMwEzG&)0l(Cs4A)z78&|JNOSa^a7Z^lR zKz9*tmDze$ektR!Y@!i|V2Z&mjsm^fSrJ<2MBO8pt!EUs`r26$TIWRFBbcpc6u0`? zSrJ<2MBO8pt!EUs`r26$TIWRFBbcpc6u0`?SrJ<2MBO8pt!EUs`r26$TIWRFBbcpc z6gPa+ZvpZ;osUzI@8#b#rzVEri^R^Q?p1zCApO^$rtYQm{yP1j-<#B57AoruUHFDWu+`tWQ_DkuCrL literal 0 HcmV?d00001 diff --git a/tests/images/bigtiff/BigTIFFMotorola.tif b/tests/images/bigtiff/BigTIFFMotorola.tif new file mode 100644 index 0000000000000000000000000000000000000000..4699ecd7bc8ba60d79b8c9449b59affe83e94c1f GIT binary patch literal 12480 zcmeI3O;Q^%5QS%;D#a2ONe+<>N8ke7$u}o0J@r#dw%S6XcUGvGr`Lan~ zwoZ4(JN!Z-3p^CWvyRnF$fDx}KuW*#=R$~A@gJ|kx5^PBqDpl>c5yrAlm>{tX zHdz>i&9;*m%V``GB$mM@3xlxPb`oPbje~;3GT3Bc5H{ORVl1a|P>@&#n=A~%X4^@O z9bp8uUE@Ob|I z6Igy>PZs*q_oI^-%W3Qcgl4yy~3%+}NHn$DOD%VD9fom;0Ub5eb~NF}zy z6wZ-jeJv?S7@ZTUgRQ;VH1X}a1>b||(4MpHQ=hiYmmF@5sI&r*bE<=_y>|Qq=GuXS zaueovLcwO6GjTk4V*7(`M) zcMiA8YgepjSI9LhGEUdjzxX8O5!A?W_o`bE57M%(iC~xAwKO zBDBtlx<@eEo>AP|*UpO2Iw$HL!EAd*acf^YD?;m>sCxvn?HR?beeJ9Wt#hL85zMw{ z6nE42