@@ -565,74 +565,157 @@ impl Entry {
565565 }
566566
567567 // Case 4: there is more than one value, and it doesn't fit in the offset field.
568+ let mut v;
569+ self . set_reader_offset ( bo, bigtiff, reader) ?;
570+
568571 match self . type_ {
569572 // TODO check if this could give wrong results
570573 // at a different endianess of file/computer.
571- Type :: BYTE => self . decode_offset ( self . count , bo, bigtiff, limits, reader, |reader| {
572- let mut buf = [ 0 ; 1 ] ;
573- reader. inner ( ) . read_exact ( & mut buf) ?;
574- Ok ( Byte ( buf[ 0 ] ) )
575- } ) ,
576- Type :: SBYTE => self . decode_offset ( self . count , bo, bigtiff, limits, reader, |reader| {
577- Ok ( SignedByte ( reader. read_i8 ( ) ?) )
578- } ) ,
579- Type :: SHORT => self . decode_offset ( self . count , bo, bigtiff, limits, reader, |reader| {
580- Ok ( Short ( reader. read_u16 ( ) ?) )
581- } ) ,
582- Type :: SSHORT => self . decode_offset ( self . count , bo, bigtiff, limits, reader, |reader| {
583- Ok ( SignedShort ( reader. read_i16 ( ) ?) )
584- } ) ,
585- Type :: LONG => self . decode_offset ( self . count , bo, bigtiff, limits, reader, |reader| {
586- Ok ( Unsigned ( reader. read_u32 ( ) ?) )
587- } ) ,
588- Type :: SLONG => self . decode_offset ( self . count , bo, bigtiff, limits, reader, |reader| {
589- Ok ( Signed ( reader. read_i32 ( ) ?) )
590- } ) ,
591- Type :: FLOAT => self . decode_offset ( self . count , bo, bigtiff, limits, reader, |reader| {
592- Ok ( Float ( reader. read_f32 ( ) ?) )
593- } ) ,
594- Type :: DOUBLE => self . decode_offset ( self . count , bo, bigtiff, limits, reader, |reader| {
595- Ok ( Double ( reader. read_f64 ( ) ?) )
596- } ) ,
574+ Type :: UNDEFINED => {
575+ v = Self :: vec_with_capacity ( self . count , limits) ?;
576+ self . decode_values ( self . count , self . type_ , reader, |bytes| {
577+ v. extend ( bytes. iter ( ) . copied ( ) . map ( |v| Byte ( v) ) )
578+ } )
579+ }
580+ Type :: BYTE => {
581+ v = Self :: vec_with_capacity ( self . count , limits) ?;
582+ self . decode_values ( self . count , self . type_ , reader, |bytes| {
583+ v. extend ( bytes. iter ( ) . copied ( ) . map ( |v| Byte ( v) ) )
584+ } )
585+ }
586+ Type :: SBYTE => {
587+ v = Self :: vec_with_capacity ( self . count , limits) ?;
588+ self . decode_values ( self . count , self . type_ , reader, |bytes| {
589+ v. extend ( bytes. iter ( ) . copied ( ) . map ( |v| SignedByte ( v as i8 ) ) )
590+ } )
591+ }
592+ Type :: SHORT => {
593+ v = Self :: vec_with_capacity ( self . count , limits) ?;
594+ self . decode_values ( self . count , self . type_ , reader, |bytes| {
595+ v. extend (
596+ bytes
597+ . chunks_exact ( 2 )
598+ . map ( |ch| Short ( u16:: from_ne_bytes ( ch. try_into ( ) . unwrap ( ) ) ) ) ,
599+ )
600+ } )
601+ }
602+ Type :: SSHORT => {
603+ v = Self :: vec_with_capacity ( self . count , limits) ?;
604+ self . decode_values ( self . count , self . type_ , reader, |bytes| {
605+ v. extend (
606+ bytes
607+ . chunks_exact ( 2 )
608+ . map ( |ch| SignedShort ( i16:: from_ne_bytes ( ch. try_into ( ) . unwrap ( ) ) ) ) ,
609+ )
610+ } )
611+ }
612+ Type :: LONG => {
613+ v = Self :: vec_with_capacity ( self . count , limits) ?;
614+ self . decode_values ( self . count , self . type_ , reader, |bytes| {
615+ v. extend (
616+ bytes
617+ . chunks_exact ( 4 )
618+ . map ( |ch| Unsigned ( u32:: from_ne_bytes ( ch. try_into ( ) . unwrap ( ) ) ) ) ,
619+ )
620+ } )
621+ }
622+ Type :: SLONG => {
623+ v = Self :: vec_with_capacity ( self . count , limits) ?;
624+ self . decode_values ( self . count , self . type_ , reader, |bytes| {
625+ v. extend (
626+ bytes
627+ . chunks_exact ( 4 )
628+ . map ( |ch| Signed ( i32:: from_ne_bytes ( ch. try_into ( ) . unwrap ( ) ) ) ) ,
629+ )
630+ } )
631+ }
632+ Type :: FLOAT => {
633+ v = Self :: vec_with_capacity ( self . count , limits) ?;
634+ self . decode_values ( self . count , self . type_ , reader, |bytes| {
635+ v. extend (
636+ bytes
637+ . chunks_exact ( 4 )
638+ . map ( |ch| Float ( f32:: from_ne_bytes ( ch. try_into ( ) . unwrap ( ) ) ) ) ,
639+ )
640+ } )
641+ }
642+ Type :: DOUBLE => {
643+ v = Self :: vec_with_capacity ( self . count , limits) ?;
644+ self . decode_values ( self . count , self . type_ , reader, |bytes| {
645+ v. extend (
646+ bytes
647+ . chunks_exact ( 8 )
648+ . map ( |ch| Double ( f64:: from_ne_bytes ( ch. try_into ( ) . unwrap ( ) ) ) ) ,
649+ )
650+ } )
651+ }
597652 Type :: RATIONAL => {
598- self . decode_offset ( self . count , bo, bigtiff, limits, reader, |reader| {
599- Ok ( Rational ( reader. read_u32 ( ) ?, reader. read_u32 ( ) ?) )
653+ v = Self :: vec_with_capacity ( self . count , limits) ?;
654+ self . decode_values ( self . count , self . type_ , reader, |bytes| {
655+ v. extend ( bytes. chunks_exact ( 8 ) . map ( |ch| {
656+ Rational (
657+ u32:: from_ne_bytes ( ch[ ..4 ] . try_into ( ) . unwrap ( ) ) ,
658+ u32:: from_ne_bytes ( ch[ 4 ..] . try_into ( ) . unwrap ( ) ) ,
659+ )
660+ } ) )
600661 } )
601662 }
602663 Type :: SRATIONAL => {
603- self . decode_offset ( self . count , bo, bigtiff, limits, reader, |reader| {
604- Ok ( SRational ( reader. read_i32 ( ) ?, reader. read_i32 ( ) ?) )
664+ v = Self :: vec_with_capacity ( self . count , limits) ?;
665+ self . decode_values ( self . count , self . type_ , reader, |bytes| {
666+ v. extend ( bytes. chunks_exact ( 8 ) . map ( |ch| {
667+ SRational (
668+ i32:: from_ne_bytes ( ch[ ..4 ] . try_into ( ) . unwrap ( ) ) ,
669+ i32:: from_ne_bytes ( ch[ 4 ..] . try_into ( ) . unwrap ( ) ) ,
670+ )
671+ } ) )
605672 } )
606673 }
607- Type :: LONG8 => self . decode_offset ( self . count , bo, bigtiff, limits, reader, |reader| {
608- Ok ( UnsignedBig ( reader. read_u64 ( ) ?) )
609- } ) ,
610- Type :: SLONG8 => self . decode_offset ( self . count , bo, bigtiff, limits, reader, |reader| {
611- Ok ( SignedBig ( reader. read_i64 ( ) ?) )
612- } ) ,
613- Type :: IFD => self . decode_offset ( self . count , bo, bigtiff, limits, reader, |reader| {
614- Ok ( Ifd ( reader. read_u32 ( ) ?) )
615- } ) ,
616- Type :: IFD8 => self . decode_offset ( self . count , bo, bigtiff, limits, reader, |reader| {
617- Ok ( IfdBig ( reader. read_u64 ( ) ?) )
618- } ) ,
619- Type :: UNDEFINED => {
620- self . decode_offset ( self . count , bo, bigtiff, limits, reader, |reader| {
621- let mut buf = [ 0 ; 1 ] ;
622- reader. inner ( ) . read_exact ( & mut buf) ?;
623- Ok ( Byte ( buf[ 0 ] ) )
674+ Type :: LONG8 => {
675+ v = Self :: vec_with_capacity ( self . count , limits) ?;
676+ self . decode_values ( self . count , self . type_ , reader, |bytes| {
677+ v. extend (
678+ bytes
679+ . chunks_exact ( 8 )
680+ . map ( |ch| UnsignedBig ( u64:: from_ne_bytes ( ch. try_into ( ) . unwrap ( ) ) ) ) ,
681+ )
682+ } )
683+ }
684+ Type :: SLONG8 => {
685+ v = Self :: vec_with_capacity ( self . count , limits) ?;
686+ self . decode_values ( self . count , self . type_ , reader, |bytes| {
687+ v. extend (
688+ bytes
689+ . chunks_exact ( 8 )
690+ . map ( |ch| SignedBig ( i64:: from_ne_bytes ( ch. try_into ( ) . unwrap ( ) ) ) ) ,
691+ )
692+ } )
693+ }
694+ Type :: IFD => {
695+ v = Self :: vec_with_capacity ( self . count , limits) ?;
696+ self . decode_values ( self . count , self . type_ , reader, |bytes| {
697+ v. extend (
698+ bytes
699+ . chunks_exact ( 4 )
700+ . map ( |ch| Ifd ( u32:: from_ne_bytes ( ch. try_into ( ) . unwrap ( ) ) ) ) ,
701+ )
702+ } )
703+ }
704+ Type :: IFD8 => {
705+ v = Self :: vec_with_capacity ( self . count , limits) ?;
706+ self . decode_values ( self . count , self . type_ , reader, |bytes| {
707+ v. extend (
708+ bytes
709+ . chunks_exact ( 8 )
710+ . map ( |ch| IfdBig ( u64:: from_ne_bytes ( ch. try_into ( ) . unwrap ( ) ) ) ) ,
711+ )
624712 } )
625713 }
626714 Type :: ASCII => {
627715 let n = usize:: try_from ( self . count ) ?;
628- if n > limits. decoding_buffer_size {
629- return Err ( TiffError :: LimitsExceeded ) ;
630- }
631716
632- if bigtiff {
633- reader. goto_offset ( self . offset_field_reader ( bo) . read_u64 ( ) ?) ?
634- } else {
635- reader. goto_offset ( self . offset_field_reader ( bo) . read_u32 ( ) ?. into ( ) ) ?
717+ if n > limits. decoding_buffer_size {
718+ return Err ( dbg ! ( TiffError :: LimitsExceeded ) ) ;
636719 }
637720
638721 let mut out = vec ! [ 0 ; n] ;
@@ -641,43 +724,81 @@ impl Entry {
641724 if let Some ( first) = out. iter ( ) . position ( |& b| b == 0 ) {
642725 out. truncate ( first) ;
643726 }
644- Ok ( Ascii ( String :: from_utf8 ( out) ?) )
727+
728+ return Ok ( Ascii ( String :: from_utf8 ( out) ?) ) ;
645729 }
646- }
730+ } ?;
731+
732+ Ok ( List ( v) )
647733 }
648734
649- #[ inline]
650- fn decode_offset < R , F > (
651- & self ,
735+ fn vec_with_capacity (
652736 value_count : u64 ,
653- bo : ByteOrder ,
654- bigtiff : bool ,
655737 limits : & super :: Limits ,
656- reader : & mut EndianReader < R > ,
657- decode_fn : F ,
658- ) -> TiffResult < Value >
659- where
660- R : Read + Seek ,
661- F : Fn ( & mut EndianReader < R > ) -> TiffResult < Value > ,
662- {
738+ ) -> Result < Vec < Value > , TiffError > {
663739 let value_count = usize:: try_from ( value_count) ?;
740+
664741 if value_count > limits. decoding_buffer_size / mem:: size_of :: < Value > ( ) {
665742 return Err ( TiffError :: LimitsExceeded ) ;
666743 }
667744
668- let mut v = Vec :: with_capacity ( value_count) ;
745+ Ok ( Vec :: with_capacity ( value_count) )
746+ }
669747
748+ fn set_reader_offset < R > (
749+ & self ,
750+ bo : ByteOrder ,
751+ bigtiff : bool ,
752+ reader : & mut EndianReader < R > ,
753+ ) -> TiffResult < ( ) >
754+ where
755+ R : Read + Seek ,
756+ {
670757 let offset = if bigtiff {
671758 self . offset_field_reader ( bo) . read_u64 ( ) ?
672759 } else {
673760 self . offset_field_reader ( bo) . read_u32 ( ) ?. into ( )
674761 } ;
762+
675763 reader. goto_offset ( offset) ?;
676764
677- for _ in 0 ..value_count {
678- v. push ( decode_fn ( reader) ?)
765+ Ok ( ( ) )
766+ }
767+
768+ #[ inline]
769+ fn decode_values < R , F > (
770+ & self ,
771+ value_count : u64 ,
772+ type_ : Type ,
773+ reader : & mut EndianReader < R > ,
774+ mut collect : F ,
775+ ) -> TiffResult < ( ) >
776+ where
777+ R : Read + Seek ,
778+ F : FnMut ( & [ u8 ] ) ,
779+ {
780+ let mut total_bytes = type_. value_bytes ( value_count) ?;
781+ let mut buffer = [ 0u8 ; 512 ] ;
782+
783+ let buf_unit = usize:: from ( type_. byte_len ( ) ) ;
784+ let mul_of_ty = buffer. len ( ) / buf_unit * buf_unit;
785+
786+ let cls = type_. byte_order_class ( ) ;
787+ let native = ByteOrder :: native ( ) ;
788+
789+ while total_bytes > 0 {
790+ // `now <= mul_of_ty < 512` so casting is mathematical
791+ let now = total_bytes. min ( mul_of_ty as u64 ) ;
792+ total_bytes -= now;
793+
794+ let buffer = & mut buffer[ ..now as usize ] ;
795+ reader. inner ( ) . read_exact ( buffer) ?;
796+
797+ reader. byte_order . convert_class ( cls, buffer, native) ;
798+ collect ( buffer) ;
679799 }
680- Ok ( List ( v) )
800+
801+ Ok ( ( ) )
681802 }
682803}
683804
0 commit comments