Skip to main content

atmos/os_lib/webp/
lossless.rs

1use alloc::vec;
2use alloc::vec::Vec;
3// Decoding of lossless WebP images
4//
5// [Lossless spec](https://developers.google.com/speed/webp/docs/webp_lossless_bitstream_specification)
6
7use 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//Decodes lossless WebP images
65#[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    /// Create a new decoder
76    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    /// Decodes a frame.
87    ///
88    /// In an alpha chunk the width and height are not included in the header, so they should be
89    /// provided by setting the `implicit_dimensions` argument. Otherwise that argument should be
90    /// `None` and the frame dimensions will be determined by reading the VP8L header.
91    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    /// Reads Image data from the bitstream
179    ///
180    /// Can be in any of the 5 roles described in the Specification. ARGB Image role has different
181    /// behaviour to the other 4. xsize and ysize describe the size of the blocks where each block
182    /// has its own entropy code
183    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    /// Reads transforms and their data from the bitstream
201    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                //can only have one of each transform, error
209                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                    //predictor
217
218                    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                    //color transform
234
235                    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                    //subtract green
251
252                    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    /// Adjusts the color map since it's subtraction coded
288    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    /// Reads huffman codes associated with an image
295    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            //meta huffman codes
311            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    /// Decodes and returns a single huffman tree
368    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    /// Reads huffman code lengths
407    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; //default code length
427
428        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    /// Decodes the image data using the huffman trees and either of the 3 methods of decoding
478    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                // Fast path: If all the codes each contain only a single
506                // symbol, then the pixel data isn't written to the bitstream
507                // and we can just fill the output buffer with the symbol
508                // directly.
509                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            //check code
540            if code < 256 {
541                //literal, so just use huffman codes and read as argb
542                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                //backward reference, so go back and use that to add image data
561                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                //color cache, so use previously stored pixels to get this pixel
602                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    /// Reads color cache data from the bitstream
627    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    /// Gets the copy distance from the prefix code and bitstream
642    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    /// Gets distance to pixel
659    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    /// Fills the buffer with bits from the input stream.
736    ///
737    /// After this function, the internal buffer will contain 64-bits or have reached the end of
738    /// the input stream.
739    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    /// Peeks at the next `num` bits in the buffer.
761    pub(crate) const fn peek(&self, num: u8) -> u64 {
762        self.buffer & ((1 << num) - 1)
763    }
764
765    /// Peeks at the full buffer.
766    pub(crate) const fn peek_full(&self) -> u64 {
767        self.buffer
768    }
769
770    /// Consumes `num` bits from the buffer returning an error if there are not enough bits.
771    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    /// Convenience function to read a number of bits and convert them to a type.
782    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