Skip to main content

otf_pixels_codec_gif/
lib.rs

1//! GIF codec for `otf-pixels`, implemented from scratch.
2//!
3//! Decode covers the whole format: all frames, both interlace layouts,
4//! transparency, and every disposal method. Encode is single-frame with
5//! palette quantization, which is SPEC §Formats' stated v1 scope — animation
6//! *pipelines* are v2.
7//!
8//! # Frames and the engine
9//!
10//! [`Decoder`] yields one image, so [`GifDecoder`] presents the first frame
11//! composited onto the canvas. Every existing pipeline therefore works on a
12//! GIF unchanged, and the engine stays frame-unaware.
13//!
14//! Callers who want the animation use [`GifDecoder::next_frame`], which walks
15//! the remaining frames and applies disposal between them. That keeps
16//! "animation pipelines are v2" honest: the decode is complete, and only the
17//! graph integration is deferred.
18//!
19//! [`Decoder`]: otf_pixels_core::Decoder
20
21mod decoder;
22mod encoder;
23mod format;
24mod quantize;
25
26pub use decoder::{Frame, GifCodec, GifDecoder, probe};
27pub use encoder::GifEncoder;
28pub use format::{Disposal, GraphicControl, ImageDescriptor, Screen};
29pub use quantize::{Dither, Palette, build_palette, quantize};
30
31/// Translate a compression failure into this crate's error type.
32///
33/// `otf-pixels-compress` deliberately does not depend on `otf-pixels-core`
34/// (ADR-0012), so the mapping lives here, where the format context is known.
35pub(crate) fn compress_error(error: otf_pixels_compress::Error) -> otf_pixels_core::PixelsError {
36    otf_pixels_core::PixelsError::malformed("gif", error.detail().to_owned())
37}