use haagenti_zstd::fse::{
cached_of_table, cloned_of_encoder, BitReader, FseBitWriter, FseDecoder, OFFSET_ACCURACY_LOG,
};
fn main() {
let of_table = cached_of_table();
println!("=== Offset table states by symbol ===");
for sym in 0..8 {
print!("Symbol {:2}: states [", sym);
for state in 0..32 {
if of_table.decode(state).symbol == sym {
print!("{} ", state);
}
}
println!("]");
}
let mut of_encoder = cloned_of_encoder();
println!("\n=== Testing offset code 0 encoding ===");
of_encoder.init_state(0);
let state_for_0 = of_encoder.get_state();
println!("init_state(0) -> state={}", state_for_0);
println!(
" Decodes to symbol: {}",
of_table.decode(state_for_0 as usize).symbol
);
let (bits, num_bits) = of_encoder.encode_symbol(1);
let state_after_1 = of_encoder.get_state();
println!("\nencode_symbol(1) from state {}:", state_for_0);
println!(" bits={}, num_bits={}", bits, num_bits);
println!(" new state={}", state_after_1);
println!(
" New state decodes to symbol: {}",
of_table.decode(state_after_1 as usize).symbol
);
println!("\n=== Testing failing case: codes [3, 0] ===");
of_encoder.init_state(0); let init_state = of_encoder.get_state();
println!("init_state(0) -> state={}", init_state);
let (bits, num_bits) = of_encoder.encode_symbol(3);
let final_state = of_encoder.get_state();
println!("encode_symbol(3) from state {}:", init_state);
println!(" bits={}, num_bits={}", bits, num_bits);
println!(" final state={}", final_state);
println!(
" Final state decodes to symbol: {}",
of_table.decode(final_state as usize).symbol
);
println!("\n=== Build and decode bitstream ===");
let mut writer = FseBitWriter::new();
of_encoder.init_state(0);
let (fse_bits, fse_num_bits) = of_encoder.encode_symbol(3);
let final_state = of_encoder.get_state();
let of_extra_0: u32 = 4;
let of_extra_bits_0: u8 = 3;
let of_extra_1: u32 = 0;
let of_extra_bits_1: u8 = 0;
if of_extra_bits_0 > 0 {
writer.write_bits(of_extra_0, of_extra_bits_0);
}
writer.write_bits(fse_bits, fse_num_bits);
if of_extra_bits_1 > 0 {
writer.write_bits(of_extra_1, of_extra_bits_1);
}
writer.write_bits(final_state, OFFSET_ACCURACY_LOG);
let bitstream = writer.finish();
println!("Bitstream: {:02x?}", bitstream);
let mut reader = BitReader::new(&bitstream);
reader.init_from_end().unwrap();
let mut decoder = FseDecoder::new(of_table);
decoder.init_state(&mut reader).unwrap();
let initial_state = decoder.state();
let symbol_0 = decoder.peek_symbol();
println!(
"\nDecoded initial state: {}, symbol: {}",
initial_state, symbol_0
);
reader.switch_to_lsb_mode().unwrap();
let decoded_extra_0 = if of_extra_bits_0 > 0 {
reader.read_bits(of_extra_bits_0 as usize).unwrap()
} else {
0
};
println!(
"Decoded seq[0] extra: {} (expected {})",
decoded_extra_0, of_extra_0
);
decoder.update_state(&mut reader).unwrap();
let symbol_1 = decoder.peek_symbol();
println!("After update, symbol: {} (expected 0)", symbol_1);
println!("\n=== Verification ===");
println!("seq[0] offset code: expected 3, got {}", symbol_0);
println!("seq[1] offset code: expected 0, got {}", symbol_1);
if symbol_0 == 3 && symbol_1 == 0 {
println!("SUCCESS!");
} else {
println!("MISMATCH!");
}
}