Utils for DecodingBuffer et.al
Most of this is slightly gratuitous for now, we have no need internally, but especially since the enums are non-exhaustive it will probably be appreciated that you can interact with the buffer at a byte-level. Additionally we make the extra promise that all sample types correspond to some supported SampleType tag value. This prepares using the same buffer for a runtime version of `Encoder::write_image`.
This commit is contained in:
1 parent
860052a8f4
commit
7491436306
1 file changed
+108
@@ -5,6 +5,7 @@ use crate::{
|
|||||||
bytecast,
|
bytecast,
|
||||||
decoder::{BufferLayoutPreference, Limits},
|
decoder::{BufferLayoutPreference, Limits},
|
||||||
error::{TiffError, TiffResult, TiffUnsupportedError},
|
error::{TiffError, TiffResult, TiffUnsupportedError},
|
||||||
|
tags::{ByteOrder, EndianBytes, SampleFormat},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Result of a decoding process
|
/// Result of a decoding process
|
||||||
@@ -131,6 +132,34 @@ impl DecodingSampleBuffer {
|
|||||||
DecodingSampleBuffer::I64(ref mut buf) => DecodingSampleSlice::I64(&mut buf[start..]),
|
DecodingSampleBuffer::I64(ref mut buf) => DecodingSampleSlice::I64(&mut buf[start..]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn sample_type(&self) -> DecodingSampleType {
|
||||||
|
match *self {
|
||||||
|
DecodingSampleBuffer::U8(_) => DecodingSampleType::U8,
|
||||||
|
DecodingSampleBuffer::U16(_) => DecodingSampleType::U16,
|
||||||
|
DecodingSampleBuffer::U32(_) => DecodingSampleType::U32,
|
||||||
|
DecodingSampleBuffer::U64(_) => DecodingSampleType::U64,
|
||||||
|
DecodingSampleBuffer::F16(_) => DecodingSampleType::F16,
|
||||||
|
DecodingSampleBuffer::F32(_) => DecodingSampleType::F32,
|
||||||
|
DecodingSampleBuffer::F64(_) => DecodingSampleType::F64,
|
||||||
|
DecodingSampleBuffer::I8(_) => DecodingSampleType::I8,
|
||||||
|
DecodingSampleBuffer::I16(_) => DecodingSampleType::I16,
|
||||||
|
DecodingSampleBuffer::I32(_) => DecodingSampleType::I32,
|
||||||
|
DecodingSampleBuffer::I64(_) => DecodingSampleType::I64,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Change the endianess of buffered data.
|
||||||
|
///
|
||||||
|
/// This utility may be used to prepare a buffer for consumption by methods taking raw bytes or
|
||||||
|
/// after filling the buffer with raw bytes.
|
||||||
|
///
|
||||||
|
/// After this, interpreting the buffer on the host may no longer produce any reasonable
|
||||||
|
/// results. For instance, floats in the wrong byte order may produce a `NaN` with varying
|
||||||
|
/// payloads. Despite unexpected result however, this operation is always sound.
|
||||||
|
pub fn convert_endian(&mut self, from: ByteOrder, to: ByteOrder) {
|
||||||
|
self.as_buffer(0).convert_endian(from, to)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A buffer for image decoding
|
// A buffer for image decoding
|
||||||
@@ -192,6 +221,51 @@ impl<'a> DecodingSampleSlice<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn reborrow(&mut self) -> DecodingSampleSlice<'_> {
|
||||||
|
match self {
|
||||||
|
DecodingSampleSlice::U8(items) => DecodingSampleSlice::U8(items),
|
||||||
|
DecodingSampleSlice::I8(items) => DecodingSampleSlice::I8(items),
|
||||||
|
DecodingSampleSlice::U16(items) => DecodingSampleSlice::U16(items),
|
||||||
|
DecodingSampleSlice::I16(items) => DecodingSampleSlice::I16(items),
|
||||||
|
DecodingSampleSlice::U32(items) => DecodingSampleSlice::U32(items),
|
||||||
|
DecodingSampleSlice::I32(items) => DecodingSampleSlice::I32(items),
|
||||||
|
DecodingSampleSlice::U64(items) => DecodingSampleSlice::U64(items),
|
||||||
|
DecodingSampleSlice::I64(items) => DecodingSampleSlice::I64(items),
|
||||||
|
DecodingSampleSlice::F16(items) => DecodingSampleSlice::F16(items),
|
||||||
|
DecodingSampleSlice::F32(items) => DecodingSampleSlice::F32(items),
|
||||||
|
DecodingSampleSlice::F64(items) => DecodingSampleSlice::F64(items),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sample_type(&self) -> DecodingSampleType {
|
||||||
|
match *self {
|
||||||
|
DecodingSampleSlice::U8(_) => DecodingSampleType::U8,
|
||||||
|
DecodingSampleSlice::U16(_) => DecodingSampleType::U16,
|
||||||
|
DecodingSampleSlice::U32(_) => DecodingSampleType::U32,
|
||||||
|
DecodingSampleSlice::U64(_) => DecodingSampleType::U64,
|
||||||
|
DecodingSampleSlice::F16(_) => DecodingSampleType::F16,
|
||||||
|
DecodingSampleSlice::F32(_) => DecodingSampleType::F32,
|
||||||
|
DecodingSampleSlice::F64(_) => DecodingSampleType::F64,
|
||||||
|
DecodingSampleSlice::I8(_) => DecodingSampleType::I8,
|
||||||
|
DecodingSampleSlice::I16(_) => DecodingSampleType::I16,
|
||||||
|
DecodingSampleSlice::I32(_) => DecodingSampleType::I32,
|
||||||
|
DecodingSampleSlice::I64(_) => DecodingSampleType::I64,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Change the endianess of referenced data.
|
||||||
|
///
|
||||||
|
/// This utility may be used to prepare a buffer for consumption by methods taking raw bytes or
|
||||||
|
/// after filling the buffer with raw bytes.
|
||||||
|
///
|
||||||
|
/// After this, interpreting the buffer on the host may no longer produce any reasonable
|
||||||
|
/// results. For instance, floats in the wrong byte order may produce a `NaN` with varying
|
||||||
|
/// payloads. Despite unexpected result however, this operation is always sound.
|
||||||
|
pub fn convert_endian(&mut self, from: ByteOrder, to: ByteOrder) {
|
||||||
|
let byte_unit = self.sample_type().endian_bytes();
|
||||||
|
from.convert_endian_bytes(byte_unit, self.as_bytes_mut(), to);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn byte_len(&self) -> usize {
|
pub fn byte_len(&self) -> usize {
|
||||||
self.as_bytes().len()
|
self.as_bytes().len()
|
||||||
}
|
}
|
||||||
@@ -213,6 +287,22 @@ pub enum DecodingSampleType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DecodingSampleType {
|
impl DecodingSampleType {
|
||||||
|
pub fn sample_format(self) -> SampleFormat {
|
||||||
|
match self {
|
||||||
|
DecodingSampleType::U8 => SampleFormat::Uint,
|
||||||
|
DecodingSampleType::U16 => SampleFormat::Uint,
|
||||||
|
DecodingSampleType::U32 => SampleFormat::Uint,
|
||||||
|
DecodingSampleType::U64 => SampleFormat::Uint,
|
||||||
|
DecodingSampleType::F16 => SampleFormat::IEEEFP,
|
||||||
|
DecodingSampleType::F32 => SampleFormat::IEEEFP,
|
||||||
|
DecodingSampleType::F64 => SampleFormat::IEEEFP,
|
||||||
|
DecodingSampleType::I8 => SampleFormat::Int,
|
||||||
|
DecodingSampleType::I16 => SampleFormat::Int,
|
||||||
|
DecodingSampleType::I32 => SampleFormat::Int,
|
||||||
|
DecodingSampleType::I64 => SampleFormat::Int,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn extent_for_bytes(self, bytes: usize) -> DecodingExtent {
|
pub(crate) fn extent_for_bytes(self, bytes: usize) -> DecodingExtent {
|
||||||
match self {
|
match self {
|
||||||
DecodingSampleType::U8 => DecodingExtent::U8(bytes),
|
DecodingSampleType::U8 => DecodingExtent::U8(bytes),
|
||||||
@@ -228,6 +318,24 @@ impl DecodingSampleType {
|
|||||||
DecodingSampleType::F64 => DecodingExtent::F64(bytes.div_ceil(8)),
|
DecodingSampleType::F64 => DecodingExtent::F64(bytes.div_ceil(8)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn endian_bytes(self) -> EndianBytes {
|
||||||
|
use EndianBytes::*;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
DecodingSampleType::U8 => One,
|
||||||
|
DecodingSampleType::U16 => Two,
|
||||||
|
DecodingSampleType::U32 => Four,
|
||||||
|
DecodingSampleType::U64 => Eight,
|
||||||
|
DecodingSampleType::F16 => Two,
|
||||||
|
DecodingSampleType::F32 => Four,
|
||||||
|
DecodingSampleType::F64 => Eight,
|
||||||
|
DecodingSampleType::I8 => One,
|
||||||
|
DecodingSampleType::I16 => Two,
|
||||||
|
DecodingSampleType::I32 => Four,
|
||||||
|
DecodingSampleType::I64 => Eight,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The count and matching discriminant for a `DecodingBuffer`.
|
/// The count and matching discriminant for a `DecodingBuffer`.
|
||||||
|
|||||||
Reference in new issue
Block a user