aboutsummaryrefslogtreecommitdiff
path: root/vendor/gif/src
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gif/src')
-rw-r--r--vendor/gif/src/common.rs346
-rw-r--r--vendor/gif/src/encoder.rs434
-rw-r--r--vendor/gif/src/lib.rs154
-rw-r--r--vendor/gif/src/reader/decoder.rs724
-rw-r--r--vendor/gif/src/reader/mod.rs522
-rw-r--r--vendor/gif/src/traits.rs49
6 files changed, 0 insertions, 2229 deletions
diff --git a/vendor/gif/src/common.rs b/vendor/gif/src/common.rs
deleted file mode 100644
index 20ba99b..0000000
--- a/vendor/gif/src/common.rs
+++ /dev/null
@@ -1,346 +0,0 @@
-use std::borrow::Cow;
-use std::collections::HashMap;
-use std::collections::HashSet;
-
-/// Disposal method
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
-#[repr(u8)]
-pub enum DisposalMethod {
- /// StreamingDecoder is not required to take any action.
- Any = 0,
- /// Do not dispose.
- Keep = 1,
- /// Restore to background color.
- Background = 2,
- /// Restore to previous.
- Previous = 3,
-}
-
-impl DisposalMethod {
- /// Converts `u8` to `Option<Self>`
- pub fn from_u8(n: u8) -> Option<DisposalMethod> {
- match n {
- 0 => Some(DisposalMethod::Any),
- 1 => Some(DisposalMethod::Keep),
- 2 => Some(DisposalMethod::Background),
- 3 => Some(DisposalMethod::Previous),
- _ => None
- }
- }
-}
-
-/// Known GIF block labels.
-///
-/// Note that the block uniquely specifies the layout of bytes that follow and how they are
-/// framed. For example, the header always has a fixed length but is followed by a variable amount
-/// of additional data. An image descriptor may be followed by a local color table depending on
-/// information read in it. Therefore, it doesn't make sense to continue parsing after encountering
-/// an unknown block as the semantics of following bytes are unclear.
-///
-/// The extension block provides a common framing for an arbitrary amount of application specific
-/// data which may be ignored.
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
-#[repr(u8)]
-pub enum Block {
- /// Image block.
- Image = 0x2C,
- /// Extension block.
- Extension = 0x21,
- /// Image trailer.
- Trailer = 0x3B,
-}
-
-impl Block {
- /// Converts `u8` to `Option<Self>`
- pub fn from_u8(n: u8) -> Option<Block> {
- match n {
- 0x2C => Some(Block::Image),
- 0x21 => Some(Block::Extension),
- 0x3B => Some(Block::Trailer),
- _ => None
- }
- }
-}
-
-/// A newtype wrapper around an arbitrary extension ID.
-///
-/// An extension is some amount of byte data organized in sub-blocks so that one can skip over it
-/// without knowing the semantics. Though technically you likely want to use a `Application`
-/// extension, the library tries to stay flexible here.
-///
-/// This allows us to customize the set of impls compared to a raw `u8`. It also clarifies the
-/// intent and gives some inherent methods for interoperability with known extension types.
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
-pub struct AnyExtension(pub u8);
-
-/// Known GIF extension labels.
-///
-/// These are extensions which may be interpreted by the library and to which a specification with
-/// the internal data layout is known.
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
-#[repr(u8)]
-pub enum Extension {
- /// Plain Text extension.
- ///
- /// This instructs the decoder to render a text as characters in a grid of cells, in a
- /// mono-spaced font of its choosing. This is seldom actually implemented and ignored by
- /// ImageMagick. The color is always taken from the global table which further complicates any
- /// use. No real information on the frame sequencing of this block is available in the
- /// standard.
- Text = 0x01,
- /// Control extension.
- Control = 0xF9,
- /// Comment extension.
- Comment = 0xFE,
- /// Application extension.
- ///
- /// See [ImageMagick] for an idea of commonly recognized extensions.
- ///
- /// [ImageMagick]: https://github.com/ImageMagick/ImageMagick/blob/b0b58c6303195928060f55f9c3ca8233ab7f7733/coders/gif.c#L1128
- Application = 0xFF,
-}
-
-impl AnyExtension {
- /// Decode the label as a known extension.
- pub fn into_known(self) -> Option<Extension> {
- Extension::from_u8(self.0)
- }
-}
-
-impl From<Extension> for AnyExtension {
- fn from(ext: Extension) -> Self {
- AnyExtension(ext as u8)
- }
-}
-
-impl Extension {
- /// Converts `u8` to a `Extension` if it is known.
- pub fn from_u8(n: u8) -> Option<Extension> {
- match n {
- 0x01 => Some(Extension::Text),
- 0xF9 => Some(Extension::Control),
- 0xFE => Some(Extension::Comment),
- 0xFF => Some(Extension::Application),
- _ => None
- }
- }
-}
-
-/// A GIF frame
-#[derive(Debug, Clone)]
-pub struct Frame<'a> {
- /// Frame delay in units of 10 ms.
- pub delay: u16,
- /// Disposal method.
- pub dispose: DisposalMethod,
- /// Transparent index (if available).
- pub transparent: Option<u8>,
- /// True if the frame needs user input to be displayed.
- pub needs_user_input: bool,
- /// Offset from the top border of the canvas.
- pub top: u16,
- /// Offset from the left border of the canvas.
- pub left: u16,
- /// Width of the frame.
- pub width: u16,
- /// Height of the frame.
- pub height: u16,
- /// True if the image is interlaced.
- pub interlaced: bool,
- /// Frame local color palette if available.
- pub palette: Option<Vec<u8>>,
- /// Buffer containing the image data.
- /// Only indices unless configured differently.
- pub buffer: Cow<'a, [u8]>
-}
-
-impl<'a> Default for Frame<'a> {
- fn default() -> Frame<'a> {
- Frame {
- delay: 0,
- dispose: DisposalMethod::Keep,
- transparent: None,
- needs_user_input: false,
- top: 0,
- left: 0,
- width: 0,
- height: 0,
- interlaced: false,
- palette: None,
- buffer: Cow::Borrowed(&[])
- }
- }
-}
-
-impl Frame<'static> {
- /// Creates a frame from pixels in RGBA format.
- ///
- /// This is a lossy method. The `gif` format does not support arbitrary alpha but only a 1-bit
- /// transparency mask per pixel. Any non-zero alpha value will be interpreted as a fully opaque
- /// pixel. Additionally, only 256 colors can appear in a single frame. The palette will be
- /// reduced by the NeuQuant algorithm if necessary. Different frames have independent palettes.
- ///
- /// *Note: This method is not optimized for speed.*
- ///
- /// # Panics:
- /// * If the length of pixels does not equal `width * height * 4`.
- #[cfg(feature = "color_quant")]
- pub fn from_rgba(width: u16, height: u16, pixels: &mut [u8]) -> Frame<'static> {
- Frame::from_rgba_speed(width, height, pixels, 1)
- }
-
- /// Creates a frame from pixels in RGBA format.
- ///
- /// `speed` is a value in the range [1, 30].
- /// The higher the value the faster it runs at the cost of image quality.
- /// A `speed` of 10 is a good compromise between speed and quality.
- ///
- /// This is a lossy method. The `gif` format does not support arbitrary alpha but only a 1-bit
- /// transparency mask per pixel. Any non-zero alpha value will be interpreted as a fully opaque
- /// pixel. Additionally, only 256 colors can appear in a single frame. The palette will be
- /// reduced by the NeuQuant algorithm if necessary. Different frames have independent palettes.
- ///
- /// # Panics:
- /// * If the length of pixels does not equal `width * height * 4`.
- /// * If `speed < 1` or `speed > 30`
- #[cfg(feature = "color_quant")]
- pub fn from_rgba_speed(width: u16, height: u16, pixels: &mut [u8], speed: i32) -> Frame<'static> {
- assert_eq!(width as usize * height as usize * 4, pixels.len(), "Too much or too little pixel data for the given width and height to create a GIF Frame");
- assert!(speed >= 1 && speed <= 30, "speed needs to be in the range [1, 30]");
- let mut transparent = None;
- for pix in pixels.chunks_exact_mut(4) {
- if pix[3] != 0 {
- pix[3] = 0xFF;
- } else {
- transparent = Some([pix[0], pix[1], pix[2], pix[3]])
- }
- }
-
- // Attempt to build a palette of all colors. If we go over 256 colors,
- // switch to the NeuQuant algorithm.
- let mut colors: HashSet<(u8, u8, u8, u8)> = HashSet::new();
- for pixel in pixels.chunks_exact(4) {
- if colors.insert((pixel[0], pixel[1], pixel[2], pixel[3])) && colors.len() > 256 {
- // > 256 colours, let's use NeuQuant.
- let nq = color_quant::NeuQuant::new(speed, 256, pixels);
-
- return Frame {
- width,
- height,
- buffer: Cow::Owned(pixels.chunks_exact(4).map(|pix| nq.index_of(pix) as u8).collect()),
- palette: Some(nq.color_map_rgb()),
- transparent: transparent.map(|t| nq.index_of(&t) as u8),
- ..Frame::default()
- };
- }
- }
-
- // Palette size <= 256 elements, we can build an exact palette.
- let mut colors_vec: Vec<(u8, u8, u8, u8)> = colors.into_iter().collect();
- colors_vec.sort();
- let palette = colors_vec.iter().flat_map(|&(r, g, b, _a)| [r, g, b]).collect();
- let colors_lookup: HashMap<(u8, u8, u8, u8), u8> = colors_vec.into_iter().zip(0..=255).collect();
-
- let index_of = | pixel: &[u8] |
- *colors_lookup.get(&(pixel[0], pixel[1], pixel[2], pixel[3])).unwrap();
-
- return Frame {
- width,
- height,
- buffer: Cow::Owned(pixels.chunks_exact(4).map(|pix| index_of(pix)).collect()),
- palette: Some(palette),
- transparent: transparent.map(|t| index_of(&t)),
- ..Frame::default()
- }
- }
-
- /// Creates a frame from a palette and indexed pixels.
- ///
- /// # Panics:
- /// * If the length of pixels does not equal `width * height`.
- /// * If the length of palette > `256 * 3`.
- pub fn from_palette_pixels(width: u16, height: u16, pixels: &[u8], palette: &[u8], transparent: Option<u8>) -> Frame<'static> {
- assert_eq!(width as usize * height as usize, pixels.len(), "Too many or too little pixels for the given width and height to create a GIF Frame");
- assert!(palette.len() <= 256*3, "Too many palette values to create a GIF Frame");
-
- Frame {
- width,
- height,
- buffer: Cow::Owned(pixels.to_vec()),
- palette: Some(palette.to_vec()),
- transparent,
- ..Frame::default()
- }
- }
-
- /// Creates a frame from indexed pixels in the global palette.
- ///
- /// # Panics:
- /// * If the length of pixels does not equal `width * height`.
- pub fn from_indexed_pixels(width: u16, height: u16, pixels: &[u8], transparent: Option<u8>) -> Frame<'static> {
- assert_eq!(width as usize * height as usize, pixels.len(), "Too many or too little pixels for the given width and height to create a GIF Frame");
-
- Frame {
- width,
- height,
- buffer: Cow::Owned(pixels.to_vec()),
- palette: None,
- transparent,
- ..Frame::default()
- }
- }
-
- /// Creates a frame from pixels in RGB format.
- ///
- /// This is a lossy method. In the `gif` format only 256 colors can appear in a single frame.
- /// The palette will be reduced by the NeuQuant algorithm if necessary. Different frames have
- /// independent palettes.
- ///
- /// *Note: This method is not optimized for speed.*
- ///
- /// # Panics:
- /// * If the length of pixels does not equal `width * height * 3`.
- #[cfg(feature = "color_quant")]
- pub fn from_rgb(width: u16, height: u16, pixels: &[u8]) -> Frame<'static> {
- Frame::from_rgb_speed(width, height, pixels, 1)
- }
-
- /// Creates a frame from pixels in RGB format.
- ///
- /// `speed` is a value in the range [1, 30].
- ///
- /// This is a lossy method. In the `gif` format only 256 colors can appear in a single frame.
- /// The palette will be reduced by the NeuQuant algorithm if necessary. Different frames have
- /// independent palettes.
- ///
- /// The higher the value the faster it runs at the cost of image quality.
- /// A `speed` of 10 is a good compromise between speed and quality.
- ///
- /// # Panics:
- /// * If the length of pixels does not equal `width * height * 3`.
- /// * If `speed < 1` or `speed > 30`
- #[cfg(feature = "color_quant")]
- pub fn from_rgb_speed(width: u16, height: u16, pixels: &[u8], speed: i32) -> Frame<'static> {
- assert_eq!(width as usize * height as usize * 3, pixels.len(), "Too much or too little pixel data for the given width and height to create a GIF Frame");
- let mut vec: Vec<u8> = Vec::with_capacity(pixels.len() + width as usize * height as usize);
- for v in pixels.chunks_exact(3) {
- vec.extend_from_slice(&[v[0], v[1], v[2], 0xFF])
- }
- Frame::from_rgba_speed(width, height, &mut vec, speed)
- }
-
- pub(crate) fn required_bytes(&self) -> usize {
- usize::from(self.width) * usize::from(self.height)
- }
-}
-
-#[test]
-#[cfg(feature = "color_quant")]
-// Creating the `colors_lookup` hashmap in Frame::from_rgba_speed panics due to
-// overflow while bypassing NeuQuant and zipping a RangeFrom with 256 colors.
-// Changing .zip(0_u8..) to .zip(0_u8..=255) fixes this issue.
-fn rgba_speed_avoid_panic_256_colors() {
- let side = 16;
- let pixel_data: Vec<u8> = (0..=255).map(|a| vec![a, a, a]).flatten().collect();
- Frame::from_rgb(side, side, &pixel_data);
-}
diff --git a/vendor/gif/src/encoder.rs b/vendor/gif/src/encoder.rs
deleted file mode 100644
index 693a8cb..0000000
--- a/vendor/gif/src/encoder.rs
+++ /dev/null
@@ -1,434 +0,0 @@
-//! # Minimal gif encoder
-use std::io;
-use std::io::prelude::*;
-use std::fmt;
-use std::error;
-use std::borrow::Cow;
-
-use weezl::{BitOrder, encode::Encoder as LzwEncoder};
-
-use crate::traits::{WriteBytesExt};
-use crate::common::{AnyExtension, Block, DisposalMethod, Extension, Frame};
-
-#[derive(Debug)]
-enum FormatErrorKind {
- /// The image has too many colors.
- TooManyColors,
- /// The image has no color palette which is required.
- MissingColorPalette,
-}
-
-/// The image has incorrect properties, making it impossible to encode as a gif.
-#[derive(Debug)]
-pub struct EncodingFormatError {
- kind: FormatErrorKind
-}
-
-impl error::Error for EncodingFormatError {}
-impl fmt::Display for EncodingFormatError {
- fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self.kind {
- FormatErrorKind::TooManyColors => write!(fmt, "the image has too many colors"),
- FormatErrorKind::MissingColorPalette => write!(fmt, "the GIF format requires a color palette but none was given")
- }
- }
-}
-
-impl From<FormatErrorKind> for EncodingFormatError {
- fn from(kind: FormatErrorKind) -> Self {
- EncodingFormatError { kind }
- }
-}
-
-#[derive(Debug)]
-/// Encoding error.
-pub enum EncodingError {
- /// Returned if the to image is not encodable as a gif.
- Format(EncodingFormatError),
- /// Wraps `std::io::Error`.
- Io(io::Error),
-}
-
-impl fmt::Display for EncodingError {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- match self {
- EncodingError::Io(err) => err.fmt(fmt),
- EncodingError::Format(err) => err.fmt(fmt),
- }
- }
-}
-
-impl error::Error for EncodingError {
- fn source(&self) -> Option<&(dyn error::Error + 'static)> {
- match self {
- EncodingError::Io(err) => Some(err),
- EncodingError::Format(err) => Some(err),
- }
- }
-}
-
-impl From<io::Error> for EncodingError {
- fn from(err: io::Error) -> Self {
- EncodingError::Io(err)
- }
-}
-
-impl From<EncodingFormatError> for EncodingError {
- fn from(err: EncodingFormatError) -> Self {
- EncodingError::Format(err)
- }
-}
-
-impl From<FormatErrorKind> for EncodingError {
- fn from(kind: FormatErrorKind) -> Self {
- EncodingError::Format(kind.into())
- }
-}
-
-
-/// Number of repetitions
-#[derive(Copy, Clone, Debug)]
-pub enum Repeat {
- /// Finite number of repetitions
- Finite(u16),
- /// Infinite number of repetitions
- Infinite
-}
-
-/// Extension data.
-pub enum ExtensionData {
- /// Control extension. Use `ExtensionData::new_control_ext` to construct.
- Control {
- /// Flags.
- flags: u8,
- /// Frame delay.
- delay: u16,
- /// Transparent index.
- trns: u8
- },
- /// Sets the number of repetitions
- Repetitions(Repeat)
-}
-
-impl ExtensionData {
- /// Constructor for control extension data.
- ///
- /// `delay` is given in units of 10 ms.
- pub fn new_control_ext(delay: u16, dispose: DisposalMethod,
- needs_user_input: bool, trns: Option<u8>) -> ExtensionData {
- let mut flags = 0;
- let trns = match trns {
- Some(trns) => {
- flags |= 1;
- trns as u8
- },
- None => 0
- };
- flags |= (needs_user_input as u8) << 1;
- flags |= (dispose as u8) << 2;
- ExtensionData::Control {
- flags: flags,
- delay: delay,
- trns: trns
- }
- }
-}
-
-impl<W: Write> Encoder<W> {
- /// Creates a new encoder.
- ///
- /// `global_palette` gives the global color palette in the format `[r, g, b, ...]`,
- /// if no global palette shall be used an empty slice may be supplied.
- pub fn new(w: W, width: u16, height: u16, global_palette: &[u8]) -> Result<Self, EncodingError> {
- let buffer_size = (width as usize) * (height as usize);
- Encoder {
- w: Some(w),
- global_palette: false,
- width: width,
- height: height,
- buffer: Vec::with_capacity(buffer_size)
- }.write_global_palette(global_palette)
- }
-
- /// Write an extension block that signals a repeat behaviour.
- pub fn set_repeat(&mut self, repeat: Repeat) -> Result<(), EncodingError> {
- self.write_extension(ExtensionData::Repetitions(repeat))
- }
-
- /// Writes the global color palette.
- pub fn write_global_palette(mut self, palette: &[u8]) -> Result<Self, EncodingError> {
- self.global_palette = true;
- let mut flags = 0;
- flags |= 0b1000_0000;
- let num_colors = palette.len() / 3;
- if num_colors > 256 {
- return Err(EncodingError::from(FormatErrorKind::TooManyColors));
- }
- // Size of global color table.
- flags |= flag_size(num_colors);
- // Color resolution .. FIXME. This is mostly ignored (by ImageMagick at least) but hey, we
- // should use some sensible value here or even allow configuring it?
- flags |= flag_size(num_colors) << 4; // wtf flag
- self.write_screen_desc(flags)?;
- self.write_color_table(palette)?;
- Ok(self)
- }
-
- /// Writes a frame to the image.
- ///
- /// Note: This function also writes a control extension if necessary.
- pub fn write_frame(&mut self, frame: &Frame) -> Result<(), EncodingError> {
- self.write_frame_header(frame)?;
- self.write_image_block(&frame.buffer)
- }
-
- fn write_frame_header(&mut self, frame: &Frame) -> Result<(), EncodingError> {
- // TODO commented off to pass test in lib.rs
- //if frame.delay > 0 || frame.transparent.is_some() {
- self.write_extension(ExtensionData::new_control_ext(
- frame.delay,
- frame.dispose,
- frame.needs_user_input,
- frame.transparent
-
- ))?;
- //}
- let writer = self.w.as_mut().unwrap();
- writer.write_le(Block::Image as u8)?;
- writer.write_le(frame.left)?;
- writer.write_le(frame.top)?;
- writer.write_le(frame.width)?;
- writer.write_le(frame.height)?;
- let mut flags = 0;
- if frame.interlaced {
- flags |= 0b0100_0000;
- }
- match frame.palette {
- Some(ref palette) => {
- flags |= 0b1000_0000;
- let num_colors = palette.len() / 3;
- if num_colors > 256 {
- return Err(EncodingError::from(FormatErrorKind::TooManyColors));
- }
- flags |= flag_size(num_colors);
- writer.write_le(flags)?;
- self.write_color_table(palette)
- },
- None => if !self.global_palette {
- Err(EncodingError::from(FormatErrorKind::MissingColorPalette))
- } else {
- writer.write_le(flags).map_err(Into::into)
- }
- }
- }
-
- fn write_image_block(&mut self, data: &[u8]) -> Result<(), EncodingError> {
- self.buffer.clear();
- lzw_encode(data, &mut self.buffer);
-
- let writer = self.w.as_mut().unwrap();
- Self::write_encoded_image_block(writer, &self.buffer)
- }
-
- fn write_encoded_image_block(writer: &mut W, data_with_min_code_size: &[u8]) -> Result<(), EncodingError> {
- let (&min_code_size, data) = data_with_min_code_size.split_first().unwrap_or((&2, &[]));
- writer.write_le(min_code_size)?;
-
- // Write blocks. `chunks_exact` seems to be slightly faster
- // than `chunks` according to both Rust docs and benchmark results.
- let mut iter = data.chunks_exact(0xFF);
- while let Some(full_block) = iter.next() {
- writer.write_le(0xFFu8)?;
- writer.write_all(full_block)?;
- }
- let last_block = iter.remainder();
- if !last_block.is_empty() {
- writer.write_le(last_block.len() as u8)?;
- writer.write_all(last_block)?;
- }
- writer.write_le(0u8).map_err(Into::into)
- }
-
- fn write_color_table(&mut self, table: &[u8]) -> Result<(), EncodingError> {
- let writer = self.w.as_mut().unwrap();
- let num_colors = table.len() / 3;
- if num_colors > 256 {
- return Err(EncodingError::from(FormatErrorKind::TooManyColors));
- }
- let size = flag_size(num_colors);
- writer.write_all(&table[..num_colors * 3])?;
- // Waste some space as of gif spec
- for _ in 0..((2 << size) - num_colors) {
- writer.write_all(&[0, 0, 0])?
- }
- Ok(())
- }
-
- /// Writes an extension to the image.
- ///
- /// It is normally not necessary to call this method manually.
- pub fn write_extension(&mut self, extension: ExtensionData) -> Result<(), EncodingError> {
- use self::ExtensionData::*;
- // 0 finite repetitions can only be achieved
- // if the corresponting extension is not written
- if let Repetitions(Repeat::Finite(0)) = extension {
- return Ok(())
- }
- let writer = self.w.as_mut().unwrap();
- writer.write_le(Block::Extension as u8)?;
- match extension {
- Control { flags, delay, trns } => {
- writer.write_le(Extension::Control as u8)?;
- writer.write_le(4u8)?;
- writer.write_le(flags)?;
- writer.write_le(delay)?;
- writer.write_le(trns)?;
- }
- Repetitions(repeat) => {
- writer.write_le(Extension::Application as u8)?;
- writer.write_le(11u8)?;
- writer.write_all(b"NETSCAPE2.0")?;
- writer.write_le(3u8)?;
- writer.write_le(1u8)?;
- match repeat {
- Repeat::Finite(no) => writer.write_le(no)?,
- Repeat::Infinite => writer.write_le(0u16)?,
- }
- }
- }
- writer.write_le(0u8).map_err(Into::into)
- }
-
- /// Writes a raw extension to the image.
- ///
- /// This method can be used to write an unsupported extension to the file. `func` is the extension
- /// identifier (e.g. `Extension::Application as u8`). `data` are the extension payload blocks. If any
- /// contained slice has a lenght > 255 it is automatically divided into sub-blocks.
- pub fn write_raw_extension(&mut self, func: AnyExtension, data: &[&[u8]]) -> io::Result<()> {
- let writer = self.w.as_mut().unwrap();
- writer.write_le(Block::Extension as u8)?;
- writer.write_le(func.0)?;
- for block in data {
- for chunk in block.chunks(0xFF) {
- writer.write_le(chunk.len() as u8)?;
- writer.write_all(chunk)?;
- }
- }
- writer.write_le(0u8)
- }
-
- /// Writes a frame to the image, but expects `Frame.buffer` to contain LZW-encoded data
- /// from [`Frame::make_lzw_pre_encoded`].
- ///
- /// Note: This function also writes a control extension if necessary.
- pub fn write_lzw_pre_encoded_frame(&mut self, frame: &Frame) -> Result<(), EncodingError> {
- self.write_frame_header(frame)?;
- let writer = self.w.as_mut().unwrap();
- Self::write_encoded_image_block(writer, &frame.buffer)
- }
-
- /// Writes the logical screen desriptor
- fn write_screen_desc(&mut self, flags: u8) -> io::Result<()> {
- let writer = self.w.as_mut().unwrap();
- writer.write_all(b"GIF89a")?;
- writer.write_le(self.width)?;
- writer.write_le(self.height)?;
- writer.write_le(flags)?; // packed field
- writer.write_le(0u8)?; // bg index
- writer.write_le(0u8) // aspect ratio
- }
-
- /// Gets a reference to the writer instance used by this encoder.
- pub fn get_ref(&self) -> &W {
- self.w.as_ref().unwrap()
- }
-
- /// Gets a mutable reference to the writer instance used by this encoder.
- ///
- /// It is inadvisable to directly write to the underlying writer.
- pub fn get_mut(&mut self) -> &mut W {
- self.w.as_mut().unwrap()
- }
-
- /// Returns writer instance used by this encoder
- pub fn into_inner(mut self) -> io::Result<W> {
- self.write_trailer()?;
- Ok(self.w.take().unwrap())
- }
-
- /// Write the final tailer.
- fn write_trailer(&mut self) -> io::Result<()> {
- self.w.as_mut().unwrap().write_le(Block::Trailer as u8)
- }
-}
-
-/// Encodes the data into the provided buffer.
-///
-/// The first byte is the minimum code size, followed by LZW data.
-fn lzw_encode(data: &[u8], buffer: &mut Vec<u8>) {
- let min_code_size = match flag_size(1 + data.iter().copied().max().unwrap_or(0) as usize) + 1 {
- 1 => 2, // As per gif spec: The minimal code size has to be >= 2
- n => n
- };
- buffer.push(min_code_size);
- let mut enc = LzwEncoder::new(BitOrder::Lsb, min_code_size);
- let len = enc.into_vec(buffer).encode_all(data).consumed_out;
- buffer.truncate(len+1);
-}
-
-impl Frame<'_> {
- /// Replace frame's buffer with a LZW-compressed one for use with [`Encoder::write_lzw_pre_encoded_frame`].
- ///
- /// Frames can be compressed in any order, separately from the `Encoder`, which can be used to compress frames in parallel.
- pub fn make_lzw_pre_encoded(&mut self) {
- let mut buffer = Vec::with_capacity(self.buffer.len() / 2);
- lzw_encode(&self.buffer, &mut buffer);
- self.buffer = Cow::Owned(buffer);
- }
-}
-
-/// GIF encoder.
-pub struct Encoder<W: Write> {
- w: Option<W>,
- global_palette: bool,
- width: u16,
- height: u16,
- buffer: Vec<u8>
-}
-
-impl<W: Write> Drop for Encoder<W> {
-
- #[cfg(feature = "raii_no_panic")]
- fn drop(&mut self) {
- if self.w.is_some() {
- let _ = self.write_trailer();
- }
- }
-
- #[cfg(not(feature = "raii_no_panic"))]
- fn drop(&mut self) {
- if self.w.is_some() {
- self.write_trailer().unwrap();
- }
- }
-}
-
-// Color table size converted to flag bits
-fn flag_size(size: usize) -> u8 {
- match size {
- 0 ..=2 => 0,
- 3 ..=4 => 1,
- 5 ..=8 => 2,
- 9 ..=16 => 3,
- 17 ..=32 => 4,
- 33 ..=64 => 5,
- 65 ..=128 => 6,
- 129..=256 => 7,
- _ => 7
- }
-}
-
-#[test]
-fn error_cast() {
- let _ : Box<dyn error::Error> = EncodingError::from(FormatErrorKind::MissingColorPalette).into();
-}
diff --git a/vendor/gif/src/lib.rs b/vendor/gif/src/lib.rs
deleted file mode 100644
index 8eb2a61..0000000
--- a/vendor/gif/src/lib.rs
+++ /dev/null
@@ -1,154 +0,0 @@
-//! # GIF en- and decoding library [![Build Status](https://github.com/image-rs/image-gif/workflows/Rust%20CI/badge.svg)](https://github.com/image-rs/image-gif/actions)
-//!
-//! GIF en- and decoder written in Rust ([API Documentation](https://docs.rs/gif)).
-//!
-//! # GIF encoding and decoding library
-//!
-//! This library provides all functions necessary to de- and encode GIF files.
-//!
-//! ## High level interface
-//!
-//! The high level interface consists of the two types
-//! [`Encoder`](struct.Encoder.html) and [`Decoder`](struct.Decoder.html).
-//!
-//! ### Decoding GIF files
-//!
-//! ```rust
-//! // Open the file
-//! use std::fs::File;
-//! let mut decoder = gif::DecodeOptions::new();
-//! // Configure the decoder such that it will expand the image to RGBA.
-//! decoder.set_color_output(gif::ColorOutput::RGBA);
-//! // Read the file header
-//! let file = File::open("tests/samples/sample_1.gif").unwrap();
-//! let mut decoder = decoder.read_info(file).unwrap();
-//! while let Some(frame) = decoder.read_next_frame().unwrap() {
-//! // Process every frame
-//! }
-//! ```
-//!
-//!
-//!
-//! ### Encoding GIF files
-//!
-//! The encoder can be used so save simple computer generated images:
-//!
-//! ```rust
-//! use gif::{Frame, Encoder, Repeat};
-//! use std::fs::File;
-//! use std::borrow::Cow;
-//!
-//! let color_map = &[0xFF, 0xFF, 0xFF, 0, 0, 0];
-//! let (width, height) = (6, 6);
-//! let mut beacon_states = [[
-//! 0, 0, 0, 0, 0, 0,
-//! 0, 1, 1, 0, 0, 0,
-//! 0, 1, 1, 0, 0, 0,
-//! 0, 0, 0, 1, 1, 0,
-//! 0, 0, 0, 1, 1, 0,
-//! 0, 0, 0, 0, 0, 0,
-//! ], [
-//! 0, 0, 0, 0, 0, 0,
-//! 0, 1, 1, 0, 0, 0,
-//! 0, 1, 0, 0, 0, 0,
-//! 0, 0, 0, 0, 1, 0,
-//! 0, 0, 0, 1, 1, 0,
-//! 0, 0, 0, 0, 0, 0,
-//! ]];
-//! let mut image = File::create("tests/samples/beacon.gif").unwrap();;
-//! let mut encoder = Encoder::new(&mut image, width, height, color_map).unwrap();
-//! encoder.set_repeat(Repeat::Infinite).unwrap();
-//! for state in &beacon_states {
-//! let mut frame = Frame::default();
-//! frame.width = width;
-//! frame.height = height;
-//! frame.buffer = Cow::Borrowed(&*state);
-//! encoder.write_frame(&frame).unwrap();
-//! }
-//! ```
-//!
-//! [`Frame::from_*`](struct.Frame.html) can be used to convert a true color image to a paletted
-//! image with a maximum of 256 colors:
-//!
-//! ```rust
-//! # #[cfg(feature = "color_quant")] {
-//! use std::fs::File;
-//!
-//! // Get pixel data from some source
-//! let mut pixels: Vec<u8> = vec![0; 30_000];
-//! // Create frame from data
-//! let frame = gif::Frame::from_rgb(100, 100, &mut *pixels);
-//! // Create encoder
-//! let mut image = File::create("target/indexed_color.gif").unwrap();
-//! let mut encoder = gif::Encoder::new(&mut image, frame.width, frame.height, &[]).unwrap();
-//! // Write frame to file
-//! encoder.write_frame(&frame).unwrap();
-//! # }
-//! ```
-
-// TODO: make this compile
-// ```rust
-// use gif::{Frame, Encoder};
-// use std::fs::File;
-// let color_map = &[0, 0, 0, 0xFF, 0xFF, 0xFF];
-// let mut frame = Frame::default();
-// // Generate checkerboard lattice
-// for (i, j) in (0..10).zip(0..10) {
-// frame.buffer.push(if (i * j) % 2 == 0 {
-// 1
-// } else {
-// 0
-// })
-// }
-// # (|| {
-// {
-// let mut file = File::create("test.gif")?;
-// let mut encoder = Encoder::new(&mut file, 100, 100);
-// encoder.write_global_palette(color_map)?.write_frame(&frame)
-// }
-// # })().unwrap();
-// ```
-#![deny(missing_docs)]
-#![cfg(feature = "std")]
-
-mod traits;
-mod common;
-mod reader;
-mod encoder;
-
-pub use crate::common::{AnyExtension, Block, Extension, DisposalMethod, Frame};
-
-pub use crate::reader::{StreamingDecoder, Decoded, DecodingError, DecodingFormatError};
-/// StreamingDecoder configuration parameters
-pub use crate::reader::{ColorOutput, MemoryLimit, Extensions};
-pub use crate::reader::{DecodeOptions, Decoder, Version};
-
-pub use crate::encoder::{Encoder, ExtensionData, Repeat, EncodingError};
-
-#[cfg(test)]
-#[test]
-fn round_trip() {
- use std::io::prelude::*;
- use std::fs::File;
- let mut data = vec![];
- File::open("tests/samples/sample_1.gif").unwrap().read_to_end(&mut data).unwrap();
- let mut decoder = Decoder::new(&*data).unwrap();
- let palette: Vec<u8> = decoder.palette().unwrap().into();
- let frame = decoder.read_next_frame().unwrap().unwrap();
- let mut data2 = vec![];
- {
- let mut encoder = Encoder::new(&mut data2, frame.width, frame.height, &palette).unwrap();
- encoder.write_frame(frame).unwrap();
- }
- assert_eq!(&data[..], &data2[..])
-}
-
-macro_rules! insert_as_doc {
- { $content:expr } => {
- #[doc = $content] extern { }
- }
-}
-
-// Provides the README.md as doc, to ensure the example works!
-#[cfg(feature = "color_quant")]
-insert_as_doc!(include_str!("../README.md"));
diff --git a/vendor/gif/src/reader/decoder.rs b/vendor/gif/src/reader/decoder.rs
deleted file mode 100644
index f0f8eea..0000000
--- a/vendor/gif/src/reader/decoder.rs
+++ /dev/null
@@ -1,724 +0,0 @@
-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
deleted file mode 100644
index a453e79..0000000
--- a/vendor/gif/src/reader/mod.rs
+++ /dev/null
@@ -1,522 +0,0 @@
-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);
- }
- }
-}
diff --git a/vendor/gif/src/traits.rs b/vendor/gif/src/traits.rs
deleted file mode 100644
index 7fe326c..0000000
--- a/vendor/gif/src/traits.rs
+++ /dev/null
@@ -1,49 +0,0 @@
-//! Traits used in this library
-use std::io;
-
-/// Writer extension to write little endian data
-pub trait WriteBytesExt<T> {
- /// Writes `T` to a bytes stream. Least significant byte first.
- fn write_le(&mut self, n: T) -> io::Result<()>;
-
- /*
- #[inline]
- fn write_byte(&mut self, n: u8) -> io::Result<()> where Self: Write {
- self.write_all(&[n])
- }
- */
-}
-
-impl<W: io::Write + ?Sized> WriteBytesExt<u8> for W {
- #[inline]
- fn write_le(&mut self, n: u8) -> io::Result<()> {
- self.write_all(&[n])
-
- }
-}
-
-impl<W: io::Write + ?Sized> WriteBytesExt<u16> for W {
- #[inline]
- fn write_le(&mut self, n: u16) -> io::Result<()> {
- self.write_all(&[n as u8, (n>>8) as u8])
-
- }
-}
-
-impl<W: io::Write + ?Sized> WriteBytesExt<u32> for W {
- #[inline]
- fn write_le(&mut self, n: u32) -> io::Result<()> {
- self.write_le(n as u16)?;
- self.write_le((n >> 16) as u16)
-
- }
-}
-
-impl<W: io::Write + ?Sized> WriteBytesExt<u64> for W {
- #[inline]
- fn write_le(&mut self, n: u64) -> io::Result<()> {
- self.write_le(n as u32)?;
- self.write_le((n >> 32) as u32)
-
- }
-}