A faster fork of the Zopfli DEFLATE compressor, written in Rust.
Zopfli produces the smallest possible DEFLATE output at the cost of speed. zenzop produces byte-identical output 2-3x faster through algorithmic improvements: precomputed lookup tables, arena-free Huffman tree construction, pre-allocated stores, and eliminated bounds checks in hot paths.
With enhanced mode enabled, zenzop applies ECT-derived optimizations — expanded precode search, multi-strategy Huffman tree selection, and enhanced parser diversification — to produce smaller output than standard Zopfli at the cost of byte-for-byte parity with the C reference.
- Byte-identical output to C Zopfli (default mode)
- Enhanced mode for smaller-than-Zopfli output (beats ECT-9 at equivalent iterations)
- 2-3x faster than the original Rust port
no_std+alloccompatible — works on embedded and WASM targets- Cooperative cancellation via
enough::Stop— cancel long-running compressions cleanly - Streaming encoder API —
DeflateEncoder,GzipEncoder,ZlibEncoder - Parallel block compression with optional
rayonsupport
Add to your Cargo.toml:
[dependencies]
zenzop = "0.3"use std::io;
fn main() -> io::Result<()> {
let data = b"Hello, world!";
let mut output = Vec::new();
zenzop::compress(
zenzop::Options::default(),
zenzop::Format::Gzip,
&data[..],
&mut output,
)?;
Ok(())
}use std::io;
fn main() -> io::Result<()> {
let data = b"Hello, world!";
let mut output = Vec::new();
let mut options = zenzop::Options::default();
options.enhanced = true;
zenzop::compress(options, zenzop::Format::Gzip, &data[..], &mut output)?;
Ok(())
}Enhanced mode produces smaller DEFLATE output than standard Zopfli with ~5% runtime overhead. At 60 iterations it beats ECT-9 on representative test data.
use std::io::{self, Write};
fn main() -> io::Result<()> {
let mut encoder = zenzop::DeflateEncoder::new_buffered(
zenzop::Options::default(),
Vec::new(),
);
encoder.write_all(b"Hello, world!")?;
let compressed = encoder.into_inner()?.finish()?.into_inner();
Ok(())
}use std::io::{self, Write};
fn compress_cancellable(data: &[u8], stop: impl zenzop::Stop) -> io::Result<Vec<u8>> {
let mut encoder = zenzop::GzipEncoder::with_stop_buffered(
zenzop::Options::default(),
Vec::new(),
stop,
)?;
encoder.write_all(data)?;
let result = encoder.into_inner()?.finish()?;
if !result.fully_optimized() {
eprintln!("compression was cut short by timeout");
}
Ok(result.into_inner())
}| Feature | Default | Description |
|---|---|---|
gzip |
yes | Gzip format support |
zlib |
yes | Zlib format support |
std |
yes | Standard library (logging, std::io traits) |
parallel |
no | Parallel block compression via rayon |
nightly |
no | Nightly-only optimizations |
For no_std usage: default-features = false.
The minimum supported Rust version is 1.85. Bumping this is not considered a breaking change.
cargo build --release
The zenzop binary will be at target/release/zenzop.
cargo test # Unit tests + property-based tests
./test/run.sh # Golden master: byte-identical to C Zopfli
Apache-2.0
Forked from zopfli-rs/zopfli, which was Carol Nichols' Rust reimplementation of Google's Zopfli. Enhanced mode optimizations derived from ECT (Efficient Compression Tool).
Developed with Claude (Anthropic). Not all code manually reviewed. Review critical paths before production use.