From 1b6a04ca5504955c571d1c97504fb45ea0befee4 Mon Sep 17 00:00:00 2001
From: Valentin Popov <valentin@popov.link>
Date: Mon, 8 Jan 2024 01:21:28 +0400
Subject: Initial vendor packages

Signed-off-by: Valentin Popov <valentin@popov.link>
---
 vendor/gif/src/reader/decoder.rs | 724 +++++++++++++++++++++++++++++++++++++++
 vendor/gif/src/reader/mod.rs     | 522 ++++++++++++++++++++++++++++
 2 files changed, 1246 insertions(+)
 create mode 100644 vendor/gif/src/reader/decoder.rs
 create mode 100644 vendor/gif/src/reader/mod.rs

(limited to 'vendor/gif/src/reader')

diff --git a/vendor/gif/src/reader/decoder.rs b/vendor/gif/src/reader/decoder.rs
new file mode 100644
index 0000000..f0f8eea
--- /dev/null
+++ b/vendor/gif/src/reader/decoder.rs
@@ -0,0 +1,724 @@
+use std::cmp;
+use std::error;
+use std::fmt;
+use std::io;
+use std::mem;
+use std::default::Default;
+
+use crate::common::{AnyExtension, Block, DisposalMethod, Extension, Frame};
+use crate::reader::DecodeOptions;
+
+use weezl::{BitOrder, decode::Decoder as LzwDecoder, LzwStatus};
+
+/// GIF palettes are RGB
+pub const PLTE_CHANNELS: usize = 3;
+
+/// An error returned in the case of the image not being formatted properly.
+#[derive(Debug)]
+pub struct DecodingFormatError {
+    underlying: Box<dyn error::Error + Send + Sync + 'static>
+}
+
+impl fmt::Display for DecodingFormatError {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(&*self.underlying, fmt)
+    }
+}
+
+impl error::Error for DecodingFormatError {
+    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
+        Some(&*self.underlying as _)
+    }
+}
+
+impl DecodingFormatError {
+    fn new(
+        err: impl Into<Box<dyn error::Error + Send + Sync>>,
+    ) -> Self {
+        DecodingFormatError {
+            underlying: err.into(),
+        }
+    }
+}
+
+#[derive(Debug)]
+/// Decoding error.
+pub enum DecodingError {
+    /// Returned if the image is found to be malformed.
+    Format(DecodingFormatError),
+    /// Wraps `std::io::Error`.
+    Io(io::Error),
+}
+
+impl DecodingError {
+    #[inline]
+    pub(crate) fn format(
+        err: impl Into<Box<dyn error::Error + Send + Sync>>,
+    ) -> Self {
+        DecodingError::Format(DecodingFormatError::new(err))
+    }
+}
+
+impl fmt::Display for DecodingError {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            DecodingError::Format(ref d) => d.fmt(fmt),
+            DecodingError::Io(ref err) => err.fmt(fmt),
+        }
+    }
+}
+
+impl error::Error for DecodingError {
+    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
+        match *self {
+            DecodingError::Format(ref err) => Some(err),
+            DecodingError::Io(ref err) => Some(err),
+        }
+    }
+}
+
+impl From<io::Error> for DecodingError {
+    fn from(err: io::Error) -> Self {
+        DecodingError::Io(err)
+    }
+}
+
+impl From<DecodingFormatError> for DecodingError {
+    fn from(err: DecodingFormatError) -> Self {
+        DecodingError::Format(err)
+    }
+}
+
+/// Configures how extensions should be handled
+#[derive(PartialEq, Debug)]
+pub enum Extensions {
+    /// Saves all extention data
+    Save,
+    /// Skips the data of unknown extensions
+    /// and extracts the data from known ones
+    Skip
+}
+
+/// Indicates whether a certain object has been decoded
+#[derive(Debug)]
+pub enum Decoded<'a> {
+    /// Decoded nothing.
+    Nothing,
+    /// Global palette.
+    GlobalPalette(Vec<u8>),
+    /// Index of the background color in the global palette.
+    BackgroundColor(u8),
+    /// Decoded the image trailer.
+    Trailer,
+    /// The start of a block.
+    BlockStart(Block),
+    /// Decoded a sub-block. More sub-block are available.
+    ///
+    /// Indicates the label of the extension which might be unknown. A label of `0` is used when
+    /// the sub block does not belong to an extension.
+    SubBlockFinished(AnyExtension, &'a [u8]),
+    /// Decoded the last (or only) sub-block of a block.
+    ///
+    /// Indicates the label of the extension which might be unknown. A label of `0` is used when
+    /// the sub block does not belong to an extension.
+    BlockFinished(AnyExtension, &'a [u8]),
+    /// Decoded all information of the next frame.
+    ///
+    /// The returned frame does **not** contain any owned image data.
+    Frame(&'a Frame<'static>),
+    /// Decoded some data of the current frame.
+    Data(&'a [u8]),
+    /// No more data available the current frame.
+    DataEnd,
+
+}
+
+/// Internal state of the GIF decoder
+#[derive(Debug)]
+enum State {
+    Magic(usize, [u8; 6]),
+    U16Byte1(U16Value, u8),
+    U16(U16Value),
+    Byte(ByteValue),
+    GlobalPalette(usize),
+    BlockStart(Option<Block>),
+    /// Block end, with remaining expected data. NonZero for invalid EOF.
+    BlockEnd(u8),
+    ExtensionBlock(AnyExtension),
+    SkipBlock(usize),
+    LocalPalette(usize),
+    LzwInit(u8),
+    DecodeSubBlock(usize),
+    FrameDecoded,
+    Trailer
+}
+use self::State::*;
+
+/// U16 values that may occur in a GIF image
+#[derive(Debug)]
+enum U16Value {
+    /// Logical screen descriptor width
+    ScreenWidth,
+    /// Logical screen descriptor height
+    ScreenHeight,
+    /// Delay time
+    Delay,
+    /// Left frame offset
+    ImageLeft,
+    /// Top frame offset
+    ImageTop,
+    /// Frame width
+    ImageWidth,
+    /// Frame height
+    ImageHeight,
+}
+
+/// Single byte screen descriptor values
+#[derive(Debug)]
+enum ByteValue {
+    GlobalFlags,
+    Background { table_size: usize },
+    AspectRatio { table_size: usize },
+    ControlFlags,
+    ImageFlags,
+    TransparentIdx,
+    CodeSize,
+}
+
+/// GIF decoder which supports streaming
+pub struct StreamingDecoder {
+    state: Option<State>,
+    lzw_reader: Option<LzwDecoder>,
+    decode_buffer: Vec<u8>,
+    skip_extensions: bool,
+    check_frame_consistency: bool,
+    check_for_end_code: bool,
+    allow_unknown_blocks: bool,
+    version: Version,
+    width: u16,
+    height: u16,
+    global_color_table: Vec<u8>,
+    background_color: [u8; 4],
+    /// ext buffer
+    ext: ExtensionData,
+    /// Frame data
+    current: Option<Frame<'static>>,
+}
+
+/// One version number of the GIF standard.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[non_exhaustive]
+pub enum Version {
+    /// Version 87a, from May 1987.
+    V87a,
+    /// Version 89a, from July 1989.
+    V89a,
+}
+
+struct ExtensionData {
+    id: AnyExtension,
+    data: Vec<u8>,
+    is_block_end: bool,
+}
+
+impl StreamingDecoder {
+    /// Creates a new streaming decoder
+    pub fn new() -> StreamingDecoder {
+        let options = DecodeOptions::new();
+        Self::with_options(&options)
+    }
+
+    pub(crate) fn with_options(options: &DecodeOptions) -> Self {
+        StreamingDecoder {
+            state: Some(Magic(0, [0; 6])),
+            lzw_reader: None,
+            decode_buffer: vec![],
+            skip_extensions: true,
+            check_frame_consistency: options.check_frame_consistency,
+            check_for_end_code: options.check_for_end_code,
+            allow_unknown_blocks: options.allow_unknown_blocks,
+            version: Version::V87a,
+            width: 0,
+            height: 0,
+            global_color_table: Vec::new(),
+            background_color: [0, 0, 0, 0xFF],
+            ext: ExtensionData {
+                id: AnyExtension(0),
+                data: Vec::with_capacity(256), // 0xFF + 1 byte length
+                is_block_end: true,
+            },
+            current: None
+        }
+    }
+    
+    /// Updates the internal state of the decoder. 
+    ///
+    /// Returns the number of bytes consumed from the input buffer 
+    /// and the last decoding result.
+    pub fn update<'a>(&'a mut self, mut buf: &[u8])
+    -> Result<(usize, Decoded<'a>), DecodingError> {
+        // NOTE: Do not change the function signature without double-checking the
+        //       unsafe block!
+        let len = buf.len();
+        while buf.len() > 0 && self.state.is_some() {
+            match self.next_state(buf) {
+                Ok((bytes, Decoded::Nothing)) => {
+                    buf = &buf[bytes..]
+                }
+                Ok((bytes, Decoded::Trailer)) => {
+                    buf = &buf[bytes..];
+                    break
+                }
+                Ok((bytes, result)) => {
+                    buf = &buf[bytes..];
+                    return Ok(
+                        (len-buf.len(), 
+                        // This transmute just casts the lifetime away. Since Rust only 
+                        // has SESE regions, this early return cannot be worked out and
+                        // such that the borrow region of self includes the whole block.
+                        // The explixit lifetimes in the function signature ensure that
+                        // this is safe.
+                        // ### NOTE
+                        // To check that everything is sound, return the result without
+                        // the match (e.g. `return Ok(self.next_state(buf)?)`). If
+                        // it compiles the returned lifetime is correct.
+                        unsafe { 
+                            mem::transmute::<Decoded, Decoded>(result)
+                        }
+                    ))
+                }
+                Err(err) => return Err(err)
+            }
+        }
+        Ok((len-buf.len(), Decoded::Nothing))
+        
+    }
+    
+    /// Returns the data of the last extension that has been decoded.
+    pub fn last_ext(&self) -> (AnyExtension, &[u8], bool) {
+        (self.ext.id, &self.ext.data, self.ext.is_block_end)
+    }
+    
+    #[inline(always)]
+    /// Current frame info as a mutable ref.
+    pub fn current_frame_mut<'a>(&'a mut self) -> &'a mut Frame<'static> {
+        self.current.as_mut().unwrap()
+    }
+    
+    #[inline(always)]
+    /// Current frame info as a ref.
+    pub fn current_frame<'a>(&'a self) -> &'a Frame<'static> {
+        self.current.as_ref().unwrap()
+    }
+
+    /// Width of the image
+    pub fn width(&self) -> u16 {
+        self.width
+    }
+
+    /// Height of the image
+    pub fn height(&self) -> u16 {
+        self.height
+    }
+
+    /// The version number of the GIF standard used in this image.
+    ///
+    /// We suppose a minimum of `V87a` compatibility. This value will be reported until we have
+    /// read the version information in the magic header bytes.
+    pub fn version(&self) -> Version {
+        self.version
+    }
+
+    /// Configure whether extensions are saved or skipped.
+    #[deprecated = "Does not work as intended. In fact, doesn't do anything. This may disappear soon."]
+    pub fn set_extensions(&mut self, extensions: Extensions) {
+        self.skip_extensions = match extensions {
+            Extensions::Skip => true,
+            Extensions::Save => false,
+        }
+    }
+
+    fn next_state<'a>(&'a mut self, buf: &[u8]) -> Result<(usize, Decoded<'a>), DecodingError> {
+        macro_rules! goto (
+            ($n:expr, $state:expr) => ({
+                self.state = Some($state); 
+                Ok(($n, Decoded::Nothing))
+            });
+            ($state:expr) => ({
+                self.state = Some($state); 
+                Ok((1, Decoded::Nothing))
+            });
+            ($n:expr, $state:expr, emit $res:expr) => ({
+                self.state = Some($state); 
+                Ok(($n, $res))
+            });
+            ($state:expr, emit $res:expr) => ({
+                self.state = Some($state); 
+                Ok((1, $res))
+            })
+        );
+        
+        let b = buf[0];
+        
+        // Driver should ensure that state is never None
+        let state = self.state.take().unwrap();
+        //println!("{:?}", state);
+        
+        match state {
+            Magic(i, mut version) => if i < 6 {
+                version[i] = b;
+                goto!(Magic(i+1, version))
+            } else if &version[..3] == b"GIF" {
+                self.version = match &version[3..] {
+                    b"87a" => Version::V87a,
+                    b"89a" => Version::V89a,
+                    _ => return Err(DecodingError::format("unsupported GIF version"))
+                };
+                goto!(U16Byte1(U16Value::ScreenWidth, b))
+            } else {
+                Err(DecodingError::format("malformed GIF header"))
+            },
+            U16(next) => goto!(U16Byte1(next, b)),
+            U16Byte1(next, value) => {
+                use self::U16Value::*;
+                let value = ((b as u16) << 8) | value as u16;
+                match (next, value) {
+                    (ScreenWidth, width) => {
+                        self.width = width;
+                        goto!(U16(U16Value::ScreenHeight))
+                    },
+                    (ScreenHeight, height) => {
+                        self.height = height;
+                        goto!(Byte(ByteValue::GlobalFlags))
+                    },
+                    (Delay, delay) => {
+                        self.ext.data.push(value as u8);
+                        self.ext.data.push(b);
+                        self.current_frame_mut().delay = delay;
+                        goto!(Byte(ByteValue::TransparentIdx))
+                    },
+                    (ImageLeft, left) => {
+                        self.current_frame_mut().left = left;
+                        goto!(U16(U16Value::ImageTop))
+                    },
+                    (ImageTop, top) => {
+                        self.current_frame_mut().top = top;
+                        goto!(U16(U16Value::ImageWidth))
+                    },
+                    (ImageWidth, width) => {
+                        self.current_frame_mut().width = width;
+                        goto!(U16(U16Value::ImageHeight))
+                    },
+                    (ImageHeight, height) => {
+                        self.current_frame_mut().height = height;
+                        goto!(Byte(ByteValue::ImageFlags))
+                    }
+                }
+            }
+            Byte(value) => {
+                use self::ByteValue::*;
+                match value {
+                    GlobalFlags => {
+                        let global_table = b & 0x80 != 0;
+                        let entries = if global_table {
+                            let entries = PLTE_CHANNELS*(1 << ((b & 0b111) + 1) as usize);
+                            self.global_color_table.reserve_exact(entries);
+                            entries
+                        } else {
+                            0usize
+                        };
+                        goto!(Byte(Background { table_size: entries }))
+                    },
+                    Background { table_size } => {
+                        goto!(
+                            Byte(AspectRatio { table_size: table_size }),
+                            emit Decoded::BackgroundColor(b)
+                        )
+                    },
+                    AspectRatio { table_size } => {
+                        goto!(GlobalPalette(table_size))
+                    },
+                    ControlFlags => {
+                        self.ext.data.push(b);
+                        let control_flags = b;
+                        if control_flags & 1 != 0 {
+                            // Set to Some(...), gets overwritten later
+                            self.current_frame_mut().transparent = Some(0)
+                        }
+                        self.current_frame_mut().needs_user_input =
+                            control_flags & 0b10 != 0;
+                        self.current_frame_mut().dispose = match DisposalMethod::from_u8(
+                            (control_flags & 0b11100) >> 2
+                        ) {
+                            Some(method) => method,
+                            None => DisposalMethod::Any
+                        };
+                        goto!(U16(U16Value::Delay))
+                    }
+                    TransparentIdx => {
+                        self.ext.data.push(b);
+                        if let Some(ref mut idx) = self.current_frame_mut().transparent {
+                             *idx = b
+                        }
+                        goto!(SkipBlock(0))
+                        //goto!(AwaitBlockEnd)
+                    }
+                    ImageFlags => {
+                        let local_table = (b & 0b1000_0000) != 0;
+                        let interlaced   = (b & 0b0100_0000) != 0;
+                        let table_size  =  b & 0b0000_0111;
+
+                        self.current_frame_mut().interlaced = interlaced;
+
+                        if self.check_frame_consistency {
+                            // Consistency checks.
+                            let (width, height) = (self.width, self.height);
+                            let frame = self.current_frame_mut();
+                            if width.checked_sub(frame.width) < Some(frame.left)
+                                || height.checked_sub(frame.height) < Some(frame.top)
+                            {
+                                return Err(DecodingError::format("frame descriptor is out-of-bounds"))
+                            }
+                        }
+
+                        if local_table {
+                            let entries = PLTE_CHANNELS * (1 << (table_size + 1));
+                            
+                            self.current_frame_mut().palette =
+                                Some(Vec::with_capacity(entries));
+                            goto!(LocalPalette(entries))
+                        } else {
+                            goto!(Byte(CodeSize))
+                        }
+                    },
+                    CodeSize => goto!(LzwInit(b))
+                }
+            }
+            GlobalPalette(left) => {
+                let n = cmp::min(left, buf.len());
+                if left > 0 {
+                    self.global_color_table.extend_from_slice(&buf[..n]);
+                    goto!(n, GlobalPalette(left - n))
+                } else {
+                    let idx = self.background_color[0];
+                    match self.global_color_table.chunks(PLTE_CHANNELS).nth(idx as usize) {
+                        Some(chunk) => self.background_color[..PLTE_CHANNELS]
+                            .copy_from_slice(&chunk[..PLTE_CHANNELS]),
+                        None => self.background_color[0] = 0
+                    }
+                    goto!(BlockStart(Block::from_u8(b)), emit Decoded::GlobalPalette(
+                        mem::replace(&mut self.global_color_table, Vec::new())
+                    ))
+                }
+            }
+            BlockStart(type_) => {
+                match type_ {
+                    Some(Block::Image) => {
+                        self.add_frame();
+                        goto!(U16Byte1(U16Value::ImageLeft, b), emit Decoded::BlockStart(Block::Image))
+                    }
+                    Some(Block::Extension) => {
+                        goto!(ExtensionBlock(AnyExtension(b)), emit Decoded::BlockStart(Block::Extension))
+                    }
+                    Some(Block::Trailer) => {
+                        goto!(0, State::Trailer, emit Decoded::BlockStart(Block::Trailer))
+                    }
+                    None => {
+                        if self.allow_unknown_blocks {
+                            goto!(SkipBlock(b as usize))
+                        } else {
+                            Err(DecodingError::format("unknown block type encountered"))
+                        }
+                    }
+                }
+            }
+            BlockEnd(terminator) => {
+                if terminator == 0 {
+                    if b == Block::Trailer as u8 {
+                        goto!(0, BlockStart(Some(Block::Trailer)))
+                    } else {
+                        goto!(BlockStart(Block::from_u8(b)))
+                    }
+                } else {
+                    return Err(DecodingError::format(
+                        "expected block terminator not found"
+                    ))
+                }
+            }
+            ExtensionBlock(id) => {
+                use Extension::*;
+                self.ext.id = id;
+                self.ext.data.clear();
+                self.ext.data.push(b);
+                if let Some(ext) = Extension::from_u8(id.0) {
+                    match ext {
+                        Control => {
+                            goto!(self.read_control_extension(b)?)
+                        }
+                        Text | Comment | Application => {
+                            goto!(SkipBlock(b as usize))
+                        }
+                    }
+                } else {
+                    return Err(DecodingError::format(
+                        "unknown extention block encountered"
+                    ))
+                }
+            }
+            SkipBlock(left) => {
+                let n = cmp::min(left, buf.len());
+                if left > 0 {
+                    self.ext.data.extend_from_slice(&buf[..n]);
+                    goto!(n, SkipBlock(left - n))
+                } else {
+                    if b == 0 {
+                        self.ext.is_block_end = true;
+                        goto!(BlockEnd(b), emit Decoded::BlockFinished(self.ext.id, &self.ext.data))
+                    } else {
+                        self.ext.is_block_end = false;
+                        goto!(SkipBlock(b as usize), emit Decoded::SubBlockFinished(self.ext.id, &self.ext.data))
+                    }
+                }
+            }
+            LocalPalette(left) => {
+                let n = cmp::min(left, buf.len());
+                if left > 0 {
+                    
+                    self.current_frame_mut().palette
+                        .as_mut().unwrap().extend(buf[..n].iter().cloned());
+                    goto!(n, LocalPalette(left - n))
+                } else {
+                    goto!(LzwInit(b))
+                }
+            }
+            LzwInit(code_size) => {
+                // LZW spec: max 12 bits per code
+                if code_size > 11 {
+                    return Err(DecodingError::format(
+                        "invalid minimal code size"
+                    ))
+                }
+                self.lzw_reader = Some(LzwDecoder::new(BitOrder::Lsb, code_size));
+                goto!(DecodeSubBlock(b as usize), emit Decoded::Frame(self.current_frame_mut()))
+            }
+            DecodeSubBlock(left) => {
+                if left > 0 {
+                    let n = cmp::min(left, buf.len());
+                    let max_bytes = self.current_frame().required_bytes();
+                    let decoder = self.lzw_reader.as_mut().unwrap();
+                    if decoder.has_ended() {
+                        debug_assert!(n > 0, "Made forward progress after LZW end");
+                        return goto!(n, DecodeSubBlock(0), emit Decoded::Data(&[]));
+                    }
+
+                    let mut dummy_target;
+                    let decode_target;
+
+                    if self.decode_buffer.is_empty() {
+                        let size = (1 << 14).min(max_bytes);
+                        self.decode_buffer = vec![0; size];
+                    }
+
+                    if max_bytes == 0 {
+                        dummy_target = [0; 16];
+                        decode_target = &mut dummy_target[..];
+                    } else {
+                        decode_target = self.decode_buffer.as_mut_slice();
+                    }
+
+                    debug_assert!(!decode_target.is_empty(), "LZW decoding can make forward progress.");
+                    let decoded = decoder.decode_bytes(&buf[..n], decode_target);
+
+                    if let Err(err) = decoded.status {
+                        return Err(io::Error::new(io::ErrorKind::InvalidData, &*format!("{:?}", err)).into());
+                    }
+
+                    let bytes = &self.decode_buffer[..decoded.consumed_out.min(max_bytes)];
+                    let consumed = decoded.consumed_in;
+                    goto!(consumed, DecodeSubBlock(left - consumed), emit Decoded::Data(bytes))
+                }  else if b != 0 { // decode next sub-block
+                    goto!(DecodeSubBlock(b as usize))
+                } else {
+                    let max_bytes = self.current_frame().required_bytes();
+                    // The end of the lzw stream is only reached if left == 0 and an additional call
+                    // to `decode_bytes` results in an empty slice.
+                    let decoder = self.lzw_reader.as_mut().unwrap();
+                    // Some mutable bytes to decode into. We need this for forward progress in
+                    // `lzw`. However, in some cases we do not actually need any bytes, when
+                    // `max_bytes` is `0`.
+                    let mut dummy_target;
+                    let decode_target;
+
+                    if self.decode_buffer.is_empty() {
+                        let size = (1 << 14).min(max_bytes);
+                        self.decode_buffer = vec![0; size];
+                    }
+
+                    if max_bytes == 0 {
+                        dummy_target = [0; 16];
+                        decode_target = &mut dummy_target[..];
+                    } else {
+                        decode_target = self.decode_buffer.as_mut_slice();
+                    }
+
+                    debug_assert!(!decode_target.is_empty(), "LZW decoding can make forward progress.");
+                    let decoded = decoder.decode_bytes(&[], decode_target);
+
+                    match decoded.status {
+                        Ok(LzwStatus::Done) | Ok(LzwStatus::Ok) => {},
+                        Ok(LzwStatus::NoProgress) => {
+                            if self.check_for_end_code {
+                                return Err(io::Error::new(io::ErrorKind::InvalidData, "No end code in lzw stream").into());
+                            } else {
+                                self.current = None;
+                                return goto!(0, FrameDecoded, emit Decoded::DataEnd);
+                            }
+                        },
+                        Err(err) => {
+                            return Err(io::Error::new(io::ErrorKind::InvalidData, &*format!("{:?}", err)).into());
+                        }
+                    }
+                    let bytes = &self.decode_buffer[..decoded.consumed_out.min(max_bytes)];
+
+                    if bytes.len() > 0 {
+                        goto!(0, DecodeSubBlock(0), emit Decoded::Data(bytes))
+                    } else {
+                        // end of image data reached
+                        self.current = None;
+                        goto!(0, FrameDecoded, emit Decoded::DataEnd)
+                    }
+                }
+            }
+            FrameDecoded => {
+                goto!(BlockEnd(b))
+            }
+            Trailer => {
+                self.state = None;
+                Ok((1, Decoded::Trailer))
+                //panic!("EOF {:?}", self)
+            }
+        }
+    }
+    
+    fn read_control_extension(&mut self, b: u8) -> Result<State, DecodingError> {
+        self.add_frame();
+        self.ext.data.push(b);
+        if b != 4 {
+            return Err(DecodingError::format(
+                "control extension has wrong length"
+            ))
+        }
+        Ok(Byte(ByteValue::ControlFlags))
+    }
+    
+    fn add_frame(&mut self) {
+        if self.current.is_none() {
+            self.current = Some(Frame::default())
+        }
+    }
+}
+
+#[test]
+fn error_cast() {
+    let _ : Box<dyn error::Error> = DecodingError::Format(DecodingFormatError::new("testing")).into();
+}
diff --git a/vendor/gif/src/reader/mod.rs b/vendor/gif/src/reader/mod.rs
new file mode 100644
index 0000000..a453e79
--- /dev/null
+++ b/vendor/gif/src/reader/mod.rs
@@ -0,0 +1,522 @@
+use std::borrow::Cow;
+use std::io;
+use std::cmp;
+use std::mem;
+use std::iter;
+use std::io::prelude::*;
+
+use crate::common::{Block, Frame};
+
+mod decoder;
+pub use self::decoder::{
+    PLTE_CHANNELS, StreamingDecoder, Decoded, DecodingError, DecodingFormatError, Extensions,
+    Version
+};
+
+const N_CHANNELS: usize = 4;
+
+/// Output mode for the image data
+#[derive(Clone, Copy, Debug, PartialEq)]
+#[repr(u8)]
+pub enum ColorOutput {
+    /// The decoder expands the image data to 32bit RGBA.
+    /// This affects:
+    ///
+    ///  - The buffer buffer of the `Frame` returned by `Decoder::read_next_frame`.
+    ///  - `Decoder::fill_buffer`, `Decoder::buffer_size` and `Decoder::line_length`.
+    RGBA = 0,
+    /// The decoder returns the raw indexed data.
+    Indexed = 1,
+}
+
+#[derive(Clone, Debug)]
+/// Memory limit in bytes. `MemoryLimit(0)` means
+/// that there is no memory limit set.
+pub struct MemoryLimit(pub u32);
+
+impl MemoryLimit {
+    /// Enforce no memory limit.
+    ///
+    /// If you intend to process images from unknown origins this is a potentially dangerous
+    /// constant to use, as your program could be vulnerable to decompression bombs. That is,
+    /// malicious images crafted specifically to require an enormous amount of memory to process
+    /// while having a disproportionately small file size.
+    ///
+    /// The risks for modern machines are a bit smaller as the dimensions of each frame can not
+    /// exceed `u32::MAX` (~4Gb) but this is still a significant amount of memory.
+    pub const NONE: MemoryLimit = MemoryLimit(0);
+
+    fn buffer_size(&self, color: ColorOutput, width: u16, height: u16) -> Option<usize> {
+        let pixels = u32::from(width) * u32::from(height);
+
+        let bytes_per_pixel = match color {
+            ColorOutput::Indexed => 1,
+            ColorOutput::RGBA => 4,
+        };
+
+        if self.0 > 0 && pixels > self.0 / bytes_per_pixel {
+            None
+        } else {
+            Some(pixels as usize * bytes_per_pixel as usize)
+        }
+    }
+}
+
+/// Options for opening a GIF decoder.
+#[derive(Clone, Debug)]
+pub struct DecodeOptions {
+    memory_limit: MemoryLimit,
+    color_output: ColorOutput,
+    check_frame_consistency: bool,
+    check_for_end_code: bool,
+    allow_unknown_blocks: bool,
+}
+
+impl DecodeOptions {
+    /// Creates a new decoder builder
+    pub fn new() -> DecodeOptions {
+        DecodeOptions {
+            memory_limit: MemoryLimit(50_000_000), // 50 MB
+            color_output: ColorOutput::Indexed,
+            check_frame_consistency: false,
+            check_for_end_code: false,
+            allow_unknown_blocks: false,
+        }
+    }
+
+    /// Configure how color data is decoded.
+    pub fn set_color_output(&mut self, color: ColorOutput) {
+        self.color_output = color;
+    }
+
+    /// Configure a memory limit for decoding.
+    pub fn set_memory_limit(&mut self, limit: MemoryLimit) {
+        self.memory_limit = limit;
+    }
+
+    /// Configure if frames must be within the screen descriptor.
+    ///
+    /// The default is `false`.
+    ///
+    /// When turned on, all frame descriptors being read must fit within the screen descriptor or
+    /// otherwise an error is returned and the stream left in an unspecified state.
+    ///
+    /// When turned off, frames may be arbitrarily larger or offset in relation to the screen. Many
+    /// other decoder libraries handle this in highly divergent ways. This moves all checks to the
+    /// caller, for example to emulate a specific style.
+    pub fn check_frame_consistency(&mut self, check: bool) {
+        self.check_frame_consistency = check;
+    }
+
+    /// Configure if LZW encoded blocks must end with a marker end code.
+    ///
+    /// The default is `false`.
+    ///
+    /// When turned on, all image data blocks—which are LZW encoded—must contain a special bit
+    /// sequence signalling the end of the data. LZW processing terminates when this code is
+    /// encountered. The specification states that it must be the last code output by the encoder
+    /// for an image.
+    ///
+    /// When turned off then image data blocks can simply end. Note that this might silently ignore
+    /// some bits of the last or second to last byte.
+    pub fn check_lzw_end_code(&mut self, check: bool) {
+        self.check_for_end_code = check;
+    }
+
+    /// Configure if unknown blocks are allowed to be decoded.
+    ///
+    /// The default is `false`.
+    ///
+    /// When turned on, the decoder will allow unknown blocks to be in the
+    /// `BlockStart` position.
+    ///
+    /// When turned off, decoded block starts must mark an `Image`, `Extension`,
+    /// or `Trailer` block. Otherwise, the decoded image will return an error.
+    /// If an unknown block error is returned from decoding, enabling this
+    /// setting may allow for a further state of decoding on the next attempt.
+    pub fn allow_unknown_blocks(&mut self, check: bool) {
+        self.allow_unknown_blocks = check;
+    }
+
+    /// Reads the logical screen descriptor including the global color palette
+    ///
+    /// Returns a `Decoder`. All decoder configuration has to be done beforehand.
+    pub fn read_info<R: Read>(self, r: R) -> Result<Decoder<R>, DecodingError> {
+        Decoder::with_no_init(r, StreamingDecoder::with_options(&self), self).init()
+    }
+}
+
+struct ReadDecoder<R: Read> {
+    reader: io::BufReader<R>,
+    decoder: StreamingDecoder,
+    at_eof: bool
+}
+
+impl<R: Read> ReadDecoder<R> {
+    fn decode_next(&mut self) -> Result<Option<Decoded>, DecodingError> {
+        while !self.at_eof {
+            let (consumed, result) = {
+                let buf = self.reader.fill_buf()?;
+                if buf.len() == 0 {
+                    return Err(DecodingError::format(
+                        "unexpected EOF"
+                    ))
+                }
+                self.decoder.update(buf)?
+            };
+            self.reader.consume(consumed);
+            match result {
+                Decoded::Nothing => (),
+                Decoded::BlockStart(Block::Trailer) => {
+                    self.at_eof = true
+                },
+                result => return Ok(unsafe{
+                    // FIXME: #6393
+                    Some(mem::transmute::<Decoded, Decoded>(result))
+                }),
+            }
+        }
+        Ok(None)
+    }
+}
+
+#[allow(dead_code)]
+/// GIF decoder
+pub struct Decoder<R: Read> {
+    decoder: ReadDecoder<R>,
+    color_output: ColorOutput,
+    memory_limit: MemoryLimit,
+    bg_color: Option<u8>,
+    global_palette: Option<Vec<u8>>,
+    current_frame: Frame<'static>,
+    buffer: Vec<u8>,
+}
+
+impl<R> Decoder<R> where R: Read {
+    /// Create a new decoder with default options.
+    pub fn new(reader: R) -> Result<Self, DecodingError> {
+        DecodeOptions::new().read_info(reader)
+    }
+
+    /// Return a builder that allows configuring limits etc.
+    pub fn build() -> DecodeOptions {
+        DecodeOptions::new()
+    }
+
+    fn with_no_init(reader: R, decoder: StreamingDecoder, options: DecodeOptions) -> Decoder<R> {
+        Decoder {
+            decoder: ReadDecoder {
+                reader: io::BufReader::new(reader),
+                decoder,
+                at_eof: false
+            },
+            bg_color: None,
+            global_palette: None,
+            buffer: Vec::with_capacity(32),
+            color_output: options.color_output,
+            memory_limit: options.memory_limit,
+            current_frame: Frame::default(),
+        }
+    }
+    
+    fn init(mut self) -> Result<Self, DecodingError> {
+        loop {
+            match self.decoder.decode_next()? {
+                Some(Decoded::BackgroundColor(bg_color)) => {
+                    self.bg_color = Some(bg_color)
+                }
+                Some(Decoded::GlobalPalette(palette)) => {
+                    self.global_palette = if palette.len() > 0 {
+                        Some(palette)
+                    } else {
+                        None
+                    };
+                    break
+                },
+                Some(_) => {
+                    // Unreachable since this loop exists after the global
+                    // palette has been read.
+                    unreachable!()
+                },
+                None => return Err(DecodingError::format(
+                    "file does not contain any image data"
+                ))
+            }
+        }
+        // If the background color is invalid, ignore it
+        if let Some(ref palette) = self.global_palette {
+            if self.bg_color.unwrap_or(0) as usize >= (palette.len() / PLTE_CHANNELS) {
+                self.bg_color = None;
+            }
+        }
+        Ok(self)
+    }
+    
+    /// Returns the next frame info
+    pub fn next_frame_info(&mut self) -> Result<Option<&Frame<'static>>, DecodingError> {
+        if !self.buffer.is_empty() {
+            // FIXME: Warn about discarding data?
+            self.buffer.clear();
+        }
+
+        loop {
+            match self.decoder.decode_next()? {
+                Some(Decoded::Frame(frame)) => {
+                    self.current_frame = frame.clone();
+                    if frame.palette.is_none() && self.global_palette.is_none() {
+                        return Err(DecodingError::format(
+                            "no color table available for current frame"
+                        ))
+                    }
+                    break
+                },
+                Some(_) => (),
+                None => return Ok(None)
+                
+            }
+        }
+        Ok(Some(&self.current_frame))
+    }
+
+    /// Reads the next frame from the image.
+    ///
+    /// Do not call `Self::next_frame_info` beforehand.
+    /// Deinterlaces the result.
+    pub fn read_next_frame(&mut self) -> Result<Option<&Frame<'static>>, DecodingError> {
+        if let Some(frame) = self.next_frame_info()? {
+            let (width, height) = (frame.width, frame.height);
+            let pixel_bytes = self.memory_limit
+                .buffer_size(self.color_output, width, height)
+                .ok_or_else(|| {
+                    DecodingError::format("image is too large to decode")
+                })?;
+
+            debug_assert_eq!(
+                pixel_bytes, self.buffer_size(),
+                "Checked computation diverges from required buffer size"
+            );
+
+            let mut vec = vec![0; pixel_bytes];
+            self.read_into_buffer(&mut vec)?;
+            self.current_frame.buffer = Cow::Owned(vec);
+            self.current_frame.interlaced = false;
+            Ok(Some(&self.current_frame))
+        } else {
+            Ok(None)
+        }
+    }
+
+    /// Reads the data of the current frame into a pre-allocated buffer.
+    ///
+    /// `Self::next_frame_info` needs to be called beforehand.
+    /// The length of `buf` must be at least `Self::buffer_size`.
+    /// Deinterlaces the result.
+    pub fn read_into_buffer(&mut self, buf: &mut [u8]) -> Result<(), DecodingError> {
+        if self.current_frame.interlaced {
+            let width = self.line_length();
+            let height = self.current_frame.height as usize;
+            for row in (InterlaceIterator { len: height, next: 0, pass: 0 }) {
+                if !self.fill_buffer(&mut buf[row*width..][..width])? {
+                    return Err(DecodingError::format("image truncated"))
+                }
+            }
+        } else {
+            let buf = &mut buf[..self.buffer_size()];
+            if !self.fill_buffer(buf)? {
+                return Err(DecodingError::format("image truncated"))
+            }
+        };
+        Ok(())
+    }
+
+    /// Reads data of the current frame into a pre-allocated buffer until the buffer has been
+    /// filled completely.
+    ///
+    /// `Self::next_frame_info` needs to be called beforehand. Returns `true` if the supplied
+    /// buffer could be filled completely. Should not be called after `false` had been returned.
+    pub fn fill_buffer(&mut self, mut buf: &mut [u8]) -> Result<bool, DecodingError> {
+        use self::ColorOutput::*;
+        const PLTE_CHANNELS: usize = 3;
+        macro_rules! handle_data(
+            ($data:expr) => {
+                match self.color_output {
+                    RGBA => {
+                        let transparent = self.current_frame.transparent;
+                        let palette: &[u8] = match self.current_frame.palette {
+                            Some(ref table) => &*table,
+                            None => &*self.global_palette.as_ref().unwrap(),
+                        };
+                        let len = cmp::min(buf.len()/N_CHANNELS, $data.len());
+                        for (rgba, &idx) in buf[..len*N_CHANNELS].chunks_mut(N_CHANNELS).zip($data.iter()) {
+                            let plte_offset = PLTE_CHANNELS * idx as usize;
+                            if palette.len() >= plte_offset + PLTE_CHANNELS {
+                                let colors = &palette[plte_offset..];
+                                rgba[0] = colors[0];
+                                rgba[1] = colors[1];
+                                rgba[2] = colors[2];
+                                rgba[3] = if let Some(t) = transparent {
+                                    if t == idx { 0x00 } else { 0xFF }
+                                } else {
+                                    0xFF
+                                }
+                            }
+                        }
+                        (len, N_CHANNELS)
+                    },
+                    Indexed => {
+                        let len = cmp::min(buf.len(), $data.len());
+                        buf[..len].copy_from_slice(&$data[..len]);
+                        (len, 1)
+                    }
+                }
+            }
+        );
+        let buf_len = self.buffer.len();
+        if buf_len > 0 {
+            let (len, channels) = handle_data!(&self.buffer);
+            let _ = self.buffer.drain(..len);
+            buf = &mut buf[len*channels..];
+            if buf.len() == 0 {
+                return Ok(true)
+            }
+        }
+        loop {
+            match self.decoder.decode_next()? {
+                Some(Decoded::Data(data)) => {
+                    let (len, channels) = handle_data!(data);
+                    buf = &mut buf[len*channels..]; // shorten buf
+                    if buf.len() > 0 {
+                        continue
+                    } else if len < data.len() {
+                        self.buffer.extend_from_slice(&data[len..]);
+                    }
+                    return Ok(true)
+                },
+                Some(_) => return Ok(false), // make sure that no important result is missed
+                None => return Ok(false)
+                
+            }
+        }
+    }
+    
+    /// Output buffer size
+    pub fn buffer_size(&self) -> usize {
+        self.line_length() * self.current_frame.height as usize
+    }
+    
+    /// Line length of the current frame
+    pub fn line_length(&self) -> usize {
+        use self::ColorOutput::*;
+        match self.color_output {
+            RGBA => self.current_frame.width as usize * N_CHANNELS,
+            Indexed => self.current_frame.width as usize
+        }
+    }
+    
+    /// Returns the color palette relevant for the current (next) frame
+    pub fn palette(&self) -> Result<&[u8], DecodingError> {
+        // TODO prevent planic
+        Ok(match self.current_frame.palette {
+            Some(ref table) => &*table,
+            None => &*self.global_palette.as_ref().ok_or(DecodingError::format(
+                "no color table available for current frame"
+            ))?,
+        })
+    }
+    
+    /// The global color palette
+    pub fn global_palette(&self) -> Option<&[u8]> {
+        self.global_palette.as_ref().map(|v| &**v)
+    }
+
+    /// Width of the image
+    pub fn width(&self) -> u16 {
+        self.decoder.decoder.width()
+    }
+
+    /// Height of the image
+    pub fn height(&self) -> u16 {
+        self.decoder.decoder.height()
+    }
+
+    /// Index of the background color in the global palette
+    pub fn bg_color(&self) -> Option<usize> {
+        self.bg_color.map(|v| v as usize)
+    }
+}
+
+struct InterlaceIterator {
+    len: usize,
+    next: usize,
+    pass: usize
+}
+
+impl iter::Iterator for InterlaceIterator {
+    type Item = usize;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        if self.len == 0 || self.pass > 3 {
+            return None
+        }
+        let mut next = self.next + [8, 8, 4, 2][self.pass];
+        while next >= self.len {
+            next = [4, 2, 1, 0][self.pass];
+            self.pass += 1;
+        }
+        mem::swap(&mut next, &mut self.next);
+        Some(next)
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use std::fs::File;
+
+    use super::{Decoder, InterlaceIterator};
+    
+    #[test]
+    fn test_simple_indexed() {
+        let mut decoder = Decoder::new(File::open("tests/samples/sample_1.gif").unwrap()).unwrap();
+        let frame = decoder.read_next_frame().unwrap().unwrap();
+        assert_eq!(&*frame.buffer, &[
+            1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
+            1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
+            1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
+            1, 1, 1, 0, 0, 0, 0, 2, 2, 2,
+            1, 1, 1, 0, 0, 0, 0, 2, 2, 2,
+            2, 2, 2, 0, 0, 0, 0, 1, 1, 1,
+            2, 2, 2, 0, 0, 0, 0, 1, 1, 1,
+            2, 2, 2, 2, 2, 1, 1, 1, 1, 1,
+            2, 2, 2, 2, 2, 1, 1, 1, 1, 1,
+            2, 2, 2, 2, 2, 1, 1, 1, 1, 1
+        ][..])
+    }
+
+    #[test]
+    fn test_interlace_iterator() {
+        for &(len, expect) in &[
+            (0, &[][..]),
+            (1, &[0][..]),
+            (2, &[0, 1][..]),
+            (3, &[0, 2, 1][..]),
+            (4, &[0, 2, 1, 3][..]),
+            (5, &[0, 4, 2, 1, 3][..]),
+            (6, &[0, 4, 2, 1, 3, 5][..]),
+            (7, &[0, 4, 2, 6, 1, 3, 5][..]),
+            (8, &[0, 4, 2, 6, 1, 3, 5, 7][..]),
+            (9, &[0, 8, 4, 2, 6, 1, 3, 5, 7][..]),
+            (10, &[0, 8, 4, 2, 6, 1, 3, 5, 7, 9][..]),
+            (11, &[0, 8, 4, 2, 6, 10, 1, 3, 5, 7, 9][..]),
+            (12, &[0, 8, 4, 2, 6, 10, 1, 3, 5, 7, 9, 11][..]),
+            (13, &[0, 8, 4, 12, 2, 6, 10, 1, 3, 5, 7, 9, 11][..]),
+            (14, &[0, 8, 4, 12, 2, 6, 10, 1, 3, 5, 7, 9, 11, 13][..]),
+            (15, &[0, 8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13][..]),
+            (16, &[0, 8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15][..]),
+            (17, &[0, 8, 16, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15][..]),
+        ] {
+            let iter = InterlaceIterator { len: len, next: 0, pass: 0 };
+            let lines = iter.collect::<Vec<_>>();
+            assert_eq!(lines, expect);
+        }
+    }
+}
-- 
cgit v1.2.3