physis/bcn/
bitreader.rs

1// SPDX-FileCopyrightText: 2023 Rudolf Kolbe
2// SPDX-License-Identifier: MIT
3
4#[inline]
5fn getbits_raw(buf: &[u8], bit_offset: usize, num_bits: usize, dst: &mut [u8]) {
6    let bytes_offset = bit_offset / 8;
7    let bytes_end: usize = (bit_offset + num_bits).div_ceil(8);
8    dst[0..(bytes_end - bytes_offset)].copy_from_slice(&buf[bytes_offset..bytes_end]);
9}
10
11pub struct BitReader<'a> {
12    data: &'a [u8],
13    bit_pos: usize,
14}
15
16impl BitReader<'_> {
17    #[inline]
18    pub const fn new(data: &[u8], bit_pos: usize) -> BitReader {
19        BitReader { data, bit_pos }
20    }
21
22    #[inline]
23    pub fn read(&mut self, num_bits: usize) -> u16 {
24        let ret = self.peek(0, num_bits);
25        self.bit_pos += num_bits;
26        ret
27    }
28
29    #[inline]
30    pub fn peek(&self, offset: usize, num_bits: usize) -> u16 {
31        let bit_pos = self.bit_pos + offset;
32        let shift = bit_pos & 7;
33
34        let mut raw = [0u8; 4];
35        getbits_raw(self.data, bit_pos, num_bits, &mut raw);
36        let data: u32 = u32::from_le_bytes(raw);
37
38        (data >> shift as u32) as u16 & ((1 << num_bits as u16) - 1)
39    }
40}