1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
// private.rs // // Copyright (c) 2019-2020 Douglas Lau // //! Private module for top-level items use crate::{decode, encode, Error}; use pix::{Raster, Rgba8}; use std::io::{BufReader, BufWriter, Read, Write}; /// GIF file decoder /// /// Can be converted to one of three `Iterator`s: /// * [into_iter] / [into_rasters] for high-level `Raster`s /// * [into_frames] for mid-level [Frame]s /// * [into_blocks] for low-level [Block]s /// /// ## Example: Get a `Raster` from a GIF /// ``` /// # fn main() -> Result<(), Box<dyn std::error::Error>> { /// # let gif = &[ /// # 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x02, 0x00, /// # 0x02, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, /// # 0xff, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00, 0x00, /// # 0x02, 0x00, 0x02, 0x00, 0x00, 0x02, 0x03, 0x0c, /// # 0x10, 0x05, 0x00, 0x3b, /// # ][..]; /// // ... open a `File` as "gif" /// if let Some(raster) = gift::Decoder::new(gif).into_iter().next() { /// // was there a decoding error? /// let raster = raster?; /// // ... work with raster /// } /// # Ok(()) /// # } /// ``` /// /// [Block]: block/enum.Block.html /// [Frame]: block/struct.Frame.html /// [into_blocks]: struct.Decoder.html#method.into_blocks /// [into_frames]: struct.Decoder.html#method.into_frames /// [into_iter]: struct.Decoder.html#method.into_iter /// [into_rasters]: struct.Decoder.html#method.into_rasters /// pub struct Decoder<R: Read> { /// Reader for input data reader: R, /// Maximum image size, in bytes max_image_sz: Option<usize>, } impl<R: Read> Decoder<BufReader<R>> { /// Create a new GIF decoder. pub fn new(reader: R) -> Self { Self::new_unbuffered(BufReader::new(reader)) } } impl<R: Read> Decoder<R> { /// Create a new unbuffered GIF decoder. pub fn new_unbuffered(reader: R) -> Self { Decoder { reader, max_image_sz: Some(1 << 25), } } /// Set the maximum image size (in bytes) to allow for decoding. pub fn max_image_sz(mut self, max_image_sz: Option<usize>) -> Self { self.max_image_sz = max_image_sz; self } /// Convert into a block `Iterator`. pub fn into_blocks(self) -> decode::Blocks<R> { decode::Blocks::new(self.reader, self.max_image_sz) } /// Convert into a frame `Iterator`. pub fn into_frames(self) -> decode::Frames<R> { decode::Frames::new(self.into_blocks()) } /// Convert into a raster `Iterator`. pub fn into_rasters(self) -> decode::Rasters<R> { decode::Rasters::new(self.into_frames()) } } impl<R: Read> IntoIterator for Decoder<R> { type Item = Result<Raster<Rgba8>, Error>; type IntoIter = decode::Rasters<R>; /// Convert into a raster `Iterator` fn into_iter(self) -> Self::IntoIter { self.into_rasters() } } /// GIF file encoder /// /// Can be converted to one of three encoders: /// * [into_raster_enc] for high-level `Raster`s /// * [into_frame_enc] for mid-level [Frame]s /// * [into_block_enc] for low-level [Block]s /// /// [Block]: block/enum.Block.html /// [Frame]: block/struct.Frame.html /// [into_block_enc]: struct.Encoder.html#method.into_block_enc /// [into_frame_enc]: struct.Encoder.html#method.into_frame_enc /// [into_raster_enc]: struct.Encoder.html#method.into_raster_enc pub struct Encoder<W: Write> { /// Writer for output data writer: W, } impl<W: Write> Encoder<BufWriter<W>> { /// Create a new GIF encoder. pub fn new(writer: W) -> Self { Self::new_unbuffered(BufWriter::new(writer)) } } impl<W: Write> Encoder<W> { /// Create a new unbuffered GIF encoder. pub fn new_unbuffered(writer: W) -> Self { Encoder { writer, } } /// Convert into a block encoder. pub fn into_block_enc(self) -> encode::BlockEnc<W> { encode::BlockEnc::new(self.writer) } /// Convert into a frame encoder. pub fn into_frame_enc(self) -> encode::FrameEnc<W> { encode::FrameEnc::new(self.into_block_enc()) } /// Convert into a raster encoder. pub fn into_raster_enc(self) -> encode::RasterEnc<W> { encode::RasterEnc::new(self.into_frame_enc()) } }