oxiarc-deflate [Stable]
Pure Rust implementation of the DEFLATE compression algorithm (RFC 1951).
Version 0.2.8 (2026-05-08) — 128 tests passing.
What's new in 0.2.8: Added async streaming support for raw DEFLATE with RawDeflateWriter and RawInflateReader (requires async-io feature).
What's new in 0.2.6: Added streaming support with GzipStreamEncoder/GzipStreamDecoder and ZlibStreamEncoder/ZlibStreamDecoder with flush modes for fine-grained control over compressed output.
Overview
DEFLATE is the compression algorithm used in:
- ZIP archives
- GZIP compressed files
- PNG images
- HTTP compression
- Many other formats
This crate provides both compression and decompression with no external dependencies.
Features
- Pure Rust - No C bindings or unsafe code
- Full RFC 1951 compliance - All block types supported
- Compression levels 0-9 - From stored to maximum compression
- Streaming API - Process data in chunks
- One-shot API - Convenient functions for simple cases
- Async I/O -
async_deflatemodule with Tokio-based async streaming (enableasync-iofeature) - GZIP support -
gzipmodule for RFC 1952 GZIP format encoding/decoding
All features are implemented and tested. API is stable.
Cargo Features
| Feature | Default | Description |
|---|---|---|
default |
yes | DEFLATE compression/decompression, LZ77, Huffman |
async-io |
no | Async streaming I/O via Tokio (enables async_deflate module) |
Usage
Add to your Cargo.toml:
[]
= "0.2.8"
With async I/O support:
[]
= { = "0.2.8", = ["async-io"] }
Quick Start
use ;
// Compress data
let original = b"Hello, World! Hello, World! Hello, World!";
let compressed = deflate?; // Level 6 (default)
// Decompress data
let decompressed = inflate?;
assert_eq!;
Compression Levels
| Level | Description | Use Case |
|---|---|---|
| 0 | Stored (no compression) | Already compressed data |
| 1-3 | Fast compression | Real-time streaming |
| 4-6 | Balanced (default: 6) | General purpose |
| 7-9 | Best compression | Archival, storage |
API
High-Level Functions
// Compress with specified level
let compressed = deflate?;
// Decompress
let decompressed = inflate?;
Streaming API
use ;
// Streaming compression
let mut deflater = new;
let compressed = deflater.compress_all?;
// Streaming decompression
let mut inflater = new;
loop
LZ77 Encoder
use ;
let mut encoder = new;
for token in encoder.encode
Huffman Trees
use ;
// Build tree from code lengths
let lengths = ;
let tree = from_lengths?;
// Decode symbols
let symbol = tree.decode?;
Algorithm Details
DEFLATE Structure
+------------------+
| Block Header | (3 bits: BFINAL + BTYPE)
+------------------+
| Block Data | (varies by type)
+------------------+
| ... more blocks |
+------------------+
Block Types
| BTYPE | Name | Description |
|---|---|---|
| 00 | Stored | Uncompressed data (up to 65535 bytes) |
| 01 | Fixed | Fixed Huffman codes (RFC 1951 Table) |
| 10 | Dynamic | Custom Huffman codes in header |
| 11 | Reserved | Invalid |
LZ77 Parameters
- Window size: 32768 bytes (32KB)
- Match length: 3-258 bytes
- Match distance: 1-32768 bytes
- Minimum match: 3 bytes
Huffman Alphabets
Literal/Length (286 symbols):
- 0-255: Literal bytes
- 256: End of block
- 257-285: Length codes (3-258)
Distance (30 symbols):
- 0-29: Distance codes (1-32768)
Fixed Huffman Code Lengths
| Range | Code Length |
|---|---|
| 0-143 | 8 bits |
| 144-255 | 9 bits |
| 256-279 | 7 bits |
| 280-287 | 8 bits |
Modules
| Module | Description |
|---|---|
deflate |
Compression (encoder) |
inflate |
Decompression (decoder) |
huffman |
Huffman tree operations |
lz77 |
LZ77 dictionary encoder |
tables |
Fixed Huffman tables, length/distance extra bits |
gzip |
GZIP format (RFC 1952) encoding and decoding |
async_deflate |
Async streaming compression/decompression (requires async-io feature) |
GZIP API
use ;
// Encode to GZIP format
let compressed = gzip_encode?;
// Decode GZIP data
let decompressed = gzip_decode?;
Async DEFLATE (requires async-io feature)
use ;
use BufReader;
// Async compression
let mut deflater = new;
let compressed = deflater.compress_all.await?;
// Async decompression
let mut inflater = new;
let decompressed = inflater.decompress_all.await?;
Performance
Compression ratios on typical data (Calgary Corpus):
| File | Original | Compressed | Ratio |
|---|---|---|---|
| book1 | 768771 | ~300000 | ~61% |
| paper1 | 53161 | ~18000 | ~66% |
| progc | 39611 | ~13000 | ~67% |
References
License
Apache-2.0