@@ -2,7 +2,7 @@ use std::io::{Read, Seek};
22use std:: mem:: size_of;
33
44use crate :: {
5- Channels , ColorFormat , ColorFormatSet , DecodingError , ImageViewMut , Precision , Rect , Size ,
5+ Channels , ColorFormat , ColorFormatSet , DecodingError , ImageViewMut , Offset , Precision , Size ,
66} ;
77
88use super :: DecodeOptions ;
@@ -11,8 +11,7 @@ pub(crate) type DecodeFn = fn(args: Args) -> Result<(), DecodingError>;
1111pub ( crate ) type DecodeRectFn = fn ( args : RArgs ) -> Result < ( ) , DecodingError > ;
1212
1313pub ( crate ) struct DecodeContext {
14- pub color : ColorFormat ,
15- pub size : Size ,
14+ pub surface_size : Size ,
1615 pub memory_limit : usize ,
1716}
1817impl DecodeContext {
@@ -51,75 +50,18 @@ impl<T: Read + Seek> ReadSeek for T {}
5150/// The "fix" is to wrap all mutable references in a struct so that compiler
5251/// can't see them in the type signature of the function pointer anymore. Truly
5352/// silly, and thankfully not necessary on never compiler versions.
54- pub ( crate ) struct Args < ' a , ' b > ( pub & ' a mut dyn Read , pub & ' b mut [ u8 ] , pub DecodeContext ) ;
55- impl < ' a , ' b > Args < ' a , ' b > {
56- pub fn new (
57- reader : & ' a mut dyn Read ,
58- output : & ' b mut [ u8 ] ,
59- context : DecodeContext ,
60- ) -> Result < Self , DecodingError > {
61- let bytes_per_pixel = context. color . bytes_per_pixel ( ) as u64 ;
62- assert_eq ! (
63- output. len( ) as u64 ,
64- context. size. pixels( ) . saturating_mul( bytes_per_pixel)
65- ) ;
66-
67- Ok ( Self ( reader, output, context) )
68- }
69- }
53+ pub ( crate ) struct Args < ' a , ' b , ' c > (
54+ pub & ' a mut dyn Read ,
55+ pub & ' b mut ImageViewMut < ' c > ,
56+ pub DecodeContext ,
57+ ) ;
7058
71- pub ( crate ) struct RArgs < ' a , ' b > (
59+ pub ( crate ) struct RArgs < ' a , ' b , ' c > (
7260 pub & ' a mut dyn ReadSeek ,
73- pub & ' b mut [ u8 ] ,
74- pub usize ,
75- pub Rect ,
61+ pub & ' b mut ImageViewMut < ' c > ,
62+ pub Offset ,
7663 pub DecodeContext ,
7764) ;
78- impl < ' a , ' b > RArgs < ' a , ' b > {
79- pub fn new (
80- reader : & ' a mut dyn ReadSeek ,
81- output : & ' b mut [ u8 ] ,
82- row_pitch : usize ,
83- rect : Rect ,
84- context : DecodeContext ,
85- ) -> Result < Self , DecodingError > {
86- // Check that the rect is within the bounds of the image.
87- if !rect. is_within_bounds ( context. size ) {
88- return Err ( DecodingError :: RectOutOfBounds ) ;
89- }
90-
91- // Check row pitch
92- let min_row_pitch = if rect. size ( ) . is_empty ( ) {
93- 0
94- } else {
95- usize:: saturating_mul (
96- rect. width as usize ,
97- context. color . bytes_per_pixel ( ) as usize ,
98- )
99- } ;
100- if row_pitch < min_row_pitch {
101- return Err ( DecodingError :: RowPitchTooSmall {
102- required_minimum : min_row_pitch,
103- } ) ;
104- }
105-
106- // Check that the buffer is long enough
107- // saturate to usize::MAX on overflow
108- let required_bytes = if rect. size ( ) . is_empty ( ) {
109- 0
110- } else {
111- usize:: saturating_mul ( row_pitch, ( rect. height - 1 ) as usize )
112- . saturating_add ( min_row_pitch)
113- } ;
114- if output. len ( ) < required_bytes {
115- return Err ( DecodingError :: RectBufferTooSmall {
116- required_minimum : required_bytes,
117- } ) ;
118- }
119-
120- Ok ( Self ( reader, output, row_pitch, rect, context) )
121- }
122- }
12365
12466/// Contains decode functions directly. These functions can be used as is.
12567pub ( crate ) struct Decoder {
@@ -219,21 +161,20 @@ impl DecoderSet {
219161 pub fn decode (
220162 & self ,
221163 reader : & mut dyn Read ,
222- mut image : ImageViewMut ,
164+ image : & mut ImageViewMut ,
223165 options : & DecodeOptions ,
224166 ) -> Result < ( ) , DecodingError > {
225167 let color = image. color ( ) ;
226168 let size = image. size ( ) ;
227169
228- let args = Args :: new (
170+ let args = Args (
229171 reader,
230- image. data ( ) ,
172+ image,
231173 DecodeContext {
232- color,
233- size,
174+ surface_size : size,
234175 memory_limit : options. memory_limit ,
235176 } ,
236- ) ? ;
177+ ) ;
237178
238179 // never decode empty images
239180 if size. is_empty ( ) {
@@ -251,33 +192,27 @@ impl DecoderSet {
251192 ( decoder. decode_fn ) ( args)
252193 }
253194
254- #[ allow( clippy:: too_many_arguments) ]
255195 pub fn decode_rect (
256196 & self ,
257- color : ColorFormat ,
258197 reader : & mut dyn ReadSeek ,
259- size : Size ,
260- rect : Rect ,
261- output : & mut [ u8 ] ,
262- row_pitch : usize ,
198+ image : & mut ImageViewMut ,
199+ offset : Offset ,
200+ surface_size : Size ,
263201 options : & DecodeOptions ,
264202 ) -> Result < ( ) , DecodingError > {
265- let args = RArgs :: new (
203+ let color = image. color ( ) ;
204+
205+ debug_assert ! ( !image. size( ) . is_empty( ) ) ;
206+
207+ let args = RArgs (
266208 reader,
267- output,
268- row_pitch,
269- rect,
209+ image,
210+ offset,
270211 DecodeContext {
271- color,
272- size,
212+ surface_size,
273213 memory_limit : options. memory_limit ,
274214 } ,
275- ) ?;
276-
277- // never decode empty rectangles
278- if rect. size ( ) . is_empty ( ) {
279- return Ok ( ( ) ) ;
280- }
215+ ) ;
281216
282217 let decoder = self . get_decoder ( color) ;
283218 ( decoder. decode_rect_fn ) ( args)
0 commit comments