oxideav_bitstream/
bit_reader.rs1use crate::BitstreamError;
16
17pub struct BitReader<'a> {
19 pub(crate) bytes: &'a [u8],
20 pub(crate) bit_pos: usize,
21}
22
23impl<'a> BitReader<'a> {
24 pub fn new(bytes: &'a [u8]) -> Self {
26 Self { bytes, bit_pos: 0 }
27 }
28
29 pub fn total_bits(&self) -> usize {
31 self.bytes.len() * 8
32 }
33
34 pub fn bit_pos(&self) -> usize {
36 self.bit_pos
37 }
38
39 pub fn bits_remaining(&self) -> usize {
41 self.total_bits().saturating_sub(self.bit_pos)
42 }
43
44 pub fn at_end(&self) -> bool {
46 self.bit_pos >= self.total_bits()
47 }
48
49 pub fn byte_aligned(&self) -> bool {
51 self.bit_pos % 8 == 0
52 }
53
54 pub fn skip(&mut self, n: usize) {
56 self.bit_pos = self.bit_pos.saturating_add(n);
57 }
58
59 pub fn align_to_byte(&mut self) {
61 let rem = self.bit_pos % 8;
62 if rem != 0 {
63 self.bit_pos += 8 - rem;
64 }
65 }
66
67 pub fn read_bit(&mut self) -> u32 {
69 let byte_idx = self.bit_pos / 8;
70 let shift = 7 - (self.bit_pos % 8) as u32;
71 let bit = if byte_idx < self.bytes.len() {
72 ((self.bytes[byte_idx] >> shift) & 1) as u32
73 } else {
74 0
75 };
76 self.bit_pos += 1;
77 bit
78 }
79
80 pub fn u(&mut self, n: u32) -> u32 {
84 debug_assert!(n <= 32, "BitReader::u({n}) > 32 bits");
85 let mut value: u32 = 0;
86 for _ in 0..n {
87 value = (value << 1) | self.read_bit();
88 }
89 value
90 }
91
92 pub fn u64(&mut self, n: u32) -> u64 {
95 debug_assert!(n <= 64, "BitReader::u64({n}) > 64 bits");
96 let mut value: u64 = 0;
97 for _ in 0..n {
98 value = (value << 1) | (self.read_bit() as u64);
99 }
100 value
101 }
102
103 pub fn ue(&mut self) -> Result<u32, BitstreamError> {
107 let mut leading_zeros = 0u32;
108 while !self.at_end() && self.read_bit() == 0 {
109 leading_zeros += 1;
110 if leading_zeros > 32 {
111 return Err(BitstreamError::InvalidData(
112 "ue(v): more than 32 leading zero bits".into(),
113 ));
114 }
115 }
116 if leading_zeros == 0 {
117 Ok(0)
118 } else {
119 let suffix = self.u(leading_zeros);
120 Ok((1u32 << leading_zeros) - 1 + suffix)
121 }
122 }
123
124 pub fn se(&mut self) -> Result<i32, BitstreamError> {
126 let code = self.ue()?;
127 if code == 0 {
128 Ok(0)
129 } else if code & 1 == 1 {
130 Ok(code.div_ceil(2) as i32)
131 } else {
132 Ok(-((code / 2) as i32))
133 }
134 }
135}
136
137#[cfg(test)]
138mod tests {
139 use super::*;
140
141 #[test]
142 fn u_reads_known_pattern() {
143 let bytes = [0b1010_1100, 0b1111_0000];
145 let mut r = BitReader::new(&bytes);
146 assert_eq!(r.u(4), 0b1010);
147 assert_eq!(r.u(4), 0b1100);
148 assert_eq!(r.u(8), 0b1111_0000);
149 }
150
151 #[test]
152 fn ue_decodes_known_values() {
153 let bytes = [0b1010_0110, 0b0100_0000];
156 let mut r = BitReader::new(&bytes);
157 assert_eq!(r.ue().unwrap(), 0);
158 assert_eq!(r.ue().unwrap(), 1);
159 assert_eq!(r.ue().unwrap(), 2);
160 assert_eq!(r.ue().unwrap(), 3);
161 }
162
163 #[test]
164 fn se_decodes_zero_pos_neg() {
165 let bytes = [0b1010_0110, 0b0000_0000];
167 let mut r = BitReader::new(&bytes);
168 assert_eq!(r.se().unwrap(), 0);
169 assert_eq!(r.se().unwrap(), 1);
170 assert_eq!(r.se().unwrap(), -1);
171 }
172
173 #[test]
174 fn align_to_byte_no_op_when_aligned() {
175 let bytes = [0xff, 0x00];
176 let mut r = BitReader::new(&bytes);
177 r.u(8);
178 assert!(r.byte_aligned());
179 r.align_to_byte();
180 assert_eq!(r.bit_pos, 8);
181 }
182
183 #[test]
184 fn align_to_byte_advances_to_next_byte() {
185 let bytes = [0xff, 0x00];
186 let mut r = BitReader::new(&bytes);
187 r.u(3);
188 r.align_to_byte();
189 assert_eq!(r.bit_pos, 8);
190 }
191
192 #[test]
193 fn past_end_reads_zero() {
194 let bytes = [0xff];
195 let mut r = BitReader::new(&bytes);
196 r.u(8);
197 assert_eq!(r.u(8), 0);
198 assert!(r.at_end());
199 }
200}