11use std:: borrow:: Cow ;
22use std:: cmp;
3+ use std:: default:: Default ;
34use std:: error;
45use std:: fmt;
56use std:: io;
67use std:: mem;
7- use std:: default:: Default ;
88use std:: num:: NonZeroUsize ;
99
10- use crate :: Repeat ;
11- use crate :: MemoryLimit ;
1210use crate :: common:: { AnyExtension , Block , DisposalMethod , Extension , Frame } ;
1311use crate :: reader:: DecodeOptions ;
12+ use crate :: MemoryLimit ;
13+ use crate :: Repeat ;
1414
15- use weezl:: { BitOrder , decode:: Decoder as LzwDecoder , LzwError , LzwStatus } ;
15+ use weezl:: { decode:: Decoder as LzwDecoder , BitOrder , LzwError , LzwStatus } ;
1616
1717/// GIF palettes are RGB
1818pub const PLTE_CHANNELS : usize = 3 ;
@@ -219,19 +219,22 @@ impl FrameDecoder {
219219 /// Converts into the given buffer. It must be [`buffer_size()`] bytes large.
220220 ///
221221 /// Pixels are always deinterlaced, so update `frame.interlaced` afterwards if you're putting the buffer back into the frame.
222- pub fn decode_lzw_encoded_frame_into_buffer ( & mut self , frame : & Frame < ' _ > , buf : & mut [ u8 ] ) -> Result < ( ) , DecodingError > {
222+ pub fn decode_lzw_encoded_frame_into_buffer (
223+ & mut self ,
224+ frame : & Frame < ' _ > ,
225+ buf : & mut [ u8 ] ,
226+ ) -> Result < ( ) , DecodingError > {
223227 let ( & min_code_size, mut data) = frame. buffer . split_first ( ) . unwrap_or ( ( & 2 , & [ ] ) ) ;
224228 self . lzw_reader . reset ( min_code_size) ?;
225229 let lzw_reader = & mut self . lzw_reader ;
226- self . pixel_converter . read_into_buffer ( frame , buf , & mut move |out| {
227- loop {
228- let ( bytes_read, bytes_written) = lzw_reader. decode_bytes ( data, out) ?;
230+ self . pixel_converter
231+ . read_into_buffer ( frame , buf , & mut move |out| loop {
232+ let ( bytes_read, bytes_written, status ) = lzw_reader. decode_bytes ( data, out) ?;
229233 data = data. get ( bytes_read..) . unwrap_or_default ( ) ;
230- if bytes_written > 0 || bytes_read == 0 || data . is_empty ( ) {
234+ if bytes_written > 0 || matches ! ( status , LzwStatus :: NoProgress ) {
231235 return Ok ( bytes_written) ;
232236 }
233- }
234- } ) ?;
237+ } ) ?;
235238 Ok ( ( ) )
236239 }
237240
@@ -285,7 +288,11 @@ impl LzwReader {
285288 self . decoder . as_ref ( ) . map_or ( true , |e| e. has_ended ( ) )
286289 }
287290
288- pub fn decode_bytes ( & mut self , lzw_data : & [ u8 ] , decode_buffer : & mut OutputBuffer < ' _ > ) -> io:: Result < ( usize , usize ) > {
291+ pub fn decode_bytes (
292+ & mut self ,
293+ lzw_data : & [ u8 ] ,
294+ decode_buffer : & mut OutputBuffer < ' _ > ,
295+ ) -> io:: Result < ( usize , usize , LzwStatus ) > {
289296 let decoder = self . decoder . as_mut ( ) . ok_or ( io:: ErrorKind :: Unsupported ) ?;
290297
291298 let decode_buffer = match decode_buffer {
@@ -296,18 +303,24 @@ impl LzwReader {
296303
297304 let decoded = decoder. decode_bytes ( lzw_data, decode_buffer) ;
298305
299- match decoded. status {
300- Ok ( LzwStatus :: Done | LzwStatus :: Ok ) => { } ,
301- Ok ( LzwStatus :: NoProgress ) => {
306+ let status = match decoded. status {
307+ Ok ( ok @ LzwStatus :: Done | ok @ LzwStatus :: Ok ) => ok ,
308+ Ok ( ok @ LzwStatus :: NoProgress ) => {
302309 if self . check_for_end_code {
303- return Err ( io:: Error :: new ( io:: ErrorKind :: InvalidData , "no end code in lzw stream" ) ) ;
310+ return Err ( io:: Error :: new (
311+ io:: ErrorKind :: InvalidData ,
312+ "no end code in lzw stream" ,
313+ ) ) ;
304314 }
305- } ,
315+
316+ ok
317+ }
306318 Err ( err @ LzwError :: InvalidCode ) => {
307319 return Err ( io:: Error :: new ( io:: ErrorKind :: InvalidData , err) ) ;
308320 }
309- }
310- Ok ( ( decoded. consumed_in , decoded. consumed_out ) )
321+ } ;
322+
323+ Ok ( ( decoded. consumed_in , decoded. consumed_out , status) )
311324 }
312325}
313326
@@ -633,7 +646,11 @@ impl StreamingDecoder {
633646 self . ext . data . clear ( ) ;
634647 self . ext . id = AnyExtension ( b) ;
635648 if self . ext . id . into_known ( ) . is_none ( ) {
636- return Err ( DecodingError :: format ( "unknown block type encountered" ) ) ;
649+ if !self . allow_unknown_blocks {
650+ return Err ( DecodingError :: format (
651+ "unknown extension block encountered" ,
652+ ) ) ;
653+ }
637654 }
638655 goto ! ( ExtensionBlockStart , emit Decoded :: BlockStart ( Block :: Extension ) )
639656 }
@@ -745,10 +762,11 @@ impl StreamingDecoder {
745762 return goto ! ( n, DecodeSubBlock ( left - n) , emit Decoded :: Nothing ) ;
746763 }
747764
748- let ( mut consumed, bytes_len) = self . lzw_reader . decode_bytes ( & buf[ ..n] , write_into) ?;
765+ let ( mut consumed, bytes_len, status) =
766+ self . lzw_reader . decode_bytes ( & buf[ ..n] , write_into) ?;
749767
750768 // skip if can't make progress (decode would fail if check_for_end_code was set)
751- if consumed == 0 && bytes_len == 0 {
769+ if matches ! ( status , LzwStatus :: NoProgress ) {
752770 consumed = n;
753771 }
754772
@@ -762,10 +780,14 @@ impl StreamingDecoder {
762780 // decode next sub-block
763781 goto ! ( DecodeSubBlock ( b as usize ) )
764782 } else {
765- let ( _, bytes_len) = self . lzw_reader . decode_bytes ( & [ ] , write_into) ?;
783+ let ( _, bytes_len, status ) = self . lzw_reader . decode_bytes ( & [ ] , write_into) ?;
766784
767785 if let Some ( bytes_len) = NonZeroUsize :: new ( bytes_len) {
768786 goto ! ( 0 , DecodeSubBlock ( 0 ) , emit Decoded :: BytesDecoded ( bytes_len) )
787+ } else if matches ! ( status, LzwStatus :: Ok ) {
788+ goto ! ( 0 , DecodeSubBlock ( 0 ) , emit Decoded :: Nothing )
789+ } else if matches ! ( status, LzwStatus :: Done ) {
790+ goto ! ( 0 , FrameDecoded )
769791 } else {
770792 goto ! ( 0 , FrameDecoded )
771793 }
0 commit comments