lzma_sdk_rs/lib.rs
1//! # lzma-sdk-rs
2//!
3//! A pure-Rust port of the **7-zip LZMA SDK 23.01** single-threaded LZMA encoder
4//! whose output is **byte-identical** to the C `LzmaEnc_MemEncode(...)` for the
5//! same input and properties.
6//!
7//! The emitted stream is a **raw LZMA stream**: no 13-byte `.lzma` file header
8//! and no end-of-stream marker, exactly matching `LzmaEnc_MemEncode` called with
9//! `writeEndMark = 0`. The 5 decoder property bytes are produced separately by
10//! [`decoder_props`] (the equivalent of `LzmaEnc_WriteProperties`).
11//!
12//! This crate is consumed by `chd-rs` and others that need to *recreate* the exact
13//! bytes 7-zip / MAME's CHD codec would produce. See `CLAUDE.md` for the porting
14//! map, the bit-exactness hazards, and the differential-test rig.
15//!
16//! ## Status
17//!
18//! [`encode`] is **byte-exact** with the C `LzmaEnc_MemEncode` across a broad
19//! corpus, verified out-of-tree against the C oracle (see
20//! `docs/comparing-against-the-c-oracle.md`). The match finder, optimal parser,
21//! decoder, and symbol layer are all complete. See `ROADMAP.md`.
22
23mod price;
24mod props;
25mod rangecoder;
26mod state;
27
28mod matchfinder;
29mod optimum;
30
31mod encoder;
32
33#[cfg(any(test, feature = "decode"))]
34mod decoder;
35
36#[cfg(test)]
37mod roundtrip_tests;
38
39pub use props::LzmaProps;
40
41/// Encode `input` into a raw LZMA stream that is byte-identical to
42/// `LzmaEnc_MemEncode(..., writeEndMark = 0, ...)` for the same `props`.
43///
44/// The returned bytes carry **no** `.lzma` header and **no** end marker. Obtain
45/// the 5 decoder property bytes with [`decoder_props`].
46pub fn encode(input: &[u8], props: &LzmaProps) -> Vec<u8> {
47 encoder::encode(input, props)
48}
49
50/// The 5 decoder property bytes for `props`, identical to
51/// `LzmaEnc_WriteProperties`.
52///
53/// Byte 0 packs `(pb*5 + lp)*9 + lc`; bytes 1..5 are the little-endian *aligned*
54/// dictionary size (see [`LzmaProps::decoder_props`] — the encoder rounds the
55/// dictionary up before writing it, it does not emit the raw `dict_size`).
56pub fn decoder_props(props: &LzmaProps) -> [u8; 5] {
57 props.decoder_props()
58}
59
60/// Decode a raw LZMA stream (no header, no end marker) of known output length.
61///
62/// A port of `LzmaDec` provided for round-trip self-tests. Available to external
63/// consumers only with the `decode` feature enabled.
64#[cfg(any(test, feature = "decode"))]
65pub fn decode_raw(input: &[u8], props: &[u8; 5], out_len: usize) -> Vec<u8> {
66 decoder::decode_raw(input, props, out_len)
67}