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 viaenough - Zero-trust: Validate all inputs, handle malformed data gracefully
- no_std compatible: Works with
alloconly (disablestdfeature)
§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): Enablesstd::error::Errorimpl and std I/Oimgref-interop: Interop with theimgrefcrate
§Color Quantization Backends
Choose one or more quantization backends for encoding:
| Feature | Quality | Speed | File Size | License | Use Case |
|---|---|---|---|---|---|
imagequant | Best | Medium | Smallest | GPL-3.0-or-later | Recommended - LZW-aware dithering |
quantizr | Good | Fast | Medium | MIT | Best MIT-licensed option |
color_quant | Good | Fastest | Large | MIT | High-throughput servers |
exoquant-deprecated | Good | Slow | Medium | MIT | Legacy 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§
- Composed
Frame - Composited frame with RGBA pixels.
- Decoder
- Streaming GIF decoder.
- Encode
Request - Request to encode a GIF animation.
- Encoder
- Streaming GIF encoder.
- Encoder
Config - Encoder configuration.
- Frame
Input - Frame input for encoding.
- Frame
Iterator - 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).
- Quantize
Config - Configuration for quantization.
- Quantized
Frame - 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.
- Screen
Builder - Builder for creating a Screen.
- Stats
- Thread-safe memory usage statistics.
- Stats
Snapshot - Immutable snapshot of statistics at a point in time.
- Tracked
Alloc - A tracked allocation that automatically updates stats on drop.
- Unstoppable
- A
Stopimplementation that never stops (no cooperative cancellation).
Enums§
- Disposal
Method - GIF disposal method.
- GifError
- All possible errors in zengif operations.
- Palette
Strategy - Strategy for palette selection during encoding.
- Quantizer
Backend - Available quantizer backends.
- Repeat
- Loop/repeat behavior for animations.
Traits§
- Quantizer
Trait - 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§
- Decode
Error - Type alias for decoding errors (for API clarity).
- Encode
Error - Type alias for encoding errors (for API clarity).
- Result
- Result type alias using
At<GifError>for automatic location tracking.