zenwebp
Pure Rust WebP encoding and decoding. No C dependencies, no unsafe code.
Getting Started
Add to your Cargo.toml:
[]
= "0.2"
Decode a WebP image
use WebPDecoder;
let webp_bytes: & = /* your WebP data */;
let mut decoder = new?;
let = decoder.dimensions;
// Decode to RGBA
let mut rgba = vec!;
decoder.read_image?;
Encode to WebP
use ;
let rgb_pixels: & = /* your RGB data */;
let = ;
// Lossy encoding at quality 75
let mut webp_output = Vecnew;
let mut encoder = new;
encoder.set_params;
encoder.encode?;
Features
- Pure Rust - no C dependencies, builds anywhere Rust does
#![forbid(unsafe_code)]- memory safety guaranteed- no_std compatible - works with just
alloc, no standard library needed - SIMD accelerated - SSE2/SSE4.1/AVX2 on x86, SIMD128 on WASM
- Full format support - lossy, lossless, alpha, animation (decode), ICC/EXIF/XMP metadata
Safe SIMD
We achieve both safety and performance through safe abstractions over CPU intrinsics:
wide- portable SIMD types that autovectorize wellarchmageandmagetypes- token-gated safe intrinsicssafe_unaligned_simd- safe unaligned load/storecore::arch- newly stabilized as safe in Rust
These abstractions may not be perfect, but we trust them over hand-rolled unsafe code.
Decoder
Supports all WebP features: lossy and lossless compression, alpha channel, animation, and extended format with ICC/EXIF/XMP chunks.
Encoder
Supports lossy and lossless encoding with configurable quality (0-100) and speed/quality tradeoff (method 0-6).
// Lossless encoding
encoder.set_params;
// Fast lossy encoding (larger files)
encoder.set_params;
// High quality lossy (slower, smaller files)
encoder.set_params;
Performance
Benchmarks on a 768x512 image (Kodak test suite):
| Operation | zenwebp | libwebp | Ratio |
|---|---|---|---|
| Decode | 4.2ms | 3.0ms | 1.4x slower |
| Encode (method 4) | 65ms | 75ms* | 1.15x faster |
*libwebp method 6 with trellis, comparable quality settings
Quality
At the same quality setting, zenwebp produces files within 1-5% of libwebp's size with comparable visual quality. Quality is slightly better than libwebp below Q75 and slightly worse above Q75.
no_std Support
[]
= { = "0.2", = false }
Both encoder and decoder work without std. The decoder takes &[u8] slices and the encoder writes to Vec<u8>. Only encode_to_writer() requires the std feature.
Origin
Forked from image-webp with significant enhancements:
- Lossy encoder (original only supported lossless)
- ~2x faster decoding through SIMD and algorithmic improvements
- Full no_std support for both encoder and decoder
- WASM SIMD128 support
License
Licensed under either Apache License, Version 2.0 or MIT license at your option.
Contributing
Contributions welcome! Please feel free to open issues or pull requests.
Credits
- image-rs/image-webp - Original crate this was forked from
- libwebp (Google) - Reference implementation and algorithm source
- wide (Lokathor) - Portable SIMD types
- archmage & magetypes (Lilith) - Safe intrinsics
- safe_unaligned_simd (Lilith) - Safe unaligned SIMD operations
- Claude (Anthropic) - AI development assistance
Code review recommended for production use.