1pub use av_bitstream::bitread::{BitRead, BitReadBE, BitReadLE};
7
8use wedeo_core::{Error, Result};
9
10const MAX_EXP_GOLOMB_LEADING_ZEROS: u32 = 31;
15
16pub fn get_ue_golomb(br: &mut BitReadBE<'_>) -> Result<u32> {
24 let buf = br.peek_bits_32(32);
27
28 if buf == 0 {
29 return Err(Error::InvalidData);
31 }
32
33 let leading_zeros = buf.leading_zeros();
36
37 if leading_zeros > MAX_EXP_GOLOMB_LEADING_ZEROS {
38 return Err(Error::InvalidData);
39 }
40
41 br.skip_bits(leading_zeros as usize);
43
44 let val = br.get_bits_32(leading_zeros as usize + 1);
46
47 Ok(val - 1)
49}
50
51pub fn get_se_golomb(br: &mut BitReadBE<'_>) -> Result<i32> {
58 let buf = get_ue_golomb(br)?;
59
60 let sign = (buf & 1) as i32 - 1; Ok(((buf >> 1) as i32 ^ sign) + 1)
65}
66
67pub fn get_te_golomb(br: &mut BitReadBE<'_>, range: u32) -> Result<u32> {
75 assert!(range >= 1, "get_te_golomb: range must be >= 1");
76
77 if range == 2 {
78 Ok(u32::from(br.get_bit()) ^ 1)
79 } else {
80 get_ue_golomb(br)
81 }
82}
83
84pub fn get_te0_golomb(br: &mut BitReadBE<'_>, range: u32) -> Result<u32> {
92 assert!(range >= 1, "get_te0_golomb: range must be >= 1");
93
94 if range == 1 {
95 Ok(0)
96 } else if range == 2 {
97 Ok(u32::from(br.get_bit()) ^ 1)
98 } else {
99 get_ue_golomb(br)
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use super::*;
106
107 fn make_reader(data: &[u8]) -> BitReadBE<'_> {
112 BitReadBE::new(data)
113 }
114
115 #[test]
118 fn ue_value_0() {
119 let data = [0x80, 0, 0, 0, 0, 0, 0, 0];
121 let mut br = make_reader(&data);
122 assert_eq!(get_ue_golomb(&mut br).unwrap(), 0);
123 }
124
125 #[test]
126 fn ue_value_1() {
127 let data = [0x40, 0, 0, 0, 0, 0, 0, 0];
129 let mut br = make_reader(&data);
130 assert_eq!(get_ue_golomb(&mut br).unwrap(), 1);
131 }
132
133 #[test]
134 fn ue_value_2() {
135 let data = [0x60, 0, 0, 0, 0, 0, 0, 0];
137 let mut br = make_reader(&data);
138 assert_eq!(get_ue_golomb(&mut br).unwrap(), 2);
139 }
140
141 #[test]
142 fn ue_value_3() {
143 let data = [0x20, 0, 0, 0, 0, 0, 0, 0];
145 let mut br = make_reader(&data);
146 assert_eq!(get_ue_golomb(&mut br).unwrap(), 3);
147 }
148
149 #[test]
150 fn ue_value_4() {
151 let data = [0x28, 0, 0, 0, 0, 0, 0, 0];
153 let mut br = make_reader(&data);
154 assert_eq!(get_ue_golomb(&mut br).unwrap(), 4);
155 }
156
157 #[test]
158 fn ue_value_5() {
159 let data = [0x30, 0, 0, 0, 0, 0, 0, 0];
161 let mut br = make_reader(&data);
162 assert_eq!(get_ue_golomb(&mut br).unwrap(), 5);
163 }
164
165 #[test]
166 fn ue_value_6() {
167 let data = [0x38, 0, 0, 0, 0, 0, 0, 0];
169 let mut br = make_reader(&data);
170 assert_eq!(get_ue_golomb(&mut br).unwrap(), 6);
171 }
172
173 #[test]
174 fn ue_sequential_values() {
175 let data = [0xA6, 0, 0, 0, 0, 0, 0, 0];
178 let mut br = make_reader(&data);
179 assert_eq!(get_ue_golomb(&mut br).unwrap(), 0); assert_eq!(get_ue_golomb(&mut br).unwrap(), 1); assert_eq!(get_ue_golomb(&mut br).unwrap(), 2); }
183
184 #[test]
185 fn ue_error_all_zeros() {
186 let data = [0u8; 8];
188 let mut br = make_reader(&data);
189 assert_eq!(get_ue_golomb(&mut br), Err(Error::InvalidData));
190 }
191
192 #[test]
195 fn se_mapping() {
196 let data = [0x80, 0, 0, 0, 0, 0, 0, 0];
200 let mut br = make_reader(&data);
201 assert_eq!(get_se_golomb(&mut br).unwrap(), 0);
202
203 let data = [0x40, 0, 0, 0, 0, 0, 0, 0];
205 let mut br = make_reader(&data);
206 assert_eq!(get_se_golomb(&mut br).unwrap(), 1);
207
208 let data = [0x60, 0, 0, 0, 0, 0, 0, 0];
210 let mut br = make_reader(&data);
211 assert_eq!(get_se_golomb(&mut br).unwrap(), -1);
212
213 let data = [0x20, 0, 0, 0, 0, 0, 0, 0];
215 let mut br = make_reader(&data);
216 assert_eq!(get_se_golomb(&mut br).unwrap(), 2);
217
218 let data = [0x28, 0, 0, 0, 0, 0, 0, 0];
220 let mut br = make_reader(&data);
221 assert_eq!(get_se_golomb(&mut br).unwrap(), -2);
222 }
223
224 #[test]
227 fn te_range_2_bit_0() {
228 let data = [0x00, 0, 0, 0, 0, 0, 0, 0]; let mut br = make_reader(&data);
232 assert_eq!(get_te_golomb(&mut br, 2).unwrap(), 1);
233 }
234
235 #[test]
236 fn te_range_2_bit_1() {
237 let data = [0x80, 0, 0, 0, 0, 0, 0, 0]; let mut br = make_reader(&data);
241 assert_eq!(get_te_golomb(&mut br, 2).unwrap(), 0);
242 }
243
244 #[test]
245 fn te_range_gt2_falls_through_to_ue() {
246 let data = [0x80, 0, 0, 0, 0, 0, 0, 0];
248 let mut br = make_reader(&data);
249 assert_eq!(get_te_golomb(&mut br, 5).unwrap(), 0);
250 }
251
252 #[test]
255 fn te0_range_1_returns_zero() {
256 let data = [0xFF, 0, 0, 0, 0, 0, 0, 0];
258 let mut br = make_reader(&data);
259 assert_eq!(get_te0_golomb(&mut br, 1).unwrap(), 0);
260 }
261
262 #[test]
263 fn te0_range_2_reads_bit() {
264 let data = [0x80, 0, 0, 0, 0, 0, 0, 0]; let mut br = make_reader(&data);
267 assert_eq!(get_te0_golomb(&mut br, 2).unwrap(), 0);
268 }
269
270 #[test]
271 fn te0_range_gt2_falls_through_to_ue() {
272 let data = [0x40, 0, 0, 0, 0, 0, 0, 0];
274 let mut br = make_reader(&data);
275 assert_eq!(get_te0_golomb(&mut br, 8).unwrap(), 1);
276 }
277
278 #[test]
281 #[should_panic(expected = "range must be >= 1")]
282 fn te_panics_on_range_0() {
283 let data = [0x80, 0, 0, 0, 0, 0, 0, 0];
284 let mut br = make_reader(&data);
285 let _ = get_te_golomb(&mut br, 0);
286 }
287
288 #[test]
289 #[should_panic(expected = "range must be >= 1")]
290 fn te0_panics_on_range_0() {
291 let data = [0x80, 0, 0, 0, 0, 0, 0, 0];
292 let mut br = make_reader(&data);
293 let _ = get_te0_golomb(&mut br, 0);
294 }
295}