oximedia_codec/
bitstream_writer.rs1#[derive(Debug, Clone)]
15#[allow(dead_code)]
16pub struct BitstreamWriter {
17 buffer: Vec<u8>,
19 bit_pos: u8,
21 current_byte: u8,
23}
24
25impl BitstreamWriter {
26 #[allow(dead_code)]
28 pub fn new() -> Self {
29 Self {
30 buffer: Vec::new(),
31 bit_pos: 0,
32 current_byte: 0,
33 }
34 }
35
36 #[allow(dead_code)]
38 pub fn write_bit(&mut self, bit: bool) {
39 if bit {
40 self.current_byte |= 0x80 >> self.bit_pos;
41 }
42 self.bit_pos += 1;
43 if self.bit_pos == 8 {
44 self.buffer.push(self.current_byte);
45 self.current_byte = 0;
46 self.bit_pos = 0;
47 }
48 }
49
50 #[allow(dead_code)]
54 pub fn write_bits(&mut self, value: u64, count: u8) {
55 assert!(count > 0 && count <= 64, "count must be in 1..=64");
56 for i in (0..count).rev() {
57 let bit = (value >> i) & 1 == 1;
58 self.write_bit(bit);
59 }
60 }
61
62 #[allow(dead_code)]
64 pub fn write_byte(&mut self, byte: u8) {
65 self.write_bits(u64::from(byte), 8);
66 }
67
68 #[allow(dead_code)]
71 pub fn flush(mut self) -> Vec<u8> {
72 if self.bit_pos > 0 {
73 self.buffer.push(self.current_byte);
74 }
75 self.buffer
76 }
77
78 #[allow(dead_code)]
81 pub fn bits_written(&self) -> u64 {
82 self.buffer.len() as u64 * 8 + u64::from(self.bit_pos)
83 }
84
85 #[allow(dead_code)]
88 pub fn bytes_used(&self) -> usize {
89 self.buffer.len()
90 }
91}
92
93#[derive(Debug, Clone)]
102#[allow(dead_code)]
103pub struct BitstreamReader {
104 data: Vec<u8>,
106 byte_pos: usize,
108 bit_pos: u8,
110}
111
112impl BitstreamReader {
113 #[allow(dead_code)]
115 pub fn new(data: Vec<u8>) -> Self {
116 Self {
117 data,
118 byte_pos: 0,
119 bit_pos: 0,
120 }
121 }
122
123 #[allow(dead_code)]
125 pub fn read_bit(&mut self) -> Option<bool> {
126 if self.byte_pos >= self.data.len() {
127 return None;
128 }
129 let byte = self.data[self.byte_pos];
130 let bit = (byte >> (7 - self.bit_pos)) & 1 == 1;
131 self.bit_pos += 1;
132 if self.bit_pos == 8 {
133 self.byte_pos += 1;
134 self.bit_pos = 0;
135 }
136 Some(bit)
137 }
138
139 #[allow(dead_code)]
144 pub fn read_bits(&mut self, count: u8) -> Option<u64> {
145 assert!(count > 0 && count <= 64, "count must be in 1..=64");
146 let mut value: u64 = 0;
147 for _ in 0..count {
148 let bit = self.read_bit()?;
149 value = (value << 1) | u64::from(bit);
150 }
151 Some(value)
152 }
153
154 #[allow(dead_code)]
158 pub fn read_byte(&mut self) -> Option<u8> {
159 self.read_bits(8).map(|v| v as u8)
160 }
161
162 #[allow(dead_code)]
164 pub fn bits_remaining(&self) -> usize {
165 let total_bits = self.data.len() * 8;
166 let consumed = self.byte_pos * 8 + usize::from(self.bit_pos);
167 total_bits.saturating_sub(consumed)
168 }
169
170 #[allow(dead_code)]
172 pub fn is_exhausted(&self) -> bool {
173 self.bits_remaining() == 0
174 }
175}
176
177#[cfg(test)]
178mod tests {
179 use super::*;
180
181 #[test]
184 fn writer_new_is_empty() {
185 let w = BitstreamWriter::new();
186 assert_eq!(w.bits_written(), 0);
187 assert_eq!(w.bytes_used(), 0);
188 }
189
190 #[test]
191 fn writer_flush_empty() {
192 let w = BitstreamWriter::new();
193 assert!(w.flush().is_empty());
194 }
195
196 #[test]
197 fn writer_write_single_bit_one() {
198 let mut w = BitstreamWriter::new();
199 w.write_bit(true);
200 assert_eq!(w.bits_written(), 1);
201 let buf = w.flush();
202 assert_eq!(buf, vec![0x80]); }
204
205 #[test]
206 fn writer_write_single_bit_zero() {
207 let mut w = BitstreamWriter::new();
208 w.write_bit(false);
209 assert_eq!(w.bits_written(), 1);
210 let buf = w.flush();
211 assert_eq!(buf, vec![0x00]);
212 }
213
214 #[test]
215 fn writer_write_byte_roundtrip() {
216 for byte in [0x00u8, 0xFF, 0xAA, 0x55, 0x12, 0xAB] {
217 let mut w = BitstreamWriter::new();
218 w.write_byte(byte);
219 let buf = w.flush();
220 assert_eq!(buf, vec![byte], "failed for byte 0x{byte:02X}");
221 }
222 }
223
224 #[test]
225 fn writer_write_bits_4() {
226 let mut w = BitstreamWriter::new();
228 w.write_bits(0b1011, 4);
229 assert_eq!(w.bits_written(), 4);
230 let buf = w.flush();
231 assert_eq!(buf, vec![0xB0]);
232 }
233
234 #[test]
235 fn writer_bits_written_and_bytes_used() {
236 let mut w = BitstreamWriter::new();
237 w.write_bits(0xFF, 8);
238 assert_eq!(w.bytes_used(), 1);
239 assert_eq!(w.bits_written(), 8);
240 w.write_bit(true);
241 assert_eq!(w.bytes_used(), 1);
243 assert_eq!(w.bits_written(), 9);
244 }
245
246 #[test]
247 fn writer_multiple_bytes() {
248 let mut w = BitstreamWriter::new();
249 w.write_byte(0xDE);
250 w.write_byte(0xAD);
251 let buf = w.flush();
252 assert_eq!(buf, vec![0xDE, 0xAD]);
253 }
254
255 #[test]
258 fn reader_empty_is_exhausted() {
259 let r = BitstreamReader::new(vec![]);
260 assert!(r.is_exhausted());
261 assert_eq!(r.bits_remaining(), 0);
262 }
263
264 #[test]
265 fn reader_read_bit_from_single_byte() {
266 let mut r = BitstreamReader::new(vec![0xA5]);
268 assert_eq!(r.read_bit(), Some(true));
269 assert_eq!(r.read_bit(), Some(false));
270 assert_eq!(r.read_bit(), Some(true));
271 assert_eq!(r.read_bit(), Some(false));
272 assert_eq!(r.read_bit(), Some(false));
273 assert_eq!(r.read_bit(), Some(true));
274 assert_eq!(r.read_bit(), Some(false));
275 assert_eq!(r.read_bit(), Some(true));
276 assert_eq!(r.read_bit(), None); }
278
279 #[test]
280 fn reader_bits_remaining_decrements() {
281 let mut r = BitstreamReader::new(vec![0xFF]);
282 assert_eq!(r.bits_remaining(), 8);
283 r.read_bit();
284 assert_eq!(r.bits_remaining(), 7);
285 }
286
287 #[test]
288 fn reader_read_byte_full() {
289 let mut r = BitstreamReader::new(vec![0x42]);
290 assert_eq!(r.read_byte(), Some(0x42));
291 assert!(r.is_exhausted());
292 }
293
294 #[test]
295 fn reader_read_byte_insufficient() {
296 let mut r = BitstreamReader::new(vec![]);
297 assert_eq!(r.read_byte(), None);
298 }
299
300 #[test]
303 fn roundtrip_byte_sequence() {
304 let original = vec![0xDE_u8, 0xAD, 0xBE, 0xEF];
305 let mut w = BitstreamWriter::new();
306 for &b in &original {
307 w.write_byte(b);
308 }
309 let buf = w.flush();
310 let mut r = BitstreamReader::new(buf);
311 for &expected in &original {
312 assert_eq!(r.read_byte(), Some(expected));
313 }
314 assert!(r.is_exhausted());
315 }
316
317 #[test]
318 fn roundtrip_mixed_bit_widths() {
319 let mut w = BitstreamWriter::new();
321 w.write_bits(5, 3);
322 w.write_bits(22, 5);
323 w.write_byte(0xFF);
324 let buf = w.flush();
325
326 let mut r = BitstreamReader::new(buf);
327 assert_eq!(r.read_bits(3), Some(5));
328 assert_eq!(r.read_bits(5), Some(22));
329 assert_eq!(r.read_byte(), Some(0xFF));
330 assert!(r.is_exhausted());
331 }
332
333 #[test]
334 fn roundtrip_single_bits() {
335 let bits = [true, false, true, true, false, false, true, false];
336 let mut w = BitstreamWriter::new();
337 for &b in &bits {
338 w.write_bit(b);
339 }
340 let buf = w.flush();
341
342 let mut r = BitstreamReader::new(buf);
343 for &expected in &bits {
344 assert_eq!(r.read_bit(), Some(expected));
345 }
346 assert!(r.is_exhausted());
347 }
348
349 #[test]
350 fn roundtrip_64bit_value() {
351 let value: u64 = 0xDEAD_BEEF_CAFE_1234;
352 let mut w = BitstreamWriter::new();
353 w.write_bits(value, 64);
354 let buf = w.flush();
355 assert_eq!(buf.len(), 8);
356 let mut r = BitstreamReader::new(buf);
357 let read_back = r.read_bits(64).expect("should succeed");
358 assert_eq!(read_back, value);
359 assert!(r.is_exhausted());
360 }
361}