@@ -156,14 +156,7 @@ impl<R: BufRead> HdrAdapter<R> {
156156 fn read_image_data ( & mut self , buf : & mut [ u8 ] ) -> ImageResult < ( ) > {
157157 assert_eq ! ( u64 :: try_from( buf. len( ) ) , Ok ( self . total_bytes( ) ) ) ;
158158 match self . inner . take ( ) {
159- Some ( decoder) => {
160- let img: Vec < Rgb < u8 > > = decoder. read_image_ldr ( ) ?;
161- for ( i, Rgb ( data) ) in img. into_iter ( ) . enumerate ( ) {
162- buf[ ( i * 3 ) ..] [ ..3 ] . copy_from_slice ( & data) ;
163- }
164-
165- Ok ( ( ) )
166- }
159+ Some ( decoder) => decoder. read_image_ldr_buf ( buf) ,
167160 None => Err ( ImageError :: Parameter ( ParameterError :: from_kind (
168161 ParameterErrorKind :: NoMoreData ,
169162 ) ) ) ,
@@ -444,29 +437,46 @@ impl<R: BufRead> HdrDecoder<R> {
444437
445438 /// Consumes decoder and returns a vector of transformed pixels
446439 pub fn read_image_transform < T : Send , F : Send + Sync + Fn ( Rgbe8Pixel ) -> T > (
440+ self ,
441+ f : F ,
442+ output_slice : & mut [ T ] ,
443+ ) -> ImageResult < ( ) > {
444+ // a bit hacky, but this function was in the public API and
445+ // thus needs to preserve it's signature.
446+ self . read_image_transform_flat ( move |v| [ f ( v) ] , output_slice)
447+ }
448+
449+ /// Consumes decoder and returns a vector of transformed pixels
450+ fn read_image_transform_flat <
451+ T : Send ,
452+ F : Send + Sync + Fn ( Rgbe8Pixel ) -> [ T ; N ] ,
453+ const N : usize ,
454+ > (
447455 mut self ,
448456 f : F ,
449457 output_slice : & mut [ T ] ,
450458 ) -> ImageResult < ( ) > {
451459 assert_eq ! (
452460 output_slice. len( ) ,
453- self . width as usize * self . height as usize
461+ self . width as usize * self . height as usize * N
454462 ) ;
455463
456464 // Don't read anything if image is empty
457465 if self . width == 0 || self . height == 0 {
458466 return Ok ( ( ) ) ;
459467 }
460468
461- let chunks_iter = output_slice. chunks_mut ( self . width as usize ) ;
469+ let chunks_iter = output_slice. chunks_mut ( self . width as usize * N ) ;
462470
463471 let mut buf = vec ! [ Default :: default ( ) ; self . width as usize ] ;
464472 for chunk in chunks_iter {
465473 // read_scanline overwrites the entire buffer or returns an Err,
466474 // so not resetting the buffer here is ok.
467475 read_scanline ( & mut self . r , & mut buf[ ..] ) ?;
468- for ( dst, & pix) in chunk. iter_mut ( ) . zip ( buf. iter ( ) ) {
469- * dst = f ( pix) ;
476+ for ( dst, & pix) in chunk. chunks_mut ( N ) . zip ( buf. iter ( ) ) {
477+ for ( d, s) in dst. iter_mut ( ) . zip ( IntoIterator :: into_iter ( f ( pix) ) ) {
478+ * d = s;
479+ }
470480 }
471481 }
472482 Ok ( ( ) )
@@ -475,17 +485,22 @@ impl<R: BufRead> HdrDecoder<R> {
475485 /// Consumes decoder and returns a vector of `Rgb<u8>` pixels.
476486 /// scale = 1, gamma = 2.2
477487 pub fn read_image_ldr ( self ) -> ImageResult < Vec < Rgb < u8 > > > {
478- let mut ret = vec ! [ Rgb ( [ 0 , 0 , 0 ] ) ; self . width as usize * self . height as usize ] ;
479- self . read_image_transform ( |pix| pix. to_ldr ( ) , & mut ret[ ..] ) ?;
480- Ok ( ret)
488+ let sz = ( self . width * self . height ) as usize ;
489+ let mut buf = vec ! [ Rgb ( [ 0 ; 3 ] ) ; sz] ;
490+ self . read_image_transform ( |pix| pix. to_ldr ( ) , & mut buf[ ..] ) ?;
491+ Ok ( buf)
492+ }
493+ fn read_image_ldr_buf ( self , buf : & mut [ u8 ] ) -> ImageResult < ( ) > {
494+ let sz = ( self . width * self . height * 3 ) as usize ;
495+ assert ! ( buf. len( ) >= sz) ;
496+ self . read_image_transform_flat ( |pix| pix. to_ldr ( ) . 0 , & mut buf[ ..sz] )
481497 }
482-
483498 /// Consumes decoder and returns a vector of `Rgb<f32>` pixels.
484- ///
485499 pub fn read_image_hdr ( self ) -> ImageResult < Vec < Rgb < f32 > > > {
486- let mut ret = vec ! [ Rgb ( [ 0.0 , 0.0 , 0.0 ] ) ; self . width as usize * self . height as usize ] ;
487- self . read_image_transform ( |pix| pix. to_hdr ( ) , & mut ret[ ..] ) ?;
488- Ok ( ret)
500+ let sz = ( self . width * self . height ) as usize ;
501+ let mut buf = vec ! [ Rgb ( [ 0.0f32 ; 3 ] ) ; sz] ;
502+ self . read_image_transform ( |pix| pix. to_hdr ( ) , & mut buf[ ..] ) ?;
503+ Ok ( buf)
489504 }
490505}
491506
@@ -971,15 +986,14 @@ fn split_at_first_test() {
971986// or return None to indicate end of file
972987fn read_line_u8 < R : BufRead > ( r : & mut R ) -> :: std:: io:: Result < Option < Vec < u8 > > > {
973988 let mut ret = Vec :: with_capacity ( 16 ) ;
974- match r. read_until ( b'\n' , & mut ret) {
975- Ok ( 0 ) => Ok ( None ) ,
976- Ok ( _ ) => {
977- if let Some ( & b'\n' ) = ret[ .. ] . last ( ) {
989+ match r. read_until ( b'\n' , & mut ret) ? {
990+ 0 => Ok ( None ) ,
991+ _ => {
992+ if let Some ( & b'\n' ) = ret. last ( ) {
978993 let _ = ret. pop ( ) ;
979994 }
980995 Ok ( Some ( ret) )
981996 }
982- Err ( err) => Err ( err) ,
983997 }
984998}
985999
0 commit comments