openjph_core/codestream/
bitbuffer_read.rs1#[derive(Debug)]
11pub struct BitBufferRead<'a> {
12 data: &'a [u8],
13 pos: usize,
14 buf: u64,
16 bits_left: u32,
18 unstuff: bool,
20}
21
22impl<'a> BitBufferRead<'a> {
23 pub fn new(data: &'a [u8]) -> Self {
25 Self {
26 data,
27 pos: 0,
28 buf: 0,
29 bits_left: 0,
30 unstuff: false,
31 }
32 }
33
34 pub fn fill(&mut self) {
36 while self.bits_left <= 32 && self.pos < self.data.len() {
37 let byte = self.data[self.pos] as u64;
38 self.pos += 1;
39 let bits_to_add = if self.unstuff { 7 } else { 8 };
40 let val = if self.unstuff { byte & 0x7F } else { byte };
41 self.buf |= val << (64 - bits_to_add - self.bits_left);
42 self.bits_left += bits_to_add;
43 self.unstuff = (self.data[self.pos - 1]) == 0xFF;
44 }
45 }
46
47 #[inline]
49 pub fn peek(&self, n: u32) -> u32 {
50 debug_assert!(n <= 32 && n <= self.bits_left);
51 (self.buf >> (64 - n)) as u32
52 }
53
54 #[inline]
56 pub fn advance(&mut self, n: u32) {
57 debug_assert!(n <= self.bits_left);
58 self.buf <<= n;
59 self.bits_left -= n;
60 }
61
62 #[inline]
64 pub fn read(&mut self, n: u32) -> u32 {
65 if self.bits_left < n {
66 self.fill();
67 }
68 let val = self.peek(n);
69 self.advance(n);
70 val
71 }
72
73 #[inline]
75 pub fn available_bits(&self) -> u32 {
76 self.bits_left
77 }
78
79 #[inline]
81 pub fn position(&self) -> usize {
82 self.pos
83 }
84
85 #[inline]
87 pub fn is_unstuffing(&self) -> bool {
88 self.unstuff
89 }
90
91 pub fn reset(&mut self, data: &'a [u8]) {
93 self.data = data;
94 self.pos = 0;
95 self.buf = 0;
96 self.bits_left = 0;
97 self.unstuff = false;
98 }
99}
100
101#[cfg(test)]
102mod tests {
103 use super::*;
104
105 #[test]
106 fn read_single_bits() {
107 let data = [0xA5u8];
109 let mut reader = BitBufferRead::new(&data);
110 assert_eq!(reader.read(1), 1);
111 assert_eq!(reader.read(1), 0);
112 assert_eq!(reader.read(1), 1);
113 assert_eq!(reader.read(1), 0);
114 assert_eq!(reader.read(1), 0);
115 assert_eq!(reader.read(1), 1);
116 assert_eq!(reader.read(1), 0);
117 assert_eq!(reader.read(1), 1);
118 }
119
120 #[test]
121 fn read_multi_bit_values() {
122 let data = [0xABu8, 0xCD];
124 let mut reader = BitBufferRead::new(&data);
125 assert_eq!(reader.read(4), 0xA); assert_eq!(reader.read(4), 0xB); assert_eq!(reader.read(8), 0xCD);
128 }
129
130 #[test]
131 fn read_across_byte_boundary() {
132 let data = [0xABu8, 0xCD];
133 let mut reader = BitBufferRead::new(&data);
134 assert_eq!(reader.read(12), 0xABC);
136 assert_eq!(reader.read(4), 0xD);
137 }
138
139 #[test]
140 fn multiple_reads_across_bytes() {
141 let data = [0xABu8, 0xCD];
143 let mut reader = BitBufferRead::new(&data);
144 assert_eq!(reader.read(4), 0b1010); assert_eq!(reader.read(8), 0b10111100); assert_eq!(reader.read(4), 0b1101); }
148
149 #[test]
150 fn unstuffing_after_0xff() {
151 let data = [0xFFu8, 0x80];
154 let mut reader = BitBufferRead::new(&data);
155 reader.fill();
156 assert_eq!(reader.read(8), 0xFF);
158 assert_eq!(reader.read(7), 0x00);
160 }
161
162 #[test]
163 fn unstuffing_preserves_lower_7_bits() {
164 let data = [0xFFu8, 0x7F, 0x42];
167 let mut reader = BitBufferRead::new(&data);
168 reader.fill();
169 assert_eq!(reader.read(8), 0xFF);
171 let bits = reader.available_bits();
173 assert!(bits >= 7);
174 }
175
176 #[test]
177 fn empty_stream() {
178 let data: &[u8] = &[];
179 let reader = BitBufferRead::new(data);
180 assert_eq!(reader.available_bits(), 0);
181 assert_eq!(reader.position(), 0);
182 }
183
184 #[test]
185 fn position_tracking() {
186 let data = [0x12u8, 0x34, 0x56, 0x78];
187 let mut reader = BitBufferRead::new(&data);
188 assert_eq!(reader.position(), 0);
189 reader.fill();
190 assert!(reader.position() > 0);
192 }
193
194 #[test]
195 fn reset_clears_state() {
196 let data1 = [0xFFu8, 0x00];
197 let data2 = [0x42u8];
198 let mut reader = BitBufferRead::new(&data1);
199 reader.fill();
200 let _ = reader.read(8);
201
202 reader.reset(&data2);
203 assert_eq!(reader.position(), 0);
204 assert_eq!(reader.available_bits(), 0);
205 assert!(!reader.is_unstuffing());
206 assert_eq!(reader.read(8), 0x42);
207 }
208
209 #[test]
210 fn fill_then_peek_advance() {
211 let data = [0xABu8, 0xCD];
212 let mut reader = BitBufferRead::new(&data);
213 reader.fill();
214 let peeked = reader.peek(8);
216 assert_eq!(peeked, 0xAB);
217 assert_eq!(reader.available_bits(), reader.available_bits());
218 reader.advance(8);
220 assert_eq!(reader.peek(8), 0xCD);
221 }
222
223 #[test]
224 fn read_full_32bits() {
225 let data = [0x12u8, 0x34, 0x56, 0x78, 0x9A];
226 let mut reader = BitBufferRead::new(&data);
227 let val = reader.read(32);
228 assert_eq!(val, 0x12345678);
229 }
230
231 #[test]
232 fn unstuffing_multiple_0xff_sequence() {
233 let data = [0xFFu8, 0x00, 0xFF, 0x00];
235 let mut reader = BitBufferRead::new(&data);
236 reader.fill();
237 assert_eq!(reader.read(8), 0xFF);
239 assert_eq!(reader.read(7), 0x00);
241 assert_eq!(reader.read(8), 0xFF);
243 assert_eq!(reader.read(7), 0x00);
245 }
246}