use crate::ans::spec::Spec;
use crate::ans::AnsState;
use crate::constants::Bitlen;
#[derive(Clone, Debug)]
pub struct Node {
pub next_state_idx_base: u16,
pub offset_bits: u8,
pub bits_to_read: u8,
}
#[derive(Clone, Debug)]
pub struct Decoder {
pub nodes: Vec<Node>,
}
impl Decoder {
pub fn new(spec: &Spec, bin_offset_bits: &[Bitlen]) -> Self {
let table_size = spec.table_size();
let mut nodes = Vec::with_capacity(table_size);
let mut symbol_x_s = spec.symbol_weights.clone();
for &symbol in &spec.state_symbols {
let next_state_base = symbol_x_s[symbol as usize] as AnsState;
let bits_to_read = next_state_base.leading_zeros() - (table_size as AnsState).leading_zeros();
let next_state_base = next_state_base << bits_to_read;
let offset_bits = bin_offset_bits.get(symbol as usize).cloned().unwrap_or(0);
nodes.push(Node {
next_state_idx_base: (next_state_base - table_size as AnsState) as u16,
offset_bits: offset_bits as u8,
bits_to_read: bits_to_read as u8,
});
symbol_x_s[symbol as usize] += 1;
}
Self { nodes }
}
}