Skip to content

Commit bc97880

Browse files
committed
Simplify responsibility of testing buffer size
1 parent d2d37a0 commit bc97880

File tree

1 file changed

+28
-75
lines changed

1 file changed

+28
-75
lines changed

src/decoder/mod.rs

Lines changed: 28 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -50,92 +50,60 @@ pub enum DecodingResult {
5050
}
5151

5252
impl DecodingResult {
53-
fn new_u8(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
54-
if size > limits.decoding_buffer_size {
53+
fn new<T: Default + Copy>(
54+
size: usize,
55+
limits: &Limits,
56+
from_fn: fn(Vec<T>) -> Self,
57+
) -> TiffResult<DecodingResult> {
58+
if size > limits.decoding_buffer_size / core::mem::size_of::<T>() {
5559
Err(TiffError::LimitsExceeded)
5660
} else {
57-
Ok(DecodingResult::U8(vec![0; size]))
61+
Ok(from_fn(vec![T::default(); size]))
5862
}
5963
}
6064

65+
fn new_u8(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
66+
Self::new(size, limits, DecodingResult::U8)
67+
}
68+
6169
fn new_u16(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
62-
if size > limits.decoding_buffer_size / 2 {
63-
Err(TiffError::LimitsExceeded)
64-
} else {
65-
Ok(DecodingResult::U16(vec![0; size]))
66-
}
70+
Self::new(size, limits, DecodingResult::U16)
6771
}
6872

6973
fn new_u32(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
70-
if size > limits.decoding_buffer_size / 4 {
71-
Err(TiffError::LimitsExceeded)
72-
} else {
73-
Ok(DecodingResult::U32(vec![0; size]))
74-
}
74+
Self::new(size, limits, DecodingResult::U32)
7575
}
7676

7777
fn new_u64(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
78-
if size > limits.decoding_buffer_size / 8 {
79-
Err(TiffError::LimitsExceeded)
80-
} else {
81-
Ok(DecodingResult::U64(vec![0; size]))
82-
}
78+
Self::new(size, limits, DecodingResult::U64)
8379
}
8480

8581
fn new_f32(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
86-
if size > limits.decoding_buffer_size / std::mem::size_of::<f32>() {
87-
Err(TiffError::LimitsExceeded)
88-
} else {
89-
Ok(DecodingResult::F32(vec![0.0; size]))
90-
}
82+
Self::new(size, limits, DecodingResult::F32)
9183
}
9284

9385
fn new_f64(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
94-
if size > limits.decoding_buffer_size / std::mem::size_of::<f64>() {
95-
Err(TiffError::LimitsExceeded)
96-
} else {
97-
Ok(DecodingResult::F64(vec![0.0; size]))
98-
}
86+
Self::new(size, limits, DecodingResult::F64)
9987
}
10088

10189
fn new_f16(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
102-
if size > limits.decoding_buffer_size / std::mem::size_of::<u16>() {
103-
Err(TiffError::LimitsExceeded)
104-
} else {
105-
Ok(DecodingResult::F16(vec![f16::ZERO; size]))
106-
}
90+
Self::new(size, limits, DecodingResult::F16)
10791
}
10892

10993
fn new_i8(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
110-
if size > limits.decoding_buffer_size / std::mem::size_of::<i8>() {
111-
Err(TiffError::LimitsExceeded)
112-
} else {
113-
Ok(DecodingResult::I8(vec![0; size]))
114-
}
94+
Self::new(size, limits, DecodingResult::I8)
11595
}
11696

11797
fn new_i16(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
118-
if size > limits.decoding_buffer_size / 2 {
119-
Err(TiffError::LimitsExceeded)
120-
} else {
121-
Ok(DecodingResult::I16(vec![0; size]))
122-
}
98+
Self::new(size, limits, DecodingResult::I16)
12399
}
124100

125101
fn new_i32(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
126-
if size > limits.decoding_buffer_size / 4 {
127-
Err(TiffError::LimitsExceeded)
128-
} else {
129-
Ok(DecodingResult::I32(vec![0; size]))
130-
}
102+
Self::new(size, limits, DecodingResult::I32)
131103
}
132104

133105
fn new_i64(size: usize, limits: &Limits) -> TiffResult<DecodingResult> {
134-
if size > limits.decoding_buffer_size / 8 {
135-
Err(TiffError::LimitsExceeded)
136-
} else {
137-
Ok(DecodingResult::I64(vec![0; size]))
138-
}
106+
Self::new(size, limits, DecodingResult::I64)
139107
}
140108

141109
pub fn as_buffer(&mut self, start: usize) -> DecodingBuffer<'_> {
@@ -233,13 +201,15 @@ impl BufferLayoutPreference {
233201
complete_len: layout.total_bytes,
234202
}
235203
}
204+
}
236205

206+
impl image::ReadoutLayout {
237207
#[inline(always)]
238-
fn assert_min_layout<T>(self, buffer: &[T]) -> TiffResult<()> {
239-
if core::mem::size_of_val(buffer) < self.len {
208+
fn assert_min_layout<T>(&self, buffer: &[T]) -> TiffResult<()> {
209+
if core::mem::size_of_val(buffer) < self.plane_stride {
240210
Err(TiffError::UsageError(
241211
UsageError::InsufficientOutputBufferSize {
242-
needed: self.len,
212+
needed: self.plane_stride,
243213
provided: buffer.len(),
244214
},
245215
))
@@ -302,21 +272,6 @@ impl DecodingExtent {
302272
}
303273
.map_err(overflow)
304274
}
305-
306-
#[inline(always)]
307-
fn assert_min_layout<T>(self, buffer: &[T]) -> TiffResult<()> {
308-
let needed_bytes = self.preferred_layout()?.size();
309-
if core::mem::size_of_val(buffer) < needed_bytes {
310-
Err(TiffError::UsageError(
311-
UsageError::InsufficientOutputBufferSize {
312-
needed: needed_bytes,
313-
provided: buffer.len(),
314-
},
315-
))
316-
} else {
317-
Ok(())
318-
}
319-
}
320275
}
321276

322277
#[derive(Debug, Copy, Clone, PartialEq)]
@@ -1222,8 +1177,7 @@ impl<R: Read + Seek> Decoder<R> {
12221177
let (width, height) = self.image().chunk_data_dimensions(chunk_index)?;
12231178

12241179
let layout = self.image().readout_for_size(width, height)?;
1225-
let extent = self.result_extent(&layout, 0..1)?;
1226-
extent.assert_min_layout(buffer)?;
1180+
layout.assert_min_layout(buffer)?;
12271181

12281182
self.read_chunk_to_bytes(buffer, chunk_index, &layout)?;
12291183

@@ -1305,8 +1259,7 @@ impl<R: Read + Seek> Decoder<R> {
13051259
ref readout,
13061260
} = readout.to_plane_layout()?;
13071261

1308-
let preference = BufferLayoutPreference::from_planes(&layout);
1309-
preference.assert_min_layout(buffer)?;
1262+
layout.readout.assert_min_layout(buffer)?;
13101263

13111264
// Note: with differently sized planes this is dependent on the plane.
13121265
let last_plane_start = buffer.len().checked_sub(readout.plane_stride);

0 commit comments

Comments
 (0)