wmv_decoder/
bitreader.rs

1/// VC-1 / WMV9 Bitstream Reader
2
3#[derive(Clone)]
4pub struct BitReader<'a> {
5    data:     &'a [u8],
6    byte_pos: usize,
7    bit_pos:  u8,
8    current:  u8,
9}
10
11impl<'a> BitReader<'a> {
12    pub fn new(data: &'a [u8]) -> Self {
13        let current = data.first().copied().unwrap_or(0);
14        BitReader { data, byte_pos: 0, bit_pos: 8, current }
15    }
16
17    /// Create a reader positioned at an arbitrary bit offset (MSB-first).
18    ///
19    /// `bit_offset=0` is identical to `BitReader::new(data)`.
20    pub fn new_at(data: &'a [u8], bit_offset: usize) -> Self {
21        let byte_pos = bit_offset / 8;
22        let bit_in_byte = (bit_offset % 8) as u8;
23        // bit_pos = how many bits remain unread in the current byte.
24        let bit_pos = if bit_in_byte == 0 { 8 } else { 8 - bit_in_byte };
25        let current = data.get(byte_pos).copied().unwrap_or(0);
26        BitReader { data, byte_pos, bit_pos, current }
27    }
28
29    pub fn read_bits(&mut self, mut n: u8) -> Option<u32> {
30        if n == 0 { return Some(0); }
31        let mut result = 0u32;
32        while n > 0 {
33            if self.byte_pos >= self.data.len() { return None; }
34            let avail = self.bit_pos.min(n);
35            let shift = self.bit_pos - avail;
36            let mask  = ((1u16 << avail) - 1) as u8;
37            result    = (result << avail) | ((self.current >> shift) & mask) as u32;
38            self.bit_pos -= avail;
39            n            -= avail;
40            if self.bit_pos == 0 {
41                self.byte_pos += 1;
42                self.current   = self.data.get(self.byte_pos).copied().unwrap_or(0);
43                self.bit_pos   = 8;
44            }
45        }
46        Some(result)
47    }
48
49    #[inline]
50    pub fn read_bit(&mut self) -> Option<bool> {
51        self.read_bits(1).map(|b| b != 0)
52    }
53
54    pub fn read_bits_signed(&mut self, n: u8) -> Option<i32> {
55        let v = self.read_bits(n)? as i32;
56        if n == 0 { return Some(0); }
57        let sign = 1i32 << (n - 1);
58        Some(if v & sign != 0 { v - (sign << 1) } else { v })
59    }
60
61    /// Peek up to 24 bits without advancing.
62    pub fn peek_bits(&self, n: u8) -> Option<u32> {
63        if n == 0 { return Some(0); }
64        let mut result    = 0u32;
65        let mut bits_left = n;
66        let mut bpos      = self.byte_pos;
67        let mut boff      = self.bit_pos;
68
69        while bits_left > 0 {
70            let avail = boff.min(bits_left);
71            let shift = boff - avail;
72            let mask  = ((1u16 << avail) - 1) as u8;
73            let byte  = if bpos < self.data.len() { self.data[bpos] } else { 0 };
74            result    = (result << avail) | ((byte >> shift) & mask) as u32;
75            bits_left -= avail;
76            boff      -= avail;
77            if boff == 0 { bpos += 1; boff = 8; }
78        }
79        Some(result)
80    }
81
82    #[inline]
83    pub fn skip_bits(&mut self, n: u8) {
84        let _ = self.read_bits(n);
85    }
86
87    /// Skip an arbitrary number of bits.
88    #[inline]
89    pub fn skip_bits_usize(&mut self, mut n: usize) {
90        while n >= 32 {
91            let _ = self.read_bits(32);
92            n -= 32;
93        }
94        if n > 0 {
95            let _ = self.read_bits(n as u8);
96        }
97    }
98
99    pub fn read_ue(&mut self) -> Option<u32> {
100        let mut zeros = 0u8;
101        while !self.read_bit()? {
102            zeros += 1;
103            if zeros > 31 { return None; }
104        }
105        let suffix = self.read_bits(zeros)?;
106        Some((1u32 << zeros) - 1 + suffix)
107    }
108
109    pub fn read_se(&mut self) -> Option<i32> {
110        let ue = self.read_ue()?;
111        let v  = ((ue + 1) >> 1) as i32;
112        Some(if ue & 1 == 0 { -v } else { v })
113    }
114
115    pub fn byte_align(&mut self) {
116        if self.bit_pos < 8 {
117            self.byte_pos += 1;
118            self.current   = self.data.get(self.byte_pos).copied().unwrap_or(0);
119            self.bit_pos   = 8;
120        }
121    }
122
123    pub fn remaining_bytes(&self) -> usize {
124        self.data.len().saturating_sub(self.byte_pos)
125    }
126
127    pub fn bits_read(&self) -> usize {
128        self.byte_pos * 8 + (8 - self.bit_pos as usize)
129    }
130
131    /// Remaining bits in the underlying buffer.
132    pub fn bits_left(&self) -> isize {
133        let total = (self.data.len() * 8) as isize;
134        let used = self.bits_read() as isize;
135        total - used
136    }
137
138    pub fn is_empty(&self) -> bool {
139        self.byte_pos >= self.data.len()
140    }
141}