use std::io::Cursor;
fn main() {
let mut input = Vec::new();
for _ in 0..50 {
input.extend_from_slice(b"ABCDEFGH");
}
input.extend_from_slice(b"XXX");
for _ in 0..30 {
input.extend_from_slice(b"IJKLMNOP");
}
input.extend_from_slice(b"YYY");
for _ in 0..20 {
input.extend_from_slice(b"QRSTUVWX");
}
println!("Input size: {} bytes", input.len());
use haagenti_core::{CompressionLevel, Compressor};
use haagenti_zstd::ZstdCompressor;
let compressor = ZstdCompressor::with_level(CompressionLevel::Fast);
let compressed = compressor.compress(&input).unwrap();
println!("Compressed: {} bytes", compressed.len());
let block_header =
compressed[6] as u32 | ((compressed[7] as u32) << 8) | ((compressed[8] as u32) << 16);
let block_type = (block_header >> 1) & 0x03;
let block_size = block_header >> 3;
println!("Block type: {} (0=Raw, 1=RLE, 2=Compressed)", block_type);
println!("Block size: {}", block_size);
if block_type == 2 {
let block_start = 9;
let lit_header = compressed[block_start];
let lit_size_type = (lit_header >> 2) & 0x03;
let (lit_header_size, lit_size) = match lit_size_type {
0 => (1, (lit_header >> 3) as usize),
1 => (
2,
((lit_header >> 4) as usize) | ((compressed[block_start + 1] as usize) << 4),
),
_ => (3, 0),
};
println!(
"Literals: header_size={}, content_size={}",
lit_header_size, lit_size
);
let seq_start = block_start + lit_header_size + lit_size;
let seq_count = compressed[seq_start];
let mode_byte = if seq_count > 0 {
compressed[seq_start + 1]
} else {
0
};
println!("Sequences start at offset {}", seq_start);
println!("Sequence count: {}", seq_count);
println!(
"Mode byte: 0x{:02x} (LL={}, OF={}, ML={})",
mode_byte,
mode_byte & 3,
(mode_byte >> 2) & 3,
(mode_byte >> 4) & 3
);
let bitstream_start = seq_start + 2;
let bitstream = &compressed[bitstream_start..];
println!("Bitstream ({} bytes): {:02x?}", bitstream.len(), bitstream);
}
match zstd::decode_all(Cursor::new(&compressed)) {
Ok(decoded) if decoded == input => {
println!("\nSUCCESS! Reference zstd decoded {} bytes", decoded.len());
}
Ok(decoded) => {
println!("\nMISMATCH! {} vs {} bytes", input.len(), decoded.len());
}
Err(e) => println!("\nFAILED: {:?}", e),
}
use haagenti_core::Decompressor;
let decompressor = haagenti_zstd::ZstdDecompressor;
match decompressor.decompress(&compressed) {
Ok(decoded) if decoded == input => println!("Our roundtrip: OK"),
_ => println!("Our roundtrip: FAILED"),
}
}