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
exoquant-deprecatedGoodSlowMediumMITLegacy compatibility only

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§

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).

Enums§

DisposalMethod
GIF disposal method.
GifError
All possible errors in zengif operations.
PaletteStrategy
Strategy for palette selection during encoding.
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.
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.