use crate::bit_reader::BitReader;
use crate::entropy_coding::decode::unpack_signed;
use crate::entropy_coding::hybrid_uint::HybridUint;
fn pack_signed(value: i32) -> u32 {
if value >= 0 {
(value as u32) << 1
} else {
((-value as u32) << 1) - 1
}
}
#[cfg(test)]
mod hybrid_uint_tests {
use super::*;
#[test]
fn test_hybrid_uint_config_000() {
let config = HybridUint::new(0, 0, 0);
let mut acc = 0u32;
let data = [0u8; 4];
let mut br = BitReader::new(&data);
assert_eq!(config.read(0, &mut br, &mut acc), 0);
let mut br = BitReader::new(&data);
assert_eq!(config.read(1, &mut br, &mut acc), 1);
let data = [0b00000000u8]; let mut br = BitReader::new(&data);
assert_eq!(config.read(2, &mut br, &mut acc), 2);
let data = [0b00000001u8]; let mut br = BitReader::new(&data);
assert_eq!(config.read(2, &mut br, &mut acc), 3);
assert!(acc < 32, "no overflow expected");
}
#[test]
fn test_hybrid_uint_config_411() {
let config = HybridUint::new(4, 1, 1);
let mut acc = 0u32;
let data = [0u8; 4];
let mut br = BitReader::new(&data);
assert_eq!(config.read(0, &mut br, &mut acc), 0);
let mut br = BitReader::new(&data);
assert_eq!(config.read(15, &mut br, &mut acc), 15);
let data = [0b00000000u8];
let mut br = BitReader::new(&data);
assert_eq!(config.read(16, &mut br, &mut acc), 16);
assert!(acc < 32);
}
#[test]
fn test_hybrid_uint_config_420() {
let config = HybridUint::new(4, 2, 0);
let mut acc = 0u32;
let data = [0u8; 4];
let mut br = BitReader::new(&data);
assert_eq!(config.read(0, &mut br, &mut acc), 0);
let mut br = BitReader::new(&data);
assert_eq!(config.read(8, &mut br, &mut acc), 8);
let mut br = BitReader::new(&data);
assert_eq!(config.read(15, &mut br, &mut acc), 15);
let data = [0b00000000u8];
let mut br = BitReader::new(&data);
assert_eq!(config.read(16, &mut br, &mut acc), 16);
assert!(acc < 32);
}
#[test]
fn test_hybrid_uint_config_421() {
let config = HybridUint::new(4, 2, 1);
let mut acc = 0u32;
let data = [0u8; 4];
let mut br = BitReader::new(&data);
assert_eq!(config.read(0, &mut br, &mut acc), 0);
let mut br = BitReader::new(&data);
assert_eq!(config.read(15, &mut br, &mut acc), 15);
let data = [0b00000000u8];
let mut br = BitReader::new(&data);
assert_eq!(config.read(16, &mut br, &mut acc), 16);
assert!(acc < 32);
}
#[test]
fn test_hybrid_uint_various_values() {
let configs = [
HybridUint::new(0, 0, 0),
HybridUint::new(4, 1, 1),
HybridUint::new(4, 2, 0),
HybridUint::new(4, 2, 1),
HybridUint::new(5, 2, 2),
HybridUint::new(6, 0, 0),
];
for config in &configs {
let data = [0u8; 8];
let mut br = BitReader::new(&data);
let mut acc = 0u32;
assert_eq!(config.read(0, &mut br, &mut acc), 0);
}
}
}
#[cfg(test)]
mod pack_unpack_tests {
use super::*;
#[test]
fn test_pack_unpack_roundtrip() {
for i in -31i32..=31 {
let packed = pack_signed(i);
assert!(
packed < 63,
"pack_signed({}) = {} should be < 63",
i,
packed
);
let unpacked = unpack_signed(packed);
assert_eq!(
i, unpacked,
"Roundtrip failed: {} -> {} -> {}",
i, packed, unpacked
);
}
}
#[test]
fn test_pack_signed_specific_values() {
assert_eq!(pack_signed(0), 0);
assert_eq!(pack_signed(1), 2);
assert_eq!(pack_signed(-1), 1);
assert_eq!(pack_signed(2), 4);
assert_eq!(pack_signed(-2), 3);
}
#[test]
fn test_unpack_signed_specific_values() {
assert_eq!(unpack_signed(0), 0);
assert_eq!(unpack_signed(1), -1);
assert_eq!(unpack_signed(2), 1);
assert_eq!(unpack_signed(3), -2);
assert_eq!(unpack_signed(4), 2);
}
#[test]
fn test_pack_unpack_large_range() {
for i in -1000i32..=1000 {
let packed = pack_signed(i);
let unpacked = unpack_signed(packed);
assert_eq!(i, unpacked, "Roundtrip failed for {}", i);
}
}
}
#[cfg(test)]
mod ans_tests {
use super::*;
#[test]
fn test_bit_reader_basic() {
let data = [0xFFu8, 0x00, 0xAA, 0x55];
let mut br = BitReader::new(&data);
let val = br.read(8).unwrap();
assert_eq!(val, 0xFF);
let val = br.read(8).unwrap();
assert_eq!(val, 0x00);
}
#[test]
fn test_bit_reader_partial_bytes() {
let data = [0b10101010u8, 0b01010101];
let mut br = BitReader::new(&data);
let val1 = br.read(4).unwrap();
let val2 = br.read(4).unwrap();
let val3 = br.read(4).unwrap();
let val4 = br.read(4).unwrap();
assert_eq!(val1, 0b1010);
assert_eq!(val2, 0b1010);
assert_eq!(val3, 0b0101);
assert_eq!(val4, 0b0101);
}
}
#[cfg(test)]
mod lz77_tests {
#[test]
fn test_lz77_special_distances() {
let special_distances: [(i8, u8); 10] = [
(0, 1),
(1, 0),
(1, 1),
(-1, 1),
(0, 2),
(2, 0),
(1, 2),
(-1, 2),
(2, 1),
(-2, 1),
];
for (i, (dx, dy)) in special_distances.iter().enumerate() {
let manhattan = dx.unsigned_abs() as u32 + *dy as u32;
assert!(manhattan > 0, "Distance {} should be non-zero", i);
}
}
#[test]
fn test_lz77_window_size() {
const LOG_WINDOW_SIZE: u32 = 20;
const WINDOW_SIZE: u32 = 1 << LOG_WINDOW_SIZE;
const WINDOW_MASK: u32 = WINDOW_SIZE - 1;
assert_eq!(WINDOW_SIZE, 1048576);
assert_eq!(WINDOW_MASK, 1048575);
assert_eq!(WINDOW_MASK, 0xFFFFF);
}
}
#[cfg(test)]
mod prefix_tests {
use super::*;
#[test]
fn test_prefix_code_simple_alphabet() {
let data = [0b01u8];
let mut br = BitReader::new(&data);
assert_eq!(br.read(1).unwrap(), 1);
assert_eq!(br.read(1).unwrap(), 0);
}
#[test]
fn test_prefix_code_variable_length() {
let data = [0b11100100u8, 0b00000001];
let mut br = BitReader::new(&data);
let v1 = br.read(1).unwrap(); let v2 = br.read(2).unwrap(); let v3 = br.read(3).unwrap(); let v4 = br.read(2).unwrap();
assert_eq!(v1, 0);
assert_eq!(v2, 2);
assert_eq!(v3, 4);
assert_eq!(v4, 3);
}
#[test]
fn test_huffman_max_bits() {
use crate::entropy_coding::huffman::HUFFMAN_MAX_BITS;
assert_eq!(HUFFMAN_MAX_BITS, 15);
}
}
#[cfg(test)]
mod context_map_tests {
#[test]
fn test_context_map_limits() {
let max_context_id: u8 = 255;
assert_eq!(max_context_id as u32, 255);
let max_contexts: usize = 256;
assert!(max_contexts <= 256);
}
}