pub use super::ans::Probability;
#[cfg(test)]
use super::Millibits;
use super::{EntropyCoder, EntropyDecoder};
#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Raw {
bits: Vec<u8>,
num_bits: u32,
#[cfg(test)]
entropy: Millibits,
}
impl EntropyCoder for Raw {
#[inline]
fn encode_bit(&mut self, _probability: Probability, bit: bool) {
#[cfg(test)]
{
self.entropy += _probability.millibits(bit);
}
let bit = u8::from(bit);
let which_bit = self.num_bits & 7;
if which_bit == 0 {
self.bits.push(bit);
} else {
*self.bits.last_mut().unwrap() |= bit << which_bit;
}
self.num_bits += 1;
}
}
impl Raw {
pub fn encode<T: super::Encode>(value: &T) -> Vec<u8> {
<Self as EntropyCoder>::encode(value).bits
}
pub fn num_bits<T: super::Encode>(value: &T) -> u32 {
<Self as EntropyCoder>::encode(value).num_bits
}
#[cfg(test)]
pub fn entropy<T: super::Encode>(value: &T) -> Millibits {
<Self as EntropyCoder>::encode(value).entropy
}
#[cfg(test)]
pub fn sizes<T: super::Encode>(value: &T) -> (usize, Millibits) {
let x = <Self as EntropyCoder>::encode(value);
(x.num_bits as usize, x.entropy)
}
pub fn decode<T: super::Encode>(bytes: &[u8]) -> Option<T> {
let mut reader = Decoder::from(bytes);
T::decode(&mut reader, &mut T::Context::default()).ok()
}
}
#[derive(Eq, PartialEq, Debug)]
pub struct Decoder<'a> {
bytes: &'a [u8],
num_bits: u32,
}
impl<'a> From<&'a [u8]> for Decoder<'a> {
#[inline(always)]
fn from(bytes: &'a [u8]) -> Self {
Self { num_bits: 0, bytes }
}
}
impl<'a> EntropyDecoder for Decoder<'a> {
#[inline(always)]
fn decode_bit_nonadaptive(
&mut self,
_probability: self::Probability,
) -> Result<bool, std::io::Error> {
let which_byte = self.num_bits as usize / 8;
let which_bit = self.num_bits & 7;
let mask = 1u8 << which_bit;
self.num_bits += 1;
Ok(self.bytes[which_byte] & mask == mask)
}
}