Expand description
PPMd variant H (7-Zip’s “Ppmd7”) compression and decompression.
ppmd-turbo implements Dmitry Shkarin’s PPMd variant H context model, its
sub-allocator and secondary escape estimation, and the two range coders
that carry it in the wild:
- the LZMA-style range coder 7-Zip uses for the
PPMDmethod in.7z(SevenZDecoder,SevenZEncoder), and - the carry-less range coder RAR 2.9 through 4.x uses for its PPMd blocks
(
RarPpmd; RAR5 has no PPMd).
Output is bit-exact with 7-Zip and RARLAB unrar: a 7z stream encoded here
is byte-identical to 7-Zip’s for the same parameters, and a RAR stream
decodes to exactly what unrar produces. Writing RAR blocks or archives is
out of scope by design; CarrylessEncoder and CarrylessDecoder
handle raw carry-less streams for round-trip testing only.
§The step API
Every codec is a step machine over slices the caller owns: a call takes
input and an output slice and reports a Progress with exact
consumed and produced counts and a status. The codecs never keep
caller bytes between calls; a non-final call decodes only while a whole
symbol’s worth of input (Params::max_input_per_symbol, at most
MAX_INPUT_PER_SYMBOL) remains. Model memory is an Arena the
caller can reuse across streams. Errors are typed (ErrorKind),
Copy, carry the stream Position, and are sticky until a reset. The
io module wraps the 7z pair in Read and Write.
use ppmd_turbo::{Params, SevenZDecoder, SevenZEncoder, SevenZStatus};
let data = b"the quick brown fox jumps over the lazy dog";
let params = Params::new(6, 1 << 20)?.reduced_for(data.len() as u64);
let mut encoder = SevenZEncoder::new(params)?;
let mut stream = vec![0u8; 128];
let mut len = encoder.encode(data, &mut stream)?.produced;
while !{
let fin = encoder.finish(&mut stream[len..], false)?;
len += fin.produced;
fin.done
} {}
let mut decoder = SevenZDecoder::new(params, Some(data.len() as u64))?;
let mut out = vec![0u8; data.len()];
let step = decoder.decode(&stream[..len], true, &mut out)?;
assert_eq!(step.status, SevenZStatus::ReachedSize);
assert_eq!(step.consumed, len);
assert_eq!(&out[..], data);§Features
std(default): theioadapters, theio::Errorconversion and run-time x86 SIMD detection. Without it the crate builds oncoreandalloc, choosing SIMD tiers at compile time; this is checked, not promised.Errorimplementscore::error::Erroreither way.internals: the engine, for the crate’s own fuzz targets, benches and differential tests. Hidden and unstable.
unsafe is permitted where it pays for itself, and only with a
// SAFETY: proof on every block, Miri coverage where Miri can run, and a
fuzz target over every decoder and encoder entry point.
Re-exports§
pub use carryless::CarrylessDecoder;pub use carryless::CarrylessEncoder;pub use rar::RarPpmd;pub use rar::RarStatus;pub use rar::Symbol;pub use sevenz::Finish;pub use sevenz::SevenZDecoder;pub use sevenz::SevenZEncoder;pub use sevenz::SevenZStatus;
Modules§
- carryless
- Raw carry-less PPMd streams.
- io
std ReadandWriteover the 7z step codecs, for code built onstd::io(a 7z coder chain, command-line tools).- rar
- The RAR framing.
- sevenz
- The 7z framing: the
PPMDmethod (03 04 01) as.7zcarries it.
Structs§
- Arena
- The memory a model’s sub-allocator works in.
- Error
- An error from a decoder or encoder, with the stream position it was found at.
- Params
- The model order and arena size of a PPMd variant H stream, checked against the limits variant H accepts.
- Position
- Where in a stream an error was found.
- Progress
- What one step call did.
Enums§
- Error
Kind - What went wrong.
Constants§
- MAX_
INPUT_ PER_ SYMBOL - The most input any decoder in the crate takes for one symbol, at the
largest order:
4 * (64 + 2)bytes of the carry-less coder. A caller that always presents at least this many bytes (or the last of its input) never seesNeedInputwith input left to give.
Type Aliases§
- Result
- The result type used throughout the crate.