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 peek_bits(&self, n: u32) -> u32 {
109 debug_assert!(n <= 32, "BitReader::peek_bits({n}) > 32 bits");
110 let mut value: u32 = 0;
111 let total = self.total_bits();
112 for offset in 0..n as usize {
113 let pos = self.bit_pos + offset;
114 let bit = if pos < total {
115 let byte_idx = pos / 8;
116 let shift = 7 - (pos % 8) as u32;
117 ((self.bytes[byte_idx] >> shift) & 1) as u32
118 } else {
119 0
120 };
121 value = (value << 1) | bit;
122 }
123 value
124 }
125
126 pub fn more_rbsp_data(&self) -> bool {
139 let total = self.total_bits();
140 if self.bit_pos >= total {
141 return false;
142 }
143 let mut saw_one = false;
144 for p in self.bit_pos..total {
145 let b = (self.bytes[p / 8] >> (7 - (p % 8))) & 1;
146 if !saw_one {
147 if b == 1 {
148 saw_one = true;
149 }
150 } else if b == 1 {
151 return true;
152 }
153 }
154 false
155 }
156
157 pub fn read_rbsp_trailing_bits(&mut self) -> Result<(), BitstreamError> {
164 if self.at_end() {
165 return Err(BitstreamError::UnexpectedEnd(
166 "rbsp_trailing_bits: no bits left for stop bit".into(),
167 ));
168 }
169 if self.read_bit() != 1 {
170 return Err(BitstreamError::InvalidData(
171 "rbsp_trailing_bits: rbsp_stop_one_bit was 0".into(),
172 ));
173 }
174 while !self.byte_aligned() {
175 if self.at_end() {
176 return Err(BitstreamError::UnexpectedEnd(
177 "rbsp_trailing_bits: stream ended before byte alignment".into(),
178 ));
179 }
180 if self.read_bit() != 0 {
181 return Err(BitstreamError::InvalidData(
182 "rbsp_trailing_bits: alignment_zero_bit was 1".into(),
183 ));
184 }
185 }
186 Ok(())
187 }
188
189 pub fn ue(&mut self) -> Result<u32, BitstreamError> {
195 let mut leading_zeros = 0u32;
196 while !self.at_end() && self.read_bit() == 0 {
197 leading_zeros += 1;
198 if leading_zeros >= 32 {
199 return Err(BitstreamError::InvalidData(
200 "ue(v): 32 or more leading zero bits".into(),
201 ));
202 }
203 }
204 if leading_zeros >= 32 {
209 return Err(BitstreamError::InvalidData(
210 "ue(v): 32 or more leading zero bits".into(),
211 ));
212 }
213 if leading_zeros == 0 {
214 Ok(0)
215 } else {
216 let suffix = self.u(leading_zeros);
217 Ok((1u32 << leading_zeros) - 1 + suffix)
218 }
219 }
220
221 pub fn se(&mut self) -> Result<i32, BitstreamError> {
223 let code = self.ue()?;
224 if code == 0 {
225 Ok(0)
226 } else if code & 1 == 1 {
227 Ok(code.div_ceil(2) as i32)
228 } else {
229 Ok(-((code / 2) as i32))
230 }
231 }
232}
233
234#[cfg(test)]
235mod tests {
236 use super::*;
237
238 #[test]
239 fn u_reads_known_pattern() {
240 let bytes = [0b1010_1100, 0b1111_0000];
242 let mut r = BitReader::new(&bytes);
243 assert_eq!(r.u(4), 0b1010);
244 assert_eq!(r.u(4), 0b1100);
245 assert_eq!(r.u(8), 0b1111_0000);
246 }
247
248 #[test]
249 fn ue_decodes_known_values() {
250 let bytes = [0b1010_0110, 0b0100_0000];
253 let mut r = BitReader::new(&bytes);
254 assert_eq!(r.ue().unwrap(), 0);
255 assert_eq!(r.ue().unwrap(), 1);
256 assert_eq!(r.ue().unwrap(), 2);
257 assert_eq!(r.ue().unwrap(), 3);
258 }
259
260 #[test]
261 fn se_decodes_zero_pos_neg() {
262 let bytes = [0b1010_0110, 0b0000_0000];
264 let mut r = BitReader::new(&bytes);
265 assert_eq!(r.se().unwrap(), 0);
266 assert_eq!(r.se().unwrap(), 1);
267 assert_eq!(r.se().unwrap(), -1);
268 }
269
270 #[test]
271 fn align_to_byte_no_op_when_aligned() {
272 let bytes = [0xff, 0x00];
273 let mut r = BitReader::new(&bytes);
274 r.u(8);
275 assert!(r.byte_aligned());
276 r.align_to_byte();
277 assert_eq!(r.bit_pos, 8);
278 }
279
280 #[test]
281 fn align_to_byte_advances_to_next_byte() {
282 let bytes = [0xff, 0x00];
283 let mut r = BitReader::new(&bytes);
284 r.u(3);
285 r.align_to_byte();
286 assert_eq!(r.bit_pos, 8);
287 }
288
289 #[test]
290 fn past_end_reads_zero() {
291 let bytes = [0xff];
292 let mut r = BitReader::new(&bytes);
293 r.u(8);
294 assert_eq!(r.u(8), 0);
295 assert!(r.at_end());
296 }
297
298 #[test]
299 fn peek_bits_does_not_advance() {
300 let bytes = [0b1010_1100, 0b1111_0000];
301 let r0 = BitReader::new(&bytes);
302 assert_eq!(r0.peek_bits(4), 0b1010);
303 let mut r = BitReader::new(&bytes);
305 let peeked = r.peek_bits(8);
306 assert_eq!(peeked, 0b1010_1100);
307 assert_eq!(r.bit_pos(), 0);
308 assert_eq!(r.u(8), 0b1010_1100);
309 }
310
311 #[test]
312 fn peek_bits_past_end_is_zero_padded() {
313 let bytes = [0b1111_0000];
314 let mut r = BitReader::new(&bytes);
315 r.u(4);
317 assert_eq!(r.peek_bits(8), 0b0000_0000);
318 r.u(4);
320 assert_eq!(r.peek_bits(16), 0);
321 }
322
323 #[test]
324 fn more_rbsp_data_after_payload() {
325 let bytes = [0xB0];
328 let mut r = BitReader::new(&bytes);
329 assert!(r.more_rbsp_data(), "before payload there's more data");
330 r.u(1); assert!(r.more_rbsp_data());
332 r.u(1); assert!(r.more_rbsp_data());
334 r.u(1); assert!(!r.more_rbsp_data());
336 }
337
338 #[test]
339 fn more_rbsp_data_minimal_stop_byte() {
340 let bytes = [0x80];
342 let r = BitReader::new(&bytes);
343 assert!(
344 !r.more_rbsp_data(),
345 "stop-bit-only buffer has no further RBSP data"
346 );
347 }
348
349 #[test]
350 fn more_rbsp_data_at_end_is_false() {
351 let bytes = [0xff];
352 let mut r = BitReader::new(&bytes);
353 r.u(8);
354 assert!(!r.more_rbsp_data());
355 }
356
357 #[test]
358 fn read_rbsp_trailing_bits_accepts_minimal_marker() {
359 let bytes = [0x80];
361 let mut r = BitReader::new(&bytes);
362 r.read_rbsp_trailing_bits().unwrap();
363 assert!(r.byte_aligned());
364 assert!(r.at_end());
365 }
366
367 #[test]
368 fn read_rbsp_trailing_bits_after_payload() {
369 let bytes = [0xB4];
371 let mut r = BitReader::new(&bytes);
372 assert_eq!(r.u(5), 0b10110);
374 r.read_rbsp_trailing_bits().unwrap();
375 assert!(r.byte_aligned());
376 assert!(r.at_end());
377 }
378
379 #[test]
380 fn read_rbsp_trailing_bits_rejects_zero_stop_bit() {
381 let bytes = [0x00];
382 let mut r = BitReader::new(&bytes);
383 match r.read_rbsp_trailing_bits() {
384 Err(BitstreamError::InvalidData(msg)) => assert!(msg.contains("stop")),
385 other => panic!("expected InvalidData, got {other:?}"),
386 }
387 }
388
389 #[test]
390 fn read_rbsp_trailing_bits_rejects_nonzero_alignment_bit() {
391 let bytes = [0b1000_1000];
393 let mut r = BitReader::new(&bytes);
394 match r.read_rbsp_trailing_bits() {
395 Err(BitstreamError::InvalidData(msg)) => assert!(msg.contains("alignment")),
396 other => panic!("expected InvalidData, got {other:?}"),
397 }
398 }
399
400 #[test]
401 fn read_rbsp_trailing_bits_rejects_empty_reader() {
402 let bytes: [u8; 0] = [];
403 let mut r = BitReader::new(&bytes);
404 match r.read_rbsp_trailing_bits() {
405 Err(BitstreamError::UnexpectedEnd(_)) => {}
406 other => panic!("expected UnexpectedEnd, got {other:?}"),
407 }
408 }
409}