Added functionality for loading selected strip

This commit is contained in:
Alan Race committed 2022-05-02 15:59:48 +02:00
1 parent 8f34748d01
commit dd8c9e4f2b
4 files changed
+31 -28

No files matched your search

+27 -26
View File
@@ -259,6 +259,7 @@ pub enum ChunkType {
Tile, Tile,
} }
#[derive(Debug)]
#[non_exhaustive] #[non_exhaustive]
pub struct ChunkInfo { pub struct ChunkInfo {
/// Width of the chunk as specified (includes potential padding) /// Width of the chunk as specified (includes potential padding)
@@ -1165,7 +1166,7 @@ impl<R: Read + Seek> Decoder<R> {
Some(ChunkInfo { Some(ChunkInfo {
chunk_width: sized_width, chunk_width: sized_width,
chunk_height: sized_height, chunk_height: rows_per_strip,
data_width: sized_width, data_width: sized_width,
data_height: strip_height, data_height: strip_height,
@@ -1332,18 +1333,16 @@ impl<R: Read + Seek> Decoder<R> {
.image() .image()
.chunk_offsets .chunk_offsets
.get(index) .get(index)
.ok_or(TiffError::FormatError( .ok_or(TiffFormatError::InvalidChunkIndex(index))?;
TiffFormatError::InconsistentSizesEncountered,
))?;
let byte_count = *self let byte_count = *self
.image() .image()
.chunk_bytes .chunk_bytes
.get(index) .get(index)
.ok_or(TiffError::FormatError( .ok_or(TiffFormatError::InvalidChunkIndex(index))?;
TiffFormatError::InconsistentSizesEncountered,
))?;
let chunk_info = self.chunk_info(index).ok_or(TiffError::IntSizeError)?; let chunk_info = self
.chunk_info(index)
.ok_or(TiffFormatError::InvalidChunkIndex(index))?;
let buffer_size = chunk_info let buffer_size = chunk_info
.data_width .data_width
@@ -1378,30 +1377,25 @@ impl<R: Read + Seek> Decoder<R> {
fn read_tile_to_buffer( fn read_tile_to_buffer(
&mut self, &mut self,
result: &mut DecodingBuffer, result: &mut DecodingBuffer,
tile: usize, tile_index: usize,
output_width: usize, output_width: usize,
) -> TiffResult<()> { ) -> TiffResult<()> {
let file_offset = *self let file_offset = *self
.image() .image()
.chunk_offsets .chunk_offsets
.get(tile) .get(tile_index)
.ok_or(TiffError::FormatError( .ok_or(TiffFormatError::InvalidChunkIndex(tile_index))?;
TiffFormatError::InconsistentSizesEncountered,
))?;
let compressed_bytes = let compressed_bytes = *self
*self
.image() .image()
.chunk_bytes .chunk_bytes
.get(tile) .get(tile_index)
.ok_or(TiffError::FormatError( .ok_or(TiffFormatError::InvalidChunkIndex(tile_index))?;
TiffFormatError::InconsistentSizesEncountered,
))?;
// Return the same error as above if the chunk doesn't exist // Return the same error as above if the chunk doesn't exist
let chunk_info = self.chunk_info(tile).ok_or(TiffError::FormatError( let chunk_info = self
TiffFormatError::InconsistentSizesEncountered, .chunk_info(tile_index)
))?; .ok_or(TiffFormatError::InvalidChunkIndex(tile_index))?;
self.expand_tile( self.expand_tile(
result.copy(), result.copy(),
@@ -1485,10 +1479,15 @@ impl<R: Read + Seek> Decoder<R> {
/// Read a single strip from the image and return it as a Vector /// Read a single strip from the image and return it as a Vector
pub fn read_strip(&mut self) -> TiffResult<(DecodingResult, ChunkInfo)> { pub fn read_strip(&mut self) -> TiffResult<(DecodingResult, ChunkInfo)> {
self.check_chunk_type(ChunkType::Strip)?; self.read_strip_at(self.current_chunk)
let index = self.current_chunk; }
let chunk_info = self.chunk_info(index).unwrap(); pub fn read_strip_at(&mut self, strip_index: usize) -> TiffResult<(DecodingResult, ChunkInfo)> {
self.check_chunk_type(ChunkType::Strip)?;
let chunk_info = self
.chunk_info(strip_index)
.ok_or(TiffFormatError::InvalidChunkIndex(strip_index))?;
let mut result = self.result_buffer(chunk_info.data_width, chunk_info.data_height)?; let mut result = self.result_buffer(chunk_info.data_width, chunk_info.data_height)?;
self.read_strip_to_buffer(result.as_buffer(0))?; self.read_strip_to_buffer(result.as_buffer(0))?;
@@ -1508,7 +1507,9 @@ impl<R: Read + Seek> Decoder<R> {
pub fn read_tile_at(&mut self, tile_index: usize) -> TiffResult<(DecodingResult, ChunkInfo)> { pub fn read_tile_at(&mut self, tile_index: usize) -> TiffResult<(DecodingResult, ChunkInfo)> {
self.check_chunk_type(ChunkType::Tile)?; self.check_chunk_type(ChunkType::Tile)?;
let chunk_info = self.chunk_info(tile_index).unwrap(); let chunk_info = self
.chunk_info(tile_index)
.ok_or(TiffFormatError::InvalidChunkIndex(tile_index))?;
let mut result = self.result_buffer(chunk_info.data_width, chunk_info.data_height)?; let mut result = self.result_buffer(chunk_info.data_width, chunk_info.data_height)?;
+2
View File
@@ -56,6 +56,7 @@ pub enum TiffFormatError {
actual_samples: usize, actual_samples: usize,
required_samples: usize, required_samples: usize,
}, },
InvalidChunkIndex(usize),
InvalidTag, InvalidTag,
InvalidTagValueType(Tag), InvalidTagValueType(Tag),
RequiredTagNotFound(Tag), RequiredTagNotFound(Tag),
@@ -100,6 +101,7 @@ impl fmt::Display for TiffFormatError {
actual_samples, required_samples actual_samples, required_samples
) )
} }
InvalidChunkIndex(index) => write!(fmt, "Image chunk index ({}) requested.", index),
InvalidTag => write!(fmt, "Image contains invalid tag."), InvalidTag => write!(fmt, "Image contains invalid tag."),
InvalidTagValueType(ref tag) => { InvalidTagValueType(ref tag) => {
write!(fmt, "Tag `{:?}` did not have the expected value type.", tag) write!(fmt, "Tag `{:?}` did not have the expected value type.", tag)
+1 -1
View File
@@ -276,7 +276,7 @@ fn test_tiled_incremental() {
for tile in 0..tiles { for tile in 0..tiles {
match decoder.read_tile().unwrap() { match decoder.read_tile().unwrap() {
(DecodingResult::U8(res), chunk_info) => { (DecodingResult::U8(res), _chunk_info) => {
let sum: u64 = res.into_iter().map(<u64>::from).sum(); let sum: u64 = res.into_iter().map(<u64>::from).sum();
assert_eq!(sum, sums[tile as usize]); assert_eq!(sum, sums[tile as usize]);
} }
+1 -1
View File
@@ -513,7 +513,7 @@ fn test_rows_per_strip() {
for i in 0..50 { for i in 0..50 {
let img2 = [i; 2 * 100]; let img2 = [i; 2 * 100];
match decoder.read_strip().unwrap() { match decoder.read_strip().unwrap() {
DecodingResult::U8(data) => assert_eq!(&img2[..], &data[..]), (DecodingResult::U8(data), _chunk_info) => assert_eq!(&img2[..], &data[..]),
other => panic!("Incorrect strip type {:?}", other), other => panic!("Incorrect strip type {:?}", other),
} }
} }