extern crate alloc;
use alloc::vec::Vec;
pub struct BitReader<'a> {
data: &'a [u8],
byte_pos: usize,
acc: u32,
nbits: u32,
avail_bits: u64,
consumed_bits: u64,
}
impl<'a> BitReader<'a> {
pub fn new(data: &'a [u8]) -> Self {
Self {
data,
byte_pos: 0,
acc: 0,
nbits: 0,
avail_bits: (data.len() as u64) * 8,
consumed_bits: 0,
}
}
pub fn overran(&self) -> bool {
self.consumed_bits > self.avail_bits
}
fn fill(&mut self, n: u32) {
while self.nbits < n {
let byte = if self.byte_pos < self.data.len() {
let b = self.data[self.byte_pos];
self.byte_pos += 1;
b as u32
} else {
0
};
self.acc = (self.acc << 8) | byte;
self.nbits += 8;
}
}
pub fn get_bits(&mut self, n: u32) -> u32 {
if n == 0 {
return 0;
}
self.fill(n);
let shift = self.nbits - n;
let val = (self.acc >> shift) & ((1u32 << n) - 1);
self.nbits = shift;
self.acc &= (1u32 << self.nbits).wrapping_sub(1);
self.consumed_bits += n as u64;
val
}
pub fn peek_bits(&mut self, n: u32) -> u32 {
if n == 0 {
return 0;
}
self.fill(n);
let shift = self.nbits - n;
(self.acc >> shift) & ((1u32 << n) - 1)
}
pub fn consume(&mut self, n: u32) {
self.fill(n);
self.nbits -= n;
self.acc &= (1u32 << self.nbits).wrapping_sub(1);
self.consumed_bits += n as u64;
}
}
pub struct BitWriter {
out: Vec<u8>,
acc: u32,
nbits: u32,
}
impl BitWriter {
pub fn new() -> Self {
Self {
out: Vec::new(),
acc: 0,
nbits: 0,
}
}
pub fn put_bits(&mut self, n: u32, val: u32) {
if n == 0 {
return;
}
let masked = val & ((1u32.checked_shl(n).unwrap_or(0)).wrapping_sub(1));
self.acc = (self.acc << n) | masked;
self.nbits += n;
while self.nbits >= 8 {
let shift = self.nbits - 8;
self.out.push(((self.acc >> shift) & 0xFF) as u8);
self.nbits = shift;
}
self.acc &= (1u32 << self.nbits).wrapping_sub(1);
}
pub fn finish(mut self) -> Vec<u8> {
if self.nbits > 0 {
let pad = 8 - self.nbits;
self.out.push(((self.acc << pad) & 0xFF) as u8);
self.nbits = 0;
}
self.out
}
}