@@ -346,7 +346,7 @@ impl<R: Read> Decoder<R> {
346
346
}
347
347
348
348
let frame = self . frame . as_ref ( ) . unwrap ( ) ;
349
- compute_image ( & frame. components , & planes, frame. output_size , self . is_jfif , self . color_transform )
349
+ compute_image ( & frame. components , planes, frame. output_size , self . is_jfif , self . color_transform )
350
350
}
351
351
352
352
fn read_marker ( & mut self ) -> Result < Marker > {
@@ -766,7 +766,7 @@ fn refine_non_zeroes<R: Read>(reader: &mut R,
766
766
}
767
767
768
768
fn compute_image ( components : & [ Component ] ,
769
- data : & [ Vec < u8 > ] ,
769
+ mut data : Vec < Vec < u8 > > ,
770
770
output_size : Dimensions ,
771
771
is_jfif : bool ,
772
772
color_transform : Option < AdobeColorTransform > ) -> Result < Vec < u8 > > {
@@ -776,29 +776,29 @@ fn compute_image(components: &[Component],
776
776
777
777
if components. len ( ) == 1 {
778
778
let component = & components[ 0 ] ;
779
- let decoded = & data[ 0 ] ;
779
+ let mut decoded: Vec < u8 > = data. remove ( 0 ) ;
780
780
781
781
let width = component. size . width as usize ;
782
782
let height = component. size . height as usize ;
783
783
let size = width * height;
784
-
785
- // if the image size is a multiple of the block size
786
- if decoded. len ( ) == size {
787
- return Ok ( decoded. to_vec ( ) )
788
- }
789
-
790
- let mut buffer = vec ! [ 0u8 ; size] ;
791
784
let line_stride = component. block_size . width as usize * component. dct_scale ;
792
785
793
- for y in 0 ..height {
794
- let destination_idx = y * width;
795
- let source_idx = y * line_stride;
796
- let destination = & mut buffer[ destination_idx..] [ ..width] ;
797
- let source = & decoded[ source_idx..] [ ..width] ;
798
- destination. copy_from_slice ( source) ;
786
+ // if the image width is a multiple of the block size,
787
+ // then we don't have to move bytes in the decoded data
788
+ if usize:: from ( output_size. width ) != line_stride {
789
+ let mut buffer = vec ! [ 0u8 ; width] ;
790
+ // The first line already starts at index 0, so we need to move only lines 1..height
791
+ for y in 1 ..height {
792
+ let destination_idx = y * width;
793
+ let source_idx = y * line_stride;
794
+ // We could use copy_within, but we need to support old rust versions
795
+ buffer. copy_from_slice ( & decoded[ source_idx..] [ ..width] ) ;
796
+ let destination = & mut decoded[ destination_idx..] [ ..width] ;
797
+ destination. copy_from_slice ( & buffer) ;
798
+ }
799
799
}
800
-
801
- Ok ( buffer )
800
+ decoded . resize ( size , 0 ) ;
801
+ Ok ( decoded )
802
802
}
803
803
else {
804
804
compute_image_parallel ( components, data, output_size, is_jfif, color_transform)
@@ -807,10 +807,10 @@ fn compute_image(components: &[Component],
807
807
808
808
#[ cfg( feature="rayon" ) ]
809
809
fn compute_image_parallel ( components : & [ Component ] ,
810
- data : & [ Vec < u8 > ] ,
811
- output_size : Dimensions ,
812
- is_jfif : bool ,
813
- color_transform : Option < AdobeColorTransform > ) -> Result < Vec < u8 > > {
810
+ data : Vec < Vec < u8 > > ,
811
+ output_size : Dimensions ,
812
+ is_jfif : bool ,
813
+ color_transform : Option < AdobeColorTransform > ) -> Result < Vec < u8 > > {
814
814
use rayon:: prelude:: * ;
815
815
816
816
let color_convert_func = choose_color_convert_func ( components. len ( ) , is_jfif, color_transform) ?;
@@ -822,7 +822,7 @@ fn compute_image_parallel(components: &[Component],
822
822
. with_max_len ( 1 )
823
823
. enumerate ( )
824
824
. for_each ( |( row, line) | {
825
- upsampler. upsample_and_interleave_row ( data, row, output_size. width as usize , line) ;
825
+ upsampler. upsample_and_interleave_row ( & data, row, output_size. width as usize , line) ;
826
826
color_convert_func ( line, output_size. width as usize ) ;
827
827
} ) ;
828
828
@@ -831,18 +831,18 @@ fn compute_image_parallel(components: &[Component],
831
831
832
832
#[ cfg( not( feature="rayon" ) ) ]
833
833
fn compute_image_parallel ( components : & [ Component ] ,
834
- data : & [ Vec < u8 > ] ,
835
- output_size : Dimensions ,
836
- is_jfif : bool ,
837
- color_transform : Option < AdobeColorTransform > ) -> Result < Vec < u8 > > {
834
+ data : Vec < Vec < u8 > > ,
835
+ output_size : Dimensions ,
836
+ is_jfif : bool ,
837
+ color_transform : Option < AdobeColorTransform > ) -> Result < Vec < u8 > > {
838
838
let color_convert_func = choose_color_convert_func ( components. len ( ) , is_jfif, color_transform) ?;
839
839
let upsampler = Upsampler :: new ( components, output_size. width , output_size. height ) ?;
840
840
let line_size = output_size. width as usize * components. len ( ) ;
841
841
let mut image = vec ! [ 0u8 ; line_size * output_size. height as usize ] ;
842
842
843
843
for ( row, line) in image. chunks_mut ( line_size)
844
844
. enumerate ( ) {
845
- upsampler. upsample_and_interleave_row ( data, row, output_size. width as usize , line) ;
845
+ upsampler. upsample_and_interleave_row ( & data, row, output_size. width as usize , line) ;
846
846
color_convert_func ( line, output_size. width as usize ) ;
847
847
}
848
848
0 commit comments