pub(crate) const ALPHABET_SIZE: usize = 128;
#[derive(Clone, Copy)]
pub(crate) struct PrefixCode {
pub(crate) depths: [u8; ALPHABET_SIZE],
pub(crate) bits: [u16; ALPHABET_SIZE],
pub(crate) single_symbol: bool,
}
impl PrefixCode {
pub(crate) const fn zero() -> Self {
Self {
depths: [0; ALPHABET_SIZE],
bits: [0; ALPHABET_SIZE],
single_symbol: false,
}
}
pub(crate) fn update_single_symbol(&mut self) {
self.single_symbol = self.depths.iter().filter(|&&d| d != 0).count() == 1;
}
}
impl Default for PrefixCode {
fn default() -> Self {
Self::zero()
}
}
fn reverse_bits(num_bits: u32, bits: u16) -> u16 {
static LUT: [u16; 16] = [
0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf,
];
let mut retval: u16 = LUT[(bits & 0xf) as usize];
let mut bits = bits >> 4;
let mut i = 4;
while i < num_bits {
retval <<= 4;
retval |= LUT[(bits & 0xf) as usize];
bits >>= 4;
i += 4;
}
retval >> ((4 - (num_bits & 3)) & 3)
}
pub(crate) fn convert_bit_depths_to_symbols(depth: &[u8], bits: &mut [u16]) {
const MAX_BITS: usize = 16;
let mut bl_count = [0u16; MAX_BITS];
for &d in depth {
bl_count[d as usize] += 1;
}
bl_count[0] = 0;
let mut next_code = [0u16; MAX_BITS];
let mut code: u32 = 0;
for i in 1..MAX_BITS {
code = (code + bl_count[i - 1] as u32) << 1;
next_code[i] = code as u16;
}
for (bits, &depth) in bits.iter_mut().zip(depth.iter()) {
if depth != 0 {
let d = depth as u32;
let raw = next_code[d as usize];
*bits = reverse_bits(d, raw);
next_code[d as usize] += 1;
} else {
*bits = 0;
}
}
}