1use oxideav_core::{Error, Result};
14
15pub struct BitReader<'a> {
17 data: &'a [u8],
18 byte_pos: usize,
19 acc: u64,
20 bits_in_acc: u32,
21}
22
23impl<'a> BitReader<'a> {
24 pub fn new(data: &'a [u8]) -> Self {
25 Self {
26 data,
27 byte_pos: 0,
28 acc: 0,
29 bits_in_acc: 0,
30 }
31 }
32
33 pub fn bit_position(&self) -> u64 {
35 self.byte_pos as u64 * 8 - self.bits_in_acc as u64
36 }
37
38 pub fn bits_remaining(&self) -> u64 {
39 (self.data.len() as u64 - self.byte_pos as u64) * 8 + self.bits_in_acc as u64
40 }
41
42 pub fn is_byte_aligned(&self) -> bool {
43 self.bits_in_acc % 8 == 0
44 }
45
46 pub fn align_to_byte(&mut self) {
48 let drop = self.bits_in_acc % 8;
49 self.acc <<= drop;
50 self.bits_in_acc -= drop;
51 }
52
53 fn refill(&mut self) {
54 while self.bits_in_acc <= 56 && self.byte_pos < self.data.len() {
55 self.acc |= (self.data[self.byte_pos] as u64) << (56 - self.bits_in_acc);
56 self.bits_in_acc += 8;
57 self.byte_pos += 1;
58 }
59 }
60
61 pub fn u(&mut self, n: u32) -> Result<u32> {
63 debug_assert!(n <= 32);
64 if n == 0 {
65 return Ok(0);
66 }
67 if self.bits_in_acc < n {
68 self.refill();
69 if self.bits_in_acc < n {
70 return Err(Error::invalid("evc bitreader: out of bits"));
71 }
72 }
73 let v = (self.acc >> (64 - n)) as u32;
74 self.acc <<= n;
75 self.bits_in_acc -= n;
76 Ok(v)
77 }
78
79 pub fn u1(&mut self) -> Result<u32> {
81 self.u(1)
82 }
83
84 pub fn u_long(&mut self, n: u32) -> Result<u64> {
86 debug_assert!(n <= 64);
87 if n <= 32 {
88 return Ok(self.u(n)? as u64);
89 }
90 let hi = self.u(n - 32)? as u64;
91 let lo = self.u(32)? as u64;
92 Ok((hi << 32) | lo)
93 }
94
95 pub fn skip(&mut self, mut n: u32) -> Result<()> {
97 while n > 32 {
98 self.u(32)?;
99 n -= 32;
100 }
101 if n > 0 {
102 self.u(n)?;
103 }
104 Ok(())
105 }
106
107 pub fn ue(&mut self) -> Result<u32> {
109 let mut zeros: u32 = 0;
110 while self.u1()? == 0 {
111 zeros += 1;
112 if zeros > 32 {
113 return Err(Error::invalid("evc ue(v): too many leading zeros"));
114 }
115 }
116 if zeros == 0 {
117 return Ok(0);
118 }
119 let suffix = self.u(zeros)?;
120 Ok((1u32 << zeros) - 1 + suffix)
121 }
122
123 pub fn se(&mut self) -> Result<i32> {
125 let k = self.ue()?;
126 let val = ((k + 1) >> 1) as i32;
128 if k & 1 == 1 {
129 Ok(val)
130 } else {
131 Ok(-val)
132 }
133 }
134
135 pub fn uek(&mut self, k: u32) -> Result<u32> {
137 let mut zeros: u32 = 0;
139 while self.u1()? == 0 {
140 zeros += 1;
141 if zeros > 32 {
142 return Err(Error::invalid("evc uek(v): too many leading zeros"));
143 }
144 }
145 let total_suffix = zeros + k;
146 let suffix = if total_suffix > 0 {
147 self.u(total_suffix)?
148 } else {
149 0
150 };
151 let base = ((1u32 << zeros).wrapping_sub(1)) << k;
153 Ok(base + suffix)
154 }
155}
156
157#[cfg(test)]
158mod tests {
159 use super::*;
160
161 #[test]
162 fn read_msb_first() {
163 let data = [0b1011_0001u8, 0b0101_0101];
164 let mut br = BitReader::new(&data);
165 assert_eq!(br.u(1).unwrap(), 1);
166 assert_eq!(br.u(2).unwrap(), 0b01);
167 assert_eq!(br.u(5).unwrap(), 0b1_0001);
168 assert_eq!(br.u(8).unwrap(), 0b0101_0101);
169 }
170
171 #[test]
172 fn ue_sequence() {
173 let data = [0b1010_0110, 0b0100_0000];
176 let mut br = BitReader::new(&data);
177 assert_eq!(br.ue().unwrap(), 0);
178 assert_eq!(br.ue().unwrap(), 1);
179 assert_eq!(br.ue().unwrap(), 2);
180 assert_eq!(br.ue().unwrap(), 3);
181 }
182
183 #[test]
184 fn se_sequence() {
185 let data = [0b1010_0110, 0b0100_0000];
187 let mut br = BitReader::new(&data);
188 assert_eq!(br.se().unwrap(), 0);
189 assert_eq!(br.se().unwrap(), 1);
190 assert_eq!(br.se().unwrap(), -1);
191 assert_eq!(br.se().unwrap(), 2);
192 }
193
194 #[test]
195 fn uek_zero_order_matches_ue() {
196 let data = [0b1010_0110, 0b0100_0000];
198 let mut br_ue = BitReader::new(&data);
199 let mut br_uek = BitReader::new(&data);
200 for _ in 0..4 {
201 assert_eq!(br_ue.ue().unwrap(), br_uek.uek(0).unwrap());
202 }
203 }
204
205 #[test]
206 fn uek_first_order() {
207 let data = [0b1011_0100, 0b0101_0000];
211 let mut br = BitReader::new(&data);
212 assert_eq!(br.uek(1).unwrap(), 0);
213 assert_eq!(br.uek(1).unwrap(), 1);
214 assert_eq!(br.uek(1).unwrap(), 2);
215 assert_eq!(br.uek(1).unwrap(), 3);
216 }
217
218 #[test]
219 fn align_to_byte() {
220 let data = [0b1111_0000u8, 0xAA];
221 let mut br = BitReader::new(&data);
222 assert_eq!(br.u(3).unwrap(), 0b111);
223 br.align_to_byte();
224 assert!(br.is_byte_aligned());
225 assert_eq!(br.u(8).unwrap(), 0xAA);
226 }
227
228 #[test]
229 fn underflow_is_error() {
230 let data = [0xFFu8];
231 let mut br = BitReader::new(&data);
232 assert!(br.u(16).is_err());
233 }
234}