msrtc-rans
Safe public Rust entropy-coder API for msrtc_rans.
This crate provides the high-level entropy coder API, wrapping the raw rANS primitives from msrtc-rans-core with PMF validation, CDF table construction, bypass coding, distribution descriptors, persistent streams, and the resizable buffer allocation layer.
Status — Phases 3 + 4 Sealed ✅
| Feature | Status |
|---|---|
EntropyEncoder |
✅ Implemented and courted |
EntropyDecoder |
✅ Implemented and courted |
| PMF validation | ✅ Implemented and courted |
| CDF table construction | ✅ Implemented and courted |
| Bypass coding (variable-width) | ✅ Implemented and courted |
RansEncoderStream (persistent push) |
✅ Sealed — MSRTC.STREAM.DIFFERENTIAL 24/24 |
RansDecoderStream (persistent cursor) |
✅ Sealed — MSRTC.STREAM.DIFFERENTIAL 24/24 |
ResizableBuffer / HeapResizableBuffer |
✅ Implemented — Microsoft growth formula |
| Entropy differential court | ✅ Sealed (6/6 cases) |
| Stream differential court | ✅ Sealed (24/24 cases) |
The full entropy encode/decode pipeline (PMF → CDF → bypass) and the persistent stream layer have been verified byte-for-byte against the pinned Microsoft C++ oracle. All 46 tests in this crate pass.
Features
#![forbid(unsafe_code)]— pure safe Rust- Both RansByte (u8) and Rans64 (u32) variant support
- PMF validation: rejects empty tables, invalid dimensions, zero frequencies
- Bypass coding for out-of-range values with configurable bypass bits
- Mixed in-range and bypass value streams
- Persistent streams — one raw rANS state across
push()calls (MicrosoftRawRansEncoderStream); LIFO multipart layout - Resizable buffer —
new = old + min(old, max_size_step)growth, rollback, backward-writing sink - Comprehensive error handling via
EntropyErrorenum - Re-exports all
msrtc-rans-coretypes and traits
Usage
Entropy Encoding/Decoding
use EntropyEncoder;
use RansByte;
let mut encoder = new;
let pmf_lengths = vec!;
let pmf_offsets = vec!;
let pmf_table = vec!; // frequencies
let symbol_bits = 16;
let bypass_bits = 4;
encoder.initialize
.expect;
let indices = vec!;
let values = vec!;
let mut buffer = Vecnew;
encoder.encode.expect;
Multipart stream (persistent encoder)
use EntropyEncoder;
use ;
use RansByte;
// Batch A pushed first, batch B second → decode B first, then A (LIFO).
let mut stream = new;
stream.push.expect;
stream.push.expect;
let data = stream.flush.expect;
let mut dstream = open_on;
// decode batch B, then batch A, then decode_eof().
Resizable buffer
use ;
let mut buffer = new;
let mut sink = new;
sink.write_u8;
sink.write_u8;
assert_eq!; // backward-written
Raw rANS (re-exported from msrtc-rans-core)
use ;
let sink = new;
let mut encoder = new;
encoder.put_raw;
encoder.flush;
let encoded = encoder.into_sink.encoded.to_vec;
let source = new;
let mut decoder = new;
assert!;
assert!;
assert!;
Repository
Full project: github.com/infinityabundance/msrtc-rans-rs