Skip to main content

Crate zengif

Crate zengif 

Source
Expand description

§zengif

Server-side GIF codec with zero-trust design, memory bounds, streaming, and full animation transparency support.

§Features

  • Streaming decode/encode: Process GIFs without loading entire file
  • Complete animation support: Disposal methods, transparency, timing
  • Memory bounded: Configurable limits, reject oversized inputs
  • Production ready: Error tracing via whereat, cancellation via enough
  • Zero-trust: Validate all inputs, handle malformed data gracefully
  • no_std compatible: Works with alloc only (disable std feature)

§Quick Start

§Decoding

use zengif::{Decoder, Limits, Unstoppable};

let data = std::fs::read("animation.gif")?;
let reader = std::io::Cursor::new(&data);
let limits = Limits::default();

let mut decoder = Decoder::new(reader, limits, &Unstoppable)?;

while let Some(frame) = decoder.next_frame()? {
    // frame.pixels is composited RGBA
    // frame.delay is in centiseconds
}

// Access memory stats after decoding
println!("Memory used: {} bytes", decoder.stats().peak());

§Encoding

use zengif::{EncodeRequest, EncoderConfig, FrameInput, Limits, Repeat, Rgba, Unstoppable};

let config = EncoderConfig::new().repeat(Repeat::Infinite);
let limits = Limits::default();

let mut encoder = EncodeRequest::new(&config, 100, 100)
    .limits(&limits)
    .stop(&Unstoppable)
    .build()?;

let pixels: Vec<Rgba> = vec![Rgba::rgb(255, 0, 0); 100 * 100];
encoder.add_frame(FrameInput::new(100, 100, 10, pixels))?;

let output: Vec<u8> = encoder.finish()?;
std::fs::write("output.gif", &output)?;

§Memory Tracking

The decoder tracks buffer allocations internally. Access stats via decoder.stats():

use zengif::{Decoder, Limits, Unstoppable};

let data = std::fs::read("animation.gif")?;
let reader = std::io::Cursor::new(&data);
let mut decoder = Decoder::new(reader, Limits::default(), &Unstoppable)?;

while let Some(frame) = decoder.next_frame()? {
    // Check memory usage during decode
    if decoder.stats().peak() > 100_000_000 {
        break; // Stop if using too much memory
    }
}

println!("Peak buffer usage: {} bytes", decoder.stats().peak());

Note: Stats tracks zengif’s own allocations (canvas, pixel buffers), not allocations made internally by the gif crate or quantizers.

§Cancellation

Operations support cooperative cancellation via the enough crate:

use almost_enough::Stopper;
use zengif::{Decoder, Limits};

let stop = Stopper::new();
let stop_clone = stop.clone();

// In another thread:
// stop_clone.cancel();

let data = std::fs::read("animation.gif")?;
let reader = std::io::Cursor::new(&data);
// Pass &stop — references are Copy and implement Stop
let mut decoder = Decoder::new(reader, Limits::default(), &stop)?;
// Decoder will return GifError::Cancelled if stop is triggered

§Feature Flags

  • std (default): Enables std::error::Error impl and std I/O
  • imgref-interop: Interop with the imgref crate

§Color Quantization Backends

Choose one or more quantization backends for encoding:

FeatureQualitySpeedFile SizeLicenseUse Case
imagequantBestMediumSmallestGPL-3.0-or-laterRecommended - LZW-aware dithering
quantizrGoodFastMediumMITBest MIT-licensed option
color_quantGoodFastestLargeMITHigh-throughput servers

Configure the quantizer using the Quantizer enum:

use zengif::{EncoderConfig, Quantizer};

// Use imagequant (recommended) for best quality
let config = EncoderConfig::new()
    .quantizer(Quantizer::imagequant());

// Use quantizr (MIT) for permissive licensing
let config = EncoderConfig::new()
    .quantizer(Quantizer::quantizr_with_dithering(0.3));

// Auto-select best available
let config = EncoderConfig::new()
    .quantizer(Quantizer::auto());

Without any quantization feature, zengif is purely MIT/Apache-2.0 licensed.

Modules§

detect
GIF source analysis and re-encoding recommendations. GIF source analysis and re-encoding recommendations.
heuristics
Resource estimation heuristics for GIF encoding and decoding operations.

Structs§

ComposedFrame
Composited frame with RGBA pixels.
Decoder
Streaming GIF decoder.
EncodeRequest
Request to encode a GIF animation.
Encoder
Streaming GIF encoder.
EncoderConfig
Encoder configuration.
FrameInput
Frame input for encoding.
FrameIterator
Iterator adapter for decoder frames.
Limits
Configuration for decode/encode limits.
Metadata
Metadata about a GIF file.
Palette
A color palette (up to 256 colors).
QuantizeConfig
Configuration for quantization.
QuantizedFrame
Result of quantizing a single frame.
RawFrame
Raw frame data as read from GIF (before compositing).
Rgba
RGBA pixel (4 bytes).
Screen
GIF compositing screen.
ScreenBuilder
Builder for creating a Screen.
Stats
Thread-safe memory usage statistics.
StatsSnapshot
Immutable snapshot of statistics at a point in time.
TrackedAlloc
A tracked allocation that automatically updates stats on drop.
Unstoppable
A Stop implementation that never stops (no cooperative cancellation).
ZenquantQuantizer
zenquant-based quantizer.

Enums§

DisposalMethod
GIF disposal method.
GifError
All possible errors in zengif operations.
PaletteStrategy
Strategy for palette selection during encoding.
Quantizer
Quantizer selection with backend-specific configuration.
QuantizerBackend
Available quantizer backends.
Repeat
Loop/repeat behavior for animations.

Traits§

QuantizerTrait
Trait for color quantization implementations.
Stop
Cooperative cancellation check.

Functions§

decode_gif
Convenience function to decode a GIF from bytes.
encode_gif
Convenience function to encode frames to a GIF byte vector.
encode_gif_shared_palette
Encode frames using a shared palette computed from all frames.
encode_gif_with_quantizer
Encode frames using a custom quantizer.
tracked_vec_filled
Helper to allocate a Vec filled with a value.
tracked_vec_with_capacity
Helper to allocate a Vec with tracking.

Type Aliases§

DecodeError
Type alias for decoding errors (for API clarity).
EncodeError
Type alias for encoding errors (for API clarity).
Result
Result type alias using At<GifError> for automatic location tracking.