diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 03975fc..e0c9672 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -259,6 +259,7 @@ pub enum ChunkType { Tile, } +#[non_exhaustive] pub struct ChunkInfo { /// Width of the chunk as specified (includes potential padding) pub chunk_width: usize, @@ -626,7 +627,7 @@ impl Decoder { } /// Loads the IFD at the specified index in the list, if one exists - pub fn image_at(&mut self, ifd_index: usize) -> TiffResult<()> { + pub fn seek_to_image(&mut self, ifd_index: usize) -> TiffResult<()> { // Check whether we have seen this IFD before, if so then the index will be less than the length of the list of ifd offsets if ifd_index >= self.ifd_offsets.len() { // We possibly need to load in the next IFD @@ -651,12 +652,8 @@ impl Decoder { } // If the index is within the list of ifds then we can load the selected image/IFD - if ifd_index < self.ifd_offsets.len() { - let (ifd, _next_ifd) = Self::read_ifd( - &mut self.reader, - self.bigtiff, - *self.ifd_offsets.get(ifd_index).unwrap(), - )?; + if let Some(ifd_offset) = self.ifd_offsets.get(ifd_index) { + let (ifd, _next_ifd) = Self::read_ifd(&mut self.reader, self.bigtiff, *ifd_offset)?; self.current_chunk = 0; self.image = Image::from_reader(&mut self.reader, ifd, &self.limits, self.bigtiff)?; @@ -1151,14 +1148,13 @@ impl Decoder { Ok(()) } - pub fn chunk_info(&self, chunk_index: usize) -> Option { + fn chunk_info(&self, chunk_index: usize) -> Option { match &self.image().chunk_type { ChunkType::Strip => { - let rows_per_strip = - usize::try_from(self.image().strip_decoder.as_ref()?.rows_per_strip).unwrap(); + let rows_per_strip = self.image().strip_decoder.as_ref()?.rows_per_strip as usize; - let sized_width = usize::try_from(self.image().width).unwrap(); - let sized_height = usize::try_from(self.image().height).unwrap(); + let sized_width = self.image().width as usize; + let sized_height = self.image().height as usize; let strip_height_without_padding = chunk_index .checked_mul(rows_per_strip) @@ -1402,7 +1398,10 @@ impl Decoder { TiffFormatError::InconsistentSizesEncountered, ))?; - let chunk_info = self.chunk_info(tile).unwrap(); + // Return the same error as above if the chunk doesn't exist + let chunk_info = self.chunk_info(tile).ok_or(TiffError::FormatError( + TiffFormatError::InconsistentSizesEncountered, + ))?; self.expand_tile( result.copy(), @@ -1504,7 +1503,7 @@ impl Decoder { } /// Read a single tile from the image and return it as a Vector - pub fn read_tile(&mut self) -> TiffResult { + pub fn read_tile(&mut self) -> TiffResult<(DecodingResult, ChunkInfo)> { let result = self.read_tile_at(self.current_chunk); self.current_chunk += 1; @@ -1512,7 +1511,7 @@ impl Decoder { result } - pub fn read_tile_at(&mut self, tile_index: usize) -> TiffResult { + pub fn read_tile_at(&mut self, tile_index: usize) -> TiffResult<(DecodingResult, ChunkInfo)> { self.check_chunk_type(ChunkType::Tile)?; let chunk_info = self.chunk_info(tile_index).unwrap(); @@ -1521,7 +1520,7 @@ impl Decoder { self.read_tile_to_buffer(&mut result.as_buffer(0), tile_index, chunk_info.data_width)?; - Ok(result) + Ok((result, chunk_info)) } fn read_tiled_image(&mut self) -> TiffResult { diff --git a/tests/decode_images.rs b/tests/decode_images.rs index d2a4419..c5f7612 100644 --- a/tests/decode_images.rs +++ b/tests/decode_images.rs @@ -276,7 +276,7 @@ fn test_tiled_incremental() { for tile in 0..tiles { match decoder.read_tile().unwrap() { - DecodingResult::U8(res) => { + (DecodingResult::U8(res), chunk_info) => { let sum: u64 = res.into_iter().map(::from).sum(); assert_eq!(sum, sums[tile as usize]); }