Simplify responsibility of testing buffer size
This commit is contained in:
1 parent
6439880e3d
commit
0de1261948
1 file changed
+29
-76
+29
-76
@@ -50,92 +50,60 @@ pub enum DecodingResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DecodingResult {
|
impl DecodingResult {
|
||||||
fn new_u8(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
|
fn new<T: Default + Copy>(
|
||||||
if size > limits.decoding_buffer_size {
|
size: usize,
|
||||||
|
limits: &Limits,
|
||||||
|
from_fn: fn(Vec<T>) -> Self,
|
||||||
|
) -> TiffResult<DecodingResult> {
|
||||||
|
if size > limits.decoding_buffer_size / core::mem::size_of::<T>() {
|
||||||
Err(TiffError::LimitsExceeded)
|
Err(TiffError::LimitsExceeded)
|
||||||
} else {
|
} else {
|
||||||
Ok(DecodingResult::U8(vec![0; size]))
|
Ok(from_fn(vec![T::default(); size]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn new_u8(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
|
||||||
|
Self::new(size, limits, DecodingResult::U8)
|
||||||
|
}
|
||||||
|
|
||||||
fn new_u16(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
|
fn new_u16(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
|
||||||
if size > limits.decoding_buffer_size / 2 {
|
Self::new(size, limits, DecodingResult::U16)
|
||||||
Err(TiffError::LimitsExceeded)
|
|
||||||
} else {
|
|
||||||
Ok(DecodingResult::U16(vec![0; size]))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_u32(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
|
fn new_u32(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
|
||||||
if size > limits.decoding_buffer_size / 4 {
|
Self::new(size, limits, DecodingResult::U32)
|
||||||
Err(TiffError::LimitsExceeded)
|
|
||||||
} else {
|
|
||||||
Ok(DecodingResult::U32(vec![0; size]))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_u64(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
|
fn new_u64(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
|
||||||
if size > limits.decoding_buffer_size / 8 {
|
Self::new(size, limits, DecodingResult::U64)
|
||||||
Err(TiffError::LimitsExceeded)
|
|
||||||
} else {
|
|
||||||
Ok(DecodingResult::U64(vec![0; size]))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_f32(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
|
fn new_f32(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
|
||||||
if size > limits.decoding_buffer_size / std::mem::size_of::<f32>() {
|
Self::new(size, limits, DecodingResult::F32)
|
||||||
Err(TiffError::LimitsExceeded)
|
|
||||||
} else {
|
|
||||||
Ok(DecodingResult::F32(vec![0.0; size]))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_f64(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
|
fn new_f64(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
|
||||||
if size > limits.decoding_buffer_size / std::mem::size_of::<f64>() {
|
Self::new(size, limits, DecodingResult::F64)
|
||||||
Err(TiffError::LimitsExceeded)
|
|
||||||
} else {
|
|
||||||
Ok(DecodingResult::F64(vec![0.0; size]))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_f16(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
|
fn new_f16(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
|
||||||
if size > limits.decoding_buffer_size / std::mem::size_of::<u16>() {
|
Self::new(size, limits, DecodingResult::F16)
|
||||||
Err(TiffError::LimitsExceeded)
|
|
||||||
} else {
|
|
||||||
Ok(DecodingResult::F16(vec![f16::ZERO; size]))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_i8(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
|
fn new_i8(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
|
||||||
if size > limits.decoding_buffer_size / std::mem::size_of::<i8>() {
|
Self::new(size, limits, DecodingResult::I8)
|
||||||
Err(TiffError::LimitsExceeded)
|
|
||||||
} else {
|
|
||||||
Ok(DecodingResult::I8(vec![0; size]))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_i16(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
|
fn new_i16(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
|
||||||
if size > limits.decoding_buffer_size / 2 {
|
Self::new(size, limits, DecodingResult::I16)
|
||||||
Err(TiffError::LimitsExceeded)
|
|
||||||
} else {
|
|
||||||
Ok(DecodingResult::I16(vec![0; size]))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_i32(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
|
fn new_i32(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
|
||||||
if size > limits.decoding_buffer_size / 4 {
|
Self::new(size, limits, DecodingResult::I32)
|
||||||
Err(TiffError::LimitsExceeded)
|
|
||||||
} else {
|
|
||||||
Ok(DecodingResult::I32(vec![0; size]))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_i64(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
|
fn new_i64(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
|
||||||
if size > limits.decoding_buffer_size / 8 {
|
Self::new(size, limits, DecodingResult::I64)
|
||||||
Err(TiffError::LimitsExceeded)
|
|
||||||
} else {
|
|
||||||
Ok(DecodingResult::I64(vec![0; size]))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_buffer(&mut self, start: usize) -> DecodingBuffer<'_> {
|
pub fn as_buffer(&mut self, start: usize) -> DecodingBuffer<'_> {
|
||||||
@@ -233,13 +201,15 @@ impl BufferLayoutPreference {
|
|||||||
complete_len: layout.total_bytes,
|
complete_len: layout.total_bytes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl image::ReadoutLayout {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn assert_min_layout<T>(self, buffer: &[T]) -> TiffResult<()> {
|
fn assert_min_layout<T>(&self, buffer: &[T]) -> TiffResult<()> {
|
||||||
if core::mem::size_of_val(buffer) < self.len {
|
if core::mem::size_of_val(buffer) < self.plane_stride {
|
||||||
Err(TiffError::UsageError(
|
Err(TiffError::UsageError(
|
||||||
UsageError::InsufficientOutputBufferSize {
|
UsageError::InsufficientOutputBufferSize {
|
||||||
needed: self.len,
|
needed: self.plane_stride,
|
||||||
provided: buffer.len(),
|
provided: buffer.len(),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
@@ -302,21 +272,6 @@ impl DecodingExtent {
|
|||||||
}
|
}
|
||||||
.map_err(overflow)
|
.map_err(overflow)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn assert_min_layout<T>(self, buffer: &[T]) -> TiffResult<()> {
|
|
||||||
let needed_bytes = self.preferred_layout()?.size();
|
|
||||||
if core::mem::size_of_val(buffer) < needed_bytes {
|
|
||||||
Err(TiffError::UsageError(
|
|
||||||
UsageError::InsufficientOutputBufferSize {
|
|
||||||
needed: needed_bytes,
|
|
||||||
provided: buffer.len(),
|
|
||||||
},
|
|
||||||
))
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||||
@@ -1222,8 +1177,7 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
let (width, height) = self.image().chunk_data_dimensions(chunk_index)?;
|
let (width, height) = self.image().chunk_data_dimensions(chunk_index)?;
|
||||||
|
|
||||||
let layout = self.image().readout_for_size(width, height)?;
|
let layout = self.image().readout_for_size(width, height)?;
|
||||||
let extent = self.result_extent(&layout, 0..1)?;
|
layout.assert_min_layout(buffer)?;
|
||||||
extent.assert_min_layout(buffer)?;
|
|
||||||
|
|
||||||
self.read_chunk_to_bytes(buffer, chunk_index, &layout)?;
|
self.read_chunk_to_bytes(buffer, chunk_index, &layout)?;
|
||||||
|
|
||||||
@@ -1305,8 +1259,7 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
ref readout,
|
ref readout,
|
||||||
} = readout.to_plane_layout()?;
|
} = readout.to_plane_layout()?;
|
||||||
|
|
||||||
let preference = BufferLayoutPreference::from_planes(layout);
|
layout.readout.assert_min_layout(buffer)?;
|
||||||
preference.assert_min_layout(buffer)?;
|
|
||||||
|
|
||||||
// Note: with differently sized planes this is dependent on the plane.
|
// Note: with differently sized planes this is dependent on the plane.
|
||||||
let last_plane_start = buffer.len().checked_sub(readout.plane_stride);
|
let last_plane_start = buffer.len().checked_sub(readout.plane_stride);
|
||||||
@@ -1340,7 +1293,7 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
self.image.expand_chunk(
|
self.image.expand_chunk(
|
||||||
&mut self.value_reader,
|
&mut self.value_reader,
|
||||||
&mut buffer[plane_offset..][buffer_offset..],
|
&mut buffer[plane_offset..][buffer_offset..],
|
||||||
&readout,
|
readout,
|
||||||
chunk,
|
chunk,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user