use crate::canonical::CanonicalCodes;
use crate::CodeMap;
#[derive(Debug, Clone)]
pub struct Encoded {
pub bits: Vec<u8>,
pub bit_length: usize,
}
pub fn encode(data: &[u8], codes: &CanonicalCodes) -> Encoded {
encode_with_map(data, codes.map())
}
pub fn encode_with_map(data: &[u8], map: &CodeMap) -> Encoded {
let mut bits: Vec<u8> = Vec::new();
let mut current: u64 = 0;
let mut current_len: u8 = 0;
let mut total_bits: usize = 0;
for &symbol in data {
let (code, len) = map[&symbol];
current = (current << len) | code;
current_len += len;
while current_len >= 8 {
current_len -= 8;
bits.push(((current >> current_len) & 0xFF) as u8);
}
total_bits += len as usize;
}
if current_len > 0 {
bits.push(((current << (8 - current_len)) & 0xFF) as u8);
}
Encoded {
bits,
bit_length: total_bits,
}
}
pub fn encoded_bit_length(data: &[u8], codes: &CanonicalCodes) -> usize {
let mut total = 0;
for &symbol in data {
if let Some(&(_, len)) = codes.get(&symbol) {
total += len as usize;
}
}
total
}