otf_pixels_codec_avif/av1/
bits.rs1use otf_pixels_core::{PixelsError, Result};
14
15pub struct BitReader<'a> {
20 data: &'a [u8],
21 pos: usize,
24}
25
26impl<'a> BitReader<'a> {
27 #[must_use]
29 pub fn new(data: &'a [u8]) -> Self {
30 Self { data, pos: 0 }
31 }
32
33 #[must_use]
35 pub fn bit_position(&self) -> usize {
36 self.pos
37 }
38
39 #[must_use]
41 pub fn bit_len(&self) -> usize {
42 self.data.len().saturating_mul(8)
43 }
44
45 #[must_use]
47 pub fn bits_left(&self) -> usize {
48 self.bit_len().saturating_sub(self.pos)
49 }
50
51 #[must_use]
53 pub fn is_byte_aligned(&self) -> bool {
54 self.pos % 8 == 0
55 }
56
57 #[must_use]
59 pub fn byte_position(&self) -> usize {
60 self.pos / 8
61 }
62
63 fn read_bit(&mut self) -> Result<u32> {
65 let byte = self.pos / 8;
66 let Some(&value) = self.data.get(byte) else {
67 return Err(PixelsError::malformed(
68 "avif",
69 "the AV1 bitstream ended in the middle of a value",
70 ));
71 };
72 let shift = 7 - (self.pos % 8);
74 self.pos += 1;
75 Ok(u32::from((value >> shift) & 1))
76 }
77
78 pub fn f(&mut self, n: u32) -> Result<u32> {
82 if n == 0 {
83 return Ok(0);
84 }
85 if n > 32 {
86 return Err(PixelsError::malformed(
87 "avif",
88 "an AV1 fixed-width read wider than 32 bits is a decoder bug",
89 ));
90 }
91 let mut value: u32 = 0;
92 for _ in 0..n {
93 value = (value << 1) | self.read_bit()?;
96 }
97 Ok(value)
98 }
99
100 fn f64(&mut self, n: u32) -> Result<u64> {
102 if n > 64 {
103 return Err(PixelsError::malformed(
104 "avif",
105 "an AV1 fixed-width read wider than 64 bits is a decoder bug",
106 ));
107 }
108 let mut value: u64 = 0;
109 for _ in 0..n {
110 value = (value << 1) | u64::from(self.read_bit()?);
111 }
112 Ok(value)
113 }
114
115 pub fn flag(&mut self) -> Result<bool> {
117 Ok(self.f(1)? != 0)
118 }
119
120 pub fn uvlc(&mut self) -> Result<u32> {
126 let mut leading_zeros: u32 = 0;
127 loop {
128 if self.flag()? {
129 break;
130 }
131 leading_zeros += 1;
132 if leading_zeros >= 32 {
133 return Ok(u32::MAX);
134 }
135 }
136 let value = self.f(leading_zeros)?;
137 Ok(value + ((1_u32 << leading_zeros) - 1))
140 }
141
142 pub fn le(&mut self, n: u32) -> Result<u64> {
146 if !self.is_byte_aligned() {
147 return Err(PixelsError::malformed(
148 "avif",
149 "an AV1 le() read was not byte-aligned",
150 ));
151 }
152 let mut value: u64 = 0;
153 for i in 0..n {
154 let byte = self.f64(8)?;
155 value |= byte << (i * 8);
156 }
157 Ok(value)
158 }
159
160 pub fn leb128(&mut self) -> Result<u64> {
165 if !self.is_byte_aligned() {
166 return Err(PixelsError::malformed(
167 "avif",
168 "an AV1 leb128() read was not byte-aligned",
169 ));
170 }
171 let mut value: u64 = 0;
172 for i in 0..8 {
173 let byte = self.f(8)?;
174 value |= u64::from(byte & 0x7f) << (i * 7);
176 if byte & 0x80 == 0 {
177 return Ok(value);
178 }
179 }
180 Err(PixelsError::malformed(
181 "avif",
182 "an AV1 leb128 value ran past its eight-byte maximum",
183 ))
184 }
185
186 pub fn su(&mut self, n: u32) -> Result<i32> {
188 let value = self.f(n + 1)? as i32;
189 let sign_mask = 1_i32 << n;
190 if value & sign_mask != 0 {
191 Ok(value - 2 * sign_mask)
192 } else {
193 Ok(value)
194 }
195 }
196
197 pub fn ns(&mut self, n: u32) -> Result<u32> {
202 if n <= 1 {
203 return Ok(0);
204 }
205 let w = floor_log2(n) + 1;
206 let m = (1_u32 << w) - n;
207 let v = self.f(w - 1)?;
208 if v < m {
209 return Ok(v);
210 }
211 let extra_bit = self.f(1)?;
212 Ok((v << 1) - m + extra_bit)
213 }
214
215 pub fn byte_alignment(&mut self) -> Result<()> {
218 while !self.is_byte_aligned() {
219 if self.f(1)? != 0 {
220 return Err(PixelsError::malformed(
221 "avif",
222 "an AV1 byte-alignment pad bit was not zero",
223 ));
224 }
225 }
226 Ok(())
227 }
228
229 pub fn skip_bits(&mut self, n: usize) -> Result<()> {
231 let end = self.pos.checked_add(n).filter(|&e| e <= self.bit_len());
232 let Some(end) = end else {
233 return Err(PixelsError::malformed(
234 "avif",
235 "an AV1 skip ran past the end of the bitstream",
236 ));
237 };
238 self.pos = end;
239 Ok(())
240 }
241}
242
243#[must_use]
246pub fn floor_log2(x: u32) -> u32 {
247 31 - x.leading_zeros()
249}
250
251#[cfg(test)]
252#[allow(
253 clippy::unwrap_used,
254 clippy::indexing_slicing,
255 clippy::panic,
256 clippy::unusual_byte_groupings,
257 reason = "tests operate on known-good values and assert shapes directly"
258)]
259mod tests {
260 use super::*;
261 use otf_pixels_core::ErrorCode;
262
263 #[test]
264 fn f_reads_most_significant_bit_first() {
265 let data = [0xB2, 0x40];
267 let mut r = BitReader::new(&data);
268 assert_eq!(r.f(3).unwrap(), 0b101);
269 assert_eq!(r.f(5).unwrap(), 0b10010);
270 assert_eq!(r.f(2).unwrap(), 0b01);
271 assert_eq!(r.bit_position(), 10);
272 }
273
274 #[test]
275 fn f_of_zero_reads_nothing() {
276 let data = [0xFF];
277 let mut r = BitReader::new(&data);
278 assert_eq!(r.f(0).unwrap(), 0);
279 assert_eq!(r.bit_position(), 0);
280 }
281
282 #[test]
283 fn reading_past_the_end_is_an_error_not_a_panic() {
284 let data = [0xFF];
285 let mut r = BitReader::new(&data);
286 assert_eq!(r.f(8).unwrap(), 0xFF);
287 let err = r.f(1).unwrap_err();
288 assert_eq!(err.code(), ErrorCode::Malformed);
289 }
290
291 #[test]
292 fn uvlc_decodes_the_exponential_golomb_shape() {
293 let data = [0b1010_0110, 0b0100_0000];
299 let mut r = BitReader::new(&data);
300 assert_eq!(r.uvlc().unwrap(), 0);
301 assert_eq!(r.uvlc().unwrap(), 1);
302 assert_eq!(r.uvlc().unwrap(), 2);
303 assert_eq!(r.uvlc().unwrap(), 3);
304 }
305
306 #[test]
307 fn uvlc_saturates_at_thirty_two_leading_zeros() {
308 let data = [0x00, 0x00, 0x00, 0x00, 0x80];
310 let mut r = BitReader::new(&data);
311 assert_eq!(r.uvlc().unwrap(), u32::MAX);
312 }
313
314 #[test]
315 fn leb128_reads_little_endian_base_128() {
316 let data = [0xE5, 0x8E, 0x26];
318 let mut r = BitReader::new(&data);
319 assert_eq!(r.leb128().unwrap(), 624_485);
320 assert_eq!(r.byte_position(), 3);
321 }
322
323 #[test]
324 fn leb128_rejects_a_ninth_continuation_byte() {
325 let data = [0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80];
326 let mut r = BitReader::new(&data);
327 let err = r.leb128().unwrap_err();
328 assert_eq!(err.code(), ErrorCode::Malformed);
329 }
330
331 #[test]
332 fn le_reads_little_endian_bytes() {
333 let data = [0x34, 0x12];
334 let mut r = BitReader::new(&data);
335 assert_eq!(r.le(2).unwrap(), 0x1234);
336 }
337
338 #[test]
339 fn su_recovers_negative_values() {
340 let data = [0b1111_0111, 0b1000_0000];
342 let mut r = BitReader::new(&data);
343 assert_eq!(r.su(3).unwrap(), -1);
344 assert_eq!(r.su(3).unwrap(), 7);
345 assert_eq!(r.su(3).unwrap(), -8);
346 }
347
348 #[test]
349 fn ns_uses_one_fewer_bit_for_the_low_half() {
350 let data = [0b0_10_11_000];
353 let mut r = BitReader::new(&data);
354 assert_eq!(r.ns(3).unwrap(), 0);
355 assert_eq!(r.ns(3).unwrap(), 1);
356 assert_eq!(r.ns(3).unwrap(), 2);
357 }
358
359 #[test]
360 fn ns_of_a_power_of_two_is_plain_fixed_width() {
361 let data = [0b00_01_10_11];
363 let mut r = BitReader::new(&data);
364 assert_eq!(r.ns(4).unwrap(), 0);
365 assert_eq!(r.ns(4).unwrap(), 1);
366 assert_eq!(r.ns(4).unwrap(), 2);
367 assert_eq!(r.ns(4).unwrap(), 3);
368 }
369
370 #[test]
371 fn byte_alignment_requires_zero_padding() {
372 let mut r = BitReader::new(&[0b101_00000]);
373 assert_eq!(r.f(3).unwrap(), 0b101);
374 r.byte_alignment().unwrap();
375 assert!(r.is_byte_aligned());
376 assert_eq!(r.byte_position(), 1);
377
378 let mut bad = BitReader::new(&[0b101_00001]);
379 assert_eq!(bad.f(3).unwrap(), 0b101);
380 assert_eq!(
381 bad.byte_alignment().unwrap_err().code(),
382 ErrorCode::Malformed
383 );
384 }
385
386 #[test]
387 fn floor_log2_is_the_top_set_bit() {
388 assert_eq!(floor_log2(1), 0);
389 assert_eq!(floor_log2(2), 1);
390 assert_eq!(floor_log2(3), 1);
391 assert_eq!(floor_log2(255), 7);
392 assert_eq!(floor_log2(256), 8);
393 }
394}