| Crates.io | oxiarc-lzma |
| lib.rs | oxiarc-lzma |
| version | 0.1.0 |
| created_at | 2026-01-12 08:14:36.900374+00 |
| updated_at | 2026-01-12 08:14:36.900374+00 |
| description | LZMA/LZMA2 compression for OxiArc (placeholder) |
| homepage | |
| repository | https://github.com/cool-japan/oxiarc |
| max_upload_size | |
| id | 2037242 |
| size | 102,616 |
Pure Rust implementation of LZMA (Lempel-Ziv-Markov chain Algorithm) compression.
LZMA is a high-ratio compression algorithm that combines:
It's used in:
use oxiarc_lzma::{compress, decompress_bytes, LzmaLevel};
// Compress with default level
let data = b"Hello, World! Hello, World!";
let compressed = compress(data, LzmaLevel::DEFAULT)?;
// Decompress
let decompressed = decompress_bytes(&compressed)?;
assert_eq!(&decompressed, data);
| Level | Dictionary | Use Case |
|---|---|---|
| 0 | 64 KB | Fastest, minimal compression |
| 1 | 256 KB | Fast compression |
| 2 | 512 KB | Fast compression |
| 3 | 1 MB | Balanced |
| 4 | 2 MB | Balanced |
| 5 | 4 MB | Balanced |
| 6 | 8 MB | Default, good ratio |
| 7 | 16 MB | Better ratio |
| 8 | 32 MB | High ratio |
| 9 | 64 MB | Maximum ratio |
+------------------+
| Properties (1B) | lc, lp, pb encoded
+------------------+
| Dict Size (4B) | Little-endian
+------------------+
| Uncomp Size (8B) | Little-endian, 0xFF...FF = unknown
+------------------+
| Compressed Data | Range-coded LZMA
+------------------+
The properties byte encodes three parameters:
properties = (pb * 5 + lp) * 9 + lc
LZMA uses range coding with:
prob += (target - prob) >> 5LZMA has 12 states representing recent history:
| State | After Literal | After Match | After Rep |
|---|---|---|---|
| 0 | 0 | 7 | 8 |
| 1 | 0 | 7 | 8 |
| ... | ... | ... | ... |
| 11 | 0 | 10 | 11 |
| Model | Purpose | Size |
|---|---|---|
| is_match | Literal vs match | 12 * num_pos_states |
| is_rep | Match vs rep | 12 |
| is_rep0 | Rep0 vs rep1/2/3 | 12 |
| is_rep0_long | Long rep0 vs short | 12 * num_pos_states |
| is_rep1 | Rep1 vs rep2/3 | 12 |
| is_rep2 | Rep2 vs rep3 | 12 |
| literal | Literal bytes | 768 * num_lit_states |
| match_len | Match lengths | varies |
| rep_len | Rep lengths | varies |
| distance | Distance slots | 4 * 64 |
use oxiarc_lzma::{compress, compress_raw, LzmaEncoder, LzmaLevel};
// One-shot compression
let compressed = compress(data, LzmaLevel::DEFAULT)?;
// Raw compression (no header)
let raw = compress_raw(data, LzmaLevel::DEFAULT)?;
// Streaming encoder
let mut encoder = LzmaEncoder::new(LzmaLevel::DEFAULT);
let compressed = encoder.compress(data)?;
use oxiarc_lzma::{decompress, decompress_bytes, decompress_raw, LzmaDecoder};
use std::io::Cursor;
// From reader (with header)
let decompressed = decompress(Cursor::new(compressed))?;
// From bytes
let decompressed = decompress_bytes(&compressed)?;
// Raw decompression (no header)
let props = LzmaProperties::new(3, 0, 2);
let decompressed = decompress_raw(reader, props, dict_size, Some(uncompressed_size))?;
use oxiarc_lzma::LzmaProperties;
let props = LzmaProperties::new(3, 0, 2); // lc=3, lp=0, pb=2
let byte = props.to_byte(); // 0x5D
let decoded = LzmaProperties::from_byte(byte)?;
use oxiarc_lzma::{RangeEncoder, RangeDecoder};
// Encoder
let mut encoder = RangeEncoder::new();
encoder.encode_bit(&mut prob, bit);
encoder.encode_direct_bits(value, num_bits);
let output = encoder.finish();
// Decoder
let mut decoder = RangeDecoder::new(reader)?;
let bit = decoder.decode_bit(&mut prob)?;
let value = decoder.decode_direct_bits(num_bits)?;
| Module | Description |
|---|---|
encoder |
LZMA compression |
decoder |
LZMA decompression |
model |
Probability models |
range_coder |
Range encoder/decoder |
| Codec | Ratio | Speed | Memory |
|---|---|---|---|
| DEFLATE | Good | Fast | Low |
| LZMA | Excellent | Slow | High |
| Zstd | Very Good | Fast | Medium |
| BZip2 | Very Good | Medium | Medium |
MIT OR Apache-2.0