Added read_chunk_at and read_chunk_to_buffer functions
This commit is contained in:
1 parent
d5e3f4aa8a
commit
8c0c13f022
4 files changed
+72
-10
No files matched your search
+11
-8
@@ -512,9 +512,12 @@ impl Image {
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let compressed_bytes = self.chunk_bytes.get(chunk).ok_or(TiffError::FormatError(
|
||||
TiffFormatError::InconsistentSizesEncountered,
|
||||
))?;
|
||||
let compressed_bytes = self
|
||||
.chunk_bytes
|
||||
.get(chunk_index)
|
||||
.ok_or(TiffError::FormatError(
|
||||
TiffFormatError::InconsistentSizesEncountered,
|
||||
))?;
|
||||
|
||||
let byte_len = buffer.byte_len();
|
||||
let compression_method = self.compression_method;
|
||||
@@ -535,7 +538,7 @@ impl Image {
|
||||
let tile = &mut buffer.as_bytes_mut()[..total_samples * byte_len];
|
||||
reader.read_exact(tile)?;
|
||||
|
||||
for row in 0..(chunk_dimensions.1 - padding.1) {
|
||||
for row in 0..chunk_info.data_height {
|
||||
let row_start = row * output_width * samples;
|
||||
let row_end = (row + 1) * output_width * samples;
|
||||
let row = buffer.subrange(row_start..row_end);
|
||||
@@ -544,13 +547,13 @@ impl Image {
|
||||
if photometric_interpretation == PhotometricInterpretation::WhiteIsZero {
|
||||
super::invert_colors(&mut buffer.subrange(0..total_samples), color_type);
|
||||
}
|
||||
} else if padding.0 > 0 && self.predictor == Predictor::FloatingPoint {
|
||||
} else if chunk_info.padding_right() > 0 && self.predictor == Predictor::FloatingPoint {
|
||||
// The floating point predictor shuffles the padding bytes into the encoded output, so
|
||||
// this case is handled specially when needed.
|
||||
let mut encoded = vec![0u8; chunk_dimensions.0 * samples * byte_len];
|
||||
for row in 0..(chunk_dimensions.1 - padding.1) {
|
||||
let mut encoded = vec![0u8; chunk_info.chunk_width * samples * byte_len];
|
||||
for row in 0..chunk_info.data_height {
|
||||
let row_start = row * output_width * samples;
|
||||
let row_end = row_start + (chunk_dimensions.0 - padding.0) * samples;
|
||||
let row_end = row_start + chunk_info.data_width * samples;
|
||||
|
||||
reader.read_exact(&mut encoded)?;
|
||||
match buffer.subrange(row_start..row_end) {
|
||||
|
||||
@@ -1042,6 +1042,7 @@ impl<R: Read + Seek> Decoder<R> {
|
||||
self.read_image()
|
||||
}
|
||||
|
||||
#[deprecated = "Use read_chunk_to_buffer instead"]
|
||||
pub fn read_strip_to_buffer(&mut self, mut buffer: DecodingBuffer) -> TiffResult<()> {
|
||||
self.check_chunk_type(ChunkType::Strip)?;
|
||||
|
||||
@@ -1063,6 +1064,7 @@ impl<R: Read + Seek> Decoder<R> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[deprecated = "Use read_chunk_to_buffer instead"]
|
||||
fn read_tile_to_buffer(
|
||||
&mut self,
|
||||
mut buffer: DecodingBuffer,
|
||||
@@ -1087,6 +1089,28 @@ impl<R: Read + Seek> Decoder<R> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_chunk_to_buffer(
|
||||
&mut self,
|
||||
mut buffer: DecodingBuffer,
|
||||
tile_index: usize,
|
||||
output_width: usize,
|
||||
) -> TiffResult<()> {
|
||||
let offset = self.image.chunk_file_range(tile_index)?.0;
|
||||
self.goto_offset_u64(offset)?;
|
||||
|
||||
let byte_order = self.reader.byte_order;
|
||||
|
||||
self.image.expand_chunk(
|
||||
&mut self.reader,
|
||||
buffer.copy(),
|
||||
output_width,
|
||||
byte_order,
|
||||
tile_index,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn result_buffer(&self, width: usize, height: usize) -> TiffResult<DecodingResult> {
|
||||
let buffer_size = match width
|
||||
.checked_mul(height)
|
||||
@@ -1146,6 +1170,8 @@ impl<R: Read + Seek> Decoder<R> {
|
||||
/// may change at a future date to reflect this.
|
||||
///
|
||||
/// `read_strip_at` can be used to get both the strip data and the strip size.
|
||||
///
|
||||
#[deprecated = "Use read_chunk instead"]
|
||||
pub fn read_strip(&mut self) -> TiffResult<DecodingResult> {
|
||||
let result = self.read_strip_at(self.current_chunk)?;
|
||||
|
||||
@@ -1154,6 +1180,8 @@ impl<R: Read + Seek> Decoder<R> {
|
||||
|
||||
/// Read the specified strip (at index `strip_index`) and return the binary data as a Vector and
|
||||
/// `ChunkInfo` describing the size of the strip.
|
||||
///
|
||||
#[deprecated = "Use read_chunk instead"]
|
||||
pub fn read_strip_at(&mut self, strip_index: usize) -> TiffResult<(DecodingResult, ChunkInfo)> {
|
||||
self.check_chunk_type(ChunkType::Strip)?;
|
||||
|
||||
@@ -1174,6 +1202,7 @@ impl<R: Read + Seek> Decoder<R> {
|
||||
/// expected tile size. This interface may change at a future date to reflect this.
|
||||
///
|
||||
/// `read_tile_at` can be used to get both the tile data and the tile size.
|
||||
#[deprecated = "Use read_chunk instead"]
|
||||
pub fn read_tile(&mut self) -> TiffResult<DecodingResult> {
|
||||
let result = self.read_tile_at(self.current_chunk)?;
|
||||
|
||||
@@ -1184,6 +1213,7 @@ impl<R: Read + Seek> Decoder<R> {
|
||||
|
||||
/// Read the specified tile (at index `tile_index`) and return the binary data as a Vector and
|
||||
/// `ChunkInfo` describing the size of the tile.
|
||||
#[deprecated = "Use read_chunk_at instead"]
|
||||
pub fn read_tile_at(&mut self, tile_index: usize) -> TiffResult<(DecodingResult, ChunkInfo)> {
|
||||
self.check_chunk_type(ChunkType::Tile)?;
|
||||
|
||||
@@ -1199,6 +1229,35 @@ impl<R: Read + Seek> Decoder<R> {
|
||||
Ok((result, chunk_info))
|
||||
}
|
||||
|
||||
/// Read a single chunk from the image and return it as a Vector. This method does not return
|
||||
/// information on the size of the chunk read and so the caller must take care of chunks on the
|
||||
/// rightmost column and the bottommost row in the image as the data read may be less than the
|
||||
/// expected chunk size. This interface may change at a future date to reflect this.
|
||||
///
|
||||
/// `read_chunk_at` can be used to get both the chunk data and the tile size.
|
||||
pub fn read_chunk(&mut self) -> TiffResult<DecodingResult> {
|
||||
let result = self.read_chunk_at(self.current_chunk)?;
|
||||
|
||||
self.current_chunk += 1;
|
||||
|
||||
Ok(result.0)
|
||||
}
|
||||
|
||||
/// Read the specified chunk (at index `chunk_index`) and return the binary data as a Vector and
|
||||
/// `ChunkInfo` describing the size of the chunk.
|
||||
pub fn read_chunk_at(&mut self, chunk_index: usize) -> TiffResult<(DecodingResult, ChunkInfo)> {
|
||||
let chunk_info = self
|
||||
.image()
|
||||
.chunk_info(chunk_index)
|
||||
.ok_or(TiffFormatError::InvalidChunkIndex(chunk_index))?;
|
||||
|
||||
let mut result = self.result_buffer(chunk_info.data_width, chunk_info.data_height)?;
|
||||
|
||||
self.read_chunk_to_buffer(result.as_buffer(0), chunk_index, chunk_info.data_width)?;
|
||||
|
||||
Ok((result, chunk_info))
|
||||
}
|
||||
|
||||
/// Decodes the entire image and return it as a Vector
|
||||
pub fn read_image(&mut self) -> TiffResult<DecodingResult> {
|
||||
let width = usize::try_from(self.image().width)?;
|
||||
|
||||
@@ -275,7 +275,7 @@ fn test_tiled_incremental() {
|
||||
assert_eq!(tiles as usize, sums.len());
|
||||
|
||||
for tile in 0..tiles {
|
||||
match decoder.read_tile().unwrap() {
|
||||
match decoder.read_chunk().unwrap() {
|
||||
DecodingResult::U8(res) => {
|
||||
let sum: u64 = res.into_iter().map(<u64>::from).sum();
|
||||
assert_eq!(sum, sums[tile as usize]);
|
||||
|
||||
@@ -512,7 +512,7 @@ fn test_rows_per_strip() {
|
||||
|
||||
for i in 0..50 {
|
||||
let img2 = [i; 2 * 100];
|
||||
match decoder.read_strip().unwrap() {
|
||||
match decoder.read_chunk().unwrap() {
|
||||
DecodingResult::U8(data) => assert_eq!(&img2[..], &data[..]),
|
||||
other => panic!("Incorrect strip type {:?}", other),
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user