From bf79af8de40d7336ce27548c598b6ce5d7b72885 Mon Sep 17 00:00:00 2001 From: "A. Molzer" <5550310+197g@users.noreply.github.com> Date: Fri, 6 Mar 2026 06:26:41 +0100 Subject: [PATCH] Add Decoder::open, deprecate new --- benches/lzw.rs | 9 ++-- examples/decode.rs | 2 +- examples/tiff-ls.rs | 11 ++--- src/decoder/mod.rs | 62 +++++++++++++++---------- src/encoder/writer.rs | 4 +- tests/decode_bigtiff_images.rs | 4 +- tests/decode_fp16_images.rs | 25 ++++++++-- tests/decode_geotiff_images.rs | 14 ++---- tests/decode_images.rs | 62 +++++++++++++++++-------- tests/decode_libtiffpic.rs | 13 ++---- tests/decode_planes.rs | 9 ++-- tests/encode_images.rs | 49 ++++++++++++------- tests/encode_images_with_compression.rs | 3 +- tests/fuzz_tests.rs | 3 +- tests/predict.rs | 10 ++-- tests/subsubifds.rs | 4 +- 16 files changed, 176 insertions(+), 108 deletions(-) diff --git a/benches/lzw.rs b/benches/lzw.rs index 47f513b..0c9c73d 100644 --- a/benches/lzw.rs +++ b/benches/lzw.rs @@ -8,13 +8,12 @@ use tiff::decoder::Decoder; fn read_image(image: &[u8]) { let image = std::io::Cursor::new(image); - let decoder = Decoder::new(black_box(image)); - let mut reader = decoder.unwrap(); + let decoder = Decoder::open(black_box(image)); - while { + let mut reader = decoder.unwrap(); + while reader.more_images() { reader.read_image().unwrap(); - reader.more_images() - } {} + } } fn main() { diff --git a/examples/decode.rs b/examples/decode.rs index 2bad4a1..cd3d42e 100644 --- a/examples/decode.rs +++ b/examples/decode.rs @@ -8,7 +8,7 @@ fn main() -> Result<(), Box> { let file = std::fs::File::open(image)?; let io = std::io::BufReader::new(file); - let mut reader = Decoder::new(io)?; + let mut reader = Decoder::open(io)?; let mut data = DecodingResult::I8(vec![]); diff --git a/examples/tiff-ls.rs b/examples/tiff-ls.rs index 39da35e..a3aae16 100644 --- a/examples/tiff-ls.rs +++ b/examples/tiff-ls.rs @@ -10,14 +10,11 @@ fn main() -> Result<(), Box> { let file = std::fs::File::open(image)?; let io = std::io::BufReader::new(file); - let mut reader = Decoder::new(io)?; + let mut reader = Decoder::open(io)?; - loop { + while reader.more_images() { + reader.next_directory()?; ls_dir(&mut reader); - - if !reader.more_images() { - break; - } } Ok(()) @@ -29,7 +26,7 @@ fn ls_dir(reader: &mut Decoder) { } println!("Name\tHex\tType\tCount"); - let ifd = reader.image_ifd(); + let ifd = reader.current_ifd(); for (tag, entry) in ifd.directory().iter() { let name: &'static str = match tag { diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 7c931a8..05a90f6 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -857,6 +857,11 @@ impl TiffHeader { } impl Decoder { + /// Create a decoder and attempt to parse the first image directory. + /// + /// To open a file without parsing any directory yet (for instance to retain a [`Decoder`] on + /// errors in the directory), use [`TiffHeader::parse`] and [`TiffHeader::open`] instead.. + #[deprecated = "Prefer `Decoder::open`. These methods will become aliases in a future major release."] pub fn new(mut r: R) -> TiffResult> { let header = TiffHeader::parse(&mut r)?; let mut decoder = header.open(r); @@ -1483,9 +1488,10 @@ impl Decoder { /// let mut result = DecodingResult::U8(vec![]); /// /// let mut reader = /* */ - /// # Decoder::new(std::io::Cursor::new(include_bytes!(concat!( + /// # Decoder::open(std::io::Cursor::new(include_bytes!(concat!( /// # env!("CARGO_MANIFEST_DIR"), "/tests/images/tiled-gray-i1.tif" /// # )))).unwrap(); + /// # reader.next_image().unwrap(); /// let layout = reader.read_image_to_buffer(&mut result)?; /// /// if result.as_buffer(0).as_bytes().len() < layout.complete_len { @@ -1503,10 +1509,10 @@ impl Decoder { /// let mut result = DecodingResult::I8(vec![]); /// /// let mut reader = /* */ - /// # Decoder::new(std::io::Cursor::new(include_bytes!(concat!( + /// # Decoder::open(std::io::Cursor::new(include_bytes!(concat!( /// # env!("CARGO_MANIFEST_DIR"), "/tests/images/tiled-gray-i1.tif" /// # )))).unwrap(); - /// + /// # reader.next_image().unwrap(); /// reader.read_image_to_buffer(&mut result)?; /// /// # Ok::<_, tiff::TiffError>(()) @@ -1589,7 +1595,7 @@ impl Decoder { /// This may be used with any directory, valid image or otherwise. When the decoder has not /// read a directory yet (a state after [`TiffHeader::open`]) the decoder will represent an /// empty directory with only the next pointer set. - pub fn image_ifd(&mut self) -> IfdDecoder<'_> { + pub fn current_ifd(&mut self) -> IfdDecoder<'_> { IfdDecoder { inner: tag_reader::TagReader { decoder: &mut self.value_reader, @@ -1611,7 +1617,9 @@ impl Decoder { /// /// # use std::io::Cursor; /// # let mut data = Cursor::new(vec![0]); - /// let mut decoder = Decoder::new(&mut data).unwrap(); + /// let mut decoder = Decoder::open(&mut data)?; + /// + /// decoder.next_directory()?; /// let sub_ifds = decoder.get_tag(Tag::SubIfd)?.into_ifd_vec()?; /// /// for ifd in sub_ifds { @@ -1634,13 +1642,13 @@ impl Decoder { /// Tries to retrieve a tag from the current image directory. /// Return `Ok(None)` if the tag is not present. pub fn find_tag(&mut self, tag: Tag) -> TiffResult> { - self.image_ifd().find_tag(tag) + self.current_ifd().find_tag(tag) } /// Tries to retrieve a tag in the current image directory and convert it to the desired /// unsigned type. pub fn find_tag_unsigned>(&mut self, tag: Tag) -> TiffResult> { - self.image_ifd().find_tag_unsigned(tag) + self.current_ifd().find_tag_unsigned(tag) } /// Tries to retrieve a vector of all a tag's values and convert them to the desired unsigned @@ -1649,19 +1657,19 @@ impl Decoder { &mut self, tag: Tag, ) -> TiffResult>> { - self.image_ifd().find_tag_unsigned_vec(tag) + self.current_ifd().find_tag_unsigned_vec(tag) } /// Tries to retrieve a tag from the current image directory and convert it to the desired /// unsigned type. Returns an error if the tag is not present. pub fn get_tag_unsigned>(&mut self, tag: Tag) -> TiffResult { - self.image_ifd().get_tag_unsigned(tag) + self.current_ifd().get_tag_unsigned(tag) } /// Tries to retrieve a tag from the current image directory. /// Returns an error if the tag is not present pub fn get_tag(&mut self, tag: Tag) -> TiffResult { - self.image_ifd().get_tag(tag) + self.current_ifd().get_tag(tag) } pub fn get_tag_u32(&mut self, tag: Tag) -> TiffResult { @@ -1716,7 +1724,7 @@ impl Decoder { } pub fn tag_iter(&mut self) -> impl Iterator> + '_ { - self.image_ifd().tag_iter() + self.current_ifd().tag_iter() } } @@ -1972,9 +1980,11 @@ mod tests { )) .unwrap(); - let mut decoder = Decoder::new(file).unwrap(); + let mut decoder = Decoder::open(file).unwrap(); let file_bo = decoder.byte_order(); - let mut ifd = decoder.image_ifd(); + + decoder.next_image().unwrap(); + let mut ifd = decoder.current_ifd(); { let value = ifd @@ -2041,25 +2051,26 @@ mod tests { let (first_ptr, second_ptr, third_ptr); { - let mut decoder = Decoder::new(&mut cursor).unwrap(); + let mut decoder = Decoder::open(&mut cursor).unwrap(); + decoder.next_image().unwrap(); first_ptr = decoder.ifd_pointer(); - let first_ifd = decoder.image_ifd(); + let first_ifd = decoder.current_ifd(); assert!(first_ifd.directory().get(Tag::ImageWidth).is_some()); assert!(decoder.more_images()); assert!(decoder.next_image().is_err()); - let broken_ifd = decoder.image_ifd(); + let broken_ifd = decoder.current_ifd(); assert!(broken_ifd.directory().get(Tag::ImageWidth).is_some()); assert!(decoder.next_directory().is_ok()); second_ptr = decoder.ifd_pointer(); - let second_ifd = decoder.image_ifd(); + let second_ifd = decoder.current_ifd(); assert!(second_ifd.directory().get(Tag::ImageWidth).is_none()); assert!(decoder.more_images()); assert!(decoder.next_image().is_ok()); third_ptr = decoder.ifd_pointer(); - let third_ifd = decoder.image_ifd(); + let third_ifd = decoder.current_ifd(); assert!(third_ifd.directory().get(Tag::ImageWidth).is_some()); assert!(!decoder.more_images()); @@ -2073,13 +2084,14 @@ mod tests { cursor.set_position(0); { - let mut seek_immediately = Decoder::new(&mut cursor).unwrap(); + let mut seek_immediately = Decoder::open(&mut cursor).unwrap(); + assert!(seek_immediately.seek_to_image(0).is_ok()); assert_eq!(seek_immediately.ifd_pointer(), first_ptr); assert!(seek_immediately.seek_to_image(1).is_err()); assert!(seek_immediately.seek_to_image(2).is_ok()); assert_eq!(seek_immediately.ifd_pointer(), third_ptr); assert!(seek_immediately - .image_ifd() + .current_ifd() .directory() .get(Tag::ImageWidth) .is_some()); @@ -2088,11 +2100,11 @@ mod tests { cursor.set_position(0); { - let mut seek_immediately = Decoder::new(&mut cursor).unwrap(); + let mut seek_immediately = Decoder::open(&mut cursor).unwrap(); assert!(seek_immediately.seek_to_directory(1).is_ok()); assert_eq!(seek_immediately.ifd_pointer(), second_ptr); assert!(seek_immediately - .image_ifd() + .current_ifd() .directory() .get(Tag::ImageWidth) .is_none()); @@ -2115,19 +2127,19 @@ mod tests { let header = super::TiffHeader::parse(&mut cursor).unwrap(); let mut decoder = header.open(cursor); - let indicated_next = decoder.image_ifd().directory().next(); + let indicated_next = decoder.current_ifd().directory().next(); assert!(decoder.more_images()); assert_eq!(decoder.ifd_pointer(), None); assert!(decoder.next_directory().is_ok()); - let first_ifd = decoder.image_ifd(); + let first_ifd = decoder.current_ifd(); assert!(first_ifd.directory().get(Tag::ImageWidth).is_none()); assert!(decoder.more_images()); assert_eq!(decoder.ifd_pointer(), indicated_next); assert!(decoder.next_image().is_ok()); - let second_ifd = decoder.image_ifd(); + let second_ifd = decoder.current_ifd(); assert!(second_ifd.directory().get(Tag::ImageWidth).is_some()); assert!(!decoder.more_images()); } diff --git a/src/encoder/writer.rs b/src/encoder/writer.rs index 468ddf5..f204483 100644 --- a/src/encoder/writer.rs +++ b/src/encoder/writer.rs @@ -241,7 +241,9 @@ fn encoder_on_short_writes() { } write.inner.set_position(0); - let mut tiff_reader = crate::decoder::Decoder::new(&mut write.inner).unwrap(); + + let mut tiff_reader = crate::decoder::Decoder::open(&mut write.inner).unwrap(); + tiff_reader.next_image().unwrap(); let _layout = tiff_reader.read_image_to_buffer(&mut data).unwrap(); assert!( diff --git a/tests/decode_bigtiff_images.rs b/tests/decode_bigtiff_images.rs index 9113f42..127e18c 100644 --- a/tests/decode_bigtiff_images.rs +++ b/tests/decode_bigtiff_images.rs @@ -15,7 +15,9 @@ fn test_big_tiff() { 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"); + let mut decoder = Decoder::open(img_file).expect("Cannot create decoder"); + decoder.next_image().expect("Cannot read image"); + assert_eq!( decoder.dimensions().expect("Cannot get dimensions"), (64, 64) diff --git a/tests/decode_fp16_images.rs b/tests/decode_fp16_images.rs index ba6976c..56456c4 100644 --- a/tests/decode_fp16_images.rs +++ b/tests/decode_fp16_images.rs @@ -16,7 +16,9 @@ fn test_white_ieee_fp16() { 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"); + let mut decoder = Decoder::open(img_file).expect("Cannot create decoder"); + decoder.next_image().expect("Cannot read image"); + assert_eq!( decoder.dimensions().expect("Cannot get dimensions"), (256, 256) @@ -25,6 +27,7 @@ fn test_white_ieee_fp16() { decoder.colortype().expect("Cannot get colortype"), ColorType::Gray(16) ); + if let DecodingResult::F16(img) = decoder.read_image().unwrap() { for p in img { assert!(p == half::f16::from_f32_const(1.0)); @@ -43,7 +46,9 @@ fn test_one_black_pixel_ieee_fp16() { 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"); + let mut decoder = Decoder::open(img_file).expect("Cannot create decoder"); + decoder.next_image().expect("Cannot read image"); + assert_eq!( decoder.dimensions().expect("Cannot get dimensions"), (256, 256) @@ -52,6 +57,7 @@ fn test_one_black_pixel_ieee_fp16() { decoder.colortype().expect("Cannot get colortype"), ColorType::Gray(16) ); + if let DecodingResult::F16(img) = decoder.read_image().unwrap() { for (i, p) in img.iter().enumerate() { if i == 0 { @@ -74,7 +80,9 @@ fn test_pattern_horizontal_differencing_ieee_fp16() { 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"); + let mut decoder = Decoder::open(img_file).expect("Cannot create decoder"); + decoder.next_image().expect("Cannot read image"); + assert_eq!( decoder.dimensions().expect("Cannot get dimensions"), (256, 256) @@ -83,6 +91,7 @@ fn test_pattern_horizontal_differencing_ieee_fp16() { decoder.colortype().expect("Cannot get colortype"), ColorType::Gray(16) ); + if let DecodingResult::F16(img) = decoder.read_image().unwrap() { // 0, 2, 5, 8, 12, 16, 255 are black let black = [0, 2, 5, 8, 12, 16, 255]; @@ -107,7 +116,9 @@ fn test_pattern_predictor_ieee_fp16() { 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"); + let mut decoder = Decoder::open(img_file).expect("Cannot create decoder"); + decoder.next_image().expect("Cannot read image"); + assert_eq!( decoder.dimensions().expect("Cannot get dimensions"), (256, 256) @@ -116,6 +127,7 @@ fn test_pattern_predictor_ieee_fp16() { decoder.colortype().expect("Cannot get colortype"), ColorType::Gray(16) ); + if let DecodingResult::F16(img) = decoder.read_image().unwrap() { // 0, 2, 5, 8, 12, 16, 255 are black let black = [0, 2, 5, 8, 12, 16, 255]; @@ -175,7 +187,9 @@ fn test_predictor_ieee_fp16() { 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"); + let mut decoder = Decoder::open(img_file).expect("Cannot create decoder"); + decoder.next_image().expect("Cannot read image"); + assert_eq!( decoder.dimensions().expect("Cannot get dimensions"), (16, 16) @@ -184,6 +198,7 @@ fn test_predictor_ieee_fp16() { decoder.colortype().expect("Cannot get colortype"), ColorType::Gray(16) ); + if let DecodingResult::F16(img) = decoder.read_image().unwrap() { for (exp, found) in std::iter::zip(pnm_values.iter(), img.iter()) { assert!((exp - found.to_f32()).abs() < 0.0001); diff --git a/tests/decode_geotiff_images.rs b/tests/decode_geotiff_images.rs index 88edf0b..9a4c0e1 100644 --- a/tests/decode_geotiff_images.rs +++ b/tests/decode_geotiff_images.rs @@ -15,8 +15,9 @@ fn test_geo_tiff() { 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"); + let mut decoder = Decoder::open(img_file).expect("Cannot create decoder"); decoder = decoder.with_limits(tiff::decoder::Limits::unlimited()); + decoder.next_image().expect("Cannot read image"); assert_eq!( decoder.dimensions().expect("Cannot get dimensions"), @@ -71,16 +72,11 @@ fn test_webp_tiff() { 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"); - - loop { - decoder.read_image_to_buffer(&mut buffer).unwrap(); - - if !decoder.more_images() { - break; - } + let mut decoder = Decoder::open(img_file).expect("Cannot create decoder"); + while decoder.more_images() { decoder.next_image().unwrap(); + decoder.read_image_to_buffer(&mut buffer).unwrap(); } } } diff --git a/tests/decode_images.rs b/tests/decode_images.rs index 74f9f9f..b4dd38d 100644 --- a/tests/decode_images.rs +++ b/tests/decode_images.rs @@ -14,7 +14,9 @@ macro_rules! test_image_sum { fn $name(file: &str, expected_type: ColorType, expected_sum: $sum_ty) { let path = PathBuf::from(TEST_IMAGE_DIR).join(file); let img_file = File::open(path).expect("Cannot find test image!"); - let mut decoder = Decoder::new(img_file).expect("Cannot create decoder"); + let mut decoder = Decoder::open(img_file).expect("Cannot create decoder"); + + decoder.next_image().expect("Cannot read image IFD"); assert_eq!(decoder.colortype().unwrap(), expected_type); let img_res = decoder.read_image().unwrap(); @@ -44,7 +46,9 @@ test_image_sum!(test_image_sum_f64, F64, f64); fn test_image_color_type_unsupported(file: &str, expected_type: ColorType) { let path = PathBuf::from(TEST_IMAGE_DIR).join(file); let img_file = File::open(path).expect("Cannot find test image!"); - let mut decoder = Decoder::new(img_file).expect("Cannot create decoder"); + let mut decoder = Decoder::open(img_file).expect("Cannot create decoder"); + decoder.next_image().expect("Cannot read image IFD"); + assert_eq!(decoder.colortype().unwrap(), expected_type); assert!(matches!( decoder.read_image(), @@ -166,7 +170,8 @@ fn test_string_tags() { 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"); + let mut decoder = Decoder::open(img_file).expect("Cannot create decoder"); + decoder.next_image().expect("Cannot read image IFD"); let software = decoder.get_tag(tiff::tags::Tag::Software).unwrap(); match software { ifd::Value::Ascii(s) => assert_eq!( @@ -190,7 +195,8 @@ fn test_decode_data() { } } let file = File::open("./tests/decodedata-rgb-3c-8b.tiff").unwrap(); - let mut decoder = Decoder::new(file).unwrap(); + let mut decoder = Decoder::open(file).unwrap(); + decoder.next_image().expect("Cannot read image IFD"); assert_eq!(decoder.colortype().unwrap(), ColorType::RGB(8)); assert_eq!(decoder.dimensions().unwrap(), (100, 100)); if let DecodingResult::U8(img_res) = decoder.read_image().unwrap() { @@ -236,7 +242,8 @@ fn test_tiled_rect_rgb_u8() { fn test_inner_access() { let path = PathBuf::from(TEST_IMAGE_DIR).join("tiled-rect-rgb-u8.tif"); let img_file = File::open(path).expect("Cannot find test image!"); - let mut decoder = Decoder::new(img_file).expect("Cannot create decoder"); + let mut decoder = Decoder::open(img_file).expect("Cannot create decoder"); + decoder.next_image().expect("Cannot read image IFD"); assert_eq!(decoder.colortype().unwrap(), ColorType::RGB(8)); let c = decoder @@ -322,7 +329,8 @@ fn test_tiled_incremental() { let path = PathBuf::from(TEST_IMAGE_DIR).join(file); let img_file = File::open(path).expect("Cannot find test image!"); - let mut decoder = Decoder::new(img_file).expect("Cannot create decoder"); + let mut decoder = Decoder::open(img_file).expect("Cannot create decoder"); + decoder.next_image().expect("Cannot read image IFD"); assert_eq!(decoder.colortype().unwrap(), expected_type); let tiles = decoder.tile_count().unwrap(); @@ -352,7 +360,8 @@ fn test_read_planar_bands() { let path = PathBuf::from(TEST_IMAGE_DIR).join(file); let img_file = File::open(path).expect("Cannot find test image!"); - let mut decoder = Decoder::new(img_file).expect("Cannot create decoder"); + let mut decoder = Decoder::open(img_file).expect("Cannot create decoder"); + decoder.next_image().expect("Cannot read image IFD"); assert_eq!(decoder.colortype().unwrap(), expected_type); let chunks = decoder.strip_count().unwrap(); @@ -396,7 +405,8 @@ fn test_div_zero() { 178, 178, 178, ]; - let err = tiff::decoder::Decoder::new(std::io::Cursor::new(&image)).unwrap_err(); + let mut decoder = Decoder::open(std::io::Cursor::new(&image)).unwrap(); + let err = decoder.next_image().unwrap_err(); match err { TiffError::FormatError(TiffFormatError::StripTileTagConflict) => {} @@ -414,7 +424,8 @@ fn test_too_many_value_bytes() { 0, 89, 89, 89, 89, 89, 89, 89, 89, 96, 1, 20, 89, 89, 89, 89, 18, ]; - let error = tiff::decoder::Decoder::new(std::io::Cursor::new(&image)).unwrap_err(); + let mut decoder = Decoder::open(std::io::Cursor::new(&image)).unwrap(); + let error = decoder.next_image().unwrap_err(); match error { tiff::TiffError::LimitsExceeded => {} @@ -432,7 +443,8 @@ fn fuzzer_testcase5() { 178, 178, 178, ]; - let _ = tiff::decoder::Decoder::new(std::io::Cursor::new(&image)).unwrap_err(); + let mut decoder = Decoder::open(std::io::Cursor::new(&image)).unwrap(); + let _ = decoder.next_image().unwrap_err(); } #[test] @@ -445,7 +457,8 @@ fn fuzzer_testcase1() { 178, ]; - let _ = tiff::decoder::Decoder::new(std::io::Cursor::new(&image)).unwrap_err(); + let mut decoder = Decoder::open(std::io::Cursor::new(&image)).unwrap(); + let _ = decoder.next_image().unwrap_err(); } #[test] @@ -458,7 +471,8 @@ fn fuzzer_testcase6() { 178, 178, ]; - let _ = tiff::decoder::Decoder::new(std::io::Cursor::new(&image)).unwrap_err(); + let mut decoder = Decoder::open(std::io::Cursor::new(&image)).unwrap(); + let _ = decoder.next_image().unwrap_err(); } #[test] @@ -470,7 +484,8 @@ fn oom() { 0, 0, 0, 40, 0, 0, 0, 23, 1, 4, 0, 1, 0, 0, 0, 178, 48, 178, 178, 178, 178, 162, 178, ]; - let _ = tiff::decoder::Decoder::new(std::io::Cursor::new(&image)).unwrap_err(); + let mut decoder = Decoder::open(std::io::Cursor::new(&image)).unwrap(); + let _ = decoder.next_image().unwrap_err(); } #[test] @@ -482,7 +497,8 @@ fn fuzzer_testcase4() { 0, 0, 0, 40, 0, 0, 0, 23, 1, 4, 0, 1, 0, 0, 0, 48, 178, 178, 178, 0, 1, 0, 13, 13, ]; - let _ = tiff::decoder::Decoder::new(std::io::Cursor::new(&image)).unwrap_err(); + let mut decoder = Decoder::open(std::io::Cursor::new(&image)).unwrap(); + let _ = decoder.next_image().unwrap_err(); } #[test] @@ -498,7 +514,8 @@ fn fuzzer_testcase2() { 73, ]; - let _ = tiff::decoder::Decoder::new(std::io::Cursor::new(&image)).unwrap_err(); + let mut decoder = Decoder::open(std::io::Cursor::new(&image)).unwrap(); + let _ = decoder.next_image().unwrap_err(); } #[test] @@ -514,7 +531,8 @@ fn invalid_jpeg_tag_2() { 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 36, 73, 73, 0, 42, 36, 36, 36, 36, 0, 0, 8, 0, ]; - let _ = tiff::decoder::Decoder::new(std::io::Cursor::new(&image)).unwrap_err(); + let mut decoder = Decoder::open(std::io::Cursor::new(&image)).unwrap(); + let _ = decoder.next_image().unwrap_err(); } #[test] @@ -527,7 +545,8 @@ fn fuzzer_testcase3() { 255, 255, ]; - let _ = tiff::decoder::Decoder::new(std::io::Cursor::new(&image)).unwrap_err(); + let mut decoder = Decoder::open(std::io::Cursor::new(&image)).unwrap(); + let _ = decoder.next_image().unwrap_err(); } #[test] @@ -545,7 +564,8 @@ fn timeout() { 0, 0, 73, 73, 42, 0, 8, 0, 0, 0, 0, 0, 32, ]; - let error = tiff::decoder::Decoder::new(std::io::Cursor::new(&image)).unwrap_err(); + let mut decoder = Decoder::open(std::io::Cursor::new(&image)).unwrap(); + let error = decoder.next_image().unwrap_err(); match error { TiffError::FormatError(TiffFormatError::CycleInOffsets) => {} @@ -583,7 +603,8 @@ fn test_image_bytes( ) { let path = PathBuf::from(TEST_IMAGE_DIR).join(file); let img_file = File::open(path).expect("Cannot find test image!"); - let mut decoder = Decoder::new(img_file).expect("Cannot create decoder"); + let mut decoder = Decoder::open(img_file).expect("Cannot create decoder"); + decoder.next_image().unwrap(); let mut buffer = vec![0u8; 0]; for (idx, &(expected_type, expected_crc)) in expected.iter().enumerate() { @@ -726,8 +747,9 @@ fn extra_bits_rgb() { fn test_decode_huge_g4() { let path = PathBuf::from(TEST_IMAGE_DIR).join("big_g4.tif"); let img_file = File::open(path).expect("failed to open large G4 test image"); - let mut decoder = tiff::decoder::Decoder::new(img_file).expect("failed to create decoder"); + let mut decoder = Decoder::open(img_file).expect("failed to create decoder"); + decoder.next_image().expect("failed to read image IFD"); let (width, height) = decoder.dimensions().expect("failed to get dimensions"); assert!( diff --git a/tests/decode_libtiffpic.rs b/tests/decode_libtiffpic.rs index 09e08d7..e38bee9 100644 --- a/tests/decode_libtiffpic.rs +++ b/tests/decode_libtiffpic.rs @@ -153,17 +153,12 @@ fn decode_libtiffpic(path: &str) -> Result<(), tiff::TiffError> { let path = path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(path); let img_file = File::open(path)?; - let mut decoder = Decoder::new(img_file)?; + let mut decoder = Decoder::open(img_file)?; + let mut buffer = DecodingResult::U8(vec![]); - - loop { - let _layout = decoder.read_image_to_buffer(&mut buffer); - - if !decoder.more_images() { - break; - } - + while decoder.more_images() { decoder.next_image()?; + let _layout = decoder.read_image_to_buffer(&mut buffer); } Ok(()) diff --git a/tests/decode_planes.rs b/tests/decode_planes.rs index 9ce3428..c275dd1 100644 --- a/tests/decode_planes.rs +++ b/tests/decode_planes.rs @@ -10,8 +10,9 @@ fn read_all_planes() { let path = PathBuf::from(TEST_IMAGE_DIR).join("planar-rgb-u8.tif"); let file = File::open(path).unwrap(); let io = std::io::BufReader::new(file); + let mut tif = Decoder::open(io).unwrap(); - let mut tif = Decoder::new(io).unwrap(); + tif.next_image().unwrap(); let layout = tif.image_buffer_layout().unwrap(); assert_eq!(layout.planes, 3); let plane_stride = layout.plane_stride.map_or(0, |x| x.get()); @@ -36,8 +37,9 @@ fn read_first_coding_unit() { let path = PathBuf::from(TEST_IMAGE_DIR).join("planar-rgb-u8.tif"); let file = File::open(path).unwrap(); let io = std::io::BufReader::new(file); + let mut tif = Decoder::open(io).unwrap(); - let mut tif = Decoder::new(io).unwrap(); + tif.next_image().unwrap(); let layout = tif.image_coding_unit_layout(TiffCodingUnit(0)).unwrap(); assert_eq!(layout.planes, 3); @@ -85,12 +87,13 @@ fn read_planes_by_limits() { let mut buffer = DecodingResult::U8(vec![]); // Make room for 1 plane. - let mut tif = Decoder::new(io).unwrap(); + let mut tif = Decoder::open(io).unwrap(); tif = tif.with_limits({ limits.decoding_buffer_size = 374 * 499; limits.clone() }); + tif.next_image().unwrap(); tif.read_image_to_buffer(&mut buffer).unwrap(); assert_eq!(buffer.as_buffer(0).byte_len(), 374 * 499); diff --git a/tests/encode_images.rs b/tests/encode_images.rs index 3fb9dee..9160b32 100644 --- a/tests/encode_images.rs +++ b/tests/encode_images.rs @@ -33,7 +33,9 @@ fn encode_decode() { } { file.seek(SeekFrom::Start(0)).unwrap(); - let mut decoder = Decoder::new(&mut file).unwrap(); + let mut decoder = Decoder::open(&mut file).unwrap(); + decoder.next_image().unwrap(); + assert_eq!(decoder.colortype().unwrap(), ColorType::RGB(8)); assert_eq!(decoder.dimensions().unwrap(), (100, 100)); @@ -116,7 +118,9 @@ fn encode_decode_big() { } { file.seek(SeekFrom::Start(0)).unwrap(); - let mut decoder = Decoder::new(&mut file).unwrap(); + let mut decoder = Decoder::open(&mut file).unwrap(); + decoder.next_image().unwrap(); + assert_eq!(decoder.colortype().unwrap(), ColorType::RGB(8)); assert_eq!(decoder.dimensions().unwrap(), (100, 100)); @@ -207,8 +211,10 @@ fn test_encode_ifd() { // Rewind the cursor for reading data.set_position(0); + { - let mut decoder = Decoder::new(&mut data).unwrap(); + let mut decoder = Decoder::open(&mut data).unwrap(); + decoder.next_image().unwrap(); assert_eq!(decoder.assert_tag_u32(65000), 42); assert_eq!(decoder.assert_tag_u32_vec(65000), [42]); @@ -247,7 +253,9 @@ macro_rules! test_roundtrip { ) { let path = PathBuf::from(TEST_IMAGE_DIR).join(file); let img_file = File::open(path).expect("Cannot find test image!"); - let mut decoder = Decoder::new(img_file).expect("Cannot create decoder"); + let mut decoder = Decoder::open(img_file).expect("Cannot create decoder"); + decoder.next_image().unwrap(); + assert_eq!(decoder.colortype().unwrap(), expected_type); let mut buffer = tiff::decoder::DecodingResult::U8(vec![]); @@ -268,7 +276,8 @@ macro_rules! test_roundtrip { file.seek(SeekFrom::Start(0)).unwrap(); { let mut buffer = tiff::decoder::DecodingResult::U8(vec![]); - let mut decoder = Decoder::new(&mut file).unwrap(); + let mut decoder = Decoder::open(&mut file).unwrap(); + decoder.next_image().unwrap(); decoder.read_image_to_buffer(&mut buffer).unwrap(); if let DecodingResult::$buffer(img_res) = buffer { assert_eq!(*image_data, img_res); @@ -405,7 +414,8 @@ fn test_gray_f32_floating_point_predictor() { file.seek(SeekFrom::Start(0)).unwrap(); { - let mut decoder = Decoder::new(&mut file).unwrap(); + let mut decoder = Decoder::open(&mut file).unwrap(); + decoder.next_image().unwrap(); assert_eq!(decoder.colortype().unwrap(), ColorType::Gray(32)); let mut buffer = DecodingResult::F32(vec![]); @@ -451,7 +461,8 @@ fn test_rgb_f32_floating_point_predictor() { file.seek(SeekFrom::Start(0)).unwrap(); { - let mut decoder = Decoder::new(&mut file).unwrap(); + let mut decoder = Decoder::open(&mut file).unwrap(); + decoder.next_image().unwrap(); assert_eq!(decoder.colortype().unwrap(), ColorType::RGB(32)); let mut buffer = DecodingResult::F32(vec![]); @@ -494,7 +505,8 @@ fn test_gray_f64_floating_point_predictor() { file.seek(SeekFrom::Start(0)).unwrap(); { - let mut decoder = Decoder::new(&mut file).unwrap(); + let mut decoder = Decoder::open(&mut file).unwrap(); + decoder.next_image().unwrap(); assert_eq!(decoder.colortype().unwrap(), ColorType::Gray(64)); let mut buffer = DecodingResult::F64(vec![]); @@ -591,7 +603,8 @@ fn test_multiple_byte() { data.set_position(0); { - let mut decoder = Decoder::new(&mut data).unwrap(); + let mut decoder = Decoder::open(&mut data).unwrap(); + decoder.next_image().unwrap(); assert_eq!(decoder.assert_tag_u32_vec(65000), [1]); assert_eq!(decoder.assert_tag_u32_vec(65001), [1, 2]); @@ -672,7 +685,8 @@ fn test_signed() { //Rewind the cursor for reading data.set_position(0); { - let mut decoder = Decoder::new(&mut data).unwrap(); + let mut decoder = Decoder::open(&mut data).unwrap(); + decoder.next_image().unwrap(); assert_eq!(decoder.assert_tag_i32(65000), -1); assert_eq!(decoder.assert_tag_i32_vec(65001), [-1]); @@ -724,13 +738,14 @@ fn test_multipage_image() { img_file.seek(SeekFrom::Start(0)).unwrap(); { - let mut img_decoder = Decoder::new(&mut img_file).unwrap(); + let mut decoder = Decoder::open(&mut img_file).unwrap(); + decoder.next_image().unwrap(); // check the dimensions of the image in the first page - assert_eq!(img_decoder.dimensions().unwrap(), (2, 2)); - img_decoder.next_image().unwrap(); + assert_eq!(decoder.dimensions().unwrap(), (2, 2)); + decoder.next_image().unwrap(); // check the dimensions of the image in the second page - assert_eq!(img_decoder.dimensions().unwrap(), (3, 3)); + assert_eq!(decoder.dimensions().unwrap(), (3, 3)); } } @@ -759,7 +774,8 @@ fn test_rows_per_strip() { file.seek(SeekFrom::Start(0)).unwrap(); { - let mut decoder = Decoder::new(&mut file).unwrap(); + let mut decoder = Decoder::open(&mut file).unwrap(); + decoder.next_image().unwrap(); assert_eq!(decoder.get_tag_u64(Tag::RowsPerStrip).unwrap(), 2); assert_eq!(decoder.strip_count().unwrap(), 50); @@ -799,9 +815,10 @@ fn test_auxiliary_directory() { } data.set_position(0); - let mut decoder = Decoder::new(&mut data).unwrap(); + let mut decoder = Decoder::open(&mut data).unwrap(); { + decoder.next_image().unwrap(); assert_eq!(decoder.dimensions().unwrap(), (1, 1)); let _ = decoder.read_image().unwrap(); } diff --git a/tests/encode_images_with_compression.rs b/tests/encode_images_with_compression.rs index a355fb1..08b2658 100644 --- a/tests/encode_images_with_compression.rs +++ b/tests/encode_images_with_compression.rs @@ -110,7 +110,8 @@ fn encode_decode_with_compression(compression: Compression) { // Decode tiff data.set_position(0); { - let mut decoder = Decoder::new(data).unwrap(); + let mut decoder = Decoder::open(data).unwrap(); + decoder.next_image().unwrap(); // Check the RGB image assert_eq!( diff --git a/tests/fuzz_tests.rs b/tests/fuzz_tests.rs index 446d6bd..33eb389 100644 --- a/tests/fuzz_tests.rs +++ b/tests/fuzz_tests.rs @@ -13,7 +13,8 @@ fn test_directory bool>(path: &str, f: F) { } fn decode_tiff(file: File) -> TiffResult<()> { - let mut decoder = Decoder::new(file)?; + let mut decoder = Decoder::open(file)?; + decoder.next_image()?; decoder.read_image()?; Ok(()) } diff --git a/tests/predict.rs b/tests/predict.rs index 59bb79c..aef1431 100644 --- a/tests/predict.rs +++ b/tests/predict.rs @@ -18,8 +18,9 @@ macro_rules! test_predict { ) { let path = PathBuf::from(TEST_IMAGE_DIR).join(file); let file = File::open(path).expect("Cannot find test image!"); - let mut decoder = Decoder::new(file).expect("Cannot create decoder!"); + let mut decoder = Decoder::open(file).expect("Cannot create decoder!"); + decoder.next_image().unwrap(); assert_eq!(decoder.colortype().unwrap(), expected_type); let image_data = match decoder.read_image().unwrap() { DecodingResult::$buffer(res) => res, @@ -123,7 +124,9 @@ macro_rules! test_predict_roundtrip { ) { let path = PathBuf::from(TEST_IMAGE_DIR).join(file); let img_file = File::open(path).expect("Cannot find test image!"); - let mut decoder = Decoder::new(img_file).expect("Cannot create decoder"); + let mut decoder = Decoder::open(img_file).expect("Cannot create decoder"); + + decoder.next_image().unwrap(); assert_eq!(decoder.colortype().unwrap(), expected_type); let image_data = match decoder.read_image().unwrap() { @@ -142,7 +145,8 @@ macro_rules! test_predict_roundtrip { } file.seek(SeekFrom::Start(0)).unwrap(); { - let mut decoder = Decoder::new(&mut file).unwrap(); + let mut decoder = Decoder::open(&mut file).unwrap(); + decoder.next_image().unwrap(); if let DecodingResult::$buffer(img_res) = decoder.read_image().expect("Decoding image failed") { diff --git a/tests/subsubifds.rs b/tests/subsubifds.rs index 3fde959..5a24f5a 100644 --- a/tests/subsubifds.rs +++ b/tests/subsubifds.rs @@ -18,8 +18,10 @@ use std::fs::File; #[test] fn decode_seek_chain() { let file = File::open(TEST_IMAGE_SUBIFD).expect("Cannot open test image"); - let mut decoder = Decoder::new(file).expect("Invalid format to create decoder"); + let mut decoder = Decoder::open(file).expect("Invalid format to create decoder"); + assert!(decoder.ifd_pointer().is_none()); + decoder.next_image().unwrap(); // Remember the offsets in the first iteration. let offset0 = decoder.ifd_pointer().expect("First IFD pointer not found"); decoder.next_image().unwrap();