Skip to main content

oxideav_evc/
bitreader.rs

1//! MSB-first bit reader plus 0-th-order Exp-Golomb helpers for EVC RBSPs.
2//!
3//! Per ISO/IEC 23094-1 §7.2 / §9.2, EVC syntax elements are coded MSB-first
4//! within each byte. The `ue(v)` / `se(v)` codes are 0-th order Exp-Golomb,
5//! identical to the AVC / HEVC mapping.
6//!
7//! EVC uses a length-prefixed NAL framing model (Annex B `nal_unit_length` is
8//! `u(32)`), so the EVC syntax does **not** specify start-code emulation
9//! prevention bytes — RBSPs are read directly out of the NAL body. This
10//! reader therefore operates on the raw NAL payload after the 2-byte NAL
11//! header.
12
13use oxideav_core::{Error, Result};
14
15/// MSB-first bit reader over a byte slice.
16pub 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    /// Current read offset in bits, measured from the start of the input.
34    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    /// Discard bits up to the next byte boundary (§7.2 byte_aligned()).
47    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    /// Read `n` bits (0..=32) as an unsigned integer.
62    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    /// Read a single bit.
80    pub fn u1(&mut self) -> Result<u32> {
81        self.u(1)
82    }
83
84    /// Read `n` bits (0..=64).
85    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    /// Skip `n` bits.
96    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    /// Read a 0-th order unsigned Exp-Golomb code, `ue(v)` (§9.2).
108    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    /// Read a 0-th order signed Exp-Golomb code, `se(v)` (§9.2.2).
124    pub fn se(&mut self) -> Result<i32> {
125        let k = self.ue()?;
126        // 0 -> 0, 1 -> 1, 2 -> -1, 3 -> 2, 4 -> -2, ...
127        let val = ((k + 1) >> 1) as i32;
128        if k & 1 == 1 {
129            Ok(val)
130        } else {
131            Ok(-val)
132        }
133    }
134
135    /// Read a k-th order unsigned Exp-Golomb code, `uek(v)` (§9.2 with k > 0).
136    pub fn uek(&mut self, k: u32) -> Result<u32> {
137        // EG-k: prefix is unary (zero count = M), suffix length M+k bits.
138        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        // value = ((1<<zeros) - 1) * (1<<k) + suffix
152        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        // bits: 1 (=0), 010 (=1), 011 (=2), 00100 (=3)
174        // concatenated: 1 010 011 00100 = 1010_0110_0100
175        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        // se: 0 -> 0, 1 -> 1, 2 -> -1, 3 -> 2
186        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        // uek with k=0 must equal ue.
197        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        // EG-1 codewords: 0 -> "10", 1 -> "11", 2 -> "0100", 3 -> "0101",
208        // 4 -> "0110", 5 -> "0111".
209        // bits: 10 11 0100 0101 = 1011_0100_0101
210        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}