openjph_core/codestream/
bitbuffer_write.rs1#[derive(Debug)]
8pub struct BitBufferWrite {
9 data: Vec<u8>,
10 buf: u64,
12 bits_used: u32,
14 unstuff: bool,
16}
17
18impl BitBufferWrite {
19 pub fn new() -> Self {
21 Self {
22 data: Vec::with_capacity(256),
23 buf: 0,
24 bits_used: 0,
25 unstuff: false,
26 }
27 }
28
29 #[inline]
31 pub fn write(&mut self, val: u32, n: u32) {
32 debug_assert!(n <= 32);
33 self.buf |= (val as u64) << (64 - self.bits_used - n);
34 self.bits_used += n;
35 if self.bits_used >= 32 {
36 self.flush_bytes();
37 }
38 }
39
40 fn flush_bytes(&mut self) {
42 loop {
43 if self.unstuff {
44 if self.bits_used < 7 {
45 break;
46 }
47 let val = ((self.buf >> 57) as u8) & 0x7F;
49 self.data.push(val);
50 self.buf <<= 7;
51 self.bits_used -= 7;
52 self.unstuff = false;
53 } else {
54 if self.bits_used < 8 {
55 break;
56 }
57 let byte = (self.buf >> 56) as u8;
58 self.data.push(byte);
59 self.buf <<= 8;
60 self.bits_used -= 8;
61 self.unstuff = byte == 0xFF;
62 }
63 }
64 }
65
66 pub fn finalize(&mut self) -> bool {
69 let mut added_stuffing_zero = false;
70 while self.bits_used > 0 || self.unstuff {
71 if self.bits_used == 0 {
72 self.data.push(0);
74 self.unstuff = false;
75 added_stuffing_zero = true;
76 } else {
77 let byte_bits = if self.unstuff { 7u32 } else { 8u32 };
79 if self.bits_used < byte_bits {
80 self.bits_used = byte_bits;
81 } else {
82 let rem = self.bits_used % byte_bits;
83 if rem != 0 {
84 self.bits_used += byte_bits - rem;
85 }
86 }
87 self.flush_bytes();
88 }
89 }
90 added_stuffing_zero
91 }
92
93 pub fn get_data(&self) -> &[u8] {
95 &self.data
96 }
97
98 pub fn into_data(self) -> Vec<u8> {
100 self.data
101 }
102
103 pub fn len(&self) -> usize {
105 self.data.len()
106 }
107
108 pub fn is_empty(&self) -> bool {
110 self.data.is_empty() && self.bits_used == 0
111 }
112
113 pub fn reset(&mut self) {
115 self.data.clear();
116 self.buf = 0;
117 self.bits_used = 0;
118 self.unstuff = false;
119 }
120}
121
122impl Default for BitBufferWrite {
123 fn default() -> Self {
124 Self::new()
125 }
126}
127
128#[cfg(test)]
129mod tests {
130 use super::*;
131
132 #[test]
133 fn empty_writer() {
134 let writer = BitBufferWrite::new();
135 assert!(writer.is_empty());
136 assert_eq!(writer.len(), 0);
137 assert_eq!(writer.get_data(), &[]);
138 }
139
140 #[test]
141 fn write_single_byte() {
142 let mut writer = BitBufferWrite::new();
143 writer.write(0xAB, 8);
144 writer.finalize();
145 assert_eq!(writer.get_data()[0], 0xAB);
146 }
147
148 #[test]
149 fn write_individual_bits() {
150 let mut writer = BitBufferWrite::new();
151 writer.write(1, 1);
153 writer.write(0, 1);
154 writer.write(1, 1);
155 writer.write(0, 1);
156 writer.write(1, 1);
157 writer.write(0, 1);
158 writer.write(1, 1);
159 writer.write(1, 1);
160 writer.finalize();
161 assert_eq!(writer.get_data()[0], 0xAB);
162 }
163
164 #[test]
165 fn write_multi_bit_values() {
166 let mut writer = BitBufferWrite::new();
167 writer.write(0xA, 4); writer.write(0xB, 4); writer.finalize();
170 assert_eq!(writer.get_data()[0], 0xAB);
171 }
172
173 #[test]
174 fn byte_stuffing_after_0xff() {
175 let mut writer = BitBufferWrite::new();
176 writer.write(0xFF, 8);
178 writer.write(0xFF, 8);
181 writer.finalize();
182 let data = writer.get_data();
183 assert_eq!(data[0], 0xFF);
184 assert_eq!(data[1] & 0x80, 0x00);
186 }
187
188 #[test]
189 fn finalize_pads_with_zeros() {
190 let mut writer = BitBufferWrite::new();
191 writer.write(0x7, 3); writer.finalize();
193 assert_eq!(writer.get_data()[0], 0xE0);
195 }
196
197 #[test]
198 fn finalize_adds_zero_after_final_0xff() {
199 let mut writer = BitBufferWrite::new();
200 writer.write(0xFF, 8);
201 let was_ff = writer.finalize();
202 let data = writer.get_data();
203 assert!(data.len() >= 2);
205 assert_eq!(data[0], 0xFF);
206 assert_eq!(data[1], 0x00);
207 let _ = was_ff;
209 }
210
211 #[test]
212 fn len_and_is_empty() {
213 let mut writer = BitBufferWrite::new();
214 assert!(writer.is_empty());
215 assert_eq!(writer.len(), 0);
216 writer.write(0xAB, 8);
217 writer.write(0xCD, 8);
218 writer.finalize();
221 assert!(!writer.is_empty());
222 assert!(writer.len() >= 2);
223 }
224
225 #[test]
226 fn reset_clears_all() {
227 let mut writer = BitBufferWrite::new();
228 writer.write(0xAB, 8);
229 writer.write(0xCD, 8);
230 writer.finalize();
231 assert!(!writer.is_empty());
232
233 writer.reset();
234 assert!(writer.is_empty());
235 assert_eq!(writer.len(), 0);
236 assert_eq!(writer.get_data(), &[]);
237 }
238
239 #[test]
240 fn write_then_finalize_small() {
241 let mut writer = BitBufferWrite::new();
242 writer.write(0x5, 3); writer.finalize();
244 assert_eq!(writer.get_data()[0], 0xA0);
246 }
247
248 #[test]
249 fn write_32_bits() {
250 let mut writer = BitBufferWrite::new();
251 writer.write(0x12345678, 32);
252 writer.finalize();
253 let data = writer.get_data();
254 assert_eq!(data[0], 0x12);
255 assert_eq!(data[1], 0x34);
256 assert_eq!(data[2], 0x56);
257 assert_eq!(data[3], 0x78);
258 }
259
260 #[test]
261 fn into_data_takes_ownership() {
262 let mut writer = BitBufferWrite::new();
263 writer.write(0xAB, 8);
264 writer.finalize();
265 let data = writer.into_data();
266 assert_eq!(data[0], 0xAB);
267 }
268
269 #[test]
270 fn roundtrip_write_then_read() {
271 use super::super::bitbuffer_read::BitBufferRead;
272
273 let mut writer = BitBufferWrite::new();
274 writer.write(0x7, 3); writer.write(0x0, 1); writer.write(0x15, 5); writer.write(0xAB, 8); writer.write(0x3, 2); writer.finalize();
281
282 let data = writer.get_data();
283 let mut reader = BitBufferRead::new(data);
284
285 assert_eq!(reader.read(3), 0x7);
287 assert_eq!(reader.read(1), 0x0);
288 assert_eq!(reader.read(5), 0x15);
289 assert_eq!(reader.read(8), 0xAB);
290 assert_eq!(reader.read(2), 0x3);
291 }
292
293 #[test]
294 fn roundtrip_with_byte_stuffing() {
295 use super::super::bitbuffer_read::BitBufferRead;
296
297 let mut writer = BitBufferWrite::new();
299 writer.write(0xFF, 8);
300 writer.write(0x55, 8);
301 writer.finalize();
302
303 let data = writer.get_data();
304 assert_eq!(data[0], 0xFF);
305 assert_eq!(data[1] & 0x80, 0); let mut reader = BitBufferRead::new(data);
308 assert_eq!(reader.read(8), 0xFF);
309 assert_eq!(reader.read(8), 0x55);
310
311 let mut writer = BitBufferWrite::new();
313 writer.write(0xFF, 8);
314 writer.write(0xFF, 8);
315 writer.write(0xAA, 8);
316 writer.finalize();
317
318 let data = writer.get_data();
319 let mut reader = BitBufferRead::new(data);
320 assert_eq!(reader.read(8), 0xFF);
321 assert_eq!(reader.read(8), 0xFF);
322 assert_eq!(reader.read(8), 0xAA);
323
324 let mut writer = BitBufferWrite::new();
326 writer.write(0xFF, 8);
327 writer.write(0x5, 3); writer.write(0xA, 4); writer.finalize();
330
331 let data = writer.get_data();
332 let mut reader = BitBufferRead::new(data);
333 assert_eq!(reader.read(8), 0xFF);
334 assert_eq!(reader.read(3), 0x5);
335 assert_eq!(reader.read(4), 0xA);
336 }
337
338 #[test]
339 fn default_trait() {
340 let writer = BitBufferWrite::default();
341 assert!(writer.is_empty());
342 }
343}