| 1 | #![forbid (unsafe_code)] |
| 2 | //! # GIF en- and decoding library [](https://github.com/image-rs/image-gif/actions) |
| 3 | //! |
| 4 | //! GIF en- and decoder written in Rust ([API Documentation](https://docs.rs/gif)). |
| 5 | //! |
| 6 | //! # GIF encoding and decoding library |
| 7 | //! |
| 8 | //! This library provides all functions necessary to de- and encode GIF files. |
| 9 | //! |
| 10 | //! ## High level interface |
| 11 | //! |
| 12 | //! The high level interface consists of the two types |
| 13 | //! [`Encoder`](struct.Encoder.html) and [`Decoder`](struct.Decoder.html). |
| 14 | //! |
| 15 | //! ### Decoding GIF files |
| 16 | //! |
| 17 | //! ```rust |
| 18 | //! // Open the file |
| 19 | //! use std::fs::File; |
| 20 | //! let mut decoder = gif::DecodeOptions::new(); |
| 21 | //! // Configure the decoder such that it will expand the image to RGBA. |
| 22 | //! decoder.set_color_output(gif::ColorOutput::RGBA); |
| 23 | //! // Read the file header |
| 24 | //! let file = File::open("tests/samples/sample_1.gif" ).unwrap(); |
| 25 | //! let mut decoder = decoder.read_info(file).unwrap(); |
| 26 | //! while let Some(frame) = decoder.read_next_frame().unwrap() { |
| 27 | //! // Process every frame |
| 28 | //! } |
| 29 | //! ``` |
| 30 | //! |
| 31 | //! |
| 32 | //! |
| 33 | //! ### Encoding GIF files |
| 34 | //! |
| 35 | //! The encoder can be used so save simple computer generated images: |
| 36 | //! |
| 37 | //! ```rust |
| 38 | //! use gif::{Frame, Encoder, Repeat}; |
| 39 | //! use std::fs::File; |
| 40 | //! use std::borrow::Cow; |
| 41 | //! |
| 42 | //! let color_map = &[0xFF, 0xFF, 0xFF, 0, 0, 0]; |
| 43 | //! let (width, height) = (6, 6); |
| 44 | //! let mut beacon_states = [[ |
| 45 | //! 0, 0, 0, 0, 0, 0, |
| 46 | //! 0, 1, 1, 0, 0, 0, |
| 47 | //! 0, 1, 1, 0, 0, 0, |
| 48 | //! 0, 0, 0, 1, 1, 0, |
| 49 | //! 0, 0, 0, 1, 1, 0, |
| 50 | //! 0, 0, 0, 0, 0, 0, |
| 51 | //! ], [ |
| 52 | //! 0, 0, 0, 0, 0, 0, |
| 53 | //! 0, 1, 1, 0, 0, 0, |
| 54 | //! 0, 1, 0, 0, 0, 0, |
| 55 | //! 0, 0, 0, 0, 1, 0, |
| 56 | //! 0, 0, 0, 1, 1, 0, |
| 57 | //! 0, 0, 0, 0, 0, 0, |
| 58 | //! ]]; |
| 59 | //! let mut image = File::create("tests/samples/beacon.gif" ).unwrap();; |
| 60 | //! let mut encoder = Encoder::new(&mut image, width, height, color_map).unwrap(); |
| 61 | //! encoder.set_repeat(Repeat::Infinite).unwrap(); |
| 62 | //! for state in &beacon_states { |
| 63 | //! let mut frame = Frame::default(); |
| 64 | //! frame.width = width; |
| 65 | //! frame.height = height; |
| 66 | //! frame.buffer = Cow::Borrowed(&*state); |
| 67 | //! encoder.write_frame(&frame).unwrap(); |
| 68 | //! } |
| 69 | //! ``` |
| 70 | //! |
| 71 | //! [`Frame::from_*`](struct.Frame.html) can be used to convert a true color image to a paletted |
| 72 | //! image with a maximum of 256 colors: |
| 73 | //! |
| 74 | //! ```rust |
| 75 | //! # #[cfg (feature = "color_quant" )] { |
| 76 | //! use std::fs::File; |
| 77 | //! |
| 78 | //! // Get pixel data from some source |
| 79 | //! let mut pixels: Vec<u8> = vec![0; 30_000]; |
| 80 | //! // Create frame from data |
| 81 | //! let frame = gif::Frame::from_rgb(100, 100, &mut *pixels); |
| 82 | //! // Create encoder |
| 83 | //! let mut image = File::create("target/indexed_color.gif" ).unwrap(); |
| 84 | //! let mut encoder = gif::Encoder::new(&mut image, frame.width, frame.height, &[]).unwrap(); |
| 85 | //! // Write frame to file |
| 86 | //! encoder.write_frame(&frame).unwrap(); |
| 87 | //! # } |
| 88 | //! ``` |
| 89 | |
| 90 | // TODO: make this compile |
| 91 | // ```rust |
| 92 | // use gif::{Frame, Encoder}; |
| 93 | // use std::fs::File; |
| 94 | // let color_map = &[0, 0, 0, 0xFF, 0xFF, 0xFF]; |
| 95 | // let mut frame = Frame::default(); |
| 96 | // // Generate checkerboard lattice |
| 97 | // for (i, j) in (0..10).zip(0..10) { |
| 98 | // frame.buffer.push(if (i * j) % 2 == 0 { |
| 99 | // 1 |
| 100 | // } else { |
| 101 | // 0 |
| 102 | // }) |
| 103 | // } |
| 104 | // # (|| { |
| 105 | // { |
| 106 | // let mut file = File::create("test.gif")?; |
| 107 | // let mut encoder = Encoder::new(&mut file, 100, 100); |
| 108 | // encoder.write_global_palette(color_map)?.write_frame(&frame) |
| 109 | // } |
| 110 | // # })().unwrap(); |
| 111 | // ``` |
| 112 | #![deny (missing_docs)] |
| 113 | #![cfg (feature = "std" )] |
| 114 | |
| 115 | mod traits; |
| 116 | mod common; |
| 117 | mod reader; |
| 118 | mod encoder; |
| 119 | |
| 120 | pub use crate::common::{AnyExtension, Extension, DisposalMethod, Frame}; |
| 121 | |
| 122 | pub use crate::reader::{DecodingError, DecodingFormatError}; |
| 123 | pub use crate::reader::{ColorOutput, MemoryLimit}; |
| 124 | pub use crate::reader::{DecodeOptions, Decoder, Version}; |
| 125 | |
| 126 | pub use crate::encoder::{Encoder, ExtensionData, Repeat, EncodingError, EncodingFormatError}; |
| 127 | |
| 128 | /// Low-level, advanced decoder. Prefer [`Decoder`] instead, which can stream frames too. |
| 129 | pub mod streaming_decoder { |
| 130 | pub use crate::common::Block; |
| 131 | pub use crate::reader::{Decoded, FrameDataType, FrameDecoder, OutputBuffer, StreamingDecoder}; |
| 132 | } |
| 133 | |
| 134 | #[cfg (feature = "color_quant" )] |
| 135 | macro_rules! insert_as_doc { |
| 136 | { $content:expr } => { |
| 137 | #[allow(unused_doc_comments)] |
| 138 | #[doc = $content] extern { } |
| 139 | } |
| 140 | } |
| 141 | |
| 142 | // Provides the README.md as doc, to ensure the example works! |
| 143 | #[cfg (feature = "color_quant" )] |
| 144 | insert_as_doc!(include_str!("../README.md" )); |
| 145 | |