use crate::{Error, Result};
pub struct BitReader<'a> {
data: &'a [u8],
pos: usize, }
impl<'a> BitReader<'a> {
pub fn new(data: &'a [u8]) -> BitReader<'a> {
BitReader { data, pos: 0 }
}
pub fn bit_pos(&self) -> usize {
self.pos
}
pub fn f1(&mut self) -> Result<u32> {
let byte = self.pos / 8;
if byte >= self.data.len() {
return Err(Error::invalid("vp9: bit reader past end"));
}
let bit = (self.data[byte] >> (7 - (self.pos % 8))) & 1;
self.pos += 1;
Ok(bit as u32)
}
pub fn f(&mut self, n: u32) -> Result<u32> {
let mut v = 0u32;
for _ in 0..n {
v = (v << 1) | self.f1()?;
}
Ok(v)
}
pub fn s(&mut self, n: u32) -> Result<i32> {
let value = self.f(n)? as i32;
if self.f1()? == 1 {
Ok(-value)
} else {
Ok(value)
}
}
}
pub struct BoolDecoder<'a> {
data: &'a [u8],
pos: usize, value: u64, count: i32, range: u32,
}
const LOTS_OF_BITS: i32 = 0x4000_0000;
impl<'a> BoolDecoder<'a> {
pub fn new(data: &'a [u8]) -> Result<BoolDecoder<'a>> {
if data.is_empty() {
return Err(Error::invalid("vp9: empty bool decoder input"));
}
let mut d = BoolDecoder {
data,
pos: 0,
value: 0,
count: -8,
range: 255,
};
d.fill();
let _marker = d.read_bool(128);
Ok(d)
}
pub fn bit_pos(&self) -> usize {
self.pos.min(self.data.len()) * 8
}
#[inline]
fn fill(&mut self) {
let mut shift = 64 - 8 - (self.count + 8); let bytes_left = self.data.len() - self.pos;
if bytes_left * 8 > 64 {
let bits = (shift & !7) + 8;
let mut be = [0u8; 8];
be.copy_from_slice(&self.data[self.pos..self.pos + 8]);
let nv = u64::from_be_bytes(be) >> (64 - bits);
self.count += bits;
self.pos += (bits >> 3) as usize;
self.value |= nv << (shift & 7);
} else {
let bits_over = shift + 8 - (bytes_left * 8) as i32;
let mut loop_end = 0;
if bits_over >= 0 {
self.count += LOTS_OF_BITS;
loop_end = bits_over;
}
if bits_over < 0 || bytes_left > 0 {
while shift >= loop_end {
self.count += 8;
let byte = self.data.get(self.pos).copied().unwrap_or(0);
self.pos += 1;
self.value |= (byte as u64) << shift;
shift -= 8;
}
}
}
}
#[inline]
pub fn read_bool(&mut self, prob: u8) -> u32 {
let split = (self.range * prob as u32 + (256 - prob as u32)) >> 8;
if self.count < 0 {
self.fill();
}
let bigsplit = (split as u64) << 56;
let mut range = split;
let mut value = self.value;
let bit = if value >= bigsplit {
range = self.range - split;
value -= bigsplit;
1
} else {
0
};
let s = (range as u8).leading_zeros();
self.range = range << s;
self.value = value << s;
self.count -= s as i32;
bit
}
pub fn literal(&mut self, n: u32) -> u32 {
let mut v = 0u32;
for _ in 0..n {
v = (v << 1) | self.read_bool(128);
}
v
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn bitreader_msb_first() {
let mut r = BitReader::new(&[0xA2, 0x49]);
assert_eq!(r.f(2).unwrap(), 0b10); assert_eq!(r.f1().unwrap(), 1); assert_eq!(r.f1().unwrap(), 0); assert_eq!(r.f(4).unwrap(), 0b0010);
assert_eq!(r.f(8).unwrap(), 0x49);
}
#[test]
fn bool_decoder_runs() {
let mut b = BoolDecoder::new(&[0x80, 0x00, 0xFF, 0x55]).unwrap();
let _ = b.literal(8);
let _ = b.read_bool(128);
assert!(b.range >= 128);
}
}