1 //! Bitstream reader functionality.
3 //! Bitstream reader operates on `&[u8]` and allows to read bits from the slice in different modes.
7 //! Reading 17 bits from a bitstream:
9 //! use nihav_core::io::bitreader::{BitReader,BitReaderMode};
11 //! # use nihav_core::io::bitreader::BitReaderResult;
12 //! # fn foo() -> BitReaderResult<u32> {
13 //! let bits: [u8; 4] = [ 42, 43, 44, 45 ];
14 //! let mut br = BitReader::new(&bits, BitReaderMode::BE);
15 //! let value = br.read(17)?;
20 //! Reading some amount of bits and checking how many bits are left:
22 //! use nihav_core::io::bitreader::{BitReader,BitReaderMode};
24 //! # use nihav_core::io::bitreader::BitReaderResult;
25 //! # fn foo() -> BitReaderResult<()> {
26 //! let bits: [u8; 4] = [ 42, 43, 44, 45 ];
27 //! let mut br = BitReader::new(&bits, BitReaderMode::BE);
28 //! let num_skip_bits = br.read(3)?;
29 //! br.skip(num_skip_bits)?;
30 //! println!("Now there are {} bits left to read.", br.left());
37 /// Bitstream reading modes.
38 #[derive(Debug,Clone,Copy)]
39 pub enum BitReaderMode {
40 /// The stream is big endian MSB first.
42 /// The stream is little endian LSB first.
44 /// The stream is packed into 16-bit little-endian words MSB first.
46 /// The stream is packed into 32-bit little-endian words MSB first.
50 /// A list specifying general bitstream reading errors.
51 #[derive(Debug,Clone,Copy)]
52 pub enum BitReaderError {
53 /// The reader is at the end of bitstream.
55 /// The caller tried to read too many bits at once (e.g. 128).
57 /// Some argument is invalid.
61 use self::BitReaderError::*;
63 /// A specialised `Result` type for bitstream operations.
64 pub type BitReaderResult<T> = Result<T, BitReaderError>;
67 #[derive(Debug,Clone)]
68 pub struct BitReader<'a> {
76 #[allow(clippy::identity_op)]
77 impl<'a> BitReader<'a> {
79 /// Constructs a new instance of bitstream reader.
84 /// use nihav_core::io::bitreader::{BitReader,BitReaderMode};
86 /// let bits: [u8; 4] = [ 42, 43, 44, 45 ];
87 /// let mut br = BitReader::new(&bits, BitReaderMode::BE);
89 pub fn new(src: &'a [u8], mode: BitReaderMode) -> Self {
90 BitReader{ cache: 0, pos: 0, bits: 0, src, mode }
93 /// Returns the data bitstream reader uses.
94 pub fn get_data(&self) -> &'a [u8] { self.src }
96 /// Reports the current bit position in the bitstream (usually simply the number of bits read so far).
97 pub fn tell(&self) -> usize {
98 self.pos * 8 - (self.bits as usize)
101 /// Reports the amount of bits left until the end of the bitstream.
102 pub fn left(&self) -> isize {
103 ((self.src.len() as isize) - (self.pos as isize)) * 8 + (self.bits as isize)
106 fn fill32be(&mut self, src: &[u8]) {
107 let nw = (u32::from(src[0]) << 24) |
108 (u32::from(src[1]) << 16) |
109 (u32::from(src[2]) << 8) |
110 (u32::from(src[3]) << 0);
111 self.cache |= u64::from(nw) << (32 - self.bits);
114 fn fill32le16(&mut self, src: &[u8]) {
115 let nw = (u32::from(src[1]) << 24) |
116 (u32::from(src[0]) << 16) |
117 (u32::from(src[3]) << 8) |
118 (u32::from(src[2]) << 0);
119 self.cache |= u64::from(nw) << (32 - self.bits);
122 fn fill32le32(&mut self, src: &[u8], lsb: bool) {
123 let nw = (u32::from(src[3]) << 24) |
124 (u32::from(src[2]) << 16) |
125 (u32::from(src[1]) << 8) |
126 (u32::from(src[0]) << 0);
128 self.cache |= u64::from(nw) << self.bits;
130 self.cache |= u64::from(nw) << (32 - self.bits);
135 fn refill(&mut self) -> BitReaderResult<()> {
136 if self.pos >= self.src.len() { return Err(BitstreamEnd) }
137 while self.bits <= 32 {
138 if self.pos + 4 <= self.src.len() {
139 let buf = &self.src[self.pos..];
141 BitReaderMode::BE => self.fill32be (buf),
142 BitReaderMode::LE16MSB => self.fill32le16(buf),
143 BitReaderMode::LE => self.fill32le32(buf, true),
144 BitReaderMode::LE32MSB => self.fill32le32(buf, false),
149 let mut buf: [u8; 4] = [0, 0, 0, 0];
150 let mut newbits: u8 = 0;
151 for out in buf.iter_mut().take(3) {
152 if self.pos < self.src.len() {
153 *out = self.src[self.pos];
158 if newbits == 0 { break; }
160 BitReaderMode::BE => self.fill32be (&buf),
161 BitReaderMode::LE16MSB => self.fill32le16(&buf),
162 BitReaderMode::LE => self.fill32le32(&buf, true),
163 BitReaderMode::LE32MSB => self.fill32le32(&buf, false),
165 self.bits += newbits;
172 fn read_cache(&mut self, nbits: u8) -> u32 {
173 let res = match self.mode {
174 BitReaderMode::LE => ((1u64 << nbits) - 1) & self.cache,
175 _ => self.cache >> (64 - nbits),
180 fn read_cache_s(&mut self, nbits: u8) -> i32 {
181 let res = match self.mode {
182 BitReaderMode::LE => ((self.cache as i64) << (64 - nbits)) >> (64 - nbits),
183 _ => (self.cache as i64) >> (64 - nbits),
189 fn skip_cache(&mut self, nbits: u8) {
191 BitReaderMode::LE => self.cache >>= nbits,
192 _ => self.cache <<= nbits,
198 fn reset_cache(&mut self) {
203 /// Reads the specified amount of bits as an unsigned value.
205 /// The amount should fit into 32 bits, if you need more then
206 /// you should read it as several parts. If the amount of bits
207 /// requested to read is larger than the amount of bits left the
208 /// call will return [`BitstreamEnd`].
213 /// use nihav_core::io::bitreader::{BitReader,BitReaderMode};
215 /// # use nihav_core::io::bitreader::BitReaderResult;
216 /// # fn foo() -> BitReaderResult<u32> {
217 /// let bits: [u8; 4] = [ 42, 43, 44, 45 ];
218 /// let mut br = BitReader::new(&bits, BitReaderMode::BE);
219 /// let value = br.read(17)?;
224 /// [`BitstreamEnd`]: ./enum.BitReaderError.html#variant.BitstreamEnd
226 pub fn read(&mut self, nbits: u8) -> BitReaderResult<u32> {
227 if nbits == 0 { return Ok(0) }
228 if nbits > 32 { return Err(TooManyBitsRequested) }
229 if self.bits < nbits {
230 if let Err(err) = self.refill() { return Err(err) }
231 if self.bits < nbits { return Err(BitstreamEnd) }
233 let res = self.read_cache(nbits);
234 self.skip_cache(nbits);
238 /// Reads the specified amount of bits as a signed value.
240 /// Beside signedness it behaves the same as [`read`].
242 /// [`read`]: #method.read
243 pub fn read_s(&mut self, nbits: u8) -> BitReaderResult<i32> {
244 if nbits == 0 || nbits > 32 { return Err(TooManyBitsRequested) }
245 if self.bits < nbits {
246 if let Err(err) = self.refill() { return Err(err) }
247 if self.bits < nbits { return Err(BitstreamEnd) }
249 let res = self.read_cache_s(nbits);
250 self.skip_cache(nbits);
254 /// Reads single bit from the stream and interprets it as a boolean value.
256 pub fn read_bool(&mut self) -> BitReaderResult<bool> {
258 if let Err(err) = self.refill() { return Err(err) }
259 if self.bits < 1 { return Err(BitstreamEnd) }
261 let res = self.read_cache(1);
266 /// Retrieves the next bits from the stream without advancing.
268 /// If the bitstream is shorter than the amount of bits requested the result is padded with zeroes.
273 /// use nihav_core::io::bitreader::{BitReader,BitReaderMode};
275 /// # use nihav_core::io::bitreader::BitReaderResult;
276 /// # fn foo() -> BitReaderResult<u32> {
277 /// let bits: [u8; 4] = [ 42, 43, 44, 45 ];
278 /// let mut br = BitReader::new(&bits, BitReaderMode::BE);
279 /// let peek_value = br.peek(8); // this should return 42
280 /// let value = br.read(8)?; // also 42
285 pub fn peek(&mut self, nbits: u8) -> u32 {
286 if nbits > 32 { return 0 }
287 if self.bits < nbits { let _ = self.refill(); }
288 self.read_cache(nbits)
291 /// Skips the requested amount of bits.
293 /// The amount of bits to skip can be arbitrary large.
294 /// If it skips more bits than there are actually in the stream the call will return [`BitstreamEnd`]
296 /// [`read`]: #method.read
297 /// [`BitstreamEnd`]: ./enum.BitReaderError.html#variant.BitstreamEnd
299 pub fn skip(&mut self, nbits: u32) -> BitReaderResult<()> {
300 if u32::from(self.bits) >= nbits {
301 self.skip_cache(nbits as u8);
304 let mut skip_bits = nbits - u32::from(self.bits);
306 self.pos += ((skip_bits / 32) * 4) as usize;
310 self.skip_cache(skip_bits as u8);
315 /// Seeks to the absolute bit position in the stream.
316 /// If the requested position lies after the bitstream end the function returns [`TooManyBitsRequested`].
321 /// use nihav_core::io::bitreader::{BitReader,BitReaderMode};
323 /// # use nihav_core::io::bitreader::BitReaderResult;
324 /// # fn foo() -> BitReaderResult<u32> {
325 /// let bits: [u8; 4] = [ 42, 43, 44, 45 ];
326 /// let mut br = BitReader::new(&bits, BitReaderMode::BE);
328 /// let value = br.read(8)?; // this should return 44
333 /// [`TooManyBitsRequested`]: ./enum.BitReaderError.html#variant.TooManyBitsRequested
334 pub fn seek(&mut self, nbits: u32) -> BitReaderResult<()> {
335 if ((nbits + 7) >> 3) as usize > self.src.len() { return Err(TooManyBitsRequested); }
337 self.pos = ((nbits / 32) * 4) as usize;
338 self.skip(nbits & 0x1F)
341 /// Aligns the bit position to the next byte boundary. If already at byte boundary the function does nothing.
346 /// use nihav_core::io::bitreader::{BitReader,BitReaderMode};
348 /// # use nihav_core::io::bitreader::BitReaderResult;
349 /// # fn foo() -> BitReaderResult<()> {
350 /// let bits: [u8; 4] = [ 42, 43, 44, 45 ];
351 /// let mut br = BitReader::new(&bits, BitReaderMode::BE);
352 /// br.skip(17)?; // now reader is at bit position 17
353 /// br.align(); // now reader is at bit position 24
354 /// br.align(); // now reader is still at bit position 24
358 pub fn align(&mut self) {
359 let pos = self.bits & 7;
361 self.skip_cache(pos);
366 /// Returns a variable with `len` amount of low bits in reverse order.
370 /// use nihav_core::io::bitreader::reverse_bits;
371 /// reverse_bits(0b010101, 6); // the result should be 0b101010
373 pub fn reverse_bits(inval: u32, len: u8) -> u32 {
374 if len == 0 { return 0; }
375 const REV_TAB: [u8; 16] = [
376 0b0000, 0b1000, 0b0100, 0b1100, 0b0010, 0b1010, 0b0110, 0b1110,
377 0b0001, 0b1001, 0b0101, 0b1101, 0b0011, 0b1011, 0b0111, 0b1111,
383 ret = (ret << 4) | u32::from(REV_TAB[(val & 0xF) as usize]);
395 const DATA: [u8; 18] = [0b00011011; 18];
397 let mut br = BitReader::new(src, BitReaderMode::LE16MSB);
400 assert_eq!(br.read(16).unwrap(), 0x1B1B);
402 const DATA2: [u8; 1] = [ 0b00011011 ];
404 let mut br = BitReader::new(src, BitReaderMode::LE);
405 assert_eq!(br.read_s(5).unwrap(), -5);