@@ -17,7 +17,7 @@ use crate::parser::{
17
17
IccChunk , ScanInfo ,
18
18
} ;
19
19
use crate :: upsampler:: Upsampler ;
20
- use crate :: worker:: { PlatformWorker , RowData , Worker } ;
20
+ use crate :: worker:: { PreferWorkerKind , RowData , Worker , with_worker } ;
21
21
22
22
pub const MAX_COMPONENTS : usize = 4 ;
23
23
@@ -191,7 +191,9 @@ impl<R: Read> Decoder<R> {
191
191
///
192
192
/// If successful, the metadata can be obtained using the `info` method.
193
193
pub fn read_info ( & mut self ) -> Result < ( ) > {
194
- self . decode_internal ( true ) . map ( |_| ( ) )
194
+ with_worker ( PreferWorkerKind :: Multithreaded , |worker| {
195
+ self . decode_internal ( true , worker)
196
+ } ) . map ( |_| ( ) )
195
197
}
196
198
197
199
/// Configure the decoder to scale the image during decoding.
@@ -219,10 +221,16 @@ impl<R: Read> Decoder<R> {
219
221
220
222
/// Decodes the image and returns the decoded pixels if successful.
221
223
pub fn decode ( & mut self ) -> Result < Vec < u8 > > {
222
- self . decode_internal ( false )
224
+ with_worker ( PreferWorkerKind :: Multithreaded , |worker| {
225
+ self . decode_internal ( false , worker)
226
+ } )
223
227
}
224
228
225
- fn decode_internal ( & mut self , stop_after_metadata : bool ) -> Result < Vec < u8 > > {
229
+ fn decode_internal (
230
+ & mut self ,
231
+ stop_after_metadata : bool ,
232
+ worker : & mut dyn Worker ,
233
+ ) -> Result < Vec < u8 > > {
226
234
if stop_after_metadata && self . frame . is_some ( ) {
227
235
// The metadata has already been read.
228
236
return Ok ( Vec :: new ( ) ) ;
@@ -237,7 +245,6 @@ impl<R: Read> Decoder<R> {
237
245
238
246
let mut previous_marker = Marker :: SOI ;
239
247
let mut pending_marker = None ;
240
- let mut worker = None ;
241
248
let mut scans_processed = 0 ;
242
249
let mut planes = vec ! [
243
250
Vec :: <u8 >:: new( ) ;
@@ -318,9 +325,6 @@ impl<R: Read> Decoder<R> {
318
325
if self . frame . is_none ( ) {
319
326
return Err ( Error :: Format ( "scan encountered before frame" . to_owned ( ) ) ) ;
320
327
}
321
- if worker. is_none ( ) {
322
- worker = Some ( PlatformWorker :: new ( ) ?) ;
323
- }
324
328
325
329
let frame = self . frame . clone ( ) . unwrap ( ) ;
326
330
let scan = parse_sos ( & mut self . reader , & frame) ?;
@@ -383,7 +387,7 @@ impl<R: Read> Decoder<R> {
383
387
}
384
388
385
389
let ( marker, data) =
386
- self . decode_scan ( & frame, & scan, worker. as_mut ( ) . unwrap ( ) , & finished) ?;
390
+ self . decode_scan ( & frame, & scan, worker, & finished) ?;
387
391
388
392
if let Some ( data) = data {
389
393
for ( i, plane) in data
@@ -545,10 +549,6 @@ impl<R: Read> Decoder<R> {
545
549
} ;
546
550
547
551
// Get the worker prepared
548
- if worker. is_none ( ) {
549
- worker = Some ( PlatformWorker :: new ( ) ?) ;
550
- }
551
- let worker = worker. as_mut ( ) . unwrap ( ) ;
552
552
let row_data = RowData {
553
553
index : i,
554
554
component : component. clone ( ) ,
@@ -560,14 +560,17 @@ impl<R: Read> Decoder<R> {
560
560
let coefficients_per_mcu_row = usize:: from ( component. block_size . width )
561
561
* usize:: from ( component. vertical_sampling_factor )
562
562
* 64 ;
563
- for mcu_y in 0 ..frame. mcu_size . height {
564
- let row_coefficients = {
563
+
564
+ let mut tasks = ( 0 ..frame. mcu_size . height )
565
+ . map ( |mcu_y| {
565
566
let offset = usize:: from ( mcu_y) * coefficients_per_mcu_row;
566
- self . coefficients [ i] [ offset..offset + coefficients_per_mcu_row] . to_vec ( )
567
- } ;
567
+ let row_coefficients = self . coefficients [ i] [ offset..offset + coefficients_per_mcu_row] . to_vec ( ) ;
568
+ ( i, row_coefficients)
569
+ } ) ;
568
570
569
- worker. append_row ( ( i, row_coefficients) ) ?;
570
- }
571
+ // FIXME: additional potential work stealing opportunities for rayon case if we
572
+ // also internally can parallelize over components.
573
+ worker. append_rows ( & mut tasks) ?;
571
574
planes[ i] = worker. get_result ( i) ?;
572
575
}
573
576
}
@@ -616,7 +619,7 @@ impl<R: Read> Decoder<R> {
616
619
& mut self ,
617
620
frame : & FrameInfo ,
618
621
scan : & ScanInfo ,
619
- worker : & mut PlatformWorker ,
622
+ worker : & mut dyn Worker ,
620
623
finished : & [ bool ; MAX_COMPONENTS ] ,
621
624
) -> Result < ( Option < Marker > , Option < Vec < Vec < u8 > > > ) > {
622
625
assert ! ( scan. component_indices. len( ) <= MAX_COMPONENTS ) ;
@@ -871,6 +874,8 @@ impl<R: Read> Decoder<R> {
871
874
)
872
875
} ;
873
876
877
+ // FIXME: additional potential work stealing opportunities for rayon case if we
878
+ // also internally can parallelize over components.
874
879
worker. append_row ( ( i, row_coefficients) ) ?;
875
880
}
876
881
}
0 commit comments