11use byteorder_lite:: ReadBytesExt ;
2- use std:: io:: { BufRead , Read , Seek , SeekFrom } ;
2+ use std:: io:: { BufRead , Read , Seek } ;
33use std:: { error, fmt} ;
44
55use crate :: color:: ColorType ;
66use crate :: error:: {
77 DecodingError , ImageError , ImageResult , UnsupportedError , UnsupportedErrorKind ,
88} ;
9+ use crate :: utils:: seek_start_with_offset;
910use crate :: { ImageDecoder , ImageFormat } ;
1011
1112use self :: InnerDecoder :: * ;
@@ -107,6 +108,7 @@ impl From<IcoEntryImageFormat> for ImageFormat {
107108/// An ico decoder
108109pub struct IcoDecoder < R : BufRead + Seek > {
109110 selected_entry : DirEntry ,
111+ reader_offset : u64 ,
110112 inner_decoder : InnerDecoder < R > ,
111113}
112114
@@ -143,12 +145,14 @@ struct DirEntry {
143145impl < R : BufRead + Seek > IcoDecoder < R > {
144146 /// Create a new decoder that decodes from the stream ```r```
145147 pub fn new ( mut r : R ) -> ImageResult < IcoDecoder < R > > {
148+ let reader_offset = r. stream_position ( ) ?;
146149 let entries = read_entries ( & mut r) ?;
147150 let entry = best_entry ( entries) ?;
148- let decoder = entry. decoder ( r) ?;
151+ let decoder = entry. decoder ( r, reader_offset ) ?;
149152
150153 Ok ( IcoDecoder {
151154 selected_entry : entry,
155+ reader_offset,
152156 inner_decoder : decoder,
153157 } )
154158 }
@@ -230,13 +234,13 @@ impl DirEntry {
230234 && u32:: from ( self . real_height ( ) ) == height. min ( 256 )
231235 }
232236
233- fn seek_to_start < R : Read + Seek > ( & self , r : & mut R ) -> ImageResult < ( ) > {
234- r . seek ( SeekFrom :: Start ( u64:: from ( self . image_offset ) ) ) ?;
237+ fn seek_to_start < R : Read + Seek > ( & self , r : & mut R , reader_offset : u64 ) -> ImageResult < ( ) > {
238+ seek_start_with_offset ( r , reader_offset , u64:: from ( self . image_offset ) ) ?;
235239 Ok ( ( ) )
236240 }
237241
238- fn is_png < R : Read + Seek > ( & self , r : & mut R ) -> ImageResult < bool > {
239- self . seek_to_start ( r) ?;
242+ fn is_png < R : Read + Seek > ( & self , r : & mut R , reader_offset : u64 ) -> ImageResult < bool > {
243+ self . seek_to_start ( r, reader_offset ) ?;
240244
241245 // Read the first 8 bytes to sniff the image.
242246 let mut signature = [ 0u8 ; 8 ] ;
@@ -245,9 +249,13 @@ impl DirEntry {
245249 Ok ( signature == PNG_SIGNATURE )
246250 }
247251
248- fn decoder < R : BufRead + Seek > ( & self , mut r : R ) -> ImageResult < InnerDecoder < R > > {
249- let is_png = self . is_png ( & mut r) ?;
250- self . seek_to_start ( & mut r) ?;
252+ fn decoder < R : BufRead + Seek > (
253+ & self ,
254+ mut r : R ,
255+ reader_offset : u64 ,
256+ ) -> ImageResult < InnerDecoder < R > > {
257+ let is_png = self . is_png ( & mut r, reader_offset) ?;
258+ self . seek_to_start ( & mut r, reader_offset) ?;
251259
252260 if is_png {
253261 let limits = crate :: Limits {
@@ -335,7 +343,8 @@ impl<R: BufRead + Seek> ImageDecoder for IcoDecoder<R> {
335343
336344 let r = decoder. reader ( ) ;
337345 let image_end = r. stream_position ( ) ?;
338- let data_end = u64:: from ( self . selected_entry . image_offset )
346+ let data_end = self . reader_offset
347+ + u64:: from ( self . selected_entry . image_offset )
339348 + u64:: from ( self . selected_entry . image_length ) ;
340349
341350 let mask_row_bytes = width. div_ceil ( 32 ) * 4 ;
0 commit comments