1use crate::os_lib::webp::decoder::DecodingError;
2use alloc::boxed::Box;
3use alloc::vec::Vec;
4
5use super::vp8::TreeNode;
6
7#[must_use]
8#[repr(transparent)]
9pub(crate) struct BitResult<T> {
10 value_if_not_past_eof: T,
11}
12
13#[must_use]
14pub(crate) struct BitResultAccumulator;
15
16impl<T> BitResult<T> {
17 const fn ok(value: T) -> Self {
18 Self {
19 value_if_not_past_eof: value,
20 }
21 }
22
23 #[inline(always)]
26 pub(crate) fn or_accumulate(self, acc: &mut BitResultAccumulator) -> T {
27 let _ = acc;
28 self.value_if_not_past_eof
29 }
30}
31
32impl<T: Default> BitResult<T> {
33 fn err() -> Self {
34 Self {
35 value_if_not_past_eof: T::default(),
36 }
37 }
38}
39
40#[cfg_attr(test, derive(Debug))]
41pub(crate) struct ArithmeticDecoder {
42 chunks: Box<[[u8; 4]]>,
43 state: State,
44 final_bytes: [u8; 3],
45 final_bytes_remaining: i8,
46}
47
48#[cfg_attr(test, derive(Debug))]
49#[derive(Clone, Copy)]
50struct State {
51 chunk_index: usize,
52 value: u64,
53 range: u32,
54 bit_count: i32,
55}
56
57#[cfg_attr(test, derive(Debug))]
58struct FastDecoder<'a> {
59 chunks: &'a [[u8; 4]],
60 uncommitted_state: State,
61 save_state: &'a mut State,
62}
63
64impl ArithmeticDecoder {
65 pub(crate) fn new() -> ArithmeticDecoder {
66 let state = State {
67 chunk_index: 0,
68 value: 0,
69 range: 255,
70 bit_count: -8,
71 };
72 ArithmeticDecoder {
73 chunks: Box::new([]),
74 state,
75 final_bytes: [0; 3],
76 final_bytes_remaining: Self::FINAL_BYTES_REMAINING_EOF,
77 }
78 }
79
80 pub(crate) fn init(&mut self, mut buf: Vec<[u8; 4]>, len: usize) -> Result<(), DecodingError> {
81 let mut final_bytes = [0; 3];
82 let final_bytes_remaining = if len == 4 * buf.len() {
83 0
84 } else {
85 let Some(last_chunk) = buf.pop() else {
87 return Err(DecodingError::NotEnoughInitData);
88 };
89 let len_rounded_down = 4 * buf.len();
90 let num_bytes_popped = len - len_rounded_down;
91 debug_assert!(num_bytes_popped <= 3);
92 final_bytes[..num_bytes_popped].copy_from_slice(&last_chunk[..num_bytes_popped]);
93 for i in num_bytes_popped..4 {
94 debug_assert_eq!(last_chunk[i], 0, "unexpected {last_chunk:?}");
95 }
96 num_bytes_popped as i8
97 };
98
99 let chunks = buf.into_boxed_slice();
100 let state = State {
101 chunk_index: 0,
102 value: 0,
103 range: 255,
104 bit_count: -8,
105 };
106 *self = Self {
107 chunks,
108 state,
109 final_bytes,
110 final_bytes_remaining,
111 };
112 Ok(())
113 }
114
115 #[inline(always)]
124 pub(crate) fn start_accumulated_result(&mut self) -> BitResultAccumulator {
125 BitResultAccumulator
126 }
127
128 #[inline(always)]
130 pub(crate) fn check<T>(
131 &self,
132 acc: BitResultAccumulator,
133 value_if_not_past_eof: T,
134 ) -> Result<T, DecodingError> {
135 let BitResultAccumulator = acc;
140
141 if self.is_past_eof() {
142 Err(DecodingError::BitStreamError)
143 } else {
144 Ok(value_if_not_past_eof)
145 }
146 }
147
148 fn keep_accumulating<T>(
149 &self,
150 acc: BitResultAccumulator,
151 value_if_not_past_eof: T,
152 ) -> BitResult<T> {
153 let BitResultAccumulator = acc;
156
157 BitResult::ok(value_if_not_past_eof)
158 }
159
160 #[inline(never)]
162 pub(crate) fn read_bool(&mut self, probability: u8) -> BitResult<bool> {
163 if let Some(b) = self.fast().read_bool(probability) {
164 return BitResult::ok(b);
165 }
166
167 self.cold_read_bool(probability)
168 }
169
170 #[inline(never)]
172 pub(crate) fn read_flag(&mut self) -> BitResult<bool> {
173 if let Some(b) = self.fast().read_flag() {
174 return BitResult::ok(b);
175 }
176
177 self.cold_read_flag()
178 }
179
180 #[inline(never)]
182 pub(crate) fn read_literal(&mut self, n: u8) -> BitResult<u8> {
183 if let Some(v) = self.fast().read_literal(n) {
184 return BitResult::ok(v);
185 }
186
187 self.cold_read_literal(n)
188 }
189
190 #[inline(never)]
192 pub(crate) fn read_optional_signed_value(&mut self, n: u8) -> BitResult<i32> {
193 if let Some(v) = self.fast().read_optional_signed_value(n) {
194 return BitResult::ok(v);
195 }
196
197 self.cold_read_optional_signed_value(n)
198 }
199
200 #[inline]
202 pub(crate) fn read_with_tree<const N: usize>(&mut self, tree: &[TreeNode; N]) -> BitResult<i8> {
203 let first_node = tree[0];
204 self.read_with_tree_with_first_node(tree, first_node)
205 }
206
207 #[inline(never)]
209 pub(crate) fn read_with_tree_with_first_node(
210 &mut self,
211 tree: &[TreeNode],
212 first_node: TreeNode,
213 ) -> BitResult<i8> {
214 if let Some(v) = self.fast().read_with_tree(tree, first_node) {
215 return BitResult::ok(v);
216 }
217
218 self.cold_read_with_tree(tree, usize::from(first_node.index))
219 }
220
221 fn fast(&mut self) -> FastDecoder<'_> {
234 FastDecoder {
235 chunks: &self.chunks,
236 uncommitted_state: self.state,
237 save_state: &mut self.state,
238 }
239 }
240
241 const FINAL_BYTES_REMAINING_EOF: i8 = -0xE;
242
243 fn load_from_final_bytes(&mut self) {
244 match self.final_bytes_remaining {
245 1.. => {
246 self.final_bytes_remaining -= 1;
247 let byte = self.final_bytes[0];
248 self.final_bytes.rotate_left(1);
249 self.state.value <<= 8;
250 self.state.value |= u64::from(byte);
251 self.state.bit_count += 8;
252 }
253 0 => {
254 self.final_bytes_remaining -= 1;
257 self.state.value <<= 8;
258 self.state.bit_count += 8;
259 }
260 _ => {
261 self.final_bytes_remaining = Self::FINAL_BYTES_REMAINING_EOF;
262 }
263 }
264 }
265
266 fn is_past_eof(&self) -> bool {
267 self.final_bytes_remaining == Self::FINAL_BYTES_REMAINING_EOF
268 }
269
270 fn cold_read_bit(&mut self, probability: u8) -> BitResult<bool> {
271 if self.state.bit_count < 0 {
272 if let Some(chunk) = self.chunks.get(self.state.chunk_index).copied() {
273 let v = u32::from_be_bytes(chunk);
274 self.state.chunk_index += 1;
275 self.state.value <<= 32;
276 self.state.value |= u64::from(v);
277 self.state.bit_count += 32;
278 } else {
279 self.load_from_final_bytes();
280 if self.is_past_eof() {
281 return BitResult::err();
282 }
283 }
284 }
285 debug_assert!(self.state.bit_count >= 0);
286
287 let probability = u32::from(probability);
288 let split = 1 + (((self.state.range - 1) * probability) >> 8);
289 let bigsplit = u64::from(split) << self.state.bit_count;
290
291 let retval = if let Some(new_value) = self.state.value.checked_sub(bigsplit) {
292 self.state.range -= split;
293 self.state.value = new_value;
294 true
295 } else {
296 self.state.range = split;
297 false
298 };
299 debug_assert!(self.state.range > 0);
300
301 let shift = self.state.range.leading_zeros().saturating_sub(24);
307 self.state.range <<= shift;
308 self.state.bit_count -= shift as i32;
309 debug_assert!(self.state.range >= 128);
310
311 BitResult::ok(retval)
312 }
313
314 #[cold]
315 #[inline(never)]
316 fn cold_read_bool(&mut self, probability: u8) -> BitResult<bool> {
317 self.cold_read_bit(probability)
318 }
319
320 #[cold]
321 #[inline(never)]
322 fn cold_read_flag(&mut self) -> BitResult<bool> {
323 self.cold_read_bit(128)
324 }
325
326 #[cold]
327 #[inline(never)]
328 fn cold_read_literal(&mut self, n: u8) -> BitResult<u8> {
329 let mut v = 0u8;
330 let mut res = self.start_accumulated_result();
331
332 for _ in 0..n {
333 let b = self.cold_read_flag().or_accumulate(&mut res);
334 v = (v << 1) + u8::from(b);
335 }
336
337 self.keep_accumulating(res, v)
338 }
339
340 #[cold]
341 #[inline(never)]
342 fn cold_read_optional_signed_value(&mut self, n: u8) -> BitResult<i32> {
343 let mut res = self.start_accumulated_result();
344 let flag = self.cold_read_flag().or_accumulate(&mut res);
345 if !flag {
346 return self.keep_accumulating(res, 0);
348 }
349 let magnitude = self.cold_read_literal(n).or_accumulate(&mut res);
350 let sign = self.cold_read_flag().or_accumulate(&mut res);
351
352 let value = if sign {
353 -i32::from(magnitude)
354 } else {
355 i32::from(magnitude)
356 };
357 self.keep_accumulating(res, value)
358 }
359
360 #[cold]
361 #[inline(never)]
362 fn cold_read_with_tree(&mut self, tree: &[TreeNode], start: usize) -> BitResult<i8> {
363 let mut index = start;
364 let mut res = self.start_accumulated_result();
365
366 loop {
367 let node = tree[index];
368 let prob = node.prob;
369 let b = self.cold_read_bit(prob).or_accumulate(&mut res);
370 let t = if b { node.right } else { node.left };
371 let new_index = usize::from(t);
372 if new_index < tree.len() {
373 index = new_index;
374 } else {
375 let value = TreeNode::value_from_branch(t);
376 return self.keep_accumulating(res, value);
377 }
378 }
379 }
380}
381
382impl FastDecoder<'_> {
383 fn commit_if_valid<T>(self, value_if_not_past_eof: T) -> Option<T> {
384 if self.uncommitted_state.chunk_index <= self.chunks.len() {
387 *self.save_state = self.uncommitted_state;
388 Some(value_if_not_past_eof)
389 } else {
390 None
391 }
392 }
393
394 fn read_bool(mut self, probability: u8) -> Option<bool> {
395 let bit = self.fast_read_bit(probability);
396 self.commit_if_valid(bit)
397 }
398
399 fn read_flag(mut self) -> Option<bool> {
400 let value = self.fast_read_flag();
401 self.commit_if_valid(value)
402 }
403
404 fn read_literal(mut self, n: u8) -> Option<u8> {
405 let value = self.fast_read_literal(n);
406 self.commit_if_valid(value)
407 }
408
409 fn read_optional_signed_value(mut self, n: u8) -> Option<i32> {
410 let flag = self.fast_read_flag();
411 if !flag {
412 return self.commit_if_valid(0);
414 }
415 let magnitude = self.fast_read_literal(n);
416 let sign = self.fast_read_flag();
417 let value = if sign {
418 -i32::from(magnitude)
419 } else {
420 i32::from(magnitude)
421 };
422 self.commit_if_valid(value)
423 }
424
425 fn read_with_tree(mut self, tree: &[TreeNode], first_node: TreeNode) -> Option<i8> {
426 let value = self.fast_read_with_tree(tree, first_node);
427 self.commit_if_valid(value)
428 }
429
430 fn fast_read_bit(&mut self, probability: u8) -> bool {
431 let State {
432 mut chunk_index,
433 mut value,
434 mut range,
435 mut bit_count,
436 } = self.uncommitted_state;
437
438 if bit_count < 0 {
439 let chunk = self.chunks.get(chunk_index).copied();
440 let chunk = chunk.unwrap_or_default();
444
445 let v = u32::from_be_bytes(chunk);
446 chunk_index += 1;
447 value <<= 32;
448 value |= u64::from(v);
449 bit_count += 32;
450 }
451 debug_assert!(bit_count >= 0);
452
453 let probability = u32::from(probability);
454 let split = 1 + (((range - 1) * probability) >> 8);
455 let bigsplit = u64::from(split) << bit_count;
456
457 let retval = if let Some(new_value) = value.checked_sub(bigsplit) {
458 range -= split;
459 value = new_value;
460 true
461 } else {
462 range = split;
463 false
464 };
465 debug_assert!(range > 0);
466
467 let shift = range.leading_zeros().saturating_sub(24);
473 range <<= shift;
474 bit_count -= shift as i32;
475 debug_assert!(range >= 128);
476
477 self.uncommitted_state = State {
478 chunk_index,
479 value,
480 range,
481 bit_count,
482 };
483 retval
484 }
485
486 fn fast_read_flag(&mut self) -> bool {
487 let State {
488 mut chunk_index,
489 mut value,
490 mut range,
491 mut bit_count,
492 } = self.uncommitted_state;
493
494 if bit_count < 0 {
495 let chunk = self.chunks.get(chunk_index).copied();
496 let chunk = chunk.unwrap_or_default();
500
501 let v = u32::from_be_bytes(chunk);
502 chunk_index += 1;
503 value <<= 32;
504 value |= u64::from(v);
505 bit_count += 32;
506 }
507 debug_assert!(bit_count >= 0);
508
509 let half_range = range / 2;
510 let split = range - half_range;
511 let bigsplit = u64::from(split) << bit_count;
512
513 let retval = if let Some(new_value) = value.checked_sub(bigsplit) {
514 range = half_range;
515 value = new_value;
516 true
517 } else {
518 range = split;
519 false
520 };
521 debug_assert!(range > 0);
522
523 let shift = range.leading_zeros().saturating_sub(24);
529 range <<= shift;
530 bit_count -= shift as i32;
531 debug_assert!(range >= 128);
532
533 self.uncommitted_state = State {
534 chunk_index,
535 value,
536 range,
537 bit_count,
538 };
539 retval
540 }
541
542 fn fast_read_literal(&mut self, n: u8) -> u8 {
543 let mut v = 0u8;
544 for _ in 0..n {
545 let b = self.fast_read_flag();
546 v = (v << 1) + u8::from(b);
547 }
548 v
549 }
550
551 fn fast_read_with_tree(&mut self, tree: &[TreeNode], mut node: TreeNode) -> i8 {
552 loop {
553 let prob = node.prob;
554 let b = self.fast_read_bit(prob);
555 let i = if b { node.right } else { node.left };
556 let Some(next_node) = tree.get(usize::from(i)) else {
557 return TreeNode::value_from_branch(i);
558 };
559 node = *next_node;
560 }
561 }
562}
563
564