1use alloc::vec;
2use alloc::vec::Vec;
3use crate::os_lib::webp::io::BufRead;
8use core::mem;
9
10use crate::os_lib::webp::decoder::DecodingError;
11use crate::os_lib::webp::lossless_transform::{
12 apply_color_indexing_transform, apply_color_transform, apply_predictor_transform,
13 apply_subtract_green_transform,
14};
15
16use super::huffman::HuffmanTree;
17use super::lossless_transform::TransformType;
18
19const CODE_LENGTH_CODES: usize = 19;
20const CODE_LENGTH_CODE_ORDER: [usize; CODE_LENGTH_CODES] = [
21 17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
22];
23
24#[rustfmt::skip]
25const DISTANCE_MAP: [(i8, i8); 120] = [
26 (0, 1), (1, 0), (1, 1), (-1, 1), (0, 2), (2, 0), (1, 2), (-1, 2),
27 (2, 1), (-2, 1), (2, 2), (-2, 2), (0, 3), (3, 0), (1, 3), (-1, 3),
28 (3, 1), (-3, 1), (2, 3), (-2, 3), (3, 2), (-3, 2), (0, 4), (4, 0),
29 (1, 4), (-1, 4), (4, 1), (-4, 1), (3, 3), (-3, 3), (2, 4), (-2, 4),
30 (4, 2), (-4, 2), (0, 5), (3, 4), (-3, 4), (4, 3), (-4, 3), (5, 0),
31 (1, 5), (-1, 5), (5, 1), (-5, 1), (2, 5), (-2, 5), (5, 2), (-5, 2),
32 (4, 4), (-4, 4), (3, 5), (-3, 5), (5, 3), (-5, 3), (0, 6), (6, 0),
33 (1, 6), (-1, 6), (6, 1), (-6, 1), (2, 6), (-2, 6), (6, 2), (-6, 2),
34 (4, 5), (-4, 5), (5, 4), (-5, 4), (3, 6), (-3, 6), (6, 3), (-6, 3),
35 (0, 7), (7, 0), (1, 7), (-1, 7), (5, 5), (-5, 5), (7, 1), (-7, 1),
36 (4, 6), (-4, 6), (6, 4), (-6, 4), (2, 7), (-2, 7), (7, 2), (-7, 2),
37 (3, 7), (-3, 7), (7, 3), (-7, 3), (5, 6), (-5, 6), (6, 5), (-6, 5),
38 (8, 0), (4, 7), (-4, 7), (7, 4), (-7, 4), (8, 1), (8, 2), (6, 6),
39 (-6, 6), (8, 3), (5, 7), (-5, 7), (7, 5), (-7, 5), (8, 4), (6, 7),
40 (-6, 7), (7, 6), (-7, 6), (8, 5), (7, 7), (-7, 7), (8, 6), (8, 7)
41];
42
43const GREEN: usize = 0;
44const RED: usize = 1;
45const BLUE: usize = 2;
46const ALPHA: usize = 3;
47const DIST: usize = 4;
48
49const HUFFMAN_CODES_PER_META_CODE: usize = 5;
50
51type HuffmanCodeGroup = [HuffmanTree; HUFFMAN_CODES_PER_META_CODE];
52
53const ALPHABET_SIZE: [u16; HUFFMAN_CODES_PER_META_CODE] = [256 + 24, 256, 256, 256, 40];
54
55#[inline]
56pub(crate) fn subsample_size(size: u16, bits: u8) -> u16 {
57 ((u32::from(size) + (1u32 << bits) - 1) >> bits)
58 .try_into()
59 .unwrap()
60}
61
62const NUM_TRANSFORM_TYPES: usize = 4;
63
64#[derive(Debug)]
66pub(crate) struct LosslessDecoder<R> {
67 bit_reader: BitReader<R>,
68 transforms: [Option<TransformType>; NUM_TRANSFORM_TYPES],
69 transform_order: Vec<u8>,
70 width: u16,
71 height: u16,
72}
73
74impl<R: BufRead> LosslessDecoder<R> {
75 pub(crate) const fn new(r: R) -> Self {
77 Self {
78 bit_reader: BitReader::new(r),
79 transforms: [None, None, None, None],
80 transform_order: Vec::new(),
81 width: 0,
82 height: 0,
83 }
84 }
85
86 pub(crate) fn decode_frame(
92 &mut self,
93 width: u32,
94 height: u32,
95 implicit_dimensions: bool,
96 buf: &mut [u8],
97 ) -> Result<(), DecodingError> {
98 if implicit_dimensions {
99 self.width = width as u16;
100 self.height = height as u16;
101 } else {
102 let signature = self.bit_reader.read_bits::<u8>(8)?;
103 if signature != 0x2f {
104 return Err(DecodingError::LosslessSignatureInvalid(signature));
105 }
106
107 self.width = self.bit_reader.read_bits::<u16>(14)? + 1;
108 self.height = self.bit_reader.read_bits::<u16>(14)? + 1;
109 if u32::from(self.width) != width || u32::from(self.height) != height {
110 return Err(DecodingError::InconsistentImageSizes);
111 }
112
113 let _alpha_used = self.bit_reader.read_bits::<u8>(1)?;
114 let version_num = self.bit_reader.read_bits::<u8>(3)?;
115 if version_num != 0 {
116 return Err(DecodingError::VersionNumberInvalid(version_num));
117 }
118 }
119
120 let transformed_width = self.read_transforms()?;
121 let transformed_size = usize::from(transformed_width) * usize::from(self.height) * 4;
122 self.decode_image_stream(
123 transformed_width,
124 self.height,
125 true,
126 &mut buf[..transformed_size],
127 )?;
128
129 let mut image_size = transformed_size;
130 let mut width = transformed_width;
131 for &trans_index in self.transform_order.iter().rev() {
132 let transform = self.transforms[usize::from(trans_index)].as_ref().unwrap();
133 match transform {
134 TransformType::PredictorTransform {
135 size_bits,
136 predictor_data,
137 } => apply_predictor_transform(
138 &mut buf[..image_size],
139 width,
140 self.height,
141 *size_bits,
142 predictor_data,
143 )?,
144 TransformType::ColorTransform {
145 size_bits,
146 transform_data,
147 } => {
148 apply_color_transform(
149 &mut buf[..image_size],
150 width,
151 *size_bits,
152 transform_data,
153 );
154 }
155 TransformType::SubtractGreen => {
156 apply_subtract_green_transform(&mut buf[..image_size]);
157 }
158 TransformType::ColorIndexingTransform {
159 table_size,
160 table_data,
161 } => {
162 width = self.width;
163 image_size = usize::from(width) * usize::from(self.height) * 4;
164 apply_color_indexing_transform(
165 buf,
166 width,
167 self.height,
168 *table_size,
169 table_data,
170 );
171 }
172 }
173 }
174
175 Ok(())
176 }
177
178 fn decode_image_stream(
184 &mut self,
185 xsize: u16,
186 ysize: u16,
187 is_argb_img: bool,
188 data: &mut [u8],
189 ) -> Result<(), DecodingError> {
190 let color_cache_bits = self.read_color_cache()?;
191 let color_cache = color_cache_bits.map(|bits| ColorCache {
192 color_cache_bits: bits,
193 color_cache: vec![[0; 4]; 1 << bits],
194 });
195
196 let huffman_info = self.read_huffman_codes(is_argb_img, xsize, ysize, color_cache)?;
197 self.decode_image_data(xsize, ysize, huffman_info, data)
198 }
199
200 fn read_transforms(&mut self) -> Result<u16, DecodingError> {
202 let mut xsize = self.width;
203
204 while self.bit_reader.read_bits::<u8>(1)? == 1 {
205 let transform_type_val = self.bit_reader.read_bits::<u8>(2)?;
206
207 if self.transforms[usize::from(transform_type_val)].is_some() {
208 return Err(DecodingError::TransformError);
210 }
211
212 self.transform_order.push(transform_type_val);
213
214 let transform_type = match transform_type_val {
215 0 => {
216 let size_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
219
220 let block_xsize = subsample_size(xsize, size_bits);
221 let block_ysize = subsample_size(self.height, size_bits);
222
223 let mut predictor_data =
224 vec![0; usize::from(block_xsize) * usize::from(block_ysize) * 4];
225 self.decode_image_stream(block_xsize, block_ysize, false, &mut predictor_data)?;
226
227 TransformType::PredictorTransform {
228 size_bits,
229 predictor_data,
230 }
231 }
232 1 => {
233 let size_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
236
237 let block_xsize = subsample_size(xsize, size_bits);
238 let block_ysize = subsample_size(self.height, size_bits);
239
240 let mut transform_data =
241 vec![0; usize::from(block_xsize) * usize::from(block_ysize) * 4];
242 self.decode_image_stream(block_xsize, block_ysize, false, &mut transform_data)?;
243
244 TransformType::ColorTransform {
245 size_bits,
246 transform_data,
247 }
248 }
249 2 => {
250 TransformType::SubtractGreen
253 }
254 3 => {
255 let color_table_size = self.bit_reader.read_bits::<u16>(8)? + 1;
256
257 let mut color_map = vec![0; usize::from(color_table_size) * 4];
258 self.decode_image_stream(color_table_size, 1, false, &mut color_map)?;
259
260 let bits = if color_table_size <= 2 {
261 3
262 } else if color_table_size <= 4 {
263 2
264 } else if color_table_size <= 16 {
265 1
266 } else {
267 0
268 };
269 xsize = subsample_size(xsize, bits);
270
271 Self::adjust_color_map(&mut color_map);
272
273 TransformType::ColorIndexingTransform {
274 table_size: color_table_size,
275 table_data: color_map,
276 }
277 }
278 _ => unreachable!(),
279 };
280
281 self.transforms[usize::from(transform_type_val)] = Some(transform_type);
282 }
283
284 Ok(xsize)
285 }
286
287 fn adjust_color_map(color_map: &mut [u8]) {
289 for i in 4..color_map.len() {
290 color_map[i] = color_map[i].wrapping_add(color_map[i - 4]);
291 }
292 }
293
294 fn read_huffman_codes(
296 &mut self,
297 read_meta: bool,
298 xsize: u16,
299 ysize: u16,
300 color_cache: Option<ColorCache>,
301 ) -> Result<HuffmanInfo, DecodingError> {
302 let mut num_huff_groups = 1u32;
303
304 let mut huffman_bits = 0;
305 let mut huffman_xsize = 1;
306 let mut huffman_ysize = 1;
307 let mut entropy_image = Vec::new();
308
309 if read_meta && self.bit_reader.read_bits::<u8>(1)? == 1 {
310 huffman_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
312 huffman_xsize = subsample_size(xsize, huffman_bits);
313 huffman_ysize = subsample_size(ysize, huffman_bits);
314
315 let mut data = vec![0; usize::from(huffman_xsize) * usize::from(huffman_ysize) * 4];
316 self.decode_image_stream(huffman_xsize, huffman_ysize, false, &mut data)?;
317
318 entropy_image = data
319 .chunks_exact(4)
320 .map(|pixel| {
321 let meta_huff_code = (u16::from(pixel[0]) << 8) | u16::from(pixel[1]);
322 if u32::from(meta_huff_code) >= num_huff_groups {
323 num_huff_groups = u32::from(meta_huff_code) + 1;
324 }
325 meta_huff_code
326 })
327 .collect::<Vec<u16>>();
328 }
329
330 let mut hufftree_groups = Vec::new();
331
332 for _i in 0..num_huff_groups {
333 let mut group: HuffmanCodeGroup = Default::default();
334 for j in 0..HUFFMAN_CODES_PER_META_CODE {
335 let mut alphabet_size = ALPHABET_SIZE[j];
336 if j == 0 {
337 if let Some(color_cache) = color_cache.as_ref() {
338 alphabet_size += 1 << color_cache.color_cache_bits;
339 }
340 }
341
342 let tree = self.read_huffman_code(alphabet_size)?;
343 group[j] = tree;
344 }
345 hufftree_groups.push(group);
346 }
347
348 let huffman_mask = if huffman_bits == 0 {
349 !0
350 } else {
351 (1 << huffman_bits) - 1
352 };
353
354 let info = HuffmanInfo {
355 xsize: huffman_xsize,
356 _ysize: huffman_ysize,
357 color_cache,
358 image: entropy_image,
359 bits: huffman_bits,
360 mask: huffman_mask,
361 huffman_code_groups: hufftree_groups,
362 };
363
364 Ok(info)
365 }
366
367 fn read_huffman_code(&mut self, alphabet_size: u16) -> Result<HuffmanTree, DecodingError> {
369 let simple = self.bit_reader.read_bits::<u8>(1)? == 1;
370
371 if simple {
372 let num_symbols = self.bit_reader.read_bits::<u8>(1)? + 1;
373
374 let is_first_8bits = self.bit_reader.read_bits::<u8>(1)?;
375 let zero_symbol = self.bit_reader.read_bits::<u16>(1 + 7 * is_first_8bits)?;
376
377 if zero_symbol >= alphabet_size {
378 return Err(DecodingError::BitStreamError);
379 }
380
381 if num_symbols == 1 {
382 Ok(HuffmanTree::build_single_node(zero_symbol))
383 } else {
384 let one_symbol = self.bit_reader.read_bits::<u16>(8)?;
385 if one_symbol >= alphabet_size {
386 return Err(DecodingError::BitStreamError);
387 }
388 Ok(HuffmanTree::build_two_node(zero_symbol, one_symbol))
389 }
390 } else {
391 let mut code_length_code_lengths = vec![0; CODE_LENGTH_CODES];
392
393 let num_code_lengths = 4 + self.bit_reader.read_bits::<usize>(4)?;
394 for i in 0..num_code_lengths {
395 code_length_code_lengths[CODE_LENGTH_CODE_ORDER[i]] =
396 self.bit_reader.read_bits(3)?;
397 }
398
399 let new_code_lengths =
400 self.read_huffman_code_lengths(code_length_code_lengths, alphabet_size)?;
401
402 HuffmanTree::build_implicit(new_code_lengths)
403 }
404 }
405
406 fn read_huffman_code_lengths(
408 &mut self,
409 code_length_code_lengths: Vec<u16>,
410 num_symbols: u16,
411 ) -> Result<Vec<u16>, DecodingError> {
412 let table = HuffmanTree::build_implicit(code_length_code_lengths)?;
413
414 let mut max_symbol = if self.bit_reader.read_bits::<u8>(1)? == 1 {
415 let length_nbits = 2 + 2 * self.bit_reader.read_bits::<u8>(3)?;
416 let max_minus_two = self.bit_reader.read_bits::<u16>(length_nbits)?;
417 if max_minus_two > num_symbols - 2 {
418 return Err(DecodingError::BitStreamError);
419 }
420 2 + max_minus_two
421 } else {
422 num_symbols
423 };
424
425 let mut code_lengths = vec![0; usize::from(num_symbols)];
426 let mut prev_code_len = 8; let mut symbol = 0;
429 while symbol < num_symbols {
430 if max_symbol == 0 {
431 break;
432 }
433 max_symbol -= 1;
434
435 self.bit_reader.fill()?;
436 let code_len = table.read_symbol(&mut self.bit_reader)?;
437
438 if code_len < 16 {
439 code_lengths[usize::from(symbol)] = code_len;
440 symbol += 1;
441 if code_len != 0 {
442 prev_code_len = code_len;
443 }
444 } else {
445 let use_prev = code_len == 16;
446 let slot = code_len - 16;
447 let extra_bits = match slot {
448 0 => 2,
449 1 => 3,
450 2 => 7,
451 _ => return Err(DecodingError::BitStreamError),
452 };
453 let repeat_offset = match slot {
454 0 | 1 => 3,
455 2 => 11,
456 _ => return Err(DecodingError::BitStreamError),
457 };
458
459 let mut repeat = self.bit_reader.read_bits::<u16>(extra_bits)? + repeat_offset;
460
461 if symbol + repeat > num_symbols {
462 return Err(DecodingError::BitStreamError);
463 }
464
465 let length = if use_prev { prev_code_len } else { 0 };
466 while repeat > 0 {
467 repeat -= 1;
468 code_lengths[usize::from(symbol)] = length;
469 symbol += 1;
470 }
471 }
472 }
473
474 Ok(code_lengths)
475 }
476
477 fn decode_image_data(
479 &mut self,
480 width: u16,
481 height: u16,
482 mut huffman_info: HuffmanInfo,
483 data: &mut [u8],
484 ) -> Result<(), DecodingError> {
485 let num_values = usize::from(width) * usize::from(height);
486
487 let huff_index = huffman_info.get_huff_index(0, 0);
488 let mut tree = &huffman_info.huffman_code_groups[huff_index];
489 let mut index = 0;
490
491 let mut next_block_start = 0;
492 while index < num_values {
493 self.bit_reader.fill()?;
494
495 if index >= next_block_start {
496 let x = index % usize::from(width);
497 let y = index / usize::from(width);
498 next_block_start = (x | usize::from(huffman_info.mask)).min(usize::from(width - 1))
499 + y * usize::from(width)
500 + 1;
501
502 let huff_index = huffman_info.get_huff_index(x as u16, y as u16);
503 tree = &huffman_info.huffman_code_groups[huff_index];
504
505 if tree[..4].iter().all(|t| t.is_single_node()) {
510 let code = tree[GREEN].read_symbol(&mut self.bit_reader)?;
511 if code < 256 {
512 let n = if huffman_info.bits == 0 {
513 num_values
514 } else {
515 next_block_start - index
516 };
517
518 let red = tree[RED].read_symbol(&mut self.bit_reader)?;
519 let blue = tree[BLUE].read_symbol(&mut self.bit_reader)?;
520 let alpha = tree[ALPHA].read_symbol(&mut self.bit_reader)?;
521 let value = [red as u8, code as u8, blue as u8, alpha as u8];
522
523 for i in 0..n {
524 data[index * 4 + i * 4..][..4].copy_from_slice(&value);
525 }
526
527 if let Some(color_cache) = huffman_info.color_cache.as_mut() {
528 color_cache.insert(value);
529 }
530
531 index += n;
532 continue;
533 }
534 }
535 }
536
537 let code = tree[GREEN].read_symbol(&mut self.bit_reader)?;
538
539 if code < 256 {
541 let green = code as u8;
543 let red = tree[RED].read_symbol(&mut self.bit_reader)? as u8;
544 let blue = tree[BLUE].read_symbol(&mut self.bit_reader)? as u8;
545 if self.bit_reader.nbits < 15 {
546 self.bit_reader.fill()?;
547 }
548 let alpha = tree[ALPHA].read_symbol(&mut self.bit_reader)? as u8;
549
550 data[index * 4] = red;
551 data[index * 4 + 1] = green;
552 data[index * 4 + 2] = blue;
553 data[index * 4 + 3] = alpha;
554
555 if let Some(color_cache) = huffman_info.color_cache.as_mut() {
556 color_cache.insert([red, green, blue, alpha]);
557 }
558 index += 1;
559 } else if code < 256 + 24 {
560 let length_symbol = code - 256;
562 let length = Self::get_copy_distance(&mut self.bit_reader, length_symbol)?;
563
564 let dist_symbol = tree[DIST].read_symbol(&mut self.bit_reader)?;
565 let dist_code = Self::get_copy_distance(&mut self.bit_reader, dist_symbol)?;
566 let dist = Self::plane_code_to_distance(width, dist_code);
567
568 if index < dist || num_values - index < length {
569 return Err(DecodingError::BitStreamError);
570 }
571
572 if dist == 1 {
573 let value: [u8; 4] = data[(index - dist) * 4..][..4].try_into().unwrap();
574 for i in 0..length {
575 data[index * 4 + i * 4..][..4].copy_from_slice(&value);
576 }
577 } else {
578 if index + length + 3 <= num_values {
579 let start = (index - dist) * 4;
580 data.copy_within(start..start + 16, index * 4);
581
582 if length > 4 || dist < 4 {
583 for i in (0..length * 4).step_by((dist * 4).min(16)).skip(1) {
584 data.copy_within(start + i..start + i + 16, index * 4 + i);
585 }
586 }
587 } else {
588 for i in 0..length * 4 {
589 data[index * 4 + i] = data[index * 4 + i - dist * 4];
590 }
591 }
592
593 if let Some(color_cache) = huffman_info.color_cache.as_mut() {
594 for pixel in data[index * 4..][..length * 4].chunks_exact(4) {
595 color_cache.insert(pixel.try_into().unwrap());
596 }
597 }
598 }
599 index += length;
600 } else {
601 let color_cache = huffman_info
603 .color_cache
604 .as_mut()
605 .ok_or(DecodingError::BitStreamError)?;
606 let color = color_cache.lookup((code - 280).into());
607 data[index * 4..][..4].copy_from_slice(&color);
608 index += 1;
609
610 if index < next_block_start {
611 if let Some((bits, code)) = tree[GREEN].peek_symbol(&self.bit_reader) {
612 if code >= 280 {
613 self.bit_reader.consume(bits)?;
614 data[index * 4..][..4]
615 .copy_from_slice(&color_cache.lookup((code - 280).into()));
616 index += 1;
617 }
618 }
619 }
620 }
621 }
622
623 Ok(())
624 }
625
626 fn read_color_cache(&mut self) -> Result<Option<u8>, DecodingError> {
628 if self.bit_reader.read_bits::<u8>(1)? == 1 {
629 let code_bits = self.bit_reader.read_bits::<u8>(4)?;
630
631 if !(1..=11).contains(&code_bits) {
632 return Err(DecodingError::InvalidColorCacheBits(code_bits));
633 }
634
635 Ok(Some(code_bits))
636 } else {
637 Ok(None)
638 }
639 }
640
641 fn get_copy_distance(
643 bit_reader: &mut BitReader<R>,
644 prefix_code: u16,
645 ) -> Result<usize, DecodingError> {
646 if prefix_code < 4 {
647 return Ok(usize::from(prefix_code + 1));
648 }
649 let extra_bits: u8 = ((prefix_code - 2) >> 1).try_into().unwrap();
650 let offset = (2 + (usize::from(prefix_code) & 1)) << extra_bits;
651
652 let bits = bit_reader.peek(extra_bits) as usize;
653 bit_reader.consume(extra_bits)?;
654
655 Ok(offset + bits + 1)
656 }
657
658 fn plane_code_to_distance(xsize: u16, plane_code: usize) -> usize {
660 if plane_code > 120 {
661 plane_code - 120
662 } else {
663 let (xoffset, yoffset) = DISTANCE_MAP[plane_code - 1];
664
665 let dist = i32::from(xoffset) + i32::from(yoffset) * i32::from(xsize);
666 if dist < 1 {
667 return 1;
668 }
669 dist.try_into().unwrap()
670 }
671 }
672}
673
674#[derive(Debug, Clone)]
675struct HuffmanInfo {
676 xsize: u16,
677 _ysize: u16,
678 color_cache: Option<ColorCache>,
679 image: Vec<u16>,
680 bits: u8,
681 mask: u16,
682 huffman_code_groups: Vec<HuffmanCodeGroup>,
683}
684
685impl HuffmanInfo {
686 fn get_huff_index(&self, x: u16, y: u16) -> usize {
687 if self.bits == 0 {
688 return 0;
689 }
690 let position =
691 usize::from(y >> self.bits) * usize::from(self.xsize) + usize::from(x >> self.bits);
692 let meta_huff_code: usize = usize::from(self.image[position]);
693 meta_huff_code
694 }
695}
696
697#[derive(Debug, Clone)]
698struct ColorCache {
699 color_cache_bits: u8,
700 color_cache: Vec<[u8; 4]>,
701}
702
703impl ColorCache {
704 #[inline(always)]
705 fn insert(&mut self, color: [u8; 4]) {
706 let [r, g, b, a] = color;
707 let color_u32 =
708 (u32::from(r) << 16) | (u32::from(g) << 8) | (u32::from(b)) | (u32::from(a) << 24);
709 let index = (0x1e35a7bdu32.wrapping_mul(color_u32)) >> (32 - self.color_cache_bits);
710 self.color_cache[index as usize] = color;
711 }
712
713 #[inline(always)]
714 fn lookup(&self, index: usize) -> [u8; 4] {
715 self.color_cache[index]
716 }
717}
718
719#[derive(Debug, Clone)]
720pub(crate) struct BitReader<R> {
721 reader: R,
722 buffer: u64,
723 nbits: u8,
724}
725
726impl<R: BufRead> BitReader<R> {
727 const fn new(reader: R) -> Self {
728 Self {
729 reader,
730 buffer: 0,
731 nbits: 0,
732 }
733 }
734
735 pub(crate) fn fill(&mut self) -> Result<(), DecodingError> {
740 debug_assert!(self.nbits < 64);
741
742 let mut buf = self.reader.fill_buf()?;
743 if buf.len() >= 8 {
744 let lookahead = u64::from_le_bytes(buf[..8].try_into().unwrap());
745 self.reader.consume(usize::from((63 - self.nbits) / 8));
746 self.buffer |= lookahead << self.nbits;
747 self.nbits |= 56;
748 } else {
749 while !buf.is_empty() && self.nbits < 56 {
750 self.buffer |= u64::from(buf[0]) << self.nbits;
751 self.nbits += 8;
752 self.reader.consume(1);
753 buf = self.reader.fill_buf()?;
754 }
755 }
756
757 Ok(())
758 }
759
760 pub(crate) const fn peek(&self, num: u8) -> u64 {
762 self.buffer & ((1 << num) - 1)
763 }
764
765 pub(crate) const fn peek_full(&self) -> u64 {
767 self.buffer
768 }
769
770 pub(crate) fn consume(&mut self, num: u8) -> Result<(), DecodingError> {
772 if self.nbits < num {
773 return Err(DecodingError::BitStreamError);
774 }
775
776 self.buffer >>= num;
777 self.nbits -= num;
778 Ok(())
779 }
780
781 pub(crate) fn read_bits<T: TryFrom<u32>>(&mut self, num: u8) -> Result<T, DecodingError> {
783 debug_assert!(num as usize <= 8 * mem::size_of::<T>());
784 debug_assert!(num <= 32);
785
786 if self.nbits < num {
787 self.fill()?;
788 }
789 let value = self.peek(num) as u32;
790 self.consume(num)?;
791
792 value.try_into().map_err(|_| {
793 debug_assert!(false, "Value too large to fit in type");
794 DecodingError::BitStreamError
795 })
796 }
797}
798
799