zencodec
Shared traits and types for the zen* image codec family.
This crate defines the common interface that all zen* codecs implement. It contains no codec logic — just traits, types, and format negotiation helpers. no_std compatible (requires alloc), forbid(unsafe_code).
Import as zencodec — use zencodec::encode, zencodec::decode, etc.
Guides:
- Using zen* codecs — encoding, decoding, format negotiation, dyn dispatch, animation, streaming
- Implementing a codec — how to implement the traits for a new image format
Crates in the zen* family
| Crate | Format | Repo |
|---|---|---|
zenjpeg |
JPEG | imazen/zenjpeg |
zenwebp |
WebP | imazen/zenwebp |
zenpng |
PNG | imazen/zenpng |
zengif |
GIF | imazen/zengif |
zenavif |
AVIF | imazen/zenavif |
zenjxl |
JPEG XL | imazen/zenjxl |
zenbitmaps |
PNM/BMP/Farbfeld | imazen/zenbitmaps |
heic |
HEIC/HEIF | imazen/heic |
zentiff |
TIFF (experimental) | imazen/zentiff |
zenpdf |
PDF (experimental) | imazen/zenpdf |
Architecture
Every codec follows a three-layer pattern:
Config → reusable, Clone + Send + Sync, 'static
Job → per-operation, borrows temporaries (stop token, limits, metadata)
Executor → borrows pixel data or file bytes, consumes self to produce output
ENCODE: EncoderConfig → EncodeJob → Encoder / AnimationFrameEncoder
DECODE: DecoderConfig → DecodeJob<'a> → Decode / StreamingDecode / AnimationFrameDecoder
Config lives in a struct and gets shared across threads. A web server keeps one JpegEncoderConfig at quality 85 for all requests. Job borrows stack-local data (cancellation token, resource limits, metadata). Executor borrows pixels or bytes and consumes itself to produce output.
Each layer also has object-safe Dyn* variants for codec-agnostic dispatch:
DynEncoderConfig → DynEncodeJob → DynEncoder / DynAnimationFrameEncoder
DynDecoderConfig → DynDecodeJob → DynDecoder / DynStreamingDecoder / DynAnimationFrameDecoder
Blanket impls generate the dyn API automatically — codec authors implement the generic traits and get dyn dispatch for free.
Quick Example
use Cow;
use ;
use ;
use ;
// Encode
let config = new.with_generic_quality;
let output = config.job.encoder?.encode?;
let jpeg_bytes = output.into_vec;
// Decode
let config = new;
let decoded = config.job.decoder?.decode?;
let pixels = decoded.into_buffer;
Key Design Decisions
Color management is not the codec's job. Decoders return native pixels with ICC/CICP metadata. Encoders accept pixels as-is and embed the provided metadata. The caller handles CMS transforms.
Format negotiation over conversion. Decoders take a ranked &[PixelDescriptor] preference list and pick the first they can produce without lossy conversion. Pass &[] for native format.
Capabilities over try/catch. Codecs declare their capabilities as const EncodeCapabilities / DecodeCapabilities structs. Check before calling instead of catching UnsupportedOperation errors.
Pixel types from zenpixels. All pixel interchange types (PixelSlice, PixelBuffer, PixelDescriptor, etc.) are defined in the zenpixels crate. All zen* crates depend on zenpixels directly.
What's in this crate
| Module | Contents |
|---|---|
zencodec::encode |
EncoderConfig, EncodeJob, Encoder, AnimationFrameEncoder, EncodeOutput, EncodeCapabilities, EncodePolicy, best_encode_format, dyn dispatch traits (DynEncoderConfig, DynEncodeJob, DynEncoder, DynAnimationFrameEncoder) |
zencodec::decode |
DecoderConfig, DecodeJob, Decode, StreamingDecode, AnimationFrameDecoder, DecodeOutput, DecodeCapabilities, DecodePolicy, DecodeRowSink, SinkError, OutputInfo, SourceEncodingDetails, negotiate_pixel_format, is_format_available, dyn dispatch traits (DynDecoderConfig, DynDecodeJob, DynDecoder, DynStreamingDecoder, DynAnimationFrameDecoder) |
zencodec::gainmap |
GainMapInfo, GainMapParams, GainMapChannel, GainMapDirection, GainMapPresence — cross-codec gain map types (ISO 21496-1) |
zencodec::helpers |
Codec implementation helpers (not consumer API) — shared boilerplate for trait implementors |
| root | ImageFormat, ImageFormatDefinition, ImageFormatRegistry, ImageInfo, Metadata, Orientation, OrientationHint, ResourceLimits, LimitExceeded, ThreadingPolicy, UnsupportedOperation, CodecErrorExt, find_cause, Unsupported, Extensions, AnimationFrame, OwnedAnimationFrame, Cicp, ContentLightLevel, MasteringDisplay, StopToken, Unstoppable |
License
Apache-2.0 OR MIT