From 5696b0c78ba89fcf475c23ebabebbf4c68b4118c Mon Sep 17 00:00:00 2001 From: "A. Molzer" <5550310+197g@users.noreply.github.com> Date: Fri, 27 Mar 2026 17:56:47 +0100 Subject: [PATCH 1/2] Move DecodingBuffer related types to module --- src/decoder/buffer.rs | 302 +++++++++++++++++++++++++++++++++++++++++ src/decoder/mod.rs | 303 +----------------------------------------- 2 files changed, 307 insertions(+), 298 deletions(-) create mode 100644 src/decoder/buffer.rs diff --git a/src/decoder/buffer.rs b/src/decoder/buffer.rs new file mode 100644 index 0000000..3943ec7 --- /dev/null +++ b/src/decoder/buffer.rs @@ -0,0 +1,302 @@ +use half::f16; +use std::alloc::{Layout, LayoutError}; + +use crate::{ + bytecast, + decoder::{BufferLayoutPreference, Limits}, + error::{TiffError, TiffResult, TiffUnsupportedError}, +}; + +/// Result of a decoding process +#[derive(Debug)] +pub enum DecodingResult { + /// A vector of unsigned bytes + U8(Vec), + /// A vector of unsigned words + U16(Vec), + /// A vector of 32 bit unsigned ints + U32(Vec), + /// A vector of 64 bit unsigned ints + U64(Vec), + /// A vector of 16 bit IEEE floats (held in u16) + F16(Vec), + /// A vector of 32 bit IEEE floats + F32(Vec), + /// A vector of 64 bit IEEE floats + F64(Vec), + /// A vector of 8 bit signed ints + I8(Vec), + /// A vector of 16 bit signed ints + I16(Vec), + /// A vector of 32 bit signed ints + I32(Vec), + /// A vector of 64 bit signed ints + I64(Vec), +} + +impl DecodingResult { + /// Reallocate the buffer to decode all planes of the indicated layout. + pub fn resize_to( + &mut self, + buffer: &BufferLayoutPreference, + limits: &Limits, + ) -> Result<(), TiffError> { + let sample_type = buffer.sample_type.ok_or(TiffError::UnsupportedError( + TiffUnsupportedError::UnknownInterpretation, + ))?; + + let extent = sample_type.extent_for_bytes(buffer.complete_len); + self.resize_to_extent(extent, limits) + } + + pub(crate) fn resize_to_extent( + &mut self, + extent: DecodingExtent, + limits: &Limits, + ) -> Result<(), TiffError> { + // FIXME: we *can* reuse the allocation sometimes. + *self = extent.to_result_buffer(limits)?; + Ok(()) + } + + fn new( + size: usize, + limits: &Limits, + from_fn: fn(Vec) -> Self, + ) -> TiffResult { + if size > limits.decoding_buffer_size / core::mem::size_of::() { + Err(TiffError::LimitsExceeded) + } else { + Ok(from_fn(vec![T::default(); size])) + } + } + + fn new_u8(size: usize, limits: &Limits) -> TiffResult { + Self::new(size, limits, DecodingResult::U8) + } + + fn new_u16(size: usize, limits: &Limits) -> TiffResult { + Self::new(size, limits, DecodingResult::U16) + } + + fn new_u32(size: usize, limits: &Limits) -> TiffResult { + Self::new(size, limits, DecodingResult::U32) + } + + fn new_u64(size: usize, limits: &Limits) -> TiffResult { + Self::new(size, limits, DecodingResult::U64) + } + + fn new_f32(size: usize, limits: &Limits) -> TiffResult { + Self::new(size, limits, DecodingResult::F32) + } + + fn new_f64(size: usize, limits: &Limits) -> TiffResult { + Self::new(size, limits, DecodingResult::F64) + } + + fn new_f16(size: usize, limits: &Limits) -> TiffResult { + Self::new(size, limits, DecodingResult::F16) + } + + fn new_i8(size: usize, limits: &Limits) -> TiffResult { + Self::new(size, limits, DecodingResult::I8) + } + + fn new_i16(size: usize, limits: &Limits) -> TiffResult { + Self::new(size, limits, DecodingResult::I16) + } + + fn new_i32(size: usize, limits: &Limits) -> TiffResult { + Self::new(size, limits, DecodingResult::I32) + } + + fn new_i64(size: usize, limits: &Limits) -> TiffResult { + Self::new(size, limits, DecodingResult::I64) + } + + /// Get a view of this buffer starting from the nth _sample_ of the current type. + pub fn as_buffer(&mut self, start: usize) -> DecodingBuffer<'_> { + match *self { + DecodingResult::U8(ref mut buf) => DecodingBuffer::U8(&mut buf[start..]), + DecodingResult::U16(ref mut buf) => DecodingBuffer::U16(&mut buf[start..]), + DecodingResult::U32(ref mut buf) => DecodingBuffer::U32(&mut buf[start..]), + DecodingResult::U64(ref mut buf) => DecodingBuffer::U64(&mut buf[start..]), + DecodingResult::F16(ref mut buf) => DecodingBuffer::F16(&mut buf[start..]), + DecodingResult::F32(ref mut buf) => DecodingBuffer::F32(&mut buf[start..]), + DecodingResult::F64(ref mut buf) => DecodingBuffer::F64(&mut buf[start..]), + DecodingResult::I8(ref mut buf) => DecodingBuffer::I8(&mut buf[start..]), + DecodingResult::I16(ref mut buf) => DecodingBuffer::I16(&mut buf[start..]), + DecodingResult::I32(ref mut buf) => DecodingBuffer::I32(&mut buf[start..]), + DecodingResult::I64(ref mut buf) => DecodingBuffer::I64(&mut buf[start..]), + } + } +} + +// A buffer for image decoding +pub enum DecodingBuffer<'a> { + /// A slice of unsigned bytes + U8(&'a mut [u8]), + /// A slice of unsigned words + U16(&'a mut [u16]), + /// A slice of 32 bit unsigned ints + U32(&'a mut [u32]), + /// A slice of 64 bit unsigned ints + U64(&'a mut [u64]), + /// A slice of 16 bit IEEE floats + F16(&'a mut [f16]), + /// A slice of 32 bit IEEE floats + F32(&'a mut [f32]), + /// A slice of 64 bit IEEE floats + F64(&'a mut [f64]), + /// A slice of 8 bits signed ints + I8(&'a mut [i8]), + /// A slice of 16 bits signed ints + I16(&'a mut [i16]), + /// A slice of 32 bits signed ints + I32(&'a mut [i32]), + /// A slice of 64 bits signed ints + I64(&'a mut [i64]), +} + +impl<'a> DecodingBuffer<'a> { + pub fn as_bytes(&self) -> &[u8] { + match self { + DecodingBuffer::U8(buf) => buf, + DecodingBuffer::I8(buf) => bytecast::i8_as_ne_bytes(buf), + DecodingBuffer::U16(buf) => bytecast::u16_as_ne_bytes(buf), + DecodingBuffer::I16(buf) => bytecast::i16_as_ne_bytes(buf), + DecodingBuffer::U32(buf) => bytecast::u32_as_ne_bytes(buf), + DecodingBuffer::I32(buf) => bytecast::i32_as_ne_bytes(buf), + DecodingBuffer::U64(buf) => bytecast::u64_as_ne_bytes(buf), + DecodingBuffer::I64(buf) => bytecast::i64_as_ne_bytes(buf), + DecodingBuffer::F16(buf) => bytecast::f16_as_ne_bytes(buf), + DecodingBuffer::F32(buf) => bytecast::f32_as_ne_bytes(buf), + DecodingBuffer::F64(buf) => bytecast::f64_as_ne_bytes(buf), + } + } + + pub fn as_bytes_mut(&mut self) -> &mut [u8] { + match self { + DecodingBuffer::U8(buf) => buf, + DecodingBuffer::I8(buf) => bytecast::i8_as_ne_mut_bytes(buf), + DecodingBuffer::U16(buf) => bytecast::u16_as_ne_mut_bytes(buf), + DecodingBuffer::I16(buf) => bytecast::i16_as_ne_mut_bytes(buf), + DecodingBuffer::U32(buf) => bytecast::u32_as_ne_mut_bytes(buf), + DecodingBuffer::I32(buf) => bytecast::i32_as_ne_mut_bytes(buf), + DecodingBuffer::U64(buf) => bytecast::u64_as_ne_mut_bytes(buf), + DecodingBuffer::I64(buf) => bytecast::i64_as_ne_mut_bytes(buf), + DecodingBuffer::F16(buf) => bytecast::f16_as_ne_mut_bytes(buf), + DecodingBuffer::F32(buf) => bytecast::f32_as_ne_mut_bytes(buf), + DecodingBuffer::F64(buf) => bytecast::f64_as_ne_mut_bytes(buf), + } + } + + pub fn byte_len(&self) -> usize { + self.as_bytes().len() + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum DecodingSampleType { + U8, + U16, + U32, + U64, + F16, + F32, + F64, + I8, + I16, + I32, + I64, +} + +impl DecodingSampleType { + pub(crate) fn extent_for_bytes(self, bytes: usize) -> DecodingExtent { + match self { + DecodingSampleType::U8 => DecodingExtent::U8(bytes), + DecodingSampleType::U16 => DecodingExtent::U16(bytes.div_ceil(2)), + DecodingSampleType::U32 => DecodingExtent::U32(bytes.div_ceil(4)), + DecodingSampleType::U64 => DecodingExtent::U64(bytes.div_ceil(8)), + DecodingSampleType::I8 => DecodingExtent::I8(bytes), + DecodingSampleType::I16 => DecodingExtent::I16(bytes.div_ceil(2)), + DecodingSampleType::I32 => DecodingExtent::I32(bytes.div_ceil(4)), + DecodingSampleType::I64 => DecodingExtent::I64(bytes.div_ceil(8)), + DecodingSampleType::F16 => DecodingExtent::F16(bytes.div_ceil(2)), + DecodingSampleType::F32 => DecodingExtent::F32(bytes.div_ceil(4)), + DecodingSampleType::F64 => DecodingExtent::F64(bytes.div_ceil(8)), + } + } +} + +/// The count and matching discriminant for a `DecodingBuffer`. +#[derive(Clone)] +pub(crate) enum DecodingExtent { + U8(usize), + U16(usize), + U32(usize), + U64(usize), + F16(usize), + F32(usize), + F64(usize), + I8(usize), + I16(usize), + I32(usize), + I64(usize), +} + +impl DecodingExtent { + pub(crate) fn to_result_buffer(&self, limits: &Limits) -> TiffResult { + match *self { + DecodingExtent::U8(count) => DecodingResult::new_u8(count, limits), + DecodingExtent::U16(count) => DecodingResult::new_u16(count, limits), + DecodingExtent::U32(count) => DecodingResult::new_u32(count, limits), + DecodingExtent::U64(count) => DecodingResult::new_u64(count, limits), + DecodingExtent::F16(count) => DecodingResult::new_f16(count, limits), + DecodingExtent::F32(count) => DecodingResult::new_f32(count, limits), + DecodingExtent::F64(count) => DecodingResult::new_f64(count, limits), + DecodingExtent::I8(count) => DecodingResult::new_i8(count, limits), + DecodingExtent::I16(count) => DecodingResult::new_i16(count, limits), + DecodingExtent::I32(count) => DecodingResult::new_i32(count, limits), + DecodingExtent::I64(count) => DecodingResult::new_i64(count, limits), + } + } + + pub(crate) fn preferred_layout(self) -> TiffResult { + fn overflow(_: LayoutError) -> TiffError { + TiffError::LimitsExceeded + } + + match self { + DecodingExtent::U8(count) => Layout::array::(count), + DecodingExtent::U16(count) => Layout::array::(count), + DecodingExtent::U32(count) => Layout::array::(count), + DecodingExtent::U64(count) => Layout::array::(count), + DecodingExtent::F16(count) => Layout::array::(count), + DecodingExtent::F32(count) => Layout::array::(count), + DecodingExtent::F64(count) => Layout::array::(count), + DecodingExtent::I8(count) => Layout::array::(count), + DecodingExtent::I16(count) => Layout::array::(count), + DecodingExtent::I32(count) => Layout::array::(count), + DecodingExtent::I64(count) => Layout::array::(count), + } + .map_err(overflow) + } + + pub(crate) fn sample_type(&self) -> DecodingSampleType { + match *self { + DecodingExtent::U8(_) => DecodingSampleType::U8, + DecodingExtent::U16(_) => DecodingSampleType::U16, + DecodingExtent::U32(_) => DecodingSampleType::U32, + DecodingExtent::U64(_) => DecodingSampleType::U64, + DecodingExtent::F16(_) => DecodingSampleType::F16, + DecodingExtent::F32(_) => DecodingSampleType::F32, + DecodingExtent::F64(_) => DecodingSampleType::F64, + DecodingExtent::I8(_) => DecodingSampleType::I8, + DecodingExtent::I16(_) => DecodingSampleType::I16, + DecodingExtent::I32(_) => DecodingSampleType::I32, + DecodingExtent::I64(_) => DecodingSampleType::I64, + } + } +} diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 81a227c..9aed8c3 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -1,4 +1,3 @@ -use std::alloc::{Layout, LayoutError}; use std::collections::BTreeMap; use std::io::{self, Read, Seek}; use std::num::NonZeroUsize; @@ -8,14 +7,13 @@ use crate::tags::{ ValueBuffer, }; use crate::{ - bytecast, ColorType, Directory, TiffError, TiffFormatError, TiffResult, TiffUnsupportedError, - UsageError, + ColorType, Directory, TiffError, TiffFormatError, TiffResult, TiffUnsupportedError, UsageError, }; -use half::f16; use self::image::Image; use self::stream::EndianReader; +mod buffer; mod cycles; pub mod ifd; mod image; @@ -23,233 +21,13 @@ mod logluv; mod stream; mod tag_reader; +pub use self::buffer::{DecodingResult, DecodingBuffer, DecodingSampleType}; +use self::buffer::DecodingExtent; + /// An index referring to a (rectangular) region of an image. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct TiffCodingUnit(pub u32); -/// Result of a decoding process -#[derive(Debug)] -pub enum DecodingResult { - /// A vector of unsigned bytes - U8(Vec), - /// A vector of unsigned words - U16(Vec), - /// A vector of 32 bit unsigned ints - U32(Vec), - /// A vector of 64 bit unsigned ints - U64(Vec), - /// A vector of 16 bit IEEE floats (held in u16) - F16(Vec), - /// A vector of 32 bit IEEE floats - F32(Vec), - /// A vector of 64 bit IEEE floats - F64(Vec), - /// A vector of 8 bit signed ints - I8(Vec), - /// A vector of 16 bit signed ints - I16(Vec), - /// A vector of 32 bit signed ints - I32(Vec), - /// A vector of 64 bit signed ints - I64(Vec), -} - -impl DecodingResult { - /// Reallocate the buffer to decode all planes of the indicated layout. - pub fn resize_to( - &mut self, - buffer: &BufferLayoutPreference, - limits: &Limits, - ) -> Result<(), TiffError> { - let sample_type = buffer.sample_type.ok_or(TiffError::UnsupportedError( - TiffUnsupportedError::UnknownInterpretation, - ))?; - - let extent = sample_type.extent_for_bytes(buffer.complete_len); - self.resize_to_extent(extent, limits) - } - - fn resize_to_extent( - &mut self, - extent: DecodingExtent, - limits: &Limits, - ) -> Result<(), TiffError> { - // FIXME: we *can* reuse the allocation sometimes. - *self = extent.to_result_buffer(limits)?; - Ok(()) - } - - fn new( - size: usize, - limits: &Limits, - from_fn: fn(Vec) -> Self, - ) -> TiffResult { - if size > limits.decoding_buffer_size / core::mem::size_of::() { - Err(TiffError::LimitsExceeded) - } else { - Ok(from_fn(vec![T::default(); size])) - } - } - - fn new_u8(size: usize, limits: &Limits) -> TiffResult { - Self::new(size, limits, DecodingResult::U8) - } - - fn new_u16(size: usize, limits: &Limits) -> TiffResult { - Self::new(size, limits, DecodingResult::U16) - } - - fn new_u32(size: usize, limits: &Limits) -> TiffResult { - Self::new(size, limits, DecodingResult::U32) - } - - fn new_u64(size: usize, limits: &Limits) -> TiffResult { - Self::new(size, limits, DecodingResult::U64) - } - - fn new_f32(size: usize, limits: &Limits) -> TiffResult { - Self::new(size, limits, DecodingResult::F32) - } - - fn new_f64(size: usize, limits: &Limits) -> TiffResult { - Self::new(size, limits, DecodingResult::F64) - } - - fn new_f16(size: usize, limits: &Limits) -> TiffResult { - Self::new(size, limits, DecodingResult::F16) - } - - fn new_i8(size: usize, limits: &Limits) -> TiffResult { - Self::new(size, limits, DecodingResult::I8) - } - - fn new_i16(size: usize, limits: &Limits) -> TiffResult { - Self::new(size, limits, DecodingResult::I16) - } - - fn new_i32(size: usize, limits: &Limits) -> TiffResult { - Self::new(size, limits, DecodingResult::I32) - } - - fn new_i64(size: usize, limits: &Limits) -> TiffResult { - Self::new(size, limits, DecodingResult::I64) - } - - /// Get a view of this buffer starting from the nth _sample_ of the current type. - pub fn as_buffer(&mut self, start: usize) -> DecodingBuffer<'_> { - match *self { - DecodingResult::U8(ref mut buf) => DecodingBuffer::U8(&mut buf[start..]), - DecodingResult::U16(ref mut buf) => DecodingBuffer::U16(&mut buf[start..]), - DecodingResult::U32(ref mut buf) => DecodingBuffer::U32(&mut buf[start..]), - DecodingResult::U64(ref mut buf) => DecodingBuffer::U64(&mut buf[start..]), - DecodingResult::F16(ref mut buf) => DecodingBuffer::F16(&mut buf[start..]), - DecodingResult::F32(ref mut buf) => DecodingBuffer::F32(&mut buf[start..]), - DecodingResult::F64(ref mut buf) => DecodingBuffer::F64(&mut buf[start..]), - DecodingResult::I8(ref mut buf) => DecodingBuffer::I8(&mut buf[start..]), - DecodingResult::I16(ref mut buf) => DecodingBuffer::I16(&mut buf[start..]), - DecodingResult::I32(ref mut buf) => DecodingBuffer::I32(&mut buf[start..]), - DecodingResult::I64(ref mut buf) => DecodingBuffer::I64(&mut buf[start..]), - } - } -} - -// A buffer for image decoding -pub enum DecodingBuffer<'a> { - /// A slice of unsigned bytes - U8(&'a mut [u8]), - /// A slice of unsigned words - U16(&'a mut [u16]), - /// A slice of 32 bit unsigned ints - U32(&'a mut [u32]), - /// A slice of 64 bit unsigned ints - U64(&'a mut [u64]), - /// A slice of 16 bit IEEE floats - F16(&'a mut [f16]), - /// A slice of 32 bit IEEE floats - F32(&'a mut [f32]), - /// A slice of 64 bit IEEE floats - F64(&'a mut [f64]), - /// A slice of 8 bits signed ints - I8(&'a mut [i8]), - /// A slice of 16 bits signed ints - I16(&'a mut [i16]), - /// A slice of 32 bits signed ints - I32(&'a mut [i32]), - /// A slice of 64 bits signed ints - I64(&'a mut [i64]), -} - -impl<'a> DecodingBuffer<'a> { - pub fn as_bytes(&self) -> &[u8] { - match self { - DecodingBuffer::U8(buf) => buf, - DecodingBuffer::I8(buf) => bytecast::i8_as_ne_bytes(buf), - DecodingBuffer::U16(buf) => bytecast::u16_as_ne_bytes(buf), - DecodingBuffer::I16(buf) => bytecast::i16_as_ne_bytes(buf), - DecodingBuffer::U32(buf) => bytecast::u32_as_ne_bytes(buf), - DecodingBuffer::I32(buf) => bytecast::i32_as_ne_bytes(buf), - DecodingBuffer::U64(buf) => bytecast::u64_as_ne_bytes(buf), - DecodingBuffer::I64(buf) => bytecast::i64_as_ne_bytes(buf), - DecodingBuffer::F16(buf) => bytecast::f16_as_ne_bytes(buf), - DecodingBuffer::F32(buf) => bytecast::f32_as_ne_bytes(buf), - DecodingBuffer::F64(buf) => bytecast::f64_as_ne_bytes(buf), - } - } - - pub fn as_bytes_mut(&mut self) -> &mut [u8] { - match self { - DecodingBuffer::U8(buf) => buf, - DecodingBuffer::I8(buf) => bytecast::i8_as_ne_mut_bytes(buf), - DecodingBuffer::U16(buf) => bytecast::u16_as_ne_mut_bytes(buf), - DecodingBuffer::I16(buf) => bytecast::i16_as_ne_mut_bytes(buf), - DecodingBuffer::U32(buf) => bytecast::u32_as_ne_mut_bytes(buf), - DecodingBuffer::I32(buf) => bytecast::i32_as_ne_mut_bytes(buf), - DecodingBuffer::U64(buf) => bytecast::u64_as_ne_mut_bytes(buf), - DecodingBuffer::I64(buf) => bytecast::i64_as_ne_mut_bytes(buf), - DecodingBuffer::F16(buf) => bytecast::f16_as_ne_mut_bytes(buf), - DecodingBuffer::F32(buf) => bytecast::f32_as_ne_mut_bytes(buf), - DecodingBuffer::F64(buf) => bytecast::f64_as_ne_mut_bytes(buf), - } - } - - pub fn byte_len(&self) -> usize { - self.as_bytes().len() - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum DecodingSampleType { - U8, - U16, - U32, - U64, - F16, - F32, - F64, - I8, - I16, - I32, - I64, -} - -impl DecodingSampleType { - fn extent_for_bytes(self, bytes: usize) -> DecodingExtent { - match self { - DecodingSampleType::U8 => DecodingExtent::U8(bytes), - DecodingSampleType::U16 => DecodingExtent::U16(bytes.div_ceil(2)), - DecodingSampleType::U32 => DecodingExtent::U32(bytes.div_ceil(4)), - DecodingSampleType::U64 => DecodingExtent::U64(bytes.div_ceil(8)), - DecodingSampleType::I8 => DecodingExtent::I8(bytes), - DecodingSampleType::I16 => DecodingExtent::I16(bytes.div_ceil(2)), - DecodingSampleType::I32 => DecodingExtent::I32(bytes.div_ceil(4)), - DecodingSampleType::I64 => DecodingExtent::I64(bytes.div_ceil(8)), - DecodingSampleType::F16 => DecodingExtent::F16(bytes.div_ceil(2)), - DecodingSampleType::F32 => DecodingExtent::F32(bytes.div_ceil(4)), - DecodingSampleType::F64 => DecodingExtent::F64(bytes.div_ceil(8)), - } - } -} - /// Information on the byte buffer that should be supplied to the decoder. /// /// This is relevant for [`Decoder::read_image_bytes`] and [`Decoder::read_chunk_bytes`] where the @@ -383,77 +161,6 @@ impl image::ReadoutLayout { } } -/// The count and matching discriminant for a `DecodingBuffer`. -#[derive(Clone)] -enum DecodingExtent { - U8(usize), - U16(usize), - U32(usize), - U64(usize), - F16(usize), - F32(usize), - F64(usize), - I8(usize), - I16(usize), - I32(usize), - I64(usize), -} - -impl DecodingExtent { - fn to_result_buffer(&self, limits: &Limits) -> TiffResult { - match *self { - DecodingExtent::U8(count) => DecodingResult::new_u8(count, limits), - DecodingExtent::U16(count) => DecodingResult::new_u16(count, limits), - DecodingExtent::U32(count) => DecodingResult::new_u32(count, limits), - DecodingExtent::U64(count) => DecodingResult::new_u64(count, limits), - DecodingExtent::F16(count) => DecodingResult::new_f16(count, limits), - DecodingExtent::F32(count) => DecodingResult::new_f32(count, limits), - DecodingExtent::F64(count) => DecodingResult::new_f64(count, limits), - DecodingExtent::I8(count) => DecodingResult::new_i8(count, limits), - DecodingExtent::I16(count) => DecodingResult::new_i16(count, limits), - DecodingExtent::I32(count) => DecodingResult::new_i32(count, limits), - DecodingExtent::I64(count) => DecodingResult::new_i64(count, limits), - } - } - - fn preferred_layout(self) -> TiffResult { - fn overflow(_: LayoutError) -> TiffError { - TiffError::LimitsExceeded - } - - match self { - DecodingExtent::U8(count) => Layout::array::(count), - DecodingExtent::U16(count) => Layout::array::(count), - DecodingExtent::U32(count) => Layout::array::(count), - DecodingExtent::U64(count) => Layout::array::(count), - DecodingExtent::F16(count) => Layout::array::(count), - DecodingExtent::F32(count) => Layout::array::(count), - DecodingExtent::F64(count) => Layout::array::(count), - DecodingExtent::I8(count) => Layout::array::(count), - DecodingExtent::I16(count) => Layout::array::(count), - DecodingExtent::I32(count) => Layout::array::(count), - DecodingExtent::I64(count) => Layout::array::(count), - } - .map_err(overflow) - } - - fn sample_type(&self) -> DecodingSampleType { - match *self { - DecodingExtent::U8(_) => DecodingSampleType::U8, - DecodingExtent::U16(_) => DecodingSampleType::U16, - DecodingExtent::U32(_) => DecodingSampleType::U32, - DecodingExtent::U64(_) => DecodingSampleType::U64, - DecodingExtent::F16(_) => DecodingSampleType::F16, - DecodingExtent::F32(_) => DecodingSampleType::F32, - DecodingExtent::F64(_) => DecodingSampleType::F64, - DecodingExtent::I8(_) => DecodingSampleType::I8, - DecodingExtent::I16(_) => DecodingSampleType::I16, - DecodingExtent::I32(_) => DecodingSampleType::I32, - DecodingExtent::I64(_) => DecodingSampleType::I64, - } - } -} - #[derive(Debug, Copy, Clone, PartialEq)] /// Chunk type of the internal representation pub enum ChunkType { From 860052a8f4ef75bb4d146800cd3a6853a90e2996 Mon Sep 17 00:00:00 2001 From: "A. Molzer" <5550310+197g@users.noreply.github.com> Date: Fri, 27 Mar 2026 18:47:29 +0100 Subject: [PATCH 2/2] Rename decoding buffers New names align better with conventions. In particular, Buffer refers to an owning type. --- examples/decode.rs | 44 +++---- src/decoder/buffer.rs | 146 ++++++++++++------------ src/decoder/mod.rs | 17 ++- src/encoder/writer.rs | 4 +- tests/decode_fp16_images.rs | 12 +- tests/decode_geotiff_images.rs | 6 +- tests/decode_images.rs | 40 +++---- tests/decode_libtiffpic.rs | 28 ++--- tests/decode_planes.rs | 4 +- tests/encode_images.rs | 32 +++--- tests/encode_images_with_compression.rs | 6 +- tests/predict.rs | 8 +- 12 files changed, 178 insertions(+), 169 deletions(-) diff --git a/examples/decode.rs b/examples/decode.rs index cd3d42e..39ddd00 100644 --- a/examples/decode.rs +++ b/examples/decode.rs @@ -1,4 +1,4 @@ -use tiff::decoder::{BufferLayoutPreference, Decoder, DecodingBuffer, DecodingResult}; +use tiff::decoder::{BufferLayoutPreference, Decoder, DecodingSampleBuffer, DecodingSampleSlice}; fn main() -> Result<(), Box> { let Some(image) = std::env::args_os().nth(1) else { @@ -10,7 +10,7 @@ fn main() -> Result<(), Box> { let io = std::io::BufReader::new(file); let mut reader = Decoder::open(io)?; - let mut data = DecodingResult::I8(vec![]); + let mut data = DecodingSampleBuffer::I8(vec![]); for i in 0u32.. { let colortype = reader.colortype()?; @@ -31,32 +31,32 @@ fn main() -> Result<(), Box> { fn debug_planes( index: u32, - data: &mut DecodingResult, + data: &mut DecodingSampleBuffer, layout: &BufferLayoutPreference, colortype: &tiff::ColorType, (width, height): (u32, u32), ) { match data { - DecodingResult::F16(v) => { + DecodingSampleBuffer::F16(v) => { let samples = v .iter() .map(|&f| (f64::from(f) * f64::from(u16::MAX)) as u16) .collect::>(); - *data = DecodingResult::U16(samples); + *data = DecodingSampleBuffer::U16(samples); } - DecodingResult::F32(v) => { + DecodingSampleBuffer::F32(v) => { let samples = v .iter() .map(|&f| (f64::from(f) * f64::from(u16::MAX)) as u16) .collect::>(); - *data = DecodingResult::U16(samples); + *data = DecodingSampleBuffer::U16(samples); } - DecodingResult::F64(v) => { + DecodingSampleBuffer::F64(v) => { let samples = v .iter() .map(|&f| (f * f64::from(u16::MAX)) as u16) .collect::>(); - *data = DecodingResult::U16(samples); + *data = DecodingSampleBuffer::U16(samples); } _ => {} } @@ -98,24 +98,24 @@ fn debug_planes( // them here (e.g. represent 1-bit as `{0, 1}`) but we'd also set `maxval` accordingly and // this requires tupltype to be `BLACKANDWHITE` so introducing a bunch of complexity. If // you want to do that in your real code, go ahead. - DecodingBuffer::U8(buf) => match colortype.bit_depth() { + DecodingSampleSlice::U8(buf) => match colortype.bit_depth() { 8 => u64::from(u8::MAX), 4 => { fallback_buffer = vec![0; (swidth * sheight) as usize]; expand_4bit(buf, swidth, &mut fallback_buffer); - *data = DecodingResult::U8(fallback_buffer); + *data = DecodingSampleBuffer::U8(fallback_buffer); u64::from(u8::MAX) } 2 => { fallback_buffer = vec![0; (swidth * sheight) as usize]; expand_2bit(buf, swidth, &mut fallback_buffer); - *data = DecodingResult::U8(fallback_buffer); + *data = DecodingSampleBuffer::U8(fallback_buffer); u64::from(u8::MAX) } 1 => { fallback_buffer = vec![0; (swidth * sheight) as usize]; expand_1bit(buf, swidth, &mut fallback_buffer); - *data = DecodingResult::U8(fallback_buffer); + *data = DecodingSampleBuffer::U8(fallback_buffer); u64::from(u8::MAX) } _ => { @@ -126,28 +126,30 @@ fn debug_planes( return; } }, - DecodingBuffer::U16(_) => u64::from(u16::MAX), - DecodingBuffer::U32(_) => u64::from(u32::MAX), - DecodingBuffer::U64(_) => u64::MAX, + DecodingSampleSlice::U16(_) => u64::from(u16::MAX), + DecodingSampleSlice::U32(_) => u64::from(u32::MAX), + DecodingSampleSlice::U64(_) => u64::MAX, // Eh, this is a good effort I guess. - DecodingBuffer::I8(items) => { + DecodingSampleSlice::I8(items) => { items.iter_mut().for_each(|v| *v = 0.max(*v)); u64::from(i8::MAX as u8) } - DecodingBuffer::I16(items) => { + DecodingSampleSlice::I16(items) => { items.iter_mut().for_each(|v| *v = 0.max(*v)); u64::from(i16::MAX as u16) } - DecodingBuffer::I32(items) => { + DecodingSampleSlice::I32(items) => { items.iter_mut().for_each(|v| *v = 0.max(*v)); u64::from(i32::MAX as u32) } - DecodingBuffer::I64(items) => { + DecodingSampleSlice::I64(items) => { items.iter_mut().for_each(|v| *v = 0.max(*v)); i64::MAX as u64 } // Not supported by PAM. - DecodingBuffer::F16(_) | DecodingBuffer::F32(_) | DecodingBuffer::F64(_) => return, + DecodingSampleSlice::F16(_) | DecodingSampleSlice::F32(_) | DecodingSampleSlice::F64(_) => { + return + } }; let byte_len = if layout.planes > 1 { diff --git a/src/decoder/buffer.rs b/src/decoder/buffer.rs index 3943ec7..dc5a554 100644 --- a/src/decoder/buffer.rs +++ b/src/decoder/buffer.rs @@ -9,7 +9,7 @@ use crate::{ /// Result of a decoding process #[derive(Debug)] -pub enum DecodingResult { +pub enum DecodingSampleBuffer { /// A vector of unsigned bytes U8(Vec), /// A vector of unsigned words @@ -34,7 +34,7 @@ pub enum DecodingResult { I64(Vec), } -impl DecodingResult { +impl DecodingSampleBuffer { /// Reallocate the buffer to decode all planes of the indicated layout. pub fn resize_to( &mut self, @@ -63,7 +63,7 @@ impl DecodingResult { size: usize, limits: &Limits, from_fn: fn(Vec) -> Self, - ) -> TiffResult { + ) -> TiffResult { if size > limits.decoding_buffer_size / core::mem::size_of::() { Err(TiffError::LimitsExceeded) } else { @@ -71,70 +71,70 @@ impl DecodingResult { } } - fn new_u8(size: usize, limits: &Limits) -> TiffResult { - Self::new(size, limits, DecodingResult::U8) + fn new_u8(size: usize, limits: &Limits) -> TiffResult { + Self::new(size, limits, DecodingSampleBuffer::U8) } - fn new_u16(size: usize, limits: &Limits) -> TiffResult { - Self::new(size, limits, DecodingResult::U16) + fn new_u16(size: usize, limits: &Limits) -> TiffResult { + Self::new(size, limits, DecodingSampleBuffer::U16) } - fn new_u32(size: usize, limits: &Limits) -> TiffResult { - Self::new(size, limits, DecodingResult::U32) + fn new_u32(size: usize, limits: &Limits) -> TiffResult { + Self::new(size, limits, DecodingSampleBuffer::U32) } - fn new_u64(size: usize, limits: &Limits) -> TiffResult { - Self::new(size, limits, DecodingResult::U64) + fn new_u64(size: usize, limits: &Limits) -> TiffResult { + Self::new(size, limits, DecodingSampleBuffer::U64) } - fn new_f32(size: usize, limits: &Limits) -> TiffResult { - Self::new(size, limits, DecodingResult::F32) + fn new_f32(size: usize, limits: &Limits) -> TiffResult { + Self::new(size, limits, DecodingSampleBuffer::F32) } - fn new_f64(size: usize, limits: &Limits) -> TiffResult { - Self::new(size, limits, DecodingResult::F64) + fn new_f64(size: usize, limits: &Limits) -> TiffResult { + Self::new(size, limits, DecodingSampleBuffer::F64) } - fn new_f16(size: usize, limits: &Limits) -> TiffResult { - Self::new(size, limits, DecodingResult::F16) + fn new_f16(size: usize, limits: &Limits) -> TiffResult { + Self::new(size, limits, DecodingSampleBuffer::F16) } - fn new_i8(size: usize, limits: &Limits) -> TiffResult { - Self::new(size, limits, DecodingResult::I8) + fn new_i8(size: usize, limits: &Limits) -> TiffResult { + Self::new(size, limits, DecodingSampleBuffer::I8) } - fn new_i16(size: usize, limits: &Limits) -> TiffResult { - Self::new(size, limits, DecodingResult::I16) + fn new_i16(size: usize, limits: &Limits) -> TiffResult { + Self::new(size, limits, DecodingSampleBuffer::I16) } - fn new_i32(size: usize, limits: &Limits) -> TiffResult { - Self::new(size, limits, DecodingResult::I32) + fn new_i32(size: usize, limits: &Limits) -> TiffResult { + Self::new(size, limits, DecodingSampleBuffer::I32) } - fn new_i64(size: usize, limits: &Limits) -> TiffResult { - Self::new(size, limits, DecodingResult::I64) + fn new_i64(size: usize, limits: &Limits) -> TiffResult { + Self::new(size, limits, DecodingSampleBuffer::I64) } /// Get a view of this buffer starting from the nth _sample_ of the current type. - pub fn as_buffer(&mut self, start: usize) -> DecodingBuffer<'_> { + pub fn as_buffer(&mut self, start: usize) -> DecodingSampleSlice<'_> { match *self { - DecodingResult::U8(ref mut buf) => DecodingBuffer::U8(&mut buf[start..]), - DecodingResult::U16(ref mut buf) => DecodingBuffer::U16(&mut buf[start..]), - DecodingResult::U32(ref mut buf) => DecodingBuffer::U32(&mut buf[start..]), - DecodingResult::U64(ref mut buf) => DecodingBuffer::U64(&mut buf[start..]), - DecodingResult::F16(ref mut buf) => DecodingBuffer::F16(&mut buf[start..]), - DecodingResult::F32(ref mut buf) => DecodingBuffer::F32(&mut buf[start..]), - DecodingResult::F64(ref mut buf) => DecodingBuffer::F64(&mut buf[start..]), - DecodingResult::I8(ref mut buf) => DecodingBuffer::I8(&mut buf[start..]), - DecodingResult::I16(ref mut buf) => DecodingBuffer::I16(&mut buf[start..]), - DecodingResult::I32(ref mut buf) => DecodingBuffer::I32(&mut buf[start..]), - DecodingResult::I64(ref mut buf) => DecodingBuffer::I64(&mut buf[start..]), + DecodingSampleBuffer::U8(ref mut buf) => DecodingSampleSlice::U8(&mut buf[start..]), + DecodingSampleBuffer::U16(ref mut buf) => DecodingSampleSlice::U16(&mut buf[start..]), + DecodingSampleBuffer::U32(ref mut buf) => DecodingSampleSlice::U32(&mut buf[start..]), + DecodingSampleBuffer::U64(ref mut buf) => DecodingSampleSlice::U64(&mut buf[start..]), + DecodingSampleBuffer::F16(ref mut buf) => DecodingSampleSlice::F16(&mut buf[start..]), + DecodingSampleBuffer::F32(ref mut buf) => DecodingSampleSlice::F32(&mut buf[start..]), + DecodingSampleBuffer::F64(ref mut buf) => DecodingSampleSlice::F64(&mut buf[start..]), + DecodingSampleBuffer::I8(ref mut buf) => DecodingSampleSlice::I8(&mut buf[start..]), + DecodingSampleBuffer::I16(ref mut buf) => DecodingSampleSlice::I16(&mut buf[start..]), + DecodingSampleBuffer::I32(ref mut buf) => DecodingSampleSlice::I32(&mut buf[start..]), + DecodingSampleBuffer::I64(ref mut buf) => DecodingSampleSlice::I64(&mut buf[start..]), } } } // A buffer for image decoding -pub enum DecodingBuffer<'a> { +pub enum DecodingSampleSlice<'a> { /// A slice of unsigned bytes U8(&'a mut [u8]), /// A slice of unsigned words @@ -159,36 +159,36 @@ pub enum DecodingBuffer<'a> { I64(&'a mut [i64]), } -impl<'a> DecodingBuffer<'a> { +impl<'a> DecodingSampleSlice<'a> { pub fn as_bytes(&self) -> &[u8] { match self { - DecodingBuffer::U8(buf) => buf, - DecodingBuffer::I8(buf) => bytecast::i8_as_ne_bytes(buf), - DecodingBuffer::U16(buf) => bytecast::u16_as_ne_bytes(buf), - DecodingBuffer::I16(buf) => bytecast::i16_as_ne_bytes(buf), - DecodingBuffer::U32(buf) => bytecast::u32_as_ne_bytes(buf), - DecodingBuffer::I32(buf) => bytecast::i32_as_ne_bytes(buf), - DecodingBuffer::U64(buf) => bytecast::u64_as_ne_bytes(buf), - DecodingBuffer::I64(buf) => bytecast::i64_as_ne_bytes(buf), - DecodingBuffer::F16(buf) => bytecast::f16_as_ne_bytes(buf), - DecodingBuffer::F32(buf) => bytecast::f32_as_ne_bytes(buf), - DecodingBuffer::F64(buf) => bytecast::f64_as_ne_bytes(buf), + DecodingSampleSlice::U8(buf) => buf, + DecodingSampleSlice::I8(buf) => bytecast::i8_as_ne_bytes(buf), + DecodingSampleSlice::U16(buf) => bytecast::u16_as_ne_bytes(buf), + DecodingSampleSlice::I16(buf) => bytecast::i16_as_ne_bytes(buf), + DecodingSampleSlice::U32(buf) => bytecast::u32_as_ne_bytes(buf), + DecodingSampleSlice::I32(buf) => bytecast::i32_as_ne_bytes(buf), + DecodingSampleSlice::U64(buf) => bytecast::u64_as_ne_bytes(buf), + DecodingSampleSlice::I64(buf) => bytecast::i64_as_ne_bytes(buf), + DecodingSampleSlice::F16(buf) => bytecast::f16_as_ne_bytes(buf), + DecodingSampleSlice::F32(buf) => bytecast::f32_as_ne_bytes(buf), + DecodingSampleSlice::F64(buf) => bytecast::f64_as_ne_bytes(buf), } } pub fn as_bytes_mut(&mut self) -> &mut [u8] { match self { - DecodingBuffer::U8(buf) => buf, - DecodingBuffer::I8(buf) => bytecast::i8_as_ne_mut_bytes(buf), - DecodingBuffer::U16(buf) => bytecast::u16_as_ne_mut_bytes(buf), - DecodingBuffer::I16(buf) => bytecast::i16_as_ne_mut_bytes(buf), - DecodingBuffer::U32(buf) => bytecast::u32_as_ne_mut_bytes(buf), - DecodingBuffer::I32(buf) => bytecast::i32_as_ne_mut_bytes(buf), - DecodingBuffer::U64(buf) => bytecast::u64_as_ne_mut_bytes(buf), - DecodingBuffer::I64(buf) => bytecast::i64_as_ne_mut_bytes(buf), - DecodingBuffer::F16(buf) => bytecast::f16_as_ne_mut_bytes(buf), - DecodingBuffer::F32(buf) => bytecast::f32_as_ne_mut_bytes(buf), - DecodingBuffer::F64(buf) => bytecast::f64_as_ne_mut_bytes(buf), + DecodingSampleSlice::U8(buf) => buf, + DecodingSampleSlice::I8(buf) => bytecast::i8_as_ne_mut_bytes(buf), + DecodingSampleSlice::U16(buf) => bytecast::u16_as_ne_mut_bytes(buf), + DecodingSampleSlice::I16(buf) => bytecast::i16_as_ne_mut_bytes(buf), + DecodingSampleSlice::U32(buf) => bytecast::u32_as_ne_mut_bytes(buf), + DecodingSampleSlice::I32(buf) => bytecast::i32_as_ne_mut_bytes(buf), + DecodingSampleSlice::U64(buf) => bytecast::u64_as_ne_mut_bytes(buf), + DecodingSampleSlice::I64(buf) => bytecast::i64_as_ne_mut_bytes(buf), + DecodingSampleSlice::F16(buf) => bytecast::f16_as_ne_mut_bytes(buf), + DecodingSampleSlice::F32(buf) => bytecast::f32_as_ne_mut_bytes(buf), + DecodingSampleSlice::F64(buf) => bytecast::f64_as_ne_mut_bytes(buf), } } @@ -247,19 +247,19 @@ pub(crate) enum DecodingExtent { } impl DecodingExtent { - pub(crate) fn to_result_buffer(&self, limits: &Limits) -> TiffResult { + pub(crate) fn to_result_buffer(&self, limits: &Limits) -> TiffResult { match *self { - DecodingExtent::U8(count) => DecodingResult::new_u8(count, limits), - DecodingExtent::U16(count) => DecodingResult::new_u16(count, limits), - DecodingExtent::U32(count) => DecodingResult::new_u32(count, limits), - DecodingExtent::U64(count) => DecodingResult::new_u64(count, limits), - DecodingExtent::F16(count) => DecodingResult::new_f16(count, limits), - DecodingExtent::F32(count) => DecodingResult::new_f32(count, limits), - DecodingExtent::F64(count) => DecodingResult::new_f64(count, limits), - DecodingExtent::I8(count) => DecodingResult::new_i8(count, limits), - DecodingExtent::I16(count) => DecodingResult::new_i16(count, limits), - DecodingExtent::I32(count) => DecodingResult::new_i32(count, limits), - DecodingExtent::I64(count) => DecodingResult::new_i64(count, limits), + DecodingExtent::U8(count) => DecodingSampleBuffer::new_u8(count, limits), + DecodingExtent::U16(count) => DecodingSampleBuffer::new_u16(count, limits), + DecodingExtent::U32(count) => DecodingSampleBuffer::new_u32(count, limits), + DecodingExtent::U64(count) => DecodingSampleBuffer::new_u64(count, limits), + DecodingExtent::F16(count) => DecodingSampleBuffer::new_f16(count, limits), + DecodingExtent::F32(count) => DecodingSampleBuffer::new_f32(count, limits), + DecodingExtent::F64(count) => DecodingSampleBuffer::new_f64(count, limits), + DecodingExtent::I8(count) => DecodingSampleBuffer::new_i8(count, limits), + DecodingExtent::I16(count) => DecodingSampleBuffer::new_i16(count, limits), + DecodingExtent::I32(count) => DecodingSampleBuffer::new_i32(count, limits), + DecodingExtent::I64(count) => DecodingSampleBuffer::new_i64(count, limits), } } diff --git a/src/decoder/mod.rs b/src/decoder/mod.rs index 9aed8c3..53a64ba 100644 --- a/src/decoder/mod.rs +++ b/src/decoder/mod.rs @@ -21,7 +21,14 @@ mod logluv; mod stream; mod tag_reader; -pub use self::buffer::{DecodingResult, DecodingBuffer, DecodingSampleType}; +pub use self::buffer::{DecodingSampleBuffer, DecodingSampleSlice, DecodingSampleType}; + +#[deprecated = "Renamed to `DecodingSampleBuffer`"] +pub type DecodingResult = DecodingSampleBuffer; + +#[deprecated = "Renamed to `DecodingSampleSlice`"] +pub type DecodingBuffer<'a> = DecodingSampleSlice<'a>; + use self::buffer::DecodingExtent; /// An index referring to a (rectangular) region of an image. @@ -1107,7 +1114,7 @@ impl Decoder { /// Read the specified chunk (at index `chunk_index`) and return the binary data as a Vector. /// /// Note that for planar images each chunk contains only one sample of the underlying data. - pub fn read_chunk(&mut self, chunk_index: u32) -> TiffResult { + pub fn read_chunk(&mut self, chunk_index: u32) -> TiffResult { let (width, height) = self.image.chunk_data_dimensions(chunk_index)?; let readout = self.image.readout_for_size(width, height)?; @@ -1148,7 +1155,7 @@ impl Decoder { /// Note that for planar images each chunk contains only one sample of the underlying data. pub fn read_chunk_to_buffer( &mut self, - buffer: &mut DecodingResult, + buffer: &mut DecodingSampleBuffer, chunk_index: u32, output_width: usize, ) -> TiffResult<()> { @@ -1271,7 +1278,7 @@ impl Decoder { /// calls. This old method will likely keep its bugged planar behavior until it is fully /// replaced, to ensure that existing code will not run into unexpectedly large allocations /// that will error on limits instead. - pub fn read_image(&mut self) -> TiffResult { + pub fn read_image(&mut self) -> TiffResult { let readout = self.image.readout_for_image()?; let mut result = readout @@ -1332,7 +1339,7 @@ impl Decoder { /// ``` pub fn read_image_to_buffer( &mut self, - result: &mut DecodingResult, + result: &mut DecodingSampleBuffer, ) -> TiffResult { let readout = self.image.readout_for_image()?; let planes = readout.to_plane_layout()?; diff --git a/src/encoder/writer.rs b/src/encoder/writer.rs index f204483..7299282 100644 --- a/src/encoder/writer.rs +++ b/src/encoder/writer.rs @@ -221,7 +221,7 @@ fn encoder_on_short_writes() { }; let imgdata = vec![42u8; 100 * 100]; - let mut data = crate::decoder::DecodingResult::U8(vec![]); + let mut data = crate::decoder::DecodingSampleBuffer::U8(vec![]); for comp in [ super::Compression::Uncompressed, @@ -247,7 +247,7 @@ fn encoder_on_short_writes() { let _layout = tiff_reader.read_image_to_buffer(&mut data).unwrap(); assert!( - matches!(&data, crate::decoder::DecodingResult::U8(v) if *v == imgdata), + matches!(&data, crate::decoder::DecodingSampleBuffer::U8(v) if *v == imgdata), "{data:?} @ {}", data.as_buffer(0).byte_len() ); diff --git a/tests/decode_fp16_images.rs b/tests/decode_fp16_images.rs index 56456c4..3ade3c5 100644 --- a/tests/decode_fp16_images.rs +++ b/tests/decode_fp16_images.rs @@ -1,6 +1,6 @@ extern crate tiff; -use tiff::decoder::{Decoder, DecodingResult}; +use tiff::decoder::{Decoder, DecodingSampleBuffer}; use tiff::ColorType; use std::fs::File; @@ -28,7 +28,7 @@ fn test_white_ieee_fp16() { ColorType::Gray(16) ); - if let DecodingResult::F16(img) = decoder.read_image().unwrap() { + if let DecodingSampleBuffer::F16(img) = decoder.read_image().unwrap() { for p in img { assert!(p == half::f16::from_f32_const(1.0)); } @@ -58,7 +58,7 @@ fn test_one_black_pixel_ieee_fp16() { ColorType::Gray(16) ); - if let DecodingResult::F16(img) = decoder.read_image().unwrap() { + if let DecodingSampleBuffer::F16(img) = decoder.read_image().unwrap() { for (i, p) in img.iter().enumerate() { if i == 0 { assert!(p < &half::f16::from_f32_const(0.001)); @@ -92,7 +92,7 @@ fn test_pattern_horizontal_differencing_ieee_fp16() { ColorType::Gray(16) ); - if let DecodingResult::F16(img) = decoder.read_image().unwrap() { + if let DecodingSampleBuffer::F16(img) = decoder.read_image().unwrap() { // 0, 2, 5, 8, 12, 16, 255 are black let black = [0, 2, 5, 8, 12, 16, 255]; for (i, p) in img.iter().enumerate() { @@ -128,7 +128,7 @@ fn test_pattern_predictor_ieee_fp16() { ColorType::Gray(16) ); - if let DecodingResult::F16(img) = decoder.read_image().unwrap() { + if let DecodingSampleBuffer::F16(img) = decoder.read_image().unwrap() { // 0, 2, 5, 8, 12, 16, 255 are black let black = [0, 2, 5, 8, 12, 16, 255]; for (i, p) in img.iter().enumerate() { @@ -199,7 +199,7 @@ fn test_predictor_ieee_fp16() { ColorType::Gray(16) ); - if let DecodingResult::F16(img) = decoder.read_image().unwrap() { + if let DecodingSampleBuffer::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 9a4c0e1..b40aff2 100644 --- a/tests/decode_geotiff_images.rs +++ b/tests/decode_geotiff_images.rs @@ -1,6 +1,6 @@ extern crate tiff; -use tiff::decoder::{Decoder, DecodingResult}; +use tiff::decoder::{Decoder, DecodingSampleBuffer}; use tiff::tags::Tag; use tiff::ColorType; @@ -56,7 +56,7 @@ fn test_geo_tiff() { .expect("Cannot get pixel scale"), vec![60.0, 60.0, 0.0] ); - let DecodingResult::I16(data) = decoder.read_image().unwrap() else { + let DecodingSampleBuffer::I16(data) = decoder.read_image().unwrap() else { panic!("Cannot read band data") }; assert_eq!(data.len(), 500); @@ -67,7 +67,7 @@ fn test_geo_tiff() { #[test] fn test_webp_tiff() { let filenames = ["usda_naip_256_webp_z3.tif"]; - let mut buffer = DecodingResult::U8(vec![]); + let mut buffer = DecodingSampleBuffer::U8(vec![]); for filename in filenames.iter() { let path = PathBuf::from(TEST_IMAGE_DIR).join(filename); diff --git a/tests/decode_images.rs b/tests/decode_images.rs index d6339a1..213be5a 100644 --- a/tests/decode_images.rs +++ b/tests/decode_images.rs @@ -1,6 +1,6 @@ extern crate tiff; -use tiff::decoder::{ifd, Decoder, DecodingResult}; +use tiff::decoder::{ifd, Decoder, DecodingSampleBuffer}; use tiff::tags::{ByteOrder, Type}; use tiff::ColorType; @@ -23,7 +23,7 @@ macro_rules! test_image_sum { let img_res = decoder.read_image().unwrap(); match img_res { - DecodingResult::$buffer(res) => { + DecodingSampleBuffer::$buffer(res) => { let sum: $sum_ty = res.into_iter().map(<$sum_ty>::from).sum(); assert_eq!(sum, expected_sum); } @@ -88,17 +88,17 @@ fn compute_tiff_hash(reader: R) -> u32 { // Hash decoded data: TIFF type tag (u16 repr) + LE sample bytes. // Map each variant to the corresponding TIFF Type for byte-order normalization. let sample_type = match &result { - DecodingResult::U8(_) => Type::BYTE, - DecodingResult::I8(_) => Type::SBYTE, - DecodingResult::U16(_) => Type::SHORT, - DecodingResult::I16(_) => Type::SSHORT, - DecodingResult::U32(_) => Type::LONG, - DecodingResult::I32(_) => Type::SLONG, - DecodingResult::F32(_) => Type::FLOAT, - DecodingResult::U64(_) => Type::LONG8, - DecodingResult::I64(_) => Type::SLONG8, - DecodingResult::F64(_) => Type::DOUBLE, - DecodingResult::F16(_) => Type::SHORT, // f16 is 2 bytes like SHORT + DecodingSampleBuffer::U8(_) => Type::BYTE, + DecodingSampleBuffer::I8(_) => Type::SBYTE, + DecodingSampleBuffer::U16(_) => Type::SHORT, + DecodingSampleBuffer::I16(_) => Type::SSHORT, + DecodingSampleBuffer::U32(_) => Type::LONG, + DecodingSampleBuffer::I32(_) => Type::SLONG, + DecodingSampleBuffer::F32(_) => Type::FLOAT, + DecodingSampleBuffer::U64(_) => Type::LONG8, + DecodingSampleBuffer::I64(_) => Type::SLONG8, + DecodingSampleBuffer::F64(_) => Type::DOUBLE, + DecodingSampleBuffer::F16(_) => Type::SHORT, // f16 is 2 bytes like SHORT }; hasher.update(&sample_type.to_u16().to_le_bytes()); @@ -431,7 +431,7 @@ fn test_decode_data() { 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() { + if let DecodingSampleBuffer::U8(img_res) = decoder.read_image().unwrap() { assert_eq!(image_data, img_res); } else { panic!("Wrong data type"); @@ -511,7 +511,7 @@ fn test_inner_access() { let raw_sum: u64 = buf.into_iter().map(::from).sum(); match decoder.read_chunk(0).unwrap() { - DecodingResult::U8(chunk) => { + DecodingSampleBuffer::U8(chunk) => { let sum: u64 = chunk.into_iter().map(::from).sum(); assert_eq!(sum, raw_sum); } @@ -570,7 +570,7 @@ fn test_tiled_incremental() { for tile in 0..tiles { match decoder.read_chunk(tile).unwrap() { - DecodingResult::U8(res) => { + DecodingSampleBuffer::U8(res) => { let sum: u64 = res.into_iter().map(::from).sum(); assert_eq!(sum, sums[tile as usize]); } @@ -604,21 +604,21 @@ fn test_read_planar_bands() { // 1st band (red) match decoder.read_chunk(0).unwrap() { - DecodingResult::U8(chunk) => { + DecodingSampleBuffer::U8(chunk) => { assert_eq!(chunk[0], 73); } _ => panic!("Wrong bit depth"), } // 2nd band (green) match decoder.read_chunk(chunks / 3).unwrap() { - DecodingResult::U8(chunk) => { + DecodingSampleBuffer::U8(chunk) => { assert_eq!(chunk[0], 51); } _ => panic!("Wrong bit depth"), } // 3rd band (blue) match decoder.read_chunk(chunks / 3 * 2).unwrap() { - DecodingResult::U8(chunk) => { + DecodingSampleBuffer::U8(chunk) => { assert_eq!(chunk[0], 30); } _ => panic!("Wrong bit depth"), @@ -994,7 +994,7 @@ fn test_decode_huge_g4() { .read_image() .expect("failed to decode huge G4 image"); - if let tiff::decoder::DecodingResult::U8(data) = result { + if let tiff::decoder::DecodingSampleBuffer::U8(data) = result { assert_eq!(data.len(), (width as usize * height as usize)); } else { panic!("Unexpected decoding result type"); diff --git a/tests/decode_libtiffpic.rs b/tests/decode_libtiffpic.rs index 3bcd888..05097f3 100644 --- a/tests/decode_libtiffpic.rs +++ b/tests/decode_libtiffpic.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use std::{fs::File, path}; -use tiff::decoder::{Decoder, DecodingResult}; +use tiff::decoder::{Decoder, DecodingSampleBuffer}; use tiff::tags::{ByteOrder, Type}; use tiff::ColorType; @@ -252,19 +252,19 @@ fn main() { } /// Map DecodingResult variant to a TIFF Type for byte-order normalization. -fn sample_type_of(result: &DecodingResult) -> Type { +fn sample_type_of(result: &DecodingSampleBuffer) -> Type { match result { - DecodingResult::U8(_) => Type::BYTE, - DecodingResult::I8(_) => Type::SBYTE, - DecodingResult::U16(_) => Type::SHORT, - DecodingResult::I16(_) => Type::SSHORT, - DecodingResult::U32(_) => Type::LONG, - DecodingResult::I32(_) => Type::SLONG, - DecodingResult::F32(_) => Type::FLOAT, - DecodingResult::U64(_) => Type::LONG8, - DecodingResult::I64(_) => Type::SLONG8, - DecodingResult::F64(_) => Type::DOUBLE, - DecodingResult::F16(_) => Type::SHORT, // f16 is 2 bytes like SHORT + DecodingSampleBuffer::U8(_) => Type::BYTE, + DecodingSampleBuffer::I8(_) => Type::SBYTE, + DecodingSampleBuffer::U16(_) => Type::SHORT, + DecodingSampleBuffer::I16(_) => Type::SSHORT, + DecodingSampleBuffer::U32(_) => Type::LONG, + DecodingSampleBuffer::I32(_) => Type::SLONG, + DecodingSampleBuffer::F32(_) => Type::FLOAT, + DecodingSampleBuffer::U64(_) => Type::LONG8, + DecodingSampleBuffer::I64(_) => Type::SLONG8, + DecodingSampleBuffer::F64(_) => Type::DOUBLE, + DecodingSampleBuffer::F16(_) => Type::SHORT, // f16 is 2 bytes like SHORT } } @@ -299,7 +299,7 @@ fn compute_hash(path: &std::path::Path) -> Result { let img_file = File::open(path)?; let mut decoder = Decoder::open(img_file)?; let mut hasher = crc32fast::Hasher::new(); - let mut buffer = DecodingResult::U8(vec![]); + let mut buffer = DecodingSampleBuffer::U8(vec![]); let mut page = 0u32; while decoder.more_images() { diff --git a/tests/decode_planes.rs b/tests/decode_planes.rs index c275dd1..302aba6 100644 --- a/tests/decode_planes.rs +++ b/tests/decode_planes.rs @@ -1,4 +1,4 @@ -use tiff::decoder::{Decoder, DecodingResult, Limits, TiffCodingUnit}; +use tiff::decoder::{Decoder, DecodingSampleBuffer, Limits, TiffCodingUnit}; use std::fs::File; use std::path::PathBuf; @@ -84,7 +84,7 @@ fn read_planes_by_limits() { let io = std::io::BufReader::new(file); let mut limits = Limits::default(); - let mut buffer = DecodingResult::U8(vec![]); + let mut buffer = DecodingSampleBuffer::U8(vec![]); // Make room for 1 plane. let mut tif = Decoder::open(io).unwrap(); diff --git a/tests/encode_images.rs b/tests/encode_images.rs index 9160b32..63aae78 100644 --- a/tests/encode_images.rs +++ b/tests/encode_images.rs @@ -1,6 +1,6 @@ extern crate tiff; -use tiff::decoder::{ifd, Decoder, DecodingResult}; +use tiff::decoder::{ifd, Decoder, DecodingSampleBuffer}; use tiff::encoder::{colortype, Ifd, Ifd8, Predictor, SRational, TiffEncoder}; use tiff::tags::Tag; use tiff::ColorType; @@ -84,9 +84,9 @@ fn encode_decode() { ifd::Value::Ascii("Image-tiff".into()) ); - let mut buffer = tiff::decoder::DecodingResult::U8(vec![]); + let mut buffer = tiff::decoder::DecodingSampleBuffer::U8(vec![]); let _layout = decoder.read_image_to_buffer(&mut buffer).unwrap(); - if let tiff::decoder::DecodingResult::U8(img_res) = buffer { + if let tiff::decoder::DecodingSampleBuffer::U8(img_res) = buffer { assert_eq!(image_data, img_res); } else { panic!("Wrong data type"); @@ -168,9 +168,9 @@ fn encode_decode_big() { decoder.get_tag(Tag::Artist).unwrap(), ifd::Value::Ascii("Image-tiff".into()) ); - let mut buffer = tiff::decoder::DecodingResult::U8(vec![]); + let mut buffer = tiff::decoder::DecodingSampleBuffer::U8(vec![]); let _layout = decoder.read_image_to_buffer(&mut buffer).unwrap(); - if let DecodingResult::U8(img_res) = buffer { + if let DecodingSampleBuffer::U8(img_res) = buffer { assert_eq!(image_data, img_res); } else { panic!("Wrong data type"); @@ -258,11 +258,11 @@ macro_rules! test_roundtrip { assert_eq!(decoder.colortype().unwrap(), expected_type); - let mut buffer = tiff::decoder::DecodingResult::U8(vec![]); + let mut buffer = tiff::decoder::DecodingSampleBuffer::U8(vec![]); decoder.read_image_to_buffer(&mut buffer).unwrap(); let image_data = match buffer { - DecodingResult::$buffer(res) => res, + DecodingSampleBuffer::$buffer(res) => res, _ => panic!("Wrong data type"), }; @@ -275,11 +275,11 @@ macro_rules! test_roundtrip { } file.seek(SeekFrom::Start(0)).unwrap(); { - let mut buffer = tiff::decoder::DecodingResult::U8(vec![]); + let mut buffer = tiff::decoder::DecodingSampleBuffer::U8(vec![]); 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 { + if let DecodingSampleBuffer::$buffer(img_res) = buffer { assert_eq!(*image_data, img_res); } else { panic!("Wrong data type"); @@ -418,9 +418,9 @@ fn test_gray_f32_floating_point_predictor() { decoder.next_image().unwrap(); assert_eq!(decoder.colortype().unwrap(), ColorType::Gray(32)); - let mut buffer = DecodingResult::F32(vec![]); + let mut buffer = DecodingSampleBuffer::F32(vec![]); decoder.read_image_to_buffer(&mut buffer).unwrap(); - if let DecodingResult::F32(img_res) = buffer { + if let DecodingSampleBuffer::F32(img_res) = buffer { assert_eq!(image_data.len(), img_res.len()); for (orig, decoded) in image_data.iter().zip(img_res.iter()) { assert_eq!( @@ -465,9 +465,9 @@ fn test_rgb_f32_floating_point_predictor() { decoder.next_image().unwrap(); assert_eq!(decoder.colortype().unwrap(), ColorType::RGB(32)); - let mut buffer = DecodingResult::F32(vec![]); + let mut buffer = DecodingSampleBuffer::F32(vec![]); decoder.read_image_to_buffer(&mut buffer).unwrap(); - if let DecodingResult::F32(img_res) = buffer { + if let DecodingSampleBuffer::F32(img_res) = buffer { assert_eq!(image_data.len(), img_res.len()); for (i, (orig, decoded)) in image_data.iter().zip(img_res.iter()).enumerate() { assert_eq!( @@ -509,9 +509,9 @@ fn test_gray_f64_floating_point_predictor() { decoder.next_image().unwrap(); assert_eq!(decoder.colortype().unwrap(), ColorType::Gray(64)); - let mut buffer = DecodingResult::F64(vec![]); + let mut buffer = DecodingSampleBuffer::F64(vec![]); decoder.read_image_to_buffer(&mut buffer).unwrap(); - if let DecodingResult::F64(img_res) = buffer { + if let DecodingSampleBuffer::F64(img_res) = buffer { assert_eq!(image_data.len(), img_res.len()); for (orig, decoded) in image_data.iter().zip(img_res.iter()) { assert_eq!( @@ -782,7 +782,7 @@ fn test_rows_per_strip() { for i in 0..50 { let img2 = [i; 2 * 100]; match decoder.read_chunk(i as u32).unwrap() { - DecodingResult::U8(data) => assert_eq!(&img2[..], &data[..]), + DecodingSampleBuffer::U8(data) => assert_eq!(&img2[..], &data[..]), other => panic!("Incorrect strip type {other:?}"), } } diff --git a/tests/encode_images_with_compression.rs b/tests/encode_images_with_compression.rs index 0fcfed5..25164ae 100644 --- a/tests/encode_images_with_compression.rs +++ b/tests/encode_images_with_compression.rs @@ -2,7 +2,7 @@ extern crate tiff; use std::io::{Cursor, Seek, Write}; use tiff::{ - decoder::{Decoder, DecodingResult}, + decoder::{Decoder, DecodingSampleBuffer}, encoder::{ colortype::{self, ColorType}, Compression, TiffEncoder, TiffValue, @@ -115,7 +115,7 @@ fn encode_decode_with_compression(compression: Compression) { // Check the RGB image assert_eq!( match decoder.read_image() { - Ok(DecodingResult::U16(image_data)) => image_data, + Ok(DecodingSampleBuffer::U16(image_data)) => image_data, unexpected => panic!("Descoding RGB failed: {unexpected:?}"), }, image_rgb.reference_data() @@ -125,7 +125,7 @@ fn encode_decode_with_compression(compression: Compression) { decoder.next_image().unwrap(); assert_eq!( match decoder.read_image() { - Ok(DecodingResult::U8(image_data)) => image_data, + Ok(DecodingSampleBuffer::U8(image_data)) => image_data, unexpected => panic!("Decoding grayscale failed: {unexpected:?}"), }, image_grayscale.reference_data() diff --git a/tests/predict.rs b/tests/predict.rs index aef1431..98f6125 100644 --- a/tests/predict.rs +++ b/tests/predict.rs @@ -1,6 +1,6 @@ extern crate tiff; -use tiff::decoder::{Decoder, DecodingResult}; +use tiff::decoder::{Decoder, DecodingSampleBuffer}; use tiff::encoder::{colortype, Predictor, TiffEncoder}; use tiff::ColorType; @@ -23,7 +23,7 @@ macro_rules! test_predict { decoder.next_image().unwrap(); assert_eq!(decoder.colortype().unwrap(), expected_type); let image_data = match decoder.read_image().unwrap() { - DecodingResult::$buffer(res) => res, + DecodingSampleBuffer::$buffer(res) => res, _ => panic!("Wrong data type"), }; @@ -130,7 +130,7 @@ macro_rules! test_predict_roundtrip { assert_eq!(decoder.colortype().unwrap(), expected_type); let image_data = match decoder.read_image().unwrap() { - DecodingResult::$buffer(res) => res, + DecodingSampleBuffer::$buffer(res) => res, _ => panic!("Wrong data type"), }; @@ -147,7 +147,7 @@ macro_rules! test_predict_roundtrip { { let mut decoder = Decoder::open(&mut file).unwrap(); decoder.next_image().unwrap(); - if let DecodingResult::$buffer(img_res) = + if let DecodingSampleBuffer::$buffer(img_res) = decoder.read_image().expect("Decoding image failed") { assert_eq!(image_data, img_res);