use crate::error::Error;
const K_TOP_VALUE: u32 = 1 << 24;
pub(super) struct ByteSource<'a> {
pub buf: &'a [u8],
pub pos: usize,
}
impl<'a> ByteSource<'a> {
pub fn new(buf: &'a [u8], pos: usize) -> Self {
Self { buf, pos }
}
#[inline]
pub fn read(&mut self) -> Result<u8, Error> {
let b = *self.buf.get(self.pos).ok_or(Error::UnexpectedEnd)?;
self.pos += 1;
Ok(b)
}
}
#[derive(Clone, Debug)]
pub(super) struct RangeDec {
pub range: u32,
pub code: u32,
pub pos: usize,
}
impl RangeDec {
pub fn new() -> Self {
Self {
range: 0,
code: 0,
pos: 0,
}
}
pub fn init(&mut self, buf: &[u8]) -> Result<bool, Error> {
if buf.len() < self.pos + 5 {
return Ok(false);
}
if buf[self.pos] != 0 {
return Err(Error::Corrupt);
}
let b1 = buf[self.pos + 1] as u32;
let b2 = buf[self.pos + 2] as u32;
let b3 = buf[self.pos + 3] as u32;
let b4 = buf[self.pos + 4] as u32;
self.code = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
self.range = 0xFFFF_FFFF;
self.pos += 5;
if self.code == 0xFFFF_FFFF {
return Err(Error::Corrupt);
}
Ok(true)
}
#[inline]
pub fn get_threshold(&mut self, total: u32) -> u32 {
self.range /= total;
self.code / self.range
}
#[inline]
pub fn decode(&mut self, src: &mut ByteSource<'_>, start: u32, size: u32) -> Result<(), Error> {
self.code = self.code.wrapping_sub(start.wrapping_mul(self.range));
self.range = self.range.wrapping_mul(size);
self.normalize(src)
}
#[inline]
pub fn normalize(&mut self, src: &mut ByteSource<'_>) -> Result<(), Error> {
if self.range < K_TOP_VALUE {
self.code = (self.code << 8) | src.read()? as u32;
self.range <<= 8;
if self.range < K_TOP_VALUE {
self.code = (self.code << 8) | src.read()? as u32;
self.range <<= 8;
}
}
Ok(())
}
#[inline]
pub fn is_finished_ok(&self) -> bool {
self.code == 0
}
}