use super::{CODE_BOT, SYM_BITS, SYM_MAX, WINDOW_SIZE, ilog};
#[derive(Debug, Clone)]
pub struct RangeDecoder<'a> {
buf: &'a [u8],
offs: usize,
end_offs: usize,
end_window: u32,
nend_bits: u32,
leftover_bit: u32,
val: u32,
rng: u32,
nbits_total: u32,
}
impl<'a> RangeDecoder<'a> {
#[must_use]
pub fn new(buf: &'a [u8]) -> Self {
let b0 = u32::from(buf.first().copied().unwrap_or(0));
let mut dec = RangeDecoder {
buf,
offs: usize::from(!buf.is_empty()),
end_offs: 0,
end_window: 0,
nend_bits: 0,
leftover_bit: b0 & 1,
val: 127 - (b0 >> 1),
rng: 128,
nbits_total: 9,
};
dec.normalize();
dec
}
#[inline]
fn read_byte(&mut self) -> u32 {
match self.buf.get(self.offs) {
Some(&b) => {
self.offs += 1;
u32::from(b)
},
None => 0,
}
}
#[inline]
fn read_byte_from_end(&mut self) -> u32 {
if self.end_offs < self.buf.len() {
self.end_offs += 1;
u32::from(self.buf[self.buf.len() - self.end_offs])
} else {
0
}
}
fn normalize(&mut self) {
while self.rng <= CODE_BOT {
self.nbits_total += SYM_BITS;
self.rng <<= SYM_BITS;
let byte = self.read_byte();
let sym = (self.leftover_bit << 7) | (byte >> 1);
self.leftover_bit = byte & 1;
self.val = ((self.val << SYM_BITS) + (SYM_MAX - sym)) & 0x7FFF_FFFF;
}
}
#[must_use]
pub fn decode(&mut self, ft: u32) -> u32 {
debug_assert!(ft > 0 && ft <= u32::from(u16::MAX));
ft - (self.val / (self.rng / ft) + 1).min(ft)
}
#[must_use]
pub fn decode_bin(&mut self, ftb: u32) -> u32 {
debug_assert!(ftb <= 16);
let ft = 1u32 << ftb;
ft - (self.val / (self.rng >> ftb) + 1).min(ft)
}
pub fn update(&mut self, fl: u32, fh: u32, ft: u32) {
debug_assert!(fl < fh && fh <= ft);
let s = self.rng / ft;
self.val -= s * (ft - fh);
self.rng = if fl > 0 {
s * (fh - fl)
} else {
self.rng - s * (ft - fh)
};
self.normalize();
}
#[must_use]
pub fn decode_bit_logp(&mut self, logp: u32) -> bool {
let r = self.rng;
let d = self.val;
let s = r >> logp;
let bit = d < s;
if !bit {
self.val = d - s;
}
self.rng = if bit { s } else { r - s };
self.normalize();
bit
}
#[must_use]
pub fn decode_icdf(&mut self, icdf: &[u8], ftb: u32) -> usize {
let d = self.val;
let r = self.rng >> ftb;
let mut k = 0usize;
let mut t = self.rng;
let mut s = r * u32::from(icdf[0]);
while d < s {
k += 1;
t = s;
s = r * u32::from(icdf[k]);
}
self.val = d - s;
self.rng = t - s;
self.normalize();
k
}
#[must_use]
pub fn decode_raw_bits(&mut self, bits: u32) -> u32 {
debug_assert!(bits > 0 && bits <= WINDOW_SIZE - SYM_BITS);
if self.nend_bits < bits {
loop {
self.end_window |= self.read_byte_from_end() << self.nend_bits;
self.nend_bits += SYM_BITS;
if self.nend_bits > WINDOW_SIZE - SYM_BITS {
break;
}
}
}
let ret = self.end_window & ((1u32 << bits) - 1);
self.end_window >>= bits;
self.nend_bits -= bits;
self.nbits_total += bits;
ret
}
#[must_use]
pub fn decode_uint(&mut self, ft: u32) -> Option<u32> {
debug_assert!(ft > 1);
let ftb = ilog(ft - 1);
if ftb <= 8 {
let t = self.decode(ft);
self.update(t, t + 1, ft);
Some(t)
} else {
let ft_hi = ((ft - 1) >> (ftb - 8)) + 1;
let t = self.decode(ft_hi);
self.update(t, t + 1, ft_hi);
let t = (t << (ftb - 8)) | self.decode_raw_bits(ftb - 8);
(t < ft).then_some(t)
}
}
#[inline]
#[must_use]
pub fn tell(&self) -> u32 {
self.nbits_total - ilog(self.rng)
}
#[must_use]
pub fn tell_frac(&self) -> u32 {
tell_frac(self.nbits_total, self.rng)
}
pub(crate) fn force_tell(&mut self, bits: u32) {
let current = self.tell();
if bits > current {
self.nbits_total += bits - current;
}
}
pub fn shrink_storage(&mut self, new_len: usize) {
assert!(new_len <= self.buf.len());
assert!(self.end_offs == 0, "shrink before reading raw bits");
self.buf = &self.buf[..new_len];
}
#[inline]
#[must_use]
pub fn range_size(&self) -> u32 {
self.rng
}
}
pub(crate) fn tell_frac(nbits_total: u32, rng: u32) -> u32 {
let mut lg = ilog(rng);
let mut r = rng >> (lg - 16);
for _ in 0..3 {
r = (r * r) >> 15;
let bit = r >> 16;
lg = 2 * lg + bit;
r >>= bit;
}
nbits_total * 8 - lg
}