gif/reader/
decoder.rs

1use std::borrow::Cow;
2use std::cmp;
3use std::error;
4use std::fmt;
5use std::io;
6use std::mem;
7use std::default::Default;
8use std::num::NonZeroUsize;
9
10use crate::Repeat;
11use crate::MemoryLimit;
12use crate::common::{AnyExtension, Block, DisposalMethod, Extension, Frame};
13use crate::reader::DecodeOptions;
14
15use weezl::{BitOrder, decode::Decoder as LzwDecoder, LzwError, LzwStatus};
16
17/// GIF palettes are RGB
18pub const PLTE_CHANNELS: usize = 3;
19
20/// An error returned in the case of the image not being formatted properly.
21#[derive(Debug)]
22pub struct DecodingFormatError {
23    underlying: Box<dyn error::Error + Send + Sync + 'static>,
24}
25
26impl fmt::Display for DecodingFormatError {
27    #[cold]
28    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
29        fmt::Display::fmt(&*self.underlying, fmt)
30    }
31}
32
33impl error::Error for DecodingFormatError {
34    #[cold]
35    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
36        Some(&*self.underlying as _)
37    }
38}
39
40#[derive(Debug)]
41/// Decoding error.
42pub enum DecodingError {
43    /// Returned if the image is found to be malformed.
44    Format(DecodingFormatError),
45    /// Wraps `std::io::Error`.
46    Io(io::Error),
47}
48
49impl DecodingError {
50    #[cold]
51    pub(crate) fn format(err: &'static str) -> Self {
52        DecodingError::Format(DecodingFormatError {
53            underlying: err.into(),
54        })
55    }
56}
57
58impl fmt::Display for DecodingError {
59    #[cold]
60    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
61        match *self {
62            DecodingError::Format(ref d) => d.fmt(fmt),
63            DecodingError::Io(ref err) => err.fmt(fmt),
64        }
65    }
66}
67
68impl error::Error for DecodingError {
69    #[cold]
70    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
71        match *self {
72            DecodingError::Format(ref err) => Some(err),
73            DecodingError::Io(ref err) => Some(err),
74        }
75    }
76}
77
78impl From<io::Error> for DecodingError {
79    #[inline]
80    fn from(err: io::Error) -> Self {
81        DecodingError::Io(err)
82    }
83}
84
85impl From<io::ErrorKind> for DecodingError {
86    #[cold]
87    fn from(err: io::ErrorKind) -> Self {
88        DecodingError::Io(io::Error::from(err))
89    }
90}
91
92impl From<DecodingFormatError> for DecodingError {
93    #[inline]
94    fn from(err: DecodingFormatError) -> Self {
95        DecodingError::Format(err)
96    }
97}
98
99/// Varies depending on `skip_frame_decoding`
100#[derive(Debug, Copy, Clone)]
101pub enum FrameDataType {
102    /// `Frame.buffer` will be regular pixel data
103    Pixels,
104    /// Raw LZW data
105    Lzw {
106        /// Needed for decoding
107        min_code_size: u8,
108    },
109}
110
111/// Indicates whether a certain object has been decoded
112#[derive(Debug)]
113#[non_exhaustive]
114pub enum Decoded {
115    /// Decoded nothing.
116    Nothing,
117    /// Global palette.
118    GlobalPalette(Box<[u8]>),
119    /// Index of the background color in the global palette.
120    BackgroundColor(u8),
121    /// Loop count is known
122    Repetitions(Repeat),
123    /// Palette and optional `Application` extension have been parsed,
124    /// reached frame data.
125    HeaderEnd,
126    /// The start of a block.
127    /// `BlockStart(Block::Trailer)` is the very last decode event
128    BlockStart(Block),
129    /// Decoded a sub-block. More sub-block are available.
130    ///
131    /// Indicates the label of the extension which might be unknown. A label of `0` is used when
132    /// the sub block does not belong to an extension.
133    ///
134    /// Call `last_ext()` to get the data
135    SubBlockFinished(AnyExtension),
136    /// Decoded the last (or only) sub-block of a block.
137    ///
138    /// Indicates the label of the extension which might be unknown. A label of `0` is used when
139    /// the sub block does not belong to an extension.
140    ///
141    /// Call `last_ext()` to get the data
142    BlockFinished(AnyExtension),
143    /// Decoded all information of the next frame, except the image data.
144    ///
145    /// The returned frame does **not** contain any owned image data.
146    ///
147    /// Call `current_frame_mut()` to access the frame info.
148    FrameMetadata(FrameDataType),
149    /// Decoded some data of the current frame. Size is in bytes, always > 0
150    BytesDecoded(NonZeroUsize),
151    /// Copied (or consumed and discarded) compressed data of the current frame. In bytes.
152    LzwDataCopied(usize),
153    /// No more data available the current frame.
154    DataEnd,
155}
156
157/// Internal state of the GIF decoder
158#[derive(Debug, Copy, Clone)]
159enum State {
160    Magic(u8, [u8; 6]),
161    U16Byte1(U16Value, u8),
162    U16(U16Value),
163    Byte(ByteValue),
164    GlobalPalette(usize),
165    BlockStart(u8),
166    BlockEnd,
167    ExtensionBlock(AnyExtension),
168    /// Collects data in ext.data
169    ExtensionDataBlock(usize),
170    ApplicationExtension,
171    LocalPalette(usize),
172    LzwInit(u8),
173    /// Decompresses LZW
174    DecodeSubBlock(usize),
175    /// Keeps LZW compressed
176    CopySubBlock(usize),
177    FrameDecoded,
178    Trailer,
179}
180use self::State::*;
181
182use super::converter::PixelConverter;
183
184/// U16 values that may occur in a GIF image
185#[derive(Debug, Copy, Clone)]
186enum U16Value {
187    /// Logical screen descriptor width
188    ScreenWidth,
189    /// Logical screen descriptor height
190    ScreenHeight,
191    /// Delay time
192    Delay,
193    /// Left frame offset
194    ImageLeft,
195    /// Top frame offset
196    ImageTop,
197    /// Frame width
198    ImageWidth,
199    /// Frame height
200    ImageHeight,
201}
202
203/// Single byte screen descriptor values
204#[derive(Debug, Copy, Clone)]
205enum ByteValue {
206    GlobalFlags,
207    Background { global_flags: u8 },
208    AspectRatio { global_flags: u8 },
209    ControlFlags,
210    ImageFlags,
211    TransparentIdx,
212    CodeSize,
213}
214
215/// Decoder for `Frame::make_lzw_pre_encoded`
216pub struct FrameDecoder {
217    lzw_reader: LzwReader,
218    pixel_converter: PixelConverter,
219}
220
221impl FrameDecoder {
222    /// See also `set_global_palette`
223    #[inline]
224    #[must_use]
225    pub fn new(options: DecodeOptions) -> Self {
226        Self {
227            lzw_reader: LzwReader::new(options.check_for_end_code),
228            pixel_converter: PixelConverter::new(options.color_output, options.memory_limit),
229        }
230    }
231
232    /// Palette used for RGBA conversion
233    #[inline]
234    pub fn set_global_palette(&mut self, palette: Vec<u8>) {
235        self.pixel_converter.set_global_palette(palette);
236    }
237
238    /// Converts the frame in-place, replacing its LZW buffer with pixels.
239    ///
240    /// If you get an error about invalid min code size, the buffer was probably pixels, not compressed data.
241    #[inline]
242    pub fn decode_lzw_encoded_frame(&mut self, frame: &mut Frame<'_>) -> Result<(), DecodingError> {
243        let pixel_bytes = self.pixel_converter.check_buffer_size(frame)?;
244        let mut vec = vec![0; pixel_bytes];
245        self.decode_lzw_encoded_frame_into_buffer(frame, &mut vec)?;
246        frame.buffer = Cow::Owned(vec);
247        frame.interlaced = false;
248        Ok(())
249    }
250
251    /// Converts into the given buffer. It must be [`buffer_size()`] bytes large.
252    ///
253    /// Pixels are always deinterlaced, so update `frame.interlaced` afterwards if you're putting the buffer back into the frame.
254    pub fn decode_lzw_encoded_frame_into_buffer(&mut self, frame: &Frame<'_>, buf: &mut [u8]) -> Result<(), DecodingError> {
255        let (&min_code_size, mut data) = frame.buffer.split_first().unwrap_or((&2, &[]));
256        self.lzw_reader.reset(min_code_size)?;
257        let lzw_reader = &mut self.lzw_reader;
258        self.pixel_converter.read_into_buffer(frame, buf, &mut move |out| {
259            loop {
260                let (bytes_read, bytes_written) = lzw_reader.decode_bytes(data, out)?;
261                data = &data.get(bytes_read..).unwrap_or_default();
262                if bytes_written > 0 || bytes_read == 0 || data.is_empty() {
263                    return Ok(bytes_written)
264                }
265            }
266        })?;
267        Ok(())
268    }
269
270    /// Number of bytes required for `decode_lzw_encoded_frame_into_buffer`
271    #[inline]
272    #[must_use]
273    pub fn buffer_size(&self, frame: &Frame<'_>) -> usize {
274        self.pixel_converter.buffer_size(frame).unwrap()
275    }
276}
277
278struct LzwReader {
279    decoder: Option<LzwDecoder>,
280    min_code_size: u8,
281    check_for_end_code: bool,
282}
283
284impl LzwReader {
285    pub fn new(check_for_end_code: bool) -> Self {
286        Self {
287            decoder: None,
288            min_code_size: 0,
289            check_for_end_code,
290        }
291    }
292
293    pub fn check_code_size(min_code_size: u8) -> Result<(), DecodingError> {
294        // LZW spec: max 12 bits per code. This check helps catch confusion
295        // between LZW-compressed buffers and raw pixel data
296        if min_code_size > 11 || min_code_size < 1 {
297            return Err(DecodingError::format("invalid minimal code size"));
298        }
299        Ok(())
300    }
301
302    pub fn reset(&mut self, min_code_size: u8) -> Result<(), DecodingError> {
303        Self::check_code_size(min_code_size)?;
304
305        // The decoder can be reused if the code size stayed the same
306        if self.min_code_size != min_code_size || self.decoder.is_none() {
307            self.min_code_size = min_code_size;
308            self.decoder = Some(LzwDecoder::new(BitOrder::Lsb, min_code_size));
309        } else {
310            self.decoder.as_mut().ok_or_else(|| DecodingError::format("bad state"))?.reset();
311        }
312
313        Ok(())
314    }
315
316    pub fn has_ended(&self) -> bool {
317        self.decoder.as_ref().map_or(true, |e| e.has_ended())
318    }
319
320    pub fn decode_bytes(&mut self, lzw_data: &[u8], decode_buffer: &mut OutputBuffer<'_>) -> io::Result<(usize, usize)> {
321        let decoder = self.decoder.as_mut().ok_or(io::ErrorKind::Unsupported)?;
322
323        let decode_buffer = match decode_buffer {
324            OutputBuffer::Slice(buf) => &mut **buf,
325            OutputBuffer::None => &mut [],
326            OutputBuffer::Vec(_) => return Err(io::Error::from(io::ErrorKind::Unsupported)),
327        };
328
329        let decoded = decoder.decode_bytes(lzw_data, decode_buffer);
330
331        match decoded.status {
332            Ok(LzwStatus::Done | LzwStatus::Ok) => {},
333            Ok(LzwStatus::NoProgress) => {
334                if self.check_for_end_code {
335                    return Err(io::Error::new(io::ErrorKind::InvalidData, "no end code in lzw stream"));
336                }
337            },
338            Err(err @ LzwError::InvalidCode) => {
339                return Err(io::Error::new(io::ErrorKind::InvalidData, err));
340            }
341        }
342        Ok((decoded.consumed_in, decoded.consumed_out))
343    }
344}
345
346/// GIF decoder which emits [low-level events](Decoded) for items in the GIF file
347///
348/// To just get GIF frames, use [`crate::Decoder`] instead.
349pub struct StreamingDecoder {
350    state: State,
351    lzw_reader: LzwReader,
352    skip_frame_decoding: bool,
353    check_frame_consistency: bool,
354    allow_unknown_blocks: bool,
355    memory_limit: MemoryLimit,
356    version: Version,
357    width: u16,
358    height: u16,
359    global_color_table: Vec<u8>,
360    background_color: [u8; 4],
361    /// ext buffer
362    ext: ExtensionData,
363    /// Frame data
364    current: Option<Frame<'static>>,
365    /// Needs to emit `HeaderEnd` once
366    header_end_reached: bool,
367}
368
369/// One version number of the GIF standard.
370#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
371pub enum Version {
372    /// Version 87a, from May 1987.
373    V87a,
374    /// Version 89a, from July 1989.
375    V89a,
376}
377
378struct ExtensionData {
379    id: AnyExtension,
380    data: Vec<u8>,
381    is_block_end: bool,
382}
383
384/// Destination to write to for `StreamingDecoder::update`
385pub enum OutputBuffer<'a> {
386    /// Overwrite bytes
387    Slice(&'a mut [u8]),
388    /// Append LZW bytes
389    Vec(&'a mut Vec<u8>),
390    /// Discard bytes
391    None,
392}
393
394impl<'a> OutputBuffer<'a> {
395    fn append(&mut self, buf: &[u8], memory_limit: &MemoryLimit) -> Result<(usize, usize), DecodingError> {
396        let (consumed, copied) = match self {
397            OutputBuffer::Slice(slice) => {
398                let len = cmp::min(buf.len(), slice.len());
399                slice[..len].copy_from_slice(&buf[..len]);
400                (len, len)
401            },
402            OutputBuffer::Vec(vec) => {
403                let vec: &mut Vec<u8> = vec;
404                let len = buf.len();
405                memory_limit.check_size(vec.len() + len)?;
406                vec.try_reserve(len).map_err(|_| io::ErrorKind::OutOfMemory)?;
407                if vec.capacity() - vec.len() >= len {
408                    vec.extend_from_slice(buf);
409                }
410                (len, len)
411            },
412            // It's valid that bytes are discarded. For example,
413            // when using next_frame_info() with skip_frame_decoding to only get metadata.
414            OutputBuffer::None => (buf.len(), 0),
415        };
416        Ok((consumed, copied))
417    }
418}
419
420impl StreamingDecoder {
421    /// Creates a new streaming decoder
422    #[must_use]
423    pub fn new() -> StreamingDecoder {
424        let options = DecodeOptions::new();
425        Self::with_options(&options)
426    }
427
428    pub(crate) fn with_options(options: &DecodeOptions) -> Self {
429        StreamingDecoder {
430            state: Magic(0, [0; 6]),
431            lzw_reader: LzwReader::new(options.check_for_end_code),
432            skip_frame_decoding: options.skip_frame_decoding,
433            check_frame_consistency: options.check_frame_consistency,
434            allow_unknown_blocks: options.allow_unknown_blocks,
435            memory_limit: options.memory_limit.clone(),
436            version: Version::V87a,
437            width: 0,
438            height: 0,
439            global_color_table: Vec::new(),
440            background_color: [0, 0, 0, 0xFF],
441            ext: ExtensionData {
442                id: AnyExtension(0),
443                data: Vec::with_capacity(256), // 0xFF + 1 byte length
444                is_block_end: true,
445            },
446            current: None,
447            header_end_reached: false,
448        }
449    }
450
451    /// Updates the internal state of the decoder.
452    ///
453    /// Returns the number of bytes consumed from the input buffer
454    /// and the last decoding result.
455    pub fn update<'a>(
456        &'a mut self,
457        mut buf: &[u8],
458        write_into: &mut OutputBuffer<'_>,
459    ) -> Result<(usize, Decoded), DecodingError> {
460        let len = buf.len();
461        while !buf.is_empty() {
462            let (bytes, decoded) = self.next_state(buf, write_into)?;
463            buf = buf.get(bytes..).unwrap_or_default();
464            match decoded {
465                Decoded::Nothing => {},
466                result => {
467                    return Ok((len-buf.len(), result));
468                },
469            };
470        }
471        Ok((len - buf.len(), Decoded::Nothing))
472    }
473
474    /// Returns the data of the last extension that has been decoded.
475    #[must_use]
476    pub fn last_ext(&self) -> (AnyExtension, &[u8], bool) {
477        (self.ext.id, &self.ext.data, self.ext.is_block_end)
478    }
479
480    /// Current frame info as a mutable ref.
481    #[must_use]
482    #[track_caller]
483    pub fn current_frame_mut(&mut self) -> &mut Frame<'static> {
484        self.current.as_mut().unwrap()
485    }
486
487    /// Current frame info as a ref.
488    #[track_caller]
489    #[must_use]
490    pub fn current_frame(&self) -> &Frame<'static> {
491        self.current.as_ref().unwrap()
492    }
493
494    /// Current frame info as a mutable ref.
495    #[inline(always)]
496    fn try_current_frame(&mut self) -> Result<&mut Frame<'static>, DecodingError> {
497        self.current.as_mut().ok_or_else(|| DecodingError::format("bad state"))
498    }
499
500    /// Width of the image
501    #[must_use]
502    pub fn width(&self) -> u16 {
503        self.width
504    }
505
506    /// Height of the image
507    #[must_use]
508    pub fn height(&self) -> u16 {
509        self.height
510    }
511
512    /// The version number of the GIF standard used in this image.
513    ///
514    /// We suppose a minimum of `V87a` compatibility. This value will be reported until we have
515    /// read the version information in the magic header bytes.
516    #[must_use]
517    pub fn version(&self) -> Version {
518        self.version
519    }
520
521    #[inline]
522    fn next_state(&mut self, buf: &[u8], write_into: &mut OutputBuffer<'_>) -> Result<(usize, Decoded), DecodingError> {
523        macro_rules! goto (
524            ($n:expr, $state:expr) => ({
525                self.state = $state;
526                Ok(($n, Decoded::Nothing))
527            });
528            ($state:expr) => ({
529                self.state = $state;
530                Ok((1, Decoded::Nothing))
531            });
532            ($n:expr, $state:expr, emit $res:expr) => ({
533                self.state = $state;
534                Ok(($n, $res))
535            });
536            ($state:expr, emit $res:expr) => ({
537                self.state = $state;
538                Ok((1, $res))
539            })
540        );
541
542        let b = *buf.get(0).ok_or(io::ErrorKind::UnexpectedEof)?;
543
544        match self.state {
545            Magic(i, mut version) => if i < 6 {
546                version[i as usize] = b;
547                goto!(Magic(i+1, version))
548            } else if &version[..3] == b"GIF" {
549                self.version = match &version[3..] {
550                    b"87a" => Version::V87a,
551                    b"89a" => Version::V89a,
552                    _ => return Err(DecodingError::format("malformed GIF header"))
553                };
554                goto!(U16Byte1(U16Value::ScreenWidth, b))
555            } else {
556                Err(DecodingError::format("malformed GIF header"))
557            },
558            Byte(value) => {
559                use self::ByteValue::*;
560                match value {
561                    GlobalFlags => {
562                        goto!(Byte(Background { global_flags: b }))
563                    },
564                    Background { global_flags } => {
565                        goto!(
566                            Byte(AspectRatio { global_flags }),
567                            emit Decoded::BackgroundColor(b)
568                        )
569                    },
570                    AspectRatio { global_flags } => {
571                        let global_table = global_flags & 0x80 != 0;
572                        let table_size = if global_table {
573                            let table_size = PLTE_CHANNELS * (1 << ((global_flags & 0b111) + 1) as usize);
574                            self.global_color_table.try_reserve_exact(table_size).map_err(|_| io::ErrorKind::OutOfMemory)?;
575                            table_size
576                        } else {
577                            0usize
578                        };
579                        goto!(GlobalPalette(table_size))
580                    },
581                    ControlFlags => {
582                        self.ext.data.push(b);
583                        let frame = self.try_current_frame()?;
584                        let control_flags = b;
585                        if control_flags & 1 != 0 {
586                            // Set to Some(...), gets overwritten later
587                            frame.transparent = Some(0);
588                        }
589                        frame.needs_user_input =
590                            control_flags & 0b10 != 0;
591                        frame.dispose = match DisposalMethod::from_u8(
592                            (control_flags & 0b11100) >> 2
593                        ) {
594                            Some(method) => method,
595                            None => DisposalMethod::Any
596                        };
597                        goto!(U16(U16Value::Delay))
598                    }
599                    TransparentIdx => {
600                        self.ext.data.push(b);
601                        if let Some(ref mut idx) = self.try_current_frame()?.transparent {
602                            *idx = b;
603                        }
604                        goto!(ExtensionDataBlock(0))
605                    }
606                    ImageFlags => {
607                        let local_table = (b & 0b1000_0000) != 0;
608                        let interlaced = (b & 0b0100_0000) != 0;
609                        let table_size = b & 0b0000_0111;
610                        let check_frame_consistency = self.check_frame_consistency;
611                        let (width, height) = (self.width, self.height);
612
613                        let frame = self.try_current_frame()?;
614
615                        frame.interlaced = interlaced;
616                        if check_frame_consistency {
617                            // Consistency checks.
618                            if width.checked_sub(frame.width) < Some(frame.left)
619                                || height.checked_sub(frame.height) < Some(frame.top)
620                            {
621                                return Err(DecodingError::format("frame descriptor is out-of-bounds"))
622                            }
623                        }
624
625                        if local_table {
626                            let entries = PLTE_CHANNELS * (1 << (table_size + 1));
627                            let mut pal = Vec::new();
628                            pal.try_reserve_exact(entries).map_err(|_| io::ErrorKind::OutOfMemory)?;
629                            frame.palette = Some(pal);
630                            goto!(LocalPalette(entries))
631                        } else {
632                            goto!(Byte(CodeSize))
633                        }
634                    }
635                    CodeSize => goto!(LzwInit(b)),
636                }
637            }
638            GlobalPalette(left) => {
639                let n = cmp::min(left, buf.len());
640                if left > 0 {
641                    self.global_color_table.extend_from_slice(&buf[..n]);
642                    goto!(n, GlobalPalette(left - n))
643                } else {
644                    let idx = self.background_color[0];
645                    match self.global_color_table.chunks_exact(PLTE_CHANNELS).nth(idx as usize) {
646                        Some(chunk) => self.background_color[..PLTE_CHANNELS]
647                            .copy_from_slice(&chunk[..PLTE_CHANNELS]),
648                        None => self.background_color[0] = 0
649                    }
650                    goto!(BlockStart(b), emit Decoded::GlobalPalette(
651                        mem::take(&mut self.global_color_table).into_boxed_slice()
652                    ))
653                }
654            }
655            BlockStart(type_) => {
656                if !self.header_end_reached && type_ != Block::Extension as u8 {
657                    self.header_end_reached = true;
658                    return goto!(0, BlockStart(type_), emit Decoded::HeaderEnd);
659                }
660
661                match Block::from_u8(type_) {
662                    Some(Block::Image) => {
663                        self.add_frame();
664                        goto!(U16Byte1(U16Value::ImageLeft, b), emit Decoded::BlockStart(Block::Image))
665                    }
666                    Some(Block::Extension) => {
667                        goto!(ExtensionBlock(AnyExtension(b)), emit Decoded::BlockStart(Block::Extension))
668                    }
669                    Some(Block::Trailer) => {
670                        // The `Trailer` is the final state, and isn't reachable without extraneous data after the end of file
671                        goto!(Trailer, emit Decoded::BlockStart(Block::Trailer))
672                    }
673                    None => {
674                        if self.allow_unknown_blocks {
675                            goto!(ExtensionDataBlock(b as usize))
676                        } else {
677                            Err(DecodingError::format("unknown block type encountered"))
678                        }
679                    }
680                }
681            },
682            BlockEnd => {
683                if b == Block::Trailer as u8 {
684                    // can't consume yet, because the trailer is not a real block,
685                    // and won't have futher data for BlockStart
686                    goto!(0, BlockStart(b))
687                } else {
688                    goto!(BlockStart(b))
689                }
690            }
691            ExtensionBlock(id) => {
692                use Extension::*;
693                self.ext.id = id;
694                self.ext.data.clear();
695                self.ext.data.push(b);
696                if let Some(ext) = Extension::from_u8(id.0) {
697                    match ext {
698                        Control => {
699                            goto!(self.read_control_extension(b)?)
700                        }
701                        Text | Comment | Application => {
702                            goto!(ExtensionDataBlock(b as usize))
703                        }
704                    }
705                } else {
706                    Err(DecodingError::format("unknown block type encountered"))
707                }
708            }
709            ExtensionDataBlock(left) => {
710                if left > 0 {
711                    let n = cmp::min(left, buf.len());
712                    self.memory_limit.check_size(self.ext.data.len() + n)?;
713                    self.ext.data.try_reserve(n).map_err(|_| io::Error::from(io::ErrorKind::OutOfMemory))?;
714                    self.ext.data.extend_from_slice(&buf[..n]);
715                    goto!(n, ExtensionDataBlock(left - n))
716                } else if b == 0 {
717                    self.ext.is_block_end = true;
718                    if self.ext.id.into_known() == Some(Extension::Application) {
719                        goto!(0, ApplicationExtension, emit Decoded::BlockFinished(self.ext.id))
720                    } else {
721                        goto!(BlockEnd, emit Decoded::BlockFinished(self.ext.id))
722                    }
723                } else {
724                    self.ext.is_block_end = false;
725                    goto!(ExtensionDataBlock(b as usize), emit Decoded::SubBlockFinished(self.ext.id))
726                }
727            }
728            ApplicationExtension => {
729                debug_assert_eq!(0, b);
730                // the parser removes sub-block lenghts, so app name and data are concatenated
731                if self.ext.data.len() >= 15 && &self.ext.data[1..13] == b"NETSCAPE2.0\x01" {
732                    let repeat = &self.ext.data[13..15];
733                    let repeat = u16::from(repeat[0]) | u16::from(repeat[1]) << 8;
734                    goto!(BlockEnd, emit Decoded::Repetitions(if repeat == 0 { Repeat::Infinite } else { Repeat::Finite(repeat) }))
735                } else {
736                    goto!(BlockEnd)
737                }
738            }
739            LocalPalette(left) => {
740                let n = cmp::min(left, buf.len());
741                if left > 0 {
742                    let src = &buf[..n];
743                    if let Some(pal) = self.try_current_frame()?.palette.as_mut() {
744                        // capacity has already been reserved in ImageFlags
745                        if pal.capacity() - pal.len() >= src.len() {
746                            pal.extend_from_slice(src);
747                        }
748                    }
749                    goto!(n, LocalPalette(left - n))
750                } else {
751                    goto!(LzwInit(b))
752                }
753            }
754            LzwInit(min_code_size) => {
755                if !self.skip_frame_decoding {
756                    // Reset validates the min code size
757                    self.lzw_reader.reset(min_code_size)?;
758                    goto!(DecodeSubBlock(b as usize), emit Decoded::FrameMetadata(FrameDataType::Pixels))
759                } else {
760                    LzwReader::check_code_size(min_code_size)?;
761                    goto!(CopySubBlock(b as usize), emit Decoded::FrameMetadata(FrameDataType::Lzw { min_code_size }))
762                }
763            }
764            CopySubBlock(left) => {
765                debug_assert!(self.skip_frame_decoding);
766                if left > 0 {
767                    let n = cmp::min(left, buf.len());
768                    let (consumed, copied) = write_into.append(&buf[..n], &self.memory_limit)?;
769                    goto!(consumed, CopySubBlock(left - consumed), emit Decoded::LzwDataCopied(copied))
770                } else if b != 0 {
771                    goto!(CopySubBlock(b as usize))
772                } else {
773                    goto!(0, FrameDecoded)
774                }
775            }
776            DecodeSubBlock(left) => {
777                debug_assert!(!self.skip_frame_decoding);
778                if left > 0 {
779                    let n = cmp::min(left, buf.len());
780                    if self.lzw_reader.has_ended() || matches!(write_into, OutputBuffer::None) {
781                        return goto!(n, DecodeSubBlock(left - n), emit Decoded::Nothing);
782                    }
783
784                    let (mut consumed, bytes_len) = self.lzw_reader.decode_bytes(&buf[..n], write_into)?;
785
786                    // skip if can't make progress (decode would fail if check_for_end_code was set)
787                    if consumed == 0 && bytes_len == 0 {
788                        consumed = n;
789                    }
790
791                    let decoded = if let Some(bytes_len) = NonZeroUsize::new(bytes_len) {
792                        Decoded::BytesDecoded(bytes_len)
793                    } else {
794                        Decoded::Nothing
795                    };
796                    goto!(consumed, DecodeSubBlock(left - consumed), emit decoded)
797                }  else if b != 0 { // decode next sub-block
798                    goto!(DecodeSubBlock(b as usize))
799                } else {
800                    let (_, bytes_len) = self.lzw_reader.decode_bytes(&[], write_into)?;
801
802                    if let Some(bytes_len) = NonZeroUsize::new(bytes_len) {
803                        goto!(0, DecodeSubBlock(0), emit Decoded::BytesDecoded(bytes_len))
804                    } else {
805                        goto!(0, FrameDecoded)
806                    }
807                }
808            }
809            U16(next) => goto!(U16Byte1(next, b)),
810            U16Byte1(next, value) => {
811                goto!(self.read_second_byte(next, value, b)?)
812            }
813            FrameDecoded => {
814                // end of image data reached
815                self.current = None;
816                debug_assert_eq!(0, b);
817                goto!(BlockEnd, emit Decoded::DataEnd)
818            }
819            Trailer => goto!(0, Trailer, emit Decoded::Nothing),
820        }
821    }
822
823    fn read_second_byte(&mut self, next: U16Value, value: u8, b: u8) -> Result<State, DecodingError> {
824        use self::U16Value::*;
825        let value = (u16::from(b) << 8) | u16::from(value);
826        Ok(match (next, value) {
827            (ScreenWidth, width) => {
828                self.width = width;
829                U16(U16Value::ScreenHeight)
830            },
831            (ScreenHeight, height) => {
832                self.height = height;
833                Byte(ByteValue::GlobalFlags)
834            },
835            (Delay, delay) => {
836                self.try_current_frame()?.delay = delay;
837                self.ext.data.push(value as u8);
838                self.ext.data.push(b);
839                Byte(ByteValue::TransparentIdx)
840            },
841            (ImageLeft, left) => {
842                self.try_current_frame()?.left = left;
843                U16(U16Value::ImageTop)
844            },
845            (ImageTop, top) => {
846                self.try_current_frame()?.top = top;
847                U16(U16Value::ImageWidth)
848            },
849            (ImageWidth, width) => {
850                self.try_current_frame()?.width = width;
851                U16(U16Value::ImageHeight)
852            },
853            (ImageHeight, height) => {
854                self.try_current_frame()?.height = height;
855                Byte(ByteValue::ImageFlags)
856            }
857        })
858    }
859
860    fn read_control_extension(&mut self, b: u8) -> Result<State, DecodingError> {
861        self.add_frame();
862        self.ext.data.push(b);
863        if b != 4 {
864            return Err(DecodingError::format("control extension has wrong length"));
865        }
866        Ok(Byte(ByteValue::ControlFlags))
867    }
868
869    fn add_frame(&mut self) {
870        if self.current.is_none() {
871            self.current = Some(Frame::default());
872        }
873    }
874}
875
876#[test]
877fn error_cast() {
878    let _ : Box<dyn error::Error> = DecodingError::format("testing").into();
879}