Skip to content

Repository files navigation

Bürli

Pure Rust Brotli codec. The decoder reads standard Brotli streams produced at all normal quality levels. The encoder currently supports qualities 0 through 5.

Why Bürli

Fast q0..q5 encoder. Covers the transfer-oriented part of Brotli's speed/ratio curve, with aggressive skip behavior for low-compressibility input.

Memory safety. Public API has no unsafe. Unsafe is limited to small primitive helpers in the default build. The paranoid feature forbids unsafe in all Bürli crates.

Small API. One-shot helpers for simple use, caller-buffer variants for tight loops, reusable contexts for repeated work, and std::io streaming wrappers when needed.

Performance

Brotli pipeline benchmark

x86_64 details (pipeline, scatter, matrix, small inputs)

per-file pipeline encode speed vs compression ratio Silesia encode speed vs compression ratio per-file encode/decode matrix small input encode throughput small input decode throughput

API

// One-shot (allocating)
let compressed = burli::compress(input, 5)?;
let original   = burli::decompress(&compressed)?;

// One-shot into caller buffer
let n = burli::compress_into(input, &mut output_buf, 5)?;
burli::decompress_into(&compressed, &mut output_vec)?;

// Reusable context
let mut compressor = burli::Compressor::new(5)?;
let compressed = compressor.compress(input)?;

let mut decompressor = burli::Decompressor::new();
let original = decompressor.decompress(&compressed)?;

Streaming

use std::io::{Read, Write};

let mut enc = burli::StreamEncoder::new(Vec::new(), 5)?;
enc.write_all(input)?;
let compressed = enc.finish()?;

let mut dec = burli::StreamDecoder::new(&compressed[..]);
let mut decoded = Vec::new();
dec.read_to_end(&mut decoded)?;

Raw Dictionaries

Raw LZ77 prefix dictionaries are decode-only for now:

let dictionary = burli::decode::RawDictionary::new(bytes);
let original = burli::decompress_with_raw_dictionary(&compressed, &dictionary)?;

Safety

SAFETY.md documents the unsafe boundary and Brotli bug classes that Bürli is designed to prevent.

Bounded decompression is first-class: use decompress_with_options, Decompressor::with_options, StreamDecoder::with_options, or decompress_into_slice for untrusted input. Plain decompress() has no practical output cap.

Current safety checks include Kani coverage for low-level primitives and more than 6 hours of libFuzzer coverage across decode, encode/decode round trips, corruption cases, streaming, and C Brotli cross-checks.

Design

DESIGN.md covers the implemented encode/decode pipeline, bit I/O, Huffman tables, backward copies, dictionaries, streaming, and quality policy.

DEVELOPMENT.md is the contributor workflow reference for builds, tests, releases, fuzzing, benchmarks, and chart regeneration.

Levels

Bürli's encoder covers the fast end of Brotli. q0 favors throughput and may store low-compressibility blocks. q1 through q5 spend progressively more work on matching and entropy coding for better ratios.

The current encoder stops at q5. Brotli q6 through q11 spend much more CPU for ratios that usually matter more for archival storage than transfer pipelines. All implemented qualities produce standard Brotli streams decoded by the same decoder.

About

Fast, memory-safe Rust Brötli codec with all-level decode, q0..q5 encode.

Topics

Resources

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages