1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
//! `BitStreamReader` API
//!
//! This module provides an interface to read and write bits (and bytes) for
//! huffman
pub struct BitStreamReader<'src>
{
// buffer from which we are pulling in bits from
// used in decompression.
pub src: &'src [u8],
// position in our buffer,
pub position: usize,
pub bits_left: u8,
pub buffer: u64,
pub over_read: usize
}
impl<'src> BitStreamReader<'src>
{
/// Create a new `BitStreamReader` instance
///
/// # Expectations
/// The buffer must be padded with fill bytes in the end,
/// if not, this becomes UB in the refill phase.
pub fn new(in_buffer: &'src [u8]) -> BitStreamReader<'src>
{
BitStreamReader {
bits_left: 0,
buffer: 0,
src: in_buffer,
position: 0,
over_read: 0
}
}
/// Refill the bitstream ensuring the buffer has bits between
/// 56 and 63.
///
#[inline(always)]
pub fn refill(&mut self)
{
/*
* The refill always guarantees refills between 56-63
*
* Bits stored will never go above 63 and if bits are in the range 56-63 no refills occur.
*/
let mut buf = [0; 8];
match self.src.get(self.position..self.position + 8)
{
Some(bytes) =>
{
buf.copy_from_slice(bytes);
// create a u64 from an array of u8's
let new_buffer = u64::from_le_bytes(buf);
// num indicates how many bytes we actually consumed.
let num = 63 ^ self.bits_left;
// offset position
self.position += (num >> 3) as usize;
// shift number of bits
self.buffer |= new_buffer << self.bits_left;
// update bits left
// bits left are now between 56-63
self.bits_left |= 56;
}
None => self.refill_slow()
}
}
#[inline(always)]
pub fn refill_inner_loop(&mut self)
{
/*
* The refill always guarantees refills between 56-63
*
* Bits stored will never go above 63 and if bits are in the range 56-63 no refills occur.
*/
let mut buf = [0; 8];
if let Some(bytes) = self.src.get(self.position..self.position + 8)
{
{
buf.copy_from_slice(bytes);
// create a u64 from an array of u8's
let new_buffer = u64::from_le_bytes(buf);
// num indicates how many bytes we actually consumed.
let num = 63 ^ self.bits_left;
// offset position
self.position += (num >> 3) as usize;
// shift number of bits
self.buffer |= new_buffer << self.bits_left;
// update bits left
// bits left are now between 56-63
self.bits_left |= 56;
}
}
}
#[inline(never)]
fn refill_slow(&mut self)
{
let bytes = &self.src[self.position..];
for byte in bytes
{
if self.bits_left >= 56
{
break;
}
self.buffer |= u64::from(*byte) << self.bits_left;
self.bits_left += 8;
self.position += 1;
}
while self.bits_left < 56
{
self.bits_left += 8;
self.over_read += 1;
}
}
#[inline(always)]
pub fn peek_bits<const LOOKAHEAD: usize>(&self) -> usize
{
debug_assert!(self.bits_left >= LOOKAHEAD as u8);
(self.buffer & ((1 << LOOKAHEAD) - 1)) as usize
}
#[inline(always)]
pub fn peek_var_bits(&self, lookahead: usize) -> usize
{
debug_assert!(self.bits_left >= lookahead as u8);
(self.buffer & ((1 << lookahead) - 1)) as usize
}
#[inline(always)]
pub fn get_bits(&mut self, num_bits: u8) -> u64
{
debug_assert!(self.bits_left >= num_bits);
let mask = (1_u64 << num_bits) - 1;
let value = self.buffer & mask;
self.buffer >>= num_bits;
self.bits_left -= num_bits;
value
}
/// Get number of bits left in the bit buffer.
pub const fn get_bits_left(&self) -> u8
{
self.bits_left
}
/// Get position the stream is in this buffer
/// Or alternatively, number of bits read.
pub fn get_position(&self) -> usize
{
self.position
.saturating_sub(usize::from(self.bits_left >> 3))
}
/// Reset buffer and bits left to zero.
pub fn reset(&mut self)
{
self.buffer = 0;
self.bits_left = 0;
}
/// Return true if the bit buffer can satisfy
/// `bits` read without refilling,
pub const fn has(&self, bits: u8) -> bool
{
self.bits_left >= bits
}
#[inline(always)]
pub fn drop_bits(&mut self, bits: u8)
{
debug_assert!(self.bits_left >= bits);
self.bits_left -= bits;
self.buffer >>= bits;
}
/// Return the remaining bytes in this stream.
///
/// This does not consider bits in the bit-buffer hence
/// may not be accurate
pub const fn remaining_bytes(&self) -> usize
{
self.src.len().saturating_sub(self.position)
}
}