use std::cmp::min;
use std::io;
use crate::io::ReadBytes;
use crate::util::bits::*;
fn end_of_bitstream_error<T>() -> io::Result<T> {
Err(io::Error::new(io::ErrorKind::Other, "unexpected end of bitstream"))
}
pub mod vlc {
use std::cmp::max;
use std::collections::{BTreeMap, VecDeque};
use std::io;
fn codebook_error<T>(desc: &'static str) -> io::Result<T> {
Err(io::Error::new(io::ErrorKind::Other, desc))
}
#[derive(Copy, Clone)]
pub enum BitOrder {
Verbatim,
Reverse,
}
pub trait CodebookEntry: Copy + Clone + Default {
type ValueType: Copy + From<u8>;
type OffsetType: Copy;
const JUMP_OFFSET_MAX: u32;
fn new_value(value: Self::ValueType, len: u8) -> Self;
fn new_jump(offset: u32, len: u8) -> Self;
fn is_value(&self) -> bool;
fn is_jump(&self) -> bool;
fn value(&self) -> Self::ValueType;
fn value_len(&self) -> u32;
fn jump_offset(&self) -> usize;
fn jump_len(&self) -> u32;
}
macro_rules! decl_entry {
(
#[doc = $expr:expr]
$name:ident, $value_type:ty, $offset_type:ty, $offset_max:expr, $jump_flag:expr
) => {
#[doc = $expr]
#[derive(Copy, Clone, Default)]
pub struct $name($value_type, $offset_type);
impl CodebookEntry for $name {
type ValueType = $value_type;
type OffsetType = $offset_type;
const JUMP_OFFSET_MAX: u32 = $offset_max;
#[inline(always)]
fn new_value(value: Self::ValueType, len: u8) -> Self {
$name(value, len.into())
}
#[inline(always)]
fn new_jump(offset: u32, len: u8) -> Self {
$name(len.into(), $jump_flag | offset as Self::OffsetType)
}
#[inline(always)]
fn is_jump(&self) -> bool {
self.1 & $jump_flag != 0
}
#[inline(always)]
fn is_value(&self) -> bool {
self.1 & $jump_flag == 0
}
#[inline(always)]
fn value(&self) -> Self::ValueType {
debug_assert!(self.is_value());
self.0
}
#[inline(always)]
fn value_len(&self) -> u32 {
debug_assert!(self.is_value());
(self.1 & (!$jump_flag)).into()
}
#[inline(always)]
fn jump_offset(&self) -> usize {
debug_assert!(self.is_jump());
(self.1 & (!$jump_flag)) as usize
}
#[inline(always)]
fn jump_len(&self) -> u32 {
debug_assert!(self.is_jump());
self.0.into()
}
}
};
}
decl_entry!(
Entry8x8,
u8,
u8,
0x7f,
0x80
);
decl_entry!(
Entry8x16,
u8,
u16,
0x7fff,
0x8000
);
decl_entry!(
Entry8x32,
u8,
u32,
0x7fff_ffff,
0x8000_0000
);
decl_entry!(
Entry16x8,
u16,
u8,
0x7f,
0x80
);
decl_entry!(
Entry16x16,
u16,
u16,
0x7fff,
0x8000
);
decl_entry!(
Entry16x32,
u16,
u32,
0x7fff_ffff,
0x8000_0000
);
decl_entry!(
Entry32x8,
u32,
u8,
0x7fff,
0x80
);
decl_entry!(
Entry32x16,
u32,
u16,
0x7fff,
0x8000
);
decl_entry!(
Entry32x32,
u32,
u32,
0x7fff_ffff,
0x8000_0000
);
#[derive(Default)]
pub struct Codebook<E: CodebookEntry> {
pub table: Vec<E>,
}
impl<E: CodebookEntry> Codebook<E> {
pub fn is_empty(&self) -> bool {
self.table.is_empty()
}
}
#[derive(Default)]
struct CodebookValue<E: CodebookEntry> {
prefix: u16,
width: u8,
value: E::ValueType,
}
impl<E: CodebookEntry> CodebookValue<E> {
fn new(prefix: u16, width: u8, value: E::ValueType) -> Self {
CodebookValue { prefix, width, value }
}
}
#[derive(Default)]
struct CodebookBlock<E: CodebookEntry> {
width: u8,
nodes: BTreeMap<u16, usize>,
values: Vec<CodebookValue<E>>,
}
pub struct CodebookBuilder {
max_bits_per_block: u8,
bit_order: BitOrder,
is_sparse: bool,
}
impl CodebookBuilder {
pub fn new(bit_order: BitOrder) -> Self {
CodebookBuilder { max_bits_per_block: 4, bit_order, is_sparse: false }
}
pub fn new_sparse(bit_order: BitOrder) -> Self {
CodebookBuilder { max_bits_per_block: 4, bit_order, is_sparse: true }
}
pub fn bits_per_read(&mut self, max_bits_per_read: u8) -> &mut Self {
assert!(max_bits_per_read <= 16);
assert!(max_bits_per_read > 0);
self.max_bits_per_block = max_bits_per_read;
self
}
fn generate_lut<E: CodebookEntry>(
bit_order: BitOrder,
is_sparse: bool,
blocks: &[CodebookBlock<E>],
) -> io::Result<Vec<E>> {
let mut table = Vec::new();
let mut queue = VecDeque::new();
let mut table_end = 0u32;
if !blocks.is_empty() {
queue.push_front(0);
let block = &blocks[0];
table.push(CodebookEntry::new_jump(1, block.width));
table_end += 1 + (1 << block.width);
}
while !queue.is_empty() {
let mut entry_count = 0;
let block_id = queue.pop_front().unwrap();
let block = &blocks[block_id];
let block_len = 1 << block.width;
let table_base = table.len();
table.resize(table_base + block_len, Default::default());
for (&child_block_prefix, &child_block_id) in block.nodes.iter() {
queue.push_back(child_block_id);
let child_block_width = blocks[child_block_id].width;
if table_end > E::JUMP_OFFSET_MAX {
return codebook_error("core (io): codebook overflow");
}
let offset = match bit_order {
BitOrder::Verbatim => child_block_prefix,
BitOrder::Reverse => {
child_block_prefix.reverse_bits().rotate_left(u32::from(block.width))
}
} as usize;
let jump_entry = CodebookEntry::new_jump(table_end, child_block_width);
table[table_base + offset] = jump_entry;
table_end += 1 << child_block_width;
entry_count += 1;
}
for value in block.values.iter() {
let num_dnc_bits = block.width - value.width;
let base_prefix = (value.prefix << num_dnc_bits) as usize;
let count = 1 << num_dnc_bits;
let value_entry = CodebookEntry::new_value(value.value, value.width);
match bit_order {
BitOrder::Verbatim => {
let start = table_base + base_prefix;
let end = start + count;
for entry in table[start..end].iter_mut() {
*entry = value_entry;
}
}
BitOrder::Reverse => {
let start = base_prefix;
let end = start + count;
for prefix in start..end {
let offset =
prefix.reverse_bits().rotate_left(u32::from(block.width));
table[table_base + offset] = value_entry;
}
}
}
entry_count += count;
}
if !is_sparse && entry_count != block_len {
return codebook_error("core (io): codebook is incomplete");
}
}
Ok(table)
}
pub fn make<E: CodebookEntry>(
&mut self,
code_words: &[u32],
code_lens: &[u8],
values: &[E::ValueType],
) -> io::Result<Codebook<E>> {
assert!(code_words.len() == code_lens.len());
assert!(code_words.len() == values.len());
let mut blocks = Vec::<CodebookBlock<E>>::new();
if !code_words.is_empty() {
let prefix_mask = !(!0 << self.max_bits_per_block);
blocks.push(Default::default());
for ((&code, &code_len), &value) in code_words.iter().zip(code_lens).zip(values) {
let mut parent_block_id = 0;
let mut len = code_len;
if code_len == 0 {
if self.is_sparse {
continue;
}
else {
return codebook_error("core (io): zero length codeword");
}
}
while len > self.max_bits_per_block {
len -= self.max_bits_per_block;
let prefix = ((code >> len) & prefix_mask) as u16;
if let Some(&block_id) = blocks[parent_block_id].nodes.get(&prefix) {
parent_block_id = block_id;
}
else {
let block_id = blocks.len();
let mut block = &mut blocks[parent_block_id];
block.nodes.insert(prefix, block_id);
block.width = self.max_bits_per_block;
blocks.push(Default::default());
parent_block_id = block_id;
}
}
let prefix = code & (prefix_mask >> (self.max_bits_per_block - len));
let mut block = &mut blocks[parent_block_id];
block.values.push(CodebookValue::new(prefix as u16, len, value));
block.width = max(block.width, len);
}
}
let table = CodebookBuilder::generate_lut(self.bit_order, self.is_sparse, &blocks)?;
Ok(Codebook { table })
}
}
}
mod private {
use std::io;
pub trait FetchBitsLtr {
fn fetch_bits(&mut self) -> io::Result<()>;
fn fetch_bits_partial(&mut self) -> io::Result<()>;
fn get_bits(&self) -> u64;
fn num_bits_left(&self) -> u32;
fn consume_bits(&mut self, num: u32);
}
pub trait FetchBitsRtl {
fn fetch_bits(&mut self) -> io::Result<()>;
fn fetch_bits_partial(&mut self) -> io::Result<()>;
fn get_bits(&self) -> u64;
fn num_bits_left(&self) -> u32;
fn consume_bits(&mut self, num: u32);
}
}
pub trait FiniteBitStream {
fn bits_left(&self) -> u64;
}
pub trait ReadBitsLtr: private::FetchBitsLtr {
#[inline(always)]
fn realign(&mut self) {
let skip = self.num_bits_left() & 0x7;
self.consume_bits(skip);
}
#[inline(always)]
fn ignore_bits(&mut self, mut num_bits: u32) -> io::Result<()> {
if num_bits <= self.num_bits_left() {
self.consume_bits(num_bits);
}
else {
while num_bits > self.num_bits_left() {
num_bits -= self.num_bits_left();
self.fetch_bits()?;
}
if num_bits > 0 {
self.consume_bits(num_bits - 1);
self.consume_bits(1);
}
}
Ok(())
}
#[inline(always)]
fn ignore_bit(&mut self) -> io::Result<()> {
self.ignore_bits(1)
}
#[inline(always)]
fn read_bool(&mut self) -> io::Result<bool> {
if self.num_bits_left() < 1 {
self.fetch_bits()?;
}
let bit = self.get_bits() & (1 << 63) != 0;
self.consume_bits(1);
Ok(bit)
}
#[inline(always)]
fn read_bit(&mut self) -> io::Result<u32> {
if self.num_bits_left() < 1 {
self.fetch_bits()?;
}
let bit = self.get_bits() >> 63;
self.consume_bits(1);
Ok(bit as u32)
}
#[inline(always)]
fn read_bits_leq32(&mut self, mut bit_width: u32) -> io::Result<u32> {
debug_assert!(bit_width <= u32::BITS);
let mut bits = (self.get_bits() >> u32::BITS) >> (u32::BITS - bit_width);
while bit_width > self.num_bits_left() {
bit_width -= self.num_bits_left();
self.fetch_bits()?;
bits |= self.get_bits() >> (u64::BITS - bit_width);
}
self.consume_bits(bit_width);
Ok(bits as u32)
}
#[inline(always)]
fn read_bits_leq32_signed(&mut self, bit_width: u32) -> io::Result<i32> {
let value = self.read_bits_leq32(bit_width)?;
Ok(sign_extend_leq32_to_i32(value, bit_width))
}
#[inline(always)]
fn read_bits_leq64(&mut self, mut bit_width: u32) -> io::Result<u64> {
debug_assert!(bit_width <= u64::BITS);
if bit_width == 0 {
Ok(0)
}
else {
let mut bits = self.get_bits() >> (u64::BITS - bit_width);
while bit_width > self.num_bits_left() {
bit_width -= self.num_bits_left();
self.fetch_bits()?;
bits |= self.get_bits() >> (u64::BITS - bit_width);
}
self.consume_bits(bit_width - 1);
self.consume_bits(1);
Ok(bits)
}
}
#[inline(always)]
fn read_bits_leq64_signed(&mut self, bit_width: u32) -> io::Result<i64> {
let value = self.read_bits_leq64(bit_width)?;
Ok(sign_extend_leq64_to_i64(value, bit_width))
}
#[inline(always)]
fn read_unary_zeros(&mut self) -> io::Result<u32> {
let mut num = 0;
loop {
let num_zeros = self.get_bits().leading_zeros();
if num_zeros >= self.num_bits_left() {
num += self.num_bits_left();
self.fetch_bits()?;
}
else {
num += num_zeros;
self.consume_bits(num_zeros);
self.consume_bits(1);
break;
}
}
Ok(num)
}
#[inline(always)]
fn read_unary_zeros_capped(&mut self, mut limit: u32) -> io::Result<u32> {
let mut num = 0;
loop {
let num_bits_left = self.num_bits_left();
let num_zeros = min(self.get_bits().leading_zeros(), num_bits_left);
if num_zeros >= limit {
num += limit;
self.consume_bits(limit);
break;
}
else {
limit -= num_zeros;
num += num_zeros;
if num_zeros < num_bits_left {
self.consume_bits(num_zeros);
self.consume_bits(1);
break;
}
}
self.fetch_bits()?;
}
Ok(num)
}
#[inline(always)]
fn read_unary_ones(&mut self) -> io::Result<u32> {
let mut num = 0;
loop {
let num_ones = self.get_bits().leading_ones();
if num_ones >= self.num_bits_left() {
num += self.num_bits_left();
self.fetch_bits()?;
}
else {
num += num_ones;
self.consume_bits(num_ones);
self.consume_bits(1);
break;
}
}
Ok(num)
}
#[inline(always)]
fn read_unary_ones_capped(&mut self, mut limit: u32) -> io::Result<u32> {
let mut num = 0;
loop {
let num_bits_left = self.num_bits_left();
let num_ones = min(self.get_bits().leading_ones(), num_bits_left);
if num_ones >= limit {
num += limit;
self.consume_bits(limit);
break;
}
else {
limit -= num_ones;
num += num_ones;
if num_ones < num_bits_left {
self.consume_bits(num_ones);
self.consume_bits(1);
break;
}
}
self.fetch_bits()?;
}
Ok(num)
}
#[inline(always)]
fn read_codebook<E: vlc::CodebookEntry>(
&mut self,
codebook: &vlc::Codebook<E>,
) -> io::Result<(E::ValueType, u32)> {
debug_assert!(!codebook.is_empty());
let mut code_len = 0;
let mut jmp_read_len = 0;
let mut entry = codebook.table[0];
while entry.is_jump() {
self.consume_bits(jmp_read_len);
code_len += jmp_read_len;
jmp_read_len = entry.jump_len();
let addr = self.get_bits() >> (u64::BITS - jmp_read_len);
let jmp_offset = entry.jump_offset();
entry = codebook.table[jmp_offset + addr as usize];
if self.num_bits_left() < jmp_read_len {
if entry.is_value() && entry.value_len() <= self.num_bits_left() {
break;
}
self.fetch_bits_partial()?;
let addr = self.get_bits() >> (u64::BITS - jmp_read_len);
entry = codebook.table[jmp_offset + addr as usize];
}
}
let entry_code_len = entry.value_len();
self.consume_bits(entry_code_len);
Ok((entry.value(), code_len + entry_code_len))
}
}
pub struct BitStreamLtr<'a, B: ReadBytes> {
reader: &'a mut B,
bits: u64,
n_bits_left: u32,
}
impl<'a, B: ReadBytes> BitStreamLtr<'a, B> {
pub fn new(reader: &'a mut B) -> Self {
BitStreamLtr { reader, bits: 0, n_bits_left: 0 }
}
}
impl<'a, B: ReadBytes> private::FetchBitsLtr for BitStreamLtr<'a, B> {
#[inline(always)]
fn fetch_bits(&mut self) -> io::Result<()> {
self.bits = u64::from(self.reader.read_u8()?) << 56;
self.n_bits_left = u8::BITS;
Ok(())
}
#[inline(always)]
fn fetch_bits_partial(&mut self) -> io::Result<()> {
self.bits |= u64::from(self.reader.read_u8()?) << (u64::BITS - self.n_bits_left);
self.n_bits_left += u8::BITS;
todo!()
}
#[inline(always)]
fn get_bits(&self) -> u64 {
self.bits
}
#[inline(always)]
fn num_bits_left(&self) -> u32 {
self.n_bits_left
}
#[inline(always)]
fn consume_bits(&mut self, num: u32) {
self.n_bits_left -= num;
self.bits <<= num;
}
}
impl<'a, B: ReadBytes> ReadBitsLtr for BitStreamLtr<'a, B> {}
pub struct BitReaderLtr<'a> {
buf: &'a [u8],
bits: u64,
n_bits_left: u32,
}
impl<'a> BitReaderLtr<'a> {
pub fn new(buf: &'a [u8]) -> Self {
BitReaderLtr { buf, bits: 0, n_bits_left: 0 }
}
}
impl<'a> private::FetchBitsLtr for BitReaderLtr<'a> {
fn fetch_bits_partial(&mut self) -> io::Result<()> {
let mut buf = [0u8; std::mem::size_of::<u64>()];
let read_len = min(self.buf.len(), (u64::BITS - self.n_bits_left) as usize >> 3);
if read_len == 0 {
return end_of_bitstream_error();
}
buf[..read_len].copy_from_slice(&self.buf[..read_len]);
self.buf = &self.buf[read_len..];
self.bits |= u64::from_be_bytes(buf) >> self.n_bits_left;
self.n_bits_left += (read_len as u32) << 3;
Ok(())
}
fn fetch_bits(&mut self) -> io::Result<()> {
let mut buf = [0u8; std::mem::size_of::<u64>()];
let read_len = min(self.buf.len(), std::mem::size_of::<u64>());
if read_len == 0 {
return end_of_bitstream_error();
}
buf[..read_len].copy_from_slice(&self.buf[..read_len]);
self.buf = &self.buf[read_len..];
self.bits = u64::from_be_bytes(buf);
self.n_bits_left = (read_len as u32) << 3;
Ok(())
}
#[inline(always)]
fn get_bits(&self) -> u64 {
self.bits
}
#[inline(always)]
fn num_bits_left(&self) -> u32 {
self.n_bits_left
}
#[inline(always)]
fn consume_bits(&mut self, num: u32) {
self.n_bits_left -= num;
self.bits <<= num;
}
}
impl<'a> ReadBitsLtr for BitReaderLtr<'a> {}
impl<'a> FiniteBitStream for BitReaderLtr<'a> {
fn bits_left(&self) -> u64 {
(8 * self.buf.len() as u64) + u64::from(self.n_bits_left)
}
}
pub trait ReadBitsRtl: private::FetchBitsRtl {
#[inline(always)]
fn realign(&mut self) {
let skip = self.num_bits_left() & 0x7;
self.consume_bits(skip);
}
#[inline(always)]
fn ignore_bits(&mut self, mut num_bits: u32) -> io::Result<()> {
if num_bits <= self.num_bits_left() {
self.consume_bits(num_bits);
}
else {
while num_bits > self.num_bits_left() {
num_bits -= self.num_bits_left();
self.fetch_bits()?;
}
if num_bits > 0 {
self.consume_bits(num_bits - 1);
self.consume_bits(1);
}
}
Ok(())
}
#[inline(always)]
fn ignore_bit(&mut self) -> io::Result<()> {
self.ignore_bits(1)
}
#[inline(always)]
fn read_bool(&mut self) -> io::Result<bool> {
if self.num_bits_left() < 1 {
self.fetch_bits()?;
}
let bit = (self.get_bits() & 1) == 1;
self.consume_bits(1);
Ok(bit)
}
#[inline(always)]
fn read_bit(&mut self) -> io::Result<u32> {
if self.num_bits_left() < 1 {
self.fetch_bits()?;
}
let bit = self.get_bits() & 1;
self.consume_bits(1);
Ok(bit as u32)
}
#[inline(always)]
fn read_bits_leq32(&mut self, bit_width: u32) -> io::Result<u32> {
debug_assert!(bit_width <= u32::BITS);
let mut bits = self.get_bits();
let mut bits_needed = bit_width;
while bits_needed > self.num_bits_left() {
bits_needed -= self.num_bits_left();
self.fetch_bits()?;
bits |= self.get_bits() << (bit_width - bits_needed);
}
self.consume_bits(bits_needed);
let mask = !(!0 << bit_width);
Ok((bits & mask) as u32)
}
#[inline(always)]
fn read_bits_leq32_signed(&mut self, bit_width: u32) -> io::Result<i32> {
let value = self.read_bits_leq32(bit_width)?;
Ok(sign_extend_leq32_to_i32(value, bit_width))
}
#[inline(always)]
fn read_bits_leq64(&mut self, bit_width: u32) -> io::Result<u64> {
debug_assert!(bit_width <= u64::BITS);
if bit_width == 0 {
Ok(0)
}
else {
let mut bits = self.get_bits();
let mut bits_needed = bit_width;
while bits_needed > self.num_bits_left() {
bits_needed -= self.num_bits_left();
self.fetch_bits()?;
bits |= self.get_bits() << (bit_width - bits_needed);
}
self.consume_bits(bits_needed - 1);
self.consume_bits(1);
let mask = !((!0 << (bit_width - 1)) << 1);
Ok(bits & mask)
}
}
#[inline(always)]
fn read_bits_leq64_signed(&mut self, bit_width: u32) -> io::Result<i64> {
let value = self.read_bits_leq64(bit_width)?;
Ok(sign_extend_leq64_to_i64(value, bit_width))
}
#[inline(always)]
fn read_unary_zeros(&mut self) -> io::Result<u32> {
let mut num = 0;
loop {
let num_zeros = self.get_bits().trailing_zeros();
if num_zeros >= self.num_bits_left() {
num += self.num_bits_left();
self.fetch_bits()?;
}
else {
num += num_zeros;
self.consume_bits(num_zeros);
self.consume_bits(1);
break;
}
}
Ok(num)
}
#[inline(always)]
fn read_unary_zeros_capped(&mut self, mut limit: u32) -> io::Result<u32> {
let mut num = 0;
loop {
let num_bits_left = self.num_bits_left();
let num_zeros = min(self.get_bits().trailing_zeros(), num_bits_left);
if num_zeros >= limit {
num += limit;
self.consume_bits(limit);
break;
}
else {
limit -= num_zeros;
num += num_zeros;
if num_zeros < num_bits_left {
self.consume_bits(num_zeros);
self.consume_bits(1);
break;
}
}
self.fetch_bits()?;
}
Ok(num)
}
#[inline(always)]
fn read_unary_ones(&mut self) -> io::Result<u32> {
let mut num = 0;
loop {
let num_ones = self.get_bits().trailing_ones();
if num_ones >= self.num_bits_left() {
num += self.num_bits_left();
self.fetch_bits()?;
}
else {
num += num_ones;
self.consume_bits(num_ones);
self.consume_bits(1);
break;
}
}
Ok(num)
}
#[inline(always)]
fn read_unary_ones_capped(&mut self, mut limit: u32) -> io::Result<u32> {
let mut num = 0;
loop {
let num_bits_left = self.num_bits_left();
let num_ones = min(self.get_bits().trailing_ones(), num_bits_left);
if num_ones >= limit {
num += limit;
self.consume_bits(limit);
break;
}
else {
limit -= num_ones;
num += num_ones;
if num_ones < num_bits_left {
self.consume_bits(num_ones);
self.consume_bits(1);
break;
}
}
self.fetch_bits()?;
}
Ok(num)
}
#[inline(always)]
fn read_codebook<E: vlc::CodebookEntry>(
&mut self,
codebook: &vlc::Codebook<E>,
) -> io::Result<(E::ValueType, u32)> {
debug_assert!(!codebook.is_empty());
let mut code_len = 0;
let mut jmp_read_len = 0;
let mut entry = codebook.table[0];
while entry.is_jump() {
self.consume_bits(jmp_read_len);
code_len += jmp_read_len;
jmp_read_len = entry.jump_len();
let addr = self.get_bits() & ((1 << jmp_read_len) - 1);
let jmp_offset = entry.jump_offset();
entry = codebook.table[jmp_offset + addr as usize];
if self.num_bits_left() < jmp_read_len {
if entry.is_value() && entry.value_len() <= self.num_bits_left() {
break;
}
self.fetch_bits_partial()?;
let addr = self.get_bits() & ((1 << jmp_read_len) - 1);
entry = codebook.table[jmp_offset + addr as usize];
}
}
let entry_code_len = entry.value_len();
self.consume_bits(entry_code_len);
Ok((entry.value(), code_len + entry_code_len))
}
}
pub struct BitStreamRtl<'a, B: ReadBytes> {
reader: &'a mut B,
bits: u64,
n_bits_left: u32,
}
impl<'a, B: ReadBytes> BitStreamRtl<'a, B> {
pub fn new(reader: &'a mut B) -> Self {
BitStreamRtl { reader, bits: 0, n_bits_left: 0 }
}
}
impl<'a, B: ReadBytes> private::FetchBitsRtl for BitStreamRtl<'a, B> {
#[inline(always)]
fn fetch_bits(&mut self) -> io::Result<()> {
self.bits = u64::from(self.reader.read_u8()?);
self.n_bits_left = u8::BITS;
Ok(())
}
#[inline(always)]
fn fetch_bits_partial(&mut self) -> io::Result<()> {
self.bits |= u64::from(self.reader.read_u8()?) << self.n_bits_left;
self.n_bits_left += u8::BITS;
todo!()
}
#[inline(always)]
fn get_bits(&self) -> u64 {
self.bits
}
#[inline(always)]
fn num_bits_left(&self) -> u32 {
self.n_bits_left
}
#[inline(always)]
fn consume_bits(&mut self, num: u32) {
self.n_bits_left -= num;
self.bits >>= num;
}
}
impl<'a, B: ReadBytes> ReadBitsRtl for BitStreamRtl<'a, B> {}
pub struct BitReaderRtl<'a> {
buf: &'a [u8],
bits: u64,
n_bits_left: u32,
}
impl<'a> BitReaderRtl<'a> {
pub fn new(buf: &'a [u8]) -> Self {
BitReaderRtl { buf, bits: 0, n_bits_left: 0 }
}
}
impl<'a> private::FetchBitsRtl for BitReaderRtl<'a> {
fn fetch_bits_partial(&mut self) -> io::Result<()> {
let mut buf = [0u8; std::mem::size_of::<u64>()];
let read_len = min(self.buf.len(), (u64::BITS - self.n_bits_left) as usize >> 3);
if read_len == 0 {
return end_of_bitstream_error();
}
buf[..read_len].copy_from_slice(&self.buf[..read_len]);
self.buf = &self.buf[read_len..];
self.bits |= u64::from_le_bytes(buf) << self.n_bits_left;
self.n_bits_left += (read_len as u32) << 3;
Ok(())
}
fn fetch_bits(&mut self) -> io::Result<()> {
let mut buf = [0u8; std::mem::size_of::<u64>()];
let read_len = min(self.buf.len(), std::mem::size_of::<u64>());
if read_len == 0 {
return end_of_bitstream_error();
}
buf[..read_len].copy_from_slice(&self.buf[..read_len]);
self.buf = &self.buf[read_len..];
self.bits = u64::from_le_bytes(buf);
self.n_bits_left = (read_len as u32) << 3;
Ok(())
}
#[inline(always)]
fn get_bits(&self) -> u64 {
self.bits
}
#[inline(always)]
fn num_bits_left(&self) -> u32 {
self.n_bits_left
}
#[inline(always)]
fn consume_bits(&mut self, num: u32) {
self.n_bits_left -= num;
self.bits >>= num;
}
}
impl<'a> ReadBitsRtl for BitReaderRtl<'a> {}
impl<'a> FiniteBitStream for BitReaderRtl<'a> {
fn bits_left(&self) -> u64 {
(8 * self.buf.len() as u64) + u64::from(self.n_bits_left)
}
}
#[cfg(test)]
mod tests {
use super::vlc::{BitOrder, Codebook, CodebookBuilder, Entry8x8};
use super::{BitReaderLtr, ReadBitsLtr};
use super::{BitReaderRtl, ReadBitsRtl};
#[test]
#[allow(clippy::bool_assert_comparison)]
fn verify_bitstreamltr_ignore_bits() {
let mut bs = BitReaderLtr::new(&[
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, ]);
assert_eq!(bs.read_bool().unwrap(), true);
bs.ignore_bits(128).unwrap();
assert_eq!(bs.read_bool().unwrap(), true);
assert_eq!(bs.read_bool().unwrap(), false);
assert_eq!(bs.read_bool().unwrap(), false);
bs.ignore_bits(7).unwrap();
assert_eq!(bs.read_bool().unwrap(), true);
bs.ignore_bits(19).unwrap();
assert_eq!(bs.read_bool().unwrap(), true);
assert_eq!(bs.read_bool().unwrap(), false);
assert_eq!(bs.read_bool().unwrap(), false);
assert_eq!(bs.read_bool().unwrap(), false);
assert_eq!(bs.read_bool().unwrap(), false);
bs.ignore_bits(24).unwrap();
assert_eq!(bs.read_bool().unwrap(), true);
assert_eq!(bs.read_bool().unwrap(), false);
assert_eq!(bs.read_bool().unwrap(), true);
assert_eq!(bs.read_bool().unwrap(), false);
let mut bs = BitReaderLtr::new(&[0x00]);
assert!(bs.ignore_bits(0).is_ok());
let mut bs = BitReaderLtr::new(&[]);
assert!(bs.ignore_bits(0).is_ok());
assert!(bs.ignore_bits(1).is_err());
let mut bs = BitReaderLtr::new(&[
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ]);
assert!(bs.ignore_bits(64).is_ok());
assert!(bs.ignore_bits(64).is_ok());
assert!(bs.ignore_bits(32).is_ok());
assert!(bs.ignore_bits(32).is_ok());
assert!(bs.ignore_bits(64).is_ok());
}
#[test]
#[allow(clippy::bool_assert_comparison)]
fn verify_bitstreamltr_read_bool() {
let mut bs = BitReaderLtr::new(&[0b1010_1010]);
assert_eq!(bs.read_bool().unwrap(), true);
assert_eq!(bs.read_bool().unwrap(), false);
assert_eq!(bs.read_bool().unwrap(), true);
assert_eq!(bs.read_bool().unwrap(), false);
assert_eq!(bs.read_bool().unwrap(), true);
assert_eq!(bs.read_bool().unwrap(), false);
assert_eq!(bs.read_bool().unwrap(), true);
assert_eq!(bs.read_bool().unwrap(), false);
let mut bs = BitReaderLtr::new(&[]);
assert!(bs.read_bool().is_err());
}
#[test]
fn verify_bitstreamltr_read_bit() {
let mut bs = BitReaderLtr::new(&[0b1010_1010]);
assert_eq!(bs.read_bit().unwrap(), 1);
assert_eq!(bs.read_bit().unwrap(), 0);
assert_eq!(bs.read_bit().unwrap(), 1);
assert_eq!(bs.read_bit().unwrap(), 0);
assert_eq!(bs.read_bit().unwrap(), 1);
assert_eq!(bs.read_bit().unwrap(), 0);
assert_eq!(bs.read_bit().unwrap(), 1);
assert_eq!(bs.read_bit().unwrap(), 0);
let mut bs = BitReaderLtr::new(&[]);
assert!(bs.read_bool().is_err());
}
#[test]
fn verify_bitstreamltr_read_bits_leq32() {
let mut bs = BitReaderLtr::new(&[0b1010_0101, 0b0111_1110, 0b1101_0011]);
assert_eq!(bs.read_bits_leq32(4).unwrap(), 0b0000_0000_0000_1010);
assert_eq!(bs.read_bits_leq32(4).unwrap(), 0b0000_0000_0000_0101);
assert_eq!(bs.read_bits_leq32(13).unwrap(), 0b0000_1111_1101_1010);
assert_eq!(bs.read_bits_leq32(3).unwrap(), 0b0000_0000_0000_0011);
let mut bs = BitReaderLtr::new(&[0xff, 0xff, 0xff, 0xff]);
assert_eq!(bs.read_bits_leq32(0).unwrap(), 0);
let mut bs = BitReaderLtr::new(&[0xff, 0xff, 0xff, 0xff, 0x01]);
assert_eq!(bs.read_bits_leq32(32).unwrap(), u32::MAX);
assert_eq!(bs.read_bits_leq32(8).unwrap(), 0x01);
let mut bs = BitReaderLtr::new(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01]);
assert_eq!(bs.read_bits_leq32(32).unwrap(), u32::MAX);
assert_eq!(bs.read_bits_leq32(32).unwrap(), u32::MAX);
assert_eq!(bs.read_bits_leq32(8).unwrap(), 0x01);
let mut bs = BitReaderLtr::new(&[0xff]);
assert!(bs.read_bits_leq32(9).is_err());
}
#[test]
fn verify_bitstreamltr_read_bits_leq64() {
let mut bs = BitReaderLtr::new(&[
0x99, 0xaa, 0x55, 0xff, 0xff, 0x55, 0xaa, 0x99, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, ]);
assert_eq!(bs.read_bits_leq64(40).unwrap(), 0x99aa55ffff);
assert_eq!(bs.read_bits_leq64(4).unwrap(), 0x05);
assert_eq!(bs.read_bits_leq64(4).unwrap(), 0x05);
assert_eq!(bs.read_bits_leq64(16).unwrap(), 0xaa99);
assert_eq!(bs.read_bits_leq64(64).unwrap(), 0x1122334455667788);
let mut bs = BitReaderLtr::new(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
assert_eq!(bs.read_bits_leq64(0).unwrap(), 0);
let mut bs = BitReaderLtr::new(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01]);
assert_eq!(bs.read_bits_leq64(64).unwrap(), u64::MAX);
assert_eq!(bs.read_bits_leq64(8).unwrap(), 0x01);
let mut bs = BitReaderLtr::new(&[0xff]);
assert!(bs.read_bits_leq64(9).is_err());
}
#[test]
fn verify_bitstreamltr_read_unary_zeros() {
let mut bs =
BitReaderLtr::new(&[0b0000_0001, 0b0001_0000, 0b0000_0000, 0b1000_0000, 0b1111_1011]);
assert_eq!(bs.read_unary_zeros().unwrap(), 7);
assert_eq!(bs.read_unary_zeros().unwrap(), 3);
assert_eq!(bs.read_unary_zeros().unwrap(), 12);
assert_eq!(bs.read_unary_zeros().unwrap(), 7);
assert_eq!(bs.read_unary_zeros().unwrap(), 0);
assert_eq!(bs.read_unary_zeros().unwrap(), 0);
assert_eq!(bs.read_unary_zeros().unwrap(), 0);
assert_eq!(bs.read_unary_zeros().unwrap(), 0);
assert_eq!(bs.read_unary_zeros().unwrap(), 1);
assert_eq!(bs.read_unary_zeros().unwrap(), 0);
let mut bs = BitReaderLtr::new(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]);
assert_eq!(bs.read_unary_zeros().unwrap(), 63);
let mut bs = BitReaderLtr::new(&[0x80]);
assert_eq!(bs.read_unary_zeros().unwrap(), 0);
let mut bs = BitReaderLtr::new(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
assert!(bs.read_unary_zeros().is_err());
}
#[test]
fn verify_bitstreamltr_read_unary_zeros_capped() {
let mut bs = BitReaderLtr::new(&[0b0000_0001, 0b0000_0001]);
assert_eq!(bs.read_unary_zeros_capped(8).unwrap(), 7);
assert_eq!(bs.read_unary_zeros_capped(4).unwrap(), 4);
let mut bs = BitReaderLtr::new(&[
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]);
assert_eq!(bs.read_unary_zeros_capped(96).unwrap(), 79);
assert_eq!(bs.read_unary_zeros_capped(104).unwrap(), 104);
}
#[test]
fn verify_bitstreamltr_read_unary_ones() {
let mut bs =
BitReaderLtr::new(&[0b1111_1110, 0b1110_1111, 0b1111_1111, 0b0111_1111, 0b0000_0100]);
assert_eq!(bs.read_unary_ones().unwrap(), 7);
assert_eq!(bs.read_unary_ones().unwrap(), 3);
assert_eq!(bs.read_unary_ones().unwrap(), 12);
assert_eq!(bs.read_unary_ones().unwrap(), 7);
assert_eq!(bs.read_unary_ones().unwrap(), 0);
assert_eq!(bs.read_unary_ones().unwrap(), 0);
assert_eq!(bs.read_unary_ones().unwrap(), 0);
assert_eq!(bs.read_unary_ones().unwrap(), 0);
assert_eq!(bs.read_unary_ones().unwrap(), 1);
assert_eq!(bs.read_unary_ones().unwrap(), 0);
let mut bs = BitReaderLtr::new(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe]);
assert_eq!(bs.read_unary_ones().unwrap(), 63);
let mut bs = BitReaderLtr::new(&[0x7f]);
assert_eq!(bs.read_unary_ones().unwrap(), 0);
let mut bs = BitReaderLtr::new(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
assert!(bs.read_unary_ones().is_err());
}
#[test]
fn verify_bitstreamltr_read_unary_ones_capped() {
let mut bs = BitReaderLtr::new(&[0b1111_1110, 0b1111_1110]);
assert_eq!(bs.read_unary_ones_capped(8).unwrap(), 7);
assert_eq!(bs.read_unary_ones_capped(4).unwrap(), 4);
let mut bs =
BitReaderLtr::new(&[0b1111_1110, 0b1110_1111, 0b1111_1111, 0b0111_1111, 0b0000_0100]);
assert_eq!(bs.read_unary_ones_capped(9).unwrap(), 7);
assert_eq!(bs.read_unary_ones_capped(9).unwrap(), 3);
assert_eq!(bs.read_unary_ones_capped(9).unwrap(), 9); assert_eq!(bs.read_unary_ones_capped(9).unwrap(), 3);
assert_eq!(bs.read_unary_ones_capped(9).unwrap(), 7);
assert_eq!(bs.read_unary_ones_capped(9).unwrap(), 0);
assert_eq!(bs.read_unary_ones_capped(9).unwrap(), 0);
assert_eq!(bs.read_unary_ones_capped(9).unwrap(), 0);
assert_eq!(bs.read_unary_ones_capped(9).unwrap(), 0);
assert_eq!(bs.read_unary_ones_capped(9).unwrap(), 1);
let mut bs = BitReaderLtr::new(&[
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
]);
assert_eq!(bs.read_unary_ones_capped(144).unwrap(), 143);
assert_eq!(bs.read_unary_ones_capped(256).unwrap(), 256);
}
fn generate_codebook(bit_order: BitOrder) -> (Codebook<Entry8x8>, Vec<u8>, &'static str) {
#[rustfmt::skip]
const CODE_WORDS: [u32; 25] = [
0b001,
0b111,
0b010,
0b1001,
0b1101,
0b0001,
0b0111,
0b1000,
0b10110,
0b10111,
0b10101,
0b10100,
0b01100,
0b000010,
0b110000,
0b000011,
0b110001,
0b000001,
0b011010,
0b000000,
0b011011,
0b1100111,
0b1100110,
0b1100101,
0b1100100,
];
const CODE_LENS: [u8; 25] =
[3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7];
const VALUES: [u8; 25] = [
b'i', b' ', b'e', b't', b's', b'l', b'n', b'o', b'.', b'r', b'g', b'h', b'u', b'p',
b'w', b',', b'f', b'y', b'm', b'v', b'a', b'd', b'b', b'c', b'T',
];
const DATA: [u8; 57] = [
0xc9, 0x43, 0xbf, 0x48, 0xa7, 0xca, 0xbe, 0x64, 0x30, 0xf5, 0xdf, 0x31, 0xd9, 0xb6,
0xb5, 0xbb, 0x6f, 0x9f, 0xa0, 0x15, 0xc1, 0xfa, 0x5e, 0xa2, 0xb8, 0x4a, 0xfb, 0x0f,
0xe1, 0x93, 0xe6, 0x8a, 0xe8, 0x3e, 0x77, 0xe0, 0xd9, 0x92, 0xf5, 0xf8, 0xc5, 0xfb,
0x37, 0xcc, 0x7c, 0x48, 0x8f, 0x33, 0xf0, 0x33, 0x4f, 0xb0, 0xd2, 0x9a, 0x17, 0xad,
0x80,
];
const TEXT: &str = "This silence belongs to us... and every single person out \
there, is waiting for us to fill it with something.";
let data = match bit_order {
BitOrder::Verbatim => DATA.to_vec(),
BitOrder::Reverse => DATA.iter().map(|&b| b.reverse_bits()).collect(),
};
let mut builder = CodebookBuilder::new(bit_order);
let codebook = builder.make::<Entry8x8>(&CODE_WORDS, &CODE_LENS, &VALUES).unwrap();
(codebook, data, TEXT)
}
#[test]
fn verify_bitstreamltr_read_codebook() {
let (codebook, buf, text) = generate_codebook(BitOrder::Verbatim);
let mut bs = BitReaderLtr::new(&buf);
let decoded: Vec<u8> =
(0..text.len()).into_iter().map(|_| bs.read_codebook(&codebook).unwrap().0).collect();
assert_eq!(text, std::str::from_utf8(&decoded).unwrap());
}
#[test]
#[allow(clippy::bool_assert_comparison)]
fn verify_bitstreamrtl_ignore_bits() {
let mut bs = BitReaderRtl::new(&[
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, 0x50, ]);
assert_eq!(bs.read_bool().unwrap(), true);
bs.ignore_bits(128).unwrap();
assert_eq!(bs.read_bool().unwrap(), true);
assert_eq!(bs.read_bool().unwrap(), false);
assert_eq!(bs.read_bool().unwrap(), false);
bs.ignore_bits(7).unwrap();
assert_eq!(bs.read_bool().unwrap(), true);
bs.ignore_bits(19).unwrap();
assert_eq!(bs.read_bool().unwrap(), true);
assert_eq!(bs.read_bool().unwrap(), false);
assert_eq!(bs.read_bool().unwrap(), false);
assert_eq!(bs.read_bool().unwrap(), false);
assert_eq!(bs.read_bool().unwrap(), false);
bs.ignore_bits(24).unwrap();
assert_eq!(bs.read_bool().unwrap(), true);
assert_eq!(bs.read_bool().unwrap(), false);
assert_eq!(bs.read_bool().unwrap(), true);
assert_eq!(bs.read_bool().unwrap(), false);
let mut bs = BitReaderRtl::new(&[0x00]);
assert!(bs.ignore_bits(0).is_ok());
let mut bs = BitReaderRtl::new(&[]);
assert!(bs.ignore_bits(0).is_ok());
assert!(bs.ignore_bits(1).is_err());
let mut bs = BitReaderRtl::new(&[
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ]);
assert!(bs.ignore_bits(64).is_ok());
assert!(bs.ignore_bits(64).is_ok());
assert!(bs.ignore_bits(32).is_ok());
assert!(bs.ignore_bits(32).is_ok());
assert!(bs.ignore_bits(64).is_ok());
}
#[test]
#[allow(clippy::bool_assert_comparison)]
fn verify_bitstreamrtl_read_bool() {
let mut bs = BitReaderRtl::new(&[0b1010_1010]);
assert_eq!(bs.read_bool().unwrap(), false);
assert_eq!(bs.read_bool().unwrap(), true);
assert_eq!(bs.read_bool().unwrap(), false);
assert_eq!(bs.read_bool().unwrap(), true);
assert_eq!(bs.read_bool().unwrap(), false);
assert_eq!(bs.read_bool().unwrap(), true);
assert_eq!(bs.read_bool().unwrap(), false);
assert_eq!(bs.read_bool().unwrap(), true);
let mut bs = BitReaderRtl::new(&[]);
assert!(bs.read_bool().is_err());
}
#[test]
fn verify_bitstreamrtl_read_bit() {
let mut bs = BitReaderRtl::new(&[0b1010_1010]);
assert_eq!(bs.read_bit().unwrap(), 0);
assert_eq!(bs.read_bit().unwrap(), 1);
assert_eq!(bs.read_bit().unwrap(), 0);
assert_eq!(bs.read_bit().unwrap(), 1);
assert_eq!(bs.read_bit().unwrap(), 0);
assert_eq!(bs.read_bit().unwrap(), 1);
assert_eq!(bs.read_bit().unwrap(), 0);
assert_eq!(bs.read_bit().unwrap(), 1);
let mut bs = BitReaderRtl::new(&[]);
assert!(bs.read_bit().is_err());
}
#[test]
fn verify_bitstreamrtl_read_bits_leq32() {
let mut bs = BitReaderRtl::new(&[0b1010_0101, 0b0111_1110, 0b1101_0011]);
assert_eq!(bs.read_bits_leq32(4).unwrap(), 0b0000_0000_0000_0101);
assert_eq!(bs.read_bits_leq32(4).unwrap(), 0b0000_0000_0000_1010);
assert_eq!(bs.read_bits_leq32(13).unwrap(), 0b0001_0011_0111_1110);
assert_eq!(bs.read_bits_leq32(3).unwrap(), 0b0000_0000_0000_0110);
let mut bs = BitReaderRtl::new(&[0xff, 0xff, 0xff, 0xff]);
assert_eq!(bs.read_bits_leq32(0).unwrap(), 0);
let mut bs = BitReaderRtl::new(&[0xff, 0xff, 0xff, 0xff, 0x01]);
assert_eq!(bs.read_bits_leq32(32).unwrap(), u32::MAX);
assert_eq!(bs.read_bits_leq32(8).unwrap(), 0x01);
let mut bs = BitReaderRtl::new(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01]);
assert_eq!(bs.read_bits_leq32(32).unwrap(), u32::MAX);
assert_eq!(bs.read_bits_leq32(32).unwrap(), u32::MAX);
assert_eq!(bs.read_bits_leq32(8).unwrap(), 0x01);
let mut bs = BitReaderRtl::new(&[0xff]);
assert!(bs.read_bits_leq32(9).is_err());
}
#[test]
fn verify_bitstreamrtl_read_bits_leq64() {
let mut bs = BitReaderRtl::new(&[
0x99, 0xaa, 0x55, 0xff, 0xff, 0x55, 0xaa, 0x99, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x00, 0x11, 0x22, 0x33, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
]);
assert_eq!(bs.read_bits_leq64(40).unwrap(), 0xffff55aa99);
assert_eq!(bs.read_bits_leq64(4).unwrap(), 0x05);
assert_eq!(bs.read_bits_leq64(4).unwrap(), 0x05);
assert_eq!(bs.read_bits_leq64(16).unwrap(), 0x99aa);
assert_eq!(bs.read_bits_leq64(64).unwrap(), 0x8877665544332211);
assert_eq!(bs.read_bits_leq64(32).unwrap(), 0x33221100);
assert_eq!(bs.read_bits_leq64(64).unwrap(), 0x7766554433221100);
let mut bs = BitReaderRtl::new(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
assert_eq!(bs.read_bits_leq64(0).unwrap(), 0);
let mut bs = BitReaderRtl::new(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01]);
assert_eq!(bs.read_bits_leq64(64).unwrap(), u64::MAX);
assert_eq!(bs.read_bits_leq64(8).unwrap(), 0x01);
let mut bs = BitReaderRtl::new(&[0xff]);
assert!(bs.read_bits_leq64(9).is_err());
}
#[test]
fn verify_bitstreamrtl_read_unary_zeros() {
let mut bs =
BitReaderRtl::new(&[0b1000_0000, 0b0000_1000, 0b0000_0000, 0b0000_0001, 0b1101_1111]);
assert_eq!(bs.read_unary_zeros().unwrap(), 7);
assert_eq!(bs.read_unary_zeros().unwrap(), 3);
assert_eq!(bs.read_unary_zeros().unwrap(), 12);
assert_eq!(bs.read_unary_zeros().unwrap(), 7);
assert_eq!(bs.read_unary_zeros().unwrap(), 0);
assert_eq!(bs.read_unary_zeros().unwrap(), 0);
assert_eq!(bs.read_unary_zeros().unwrap(), 0);
assert_eq!(bs.read_unary_zeros().unwrap(), 0);
assert_eq!(bs.read_unary_zeros().unwrap(), 1);
assert_eq!(bs.read_unary_zeros().unwrap(), 0);
let mut bs = BitReaderRtl::new(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80]);
assert_eq!(bs.read_unary_zeros().unwrap(), 63);
let mut bs = BitReaderRtl::new(&[0x01]);
assert_eq!(bs.read_unary_zeros().unwrap(), 0);
let mut bs = BitReaderRtl::new(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
assert!(bs.read_unary_zeros().is_err());
}
#[test]
fn verify_bitstreamrtl_read_unary_zeros_capped() {
let mut bs = BitReaderRtl::new(&[0b1000_0000, 0b1000_0000]);
assert_eq!(bs.read_unary_zeros_capped(8).unwrap(), 7);
assert_eq!(bs.read_unary_zeros_capped(4).unwrap(), 4);
let mut bs = BitReaderRtl::new(&[
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]);
assert_eq!(bs.read_unary_zeros_capped(96).unwrap(), 79);
assert_eq!(bs.read_unary_zeros_capped(163).unwrap(), 163);
}
#[test]
fn verify_bitstreamrtl_read_unary_ones() {
let mut bs =
BitReaderRtl::new(&[0b0111_1111, 0b1111_0111, 0b1111_1111, 0b1111_1110, 0b0010_0000]);
assert_eq!(bs.read_unary_ones().unwrap(), 7);
assert_eq!(bs.read_unary_ones().unwrap(), 3);
assert_eq!(bs.read_unary_ones().unwrap(), 12);
assert_eq!(bs.read_unary_ones().unwrap(), 7);
assert_eq!(bs.read_unary_ones().unwrap(), 0);
assert_eq!(bs.read_unary_ones().unwrap(), 0);
assert_eq!(bs.read_unary_ones().unwrap(), 0);
assert_eq!(bs.read_unary_ones().unwrap(), 0);
assert_eq!(bs.read_unary_ones().unwrap(), 1);
assert_eq!(bs.read_unary_ones().unwrap(), 0);
let mut bs = BitReaderRtl::new(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f]);
assert_eq!(bs.read_unary_ones().unwrap(), 63);
let mut bs = BitReaderRtl::new(&[0xfe]);
assert_eq!(bs.read_unary_ones().unwrap(), 0);
let mut bs = BitReaderRtl::new(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
assert!(bs.read_unary_ones().is_err());
}
#[test]
fn verify_bitstreamrtl_read_unary_ones_capped() {
let mut bs = BitReaderRtl::new(&[0b0111_1111, 0b0111_1111]);
assert_eq!(bs.read_unary_ones_capped(8).unwrap(), 7);
assert_eq!(bs.read_unary_ones_capped(4).unwrap(), 4);
let mut bs = BitReaderRtl::new(&[
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ]);
assert_eq!(bs.read_unary_ones_capped(96).unwrap(), 79);
assert_eq!(bs.read_unary_ones_capped(163).unwrap(), 163);
}
#[test]
fn verify_bitstreamrtl_read_codebook() {
let (codebook, buf, text) = generate_codebook(BitOrder::Reverse);
let mut bs = BitReaderRtl::new(&buf);
let decoded: Vec<u8> =
(0..text.len()).into_iter().map(|_| bs.read_codebook(&codebook).unwrap().0).collect();
assert_eq!(text, std::str::from_utf8(&decoded).unwrap());
}
}