Coverage Report

Created: 2025-11-05 08:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/image-webp-0.2.4/src/lossless.rs
Line
Count
Source
1
//! Decoding of lossless WebP images
2
//!
3
//! [Lossless spec](https://developers.google.com/speed/webp/docs/webp_lossless_bitstream_specification)
4
5
use std::io::BufRead;
6
use std::mem;
7
8
use crate::decoder::DecodingError;
9
use crate::lossless_transform::{
10
    apply_color_indexing_transform, apply_color_transform, apply_predictor_transform,
11
    apply_subtract_green_transform,
12
};
13
14
use super::huffman::HuffmanTree;
15
use super::lossless_transform::TransformType;
16
17
const CODE_LENGTH_CODES: usize = 19;
18
const CODE_LENGTH_CODE_ORDER: [usize; CODE_LENGTH_CODES] = [
19
    17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
20
];
21
22
#[rustfmt::skip]
23
const DISTANCE_MAP: [(i8, i8); 120] = [
24
    (0, 1),  (1, 0),  (1, 1),  (-1, 1), (0, 2),  (2, 0),  (1, 2),  (-1, 2),
25
    (2, 1),  (-2, 1), (2, 2),  (-2, 2), (0, 3),  (3, 0),  (1, 3),  (-1, 3),
26
    (3, 1),  (-3, 1), (2, 3),  (-2, 3), (3, 2),  (-3, 2), (0, 4),  (4, 0),
27
    (1, 4),  (-1, 4), (4, 1),  (-4, 1), (3, 3),  (-3, 3), (2, 4),  (-2, 4),
28
    (4, 2),  (-4, 2), (0, 5),  (3, 4),  (-3, 4), (4, 3),  (-4, 3), (5, 0),
29
    (1, 5),  (-1, 5), (5, 1),  (-5, 1), (2, 5),  (-2, 5), (5, 2),  (-5, 2),
30
    (4, 4),  (-4, 4), (3, 5),  (-3, 5), (5, 3),  (-5, 3), (0, 6),  (6, 0),
31
    (1, 6),  (-1, 6), (6, 1),  (-6, 1), (2, 6),  (-2, 6), (6, 2),  (-6, 2),
32
    (4, 5),  (-4, 5), (5, 4),  (-5, 4), (3, 6),  (-3, 6), (6, 3),  (-6, 3),
33
    (0, 7),  (7, 0),  (1, 7),  (-1, 7), (5, 5),  (-5, 5), (7, 1),  (-7, 1),
34
    (4, 6),  (-4, 6), (6, 4),  (-6, 4), (2, 7),  (-2, 7), (7, 2),  (-7, 2),
35
    (3, 7),  (-3, 7), (7, 3),  (-7, 3), (5, 6),  (-5, 6), (6, 5),  (-6, 5),
36
    (8, 0),  (4, 7),  (-4, 7), (7, 4),  (-7, 4), (8, 1),  (8, 2),  (6, 6),
37
    (-6, 6), (8, 3),  (5, 7),  (-5, 7), (7, 5),  (-7, 5), (8, 4),  (6, 7),
38
    (-6, 7), (7, 6),  (-7, 6), (8, 5),  (7, 7),  (-7, 7), (8, 6),  (8, 7)
39
];
40
41
const GREEN: usize = 0;
42
const RED: usize = 1;
43
const BLUE: usize = 2;
44
const ALPHA: usize = 3;
45
const DIST: usize = 4;
46
47
const HUFFMAN_CODES_PER_META_CODE: usize = 5;
48
49
type HuffmanCodeGroup = [HuffmanTree; HUFFMAN_CODES_PER_META_CODE];
50
51
const ALPHABET_SIZE: [u16; HUFFMAN_CODES_PER_META_CODE] = [256 + 24, 256, 256, 256, 40];
52
53
#[inline]
54
7.34k
pub(crate) fn subsample_size(size: u16, bits: u8) -> u16 {
55
7.34k
    ((u32::from(size) + (1u32 << bits) - 1) >> bits)
56
7.34k
        .try_into()
57
7.34k
        .unwrap()
58
7.34k
}
image_webp::lossless::subsample_size
Line
Count
Source
54
1.86k
pub(crate) fn subsample_size(size: u16, bits: u8) -> u16 {
55
1.86k
    ((u32::from(size) + (1u32 << bits) - 1) >> bits)
56
1.86k
        .try_into()
57
1.86k
        .unwrap()
58
1.86k
}
image_webp::lossless::subsample_size
Line
Count
Source
54
1.88k
pub(crate) fn subsample_size(size: u16, bits: u8) -> u16 {
55
1.88k
    ((u32::from(size) + (1u32 << bits) - 1) >> bits)
56
1.88k
        .try_into()
57
1.88k
        .unwrap()
58
1.88k
}
Unexecuted instantiation: image_webp::lossless::subsample_size
Unexecuted instantiation: image_webp::lossless::subsample_size
image_webp::lossless::subsample_size
Line
Count
Source
54
3.59k
pub(crate) fn subsample_size(size: u16, bits: u8) -> u16 {
55
3.59k
    ((u32::from(size) + (1u32 << bits) - 1) >> bits)
56
3.59k
        .try_into()
57
3.59k
        .unwrap()
58
3.59k
}
Unexecuted instantiation: image_webp::lossless::subsample_size
Unexecuted instantiation: image_webp::lossless::subsample_size
Unexecuted instantiation: image_webp::lossless::subsample_size
Unexecuted instantiation: image_webp::lossless::subsample_size
Unexecuted instantiation: image_webp::lossless::subsample_size
Unexecuted instantiation: image_webp::lossless::subsample_size
Unexecuted instantiation: image_webp::lossless::subsample_size
59
60
const NUM_TRANSFORM_TYPES: usize = 4;
61
62
//Decodes lossless WebP images
63
#[derive(Debug)]
64
pub(crate) struct LosslessDecoder<R> {
65
    bit_reader: BitReader<R>,
66
    transforms: [Option<TransformType>; NUM_TRANSFORM_TYPES],
67
    transform_order: Vec<u8>,
68
    width: u16,
69
    height: u16,
70
}
71
72
impl<R: BufRead> LosslessDecoder<R> {
73
    /// Create a new decoder
74
2.63k
    pub(crate) const fn new(r: R) -> Self {
75
2.63k
        Self {
76
2.63k
            bit_reader: BitReader::new(r),
77
2.63k
            transforms: [None, None, None, None],
78
2.63k
            transform_order: Vec::new(),
79
2.63k
            width: 0,
80
2.63k
            height: 0,
81
2.63k
        }
82
2.63k
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Line
Count
Source
74
318
    pub(crate) const fn new(r: R) -> Self {
75
318
        Self {
76
318
            bit_reader: BitReader::new(r),
77
318
            transforms: [None, None, None, None],
78
318
            transform_order: Vec::new(),
79
318
            width: 0,
80
318
            height: 0,
81
318
        }
82
318
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Line
Count
Source
74
517
    pub(crate) const fn new(r: R) -> Self {
75
517
        Self {
76
517
            bit_reader: BitReader::new(r),
77
517
            transforms: [None, None, None, None],
78
517
            transform_order: Vec::new(),
79
517
            width: 0,
80
517
            height: 0,
81
517
        }
82
517
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::new
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Line
Count
Source
74
1.79k
    pub(crate) const fn new(r: R) -> Self {
75
1.79k
        Self {
76
1.79k
            bit_reader: BitReader::new(r),
77
1.79k
            transforms: [None, None, None, None],
78
1.79k
            transform_order: Vec::new(),
79
1.79k
            width: 0,
80
1.79k
            height: 0,
81
1.79k
        }
82
1.79k
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
83
84
    /// Decodes a frame.
85
    ///
86
    /// In an alpha chunk the width and height are not included in the header, so they should be
87
    /// provided by setting the `implicit_dimensions` argument. Otherwise that argument should be
88
    /// `None` and the frame dimensions will be determined by reading the VP8L header.
89
2.63k
    pub(crate) fn decode_frame(
90
2.63k
        &mut self,
91
2.63k
        width: u32,
92
2.63k
        height: u32,
93
2.63k
        implicit_dimensions: bool,
94
2.63k
        buf: &mut [u8],
95
2.63k
    ) -> Result<(), DecodingError> {
96
2.63k
        if implicit_dimensions {
97
517
            self.width = width as u16;
98
517
            self.height = height as u16;
99
517
        } else {
100
2.11k
            let signature = self.bit_reader.read_bits::<u8>(8)?;
101
2.11k
            if signature != 0x2f {
102
0
                return Err(DecodingError::LosslessSignatureInvalid(signature));
103
2.11k
            }
104
105
2.11k
            self.width = self.bit_reader.read_bits::<u16>(14)? + 1;
106
2.10k
            self.height = self.bit_reader.read_bits::<u16>(14)? + 1;
107
2.10k
            if u32::from(self.width) != width || u32::from(self.height) != height {
108
2
                return Err(DecodingError::InconsistentImageSizes);
109
2.10k
            }
110
111
2.10k
            let _alpha_used = self.bit_reader.read_bits::<u8>(1)?;
112
2.10k
            let version_num = self.bit_reader.read_bits::<u8>(3)?;
113
2.10k
            if version_num != 0 {
114
0
                return Err(DecodingError::VersionNumberInvalid(version_num));
115
2.10k
            }
116
        }
117
118
2.62k
        let transformed_width = self.read_transforms()?;
119
2.44k
        let transformed_size = usize::from(transformed_width) * usize::from(self.height) * 4;
120
2.44k
        self.decode_image_stream(
121
2.44k
            transformed_width,
122
2.44k
            self.height,
123
            true,
124
2.44k
            &mut buf[..transformed_size],
125
539
        )?;
126
127
1.90k
        let mut image_size = transformed_size;
128
1.90k
        let mut width = transformed_width;
129
3.71k
        for &trans_index in self.transform_order.iter().rev() {
130
3.71k
            let transform = self.transforms[usize::from(trans_index)].as_ref().unwrap();
131
3.71k
            match transform {
132
                TransformType::PredictorTransform {
133
1.87k
                    size_bits,
134
1.87k
                    predictor_data,
135
1.87k
                } => apply_predictor_transform(
136
1.87k
                    &mut buf[..image_size],
137
1.87k
                    width,
138
1.87k
                    self.height,
139
1.87k
                    *size_bits,
140
1.87k
                    predictor_data,
141
0
                )?,
142
                TransformType::ColorTransform {
143
7
                    size_bits,
144
7
                    transform_data,
145
7
                } => {
146
7
                    apply_color_transform(
147
7
                        &mut buf[..image_size],
148
7
                        width,
149
7
                        *size_bits,
150
7
                        transform_data,
151
7
                    );
152
7
                }
153
1.81k
                TransformType::SubtractGreen => {
154
1.81k
                    apply_subtract_green_transform(&mut buf[..image_size]);
155
1.81k
                }
156
                TransformType::ColorIndexingTransform {
157
16
                    table_size,
158
16
                    table_data,
159
16
                } => {
160
16
                    width = self.width;
161
16
                    image_size = usize::from(width) * usize::from(self.height) * 4;
162
16
                    apply_color_indexing_transform(
163
16
                        buf,
164
16
                        width,
165
16
                        self.height,
166
16
                        *table_size,
167
16
                        table_data,
168
16
                    );
169
16
                }
170
            }
171
        }
172
173
1.90k
        Ok(())
174
2.63k
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
Line
Count
Source
89
318
    pub(crate) fn decode_frame(
90
318
        &mut self,
91
318
        width: u32,
92
318
        height: u32,
93
318
        implicit_dimensions: bool,
94
318
        buf: &mut [u8],
95
318
    ) -> Result<(), DecodingError> {
96
318
        if implicit_dimensions {
97
0
            self.width = width as u16;
98
0
            self.height = height as u16;
99
0
        } else {
100
318
            let signature = self.bit_reader.read_bits::<u8>(8)?;
101
318
            if signature != 0x2f {
102
0
                return Err(DecodingError::LosslessSignatureInvalid(signature));
103
318
            }
104
105
318
            self.width = self.bit_reader.read_bits::<u16>(14)? + 1;
106
312
            self.height = self.bit_reader.read_bits::<u16>(14)? + 1;
107
312
            if u32::from(self.width) != width || u32::from(self.height) != height {
108
2
                return Err(DecodingError::InconsistentImageSizes);
109
310
            }
110
111
310
            let _alpha_used = self.bit_reader.read_bits::<u8>(1)?;
112
310
            let version_num = self.bit_reader.read_bits::<u8>(3)?;
113
310
            if version_num != 0 {
114
0
                return Err(DecodingError::VersionNumberInvalid(version_num));
115
310
            }
116
        }
117
118
310
        let transformed_width = self.read_transforms()?;
119
299
        let transformed_size = usize::from(transformed_width) * usize::from(self.height) * 4;
120
299
        self.decode_image_stream(
121
299
            transformed_width,
122
299
            self.height,
123
            true,
124
299
            &mut buf[..transformed_size],
125
279
        )?;
126
127
20
        let mut image_size = transformed_size;
128
20
        let mut width = transformed_width;
129
29
        for &trans_index in self.transform_order.iter().rev() {
130
29
            let transform = self.transforms[usize::from(trans_index)].as_ref().unwrap();
131
29
            match transform {
132
                TransformType::PredictorTransform {
133
13
                    size_bits,
134
13
                    predictor_data,
135
13
                } => apply_predictor_transform(
136
13
                    &mut buf[..image_size],
137
13
                    width,
138
13
                    self.height,
139
13
                    *size_bits,
140
13
                    predictor_data,
141
0
                )?,
142
                TransformType::ColorTransform {
143
2
                    size_bits,
144
2
                    transform_data,
145
2
                } => {
146
2
                    apply_color_transform(
147
2
                        &mut buf[..image_size],
148
2
                        width,
149
2
                        *size_bits,
150
2
                        transform_data,
151
2
                    );
152
2
                }
153
11
                TransformType::SubtractGreen => {
154
11
                    apply_subtract_green_transform(&mut buf[..image_size]);
155
11
                }
156
                TransformType::ColorIndexingTransform {
157
3
                    table_size,
158
3
                    table_data,
159
3
                } => {
160
3
                    width = self.width;
161
3
                    image_size = usize::from(width) * usize::from(self.height) * 4;
162
3
                    apply_color_indexing_transform(
163
3
                        buf,
164
3
                        width,
165
3
                        self.height,
166
3
                        *table_size,
167
3
                        table_data,
168
3
                    );
169
3
                }
170
            }
171
        }
172
173
20
        Ok(())
174
318
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
Line
Count
Source
89
517
    pub(crate) fn decode_frame(
90
517
        &mut self,
91
517
        width: u32,
92
517
        height: u32,
93
517
        implicit_dimensions: bool,
94
517
        buf: &mut [u8],
95
517
    ) -> Result<(), DecodingError> {
96
517
        if implicit_dimensions {
97
517
            self.width = width as u16;
98
517
            self.height = height as u16;
99
517
        } else {
100
0
            let signature = self.bit_reader.read_bits::<u8>(8)?;
101
0
            if signature != 0x2f {
102
0
                return Err(DecodingError::LosslessSignatureInvalid(signature));
103
0
            }
104
105
0
            self.width = self.bit_reader.read_bits::<u16>(14)? + 1;
106
0
            self.height = self.bit_reader.read_bits::<u16>(14)? + 1;
107
0
            if u32::from(self.width) != width || u32::from(self.height) != height {
108
0
                return Err(DecodingError::InconsistentImageSizes);
109
0
            }
110
111
0
            let _alpha_used = self.bit_reader.read_bits::<u8>(1)?;
112
0
            let version_num = self.bit_reader.read_bits::<u8>(3)?;
113
0
            if version_num != 0 {
114
0
                return Err(DecodingError::VersionNumberInvalid(version_num));
115
0
            }
116
        }
117
118
517
        let transformed_width = self.read_transforms()?;
119
345
        let transformed_size = usize::from(transformed_width) * usize::from(self.height) * 4;
120
345
        self.decode_image_stream(
121
345
            transformed_width,
122
345
            self.height,
123
            true,
124
345
            &mut buf[..transformed_size],
125
260
        )?;
126
127
85
        let mut image_size = transformed_size;
128
85
        let mut width = transformed_width;
129
90
        for &trans_index in self.transform_order.iter().rev() {
130
90
            let transform = self.transforms[usize::from(trans_index)].as_ref().unwrap();
131
90
            match transform {
132
                TransformType::PredictorTransform {
133
65
                    size_bits,
134
65
                    predictor_data,
135
65
                } => apply_predictor_transform(
136
65
                    &mut buf[..image_size],
137
65
                    width,
138
65
                    self.height,
139
65
                    *size_bits,
140
65
                    predictor_data,
141
0
                )?,
142
                TransformType::ColorTransform {
143
5
                    size_bits,
144
5
                    transform_data,
145
5
                } => {
146
5
                    apply_color_transform(
147
5
                        &mut buf[..image_size],
148
5
                        width,
149
5
                        *size_bits,
150
5
                        transform_data,
151
5
                    );
152
5
                }
153
7
                TransformType::SubtractGreen => {
154
7
                    apply_subtract_green_transform(&mut buf[..image_size]);
155
7
                }
156
                TransformType::ColorIndexingTransform {
157
13
                    table_size,
158
13
                    table_data,
159
13
                } => {
160
13
                    width = self.width;
161
13
                    image_size = usize::from(width) * usize::from(self.height) * 4;
162
13
                    apply_color_indexing_transform(
163
13
                        buf,
164
13
                        width,
165
13
                        self.height,
166
13
                        *table_size,
167
13
                        table_data,
168
13
                    );
169
13
                }
170
            }
171
        }
172
173
85
        Ok(())
174
517
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::decode_frame
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
Line
Count
Source
89
1.79k
    pub(crate) fn decode_frame(
90
1.79k
        &mut self,
91
1.79k
        width: u32,
92
1.79k
        height: u32,
93
1.79k
        implicit_dimensions: bool,
94
1.79k
        buf: &mut [u8],
95
1.79k
    ) -> Result<(), DecodingError> {
96
1.79k
        if implicit_dimensions {
97
0
            self.width = width as u16;
98
0
            self.height = height as u16;
99
0
        } else {
100
1.79k
            let signature = self.bit_reader.read_bits::<u8>(8)?;
101
1.79k
            if signature != 0x2f {
102
0
                return Err(DecodingError::LosslessSignatureInvalid(signature));
103
1.79k
            }
104
105
1.79k
            self.width = self.bit_reader.read_bits::<u16>(14)? + 1;
106
1.79k
            self.height = self.bit_reader.read_bits::<u16>(14)? + 1;
107
1.79k
            if u32::from(self.width) != width || u32::from(self.height) != height {
108
0
                return Err(DecodingError::InconsistentImageSizes);
109
1.79k
            }
110
111
1.79k
            let _alpha_used = self.bit_reader.read_bits::<u8>(1)?;
112
1.79k
            let version_num = self.bit_reader.read_bits::<u8>(3)?;
113
1.79k
            if version_num != 0 {
114
0
                return Err(DecodingError::VersionNumberInvalid(version_num));
115
1.79k
            }
116
        }
117
118
1.79k
        let transformed_width = self.read_transforms()?;
119
1.79k
        let transformed_size = usize::from(transformed_width) * usize::from(self.height) * 4;
120
1.79k
        self.decode_image_stream(
121
1.79k
            transformed_width,
122
1.79k
            self.height,
123
            true,
124
1.79k
            &mut buf[..transformed_size],
125
0
        )?;
126
127
1.79k
        let mut image_size = transformed_size;
128
1.79k
        let mut width = transformed_width;
129
3.59k
        for &trans_index in self.transform_order.iter().rev() {
130
3.59k
            let transform = self.transforms[usize::from(trans_index)].as_ref().unwrap();
131
3.59k
            match transform {
132
                TransformType::PredictorTransform {
133
1.79k
                    size_bits,
134
1.79k
                    predictor_data,
135
1.79k
                } => apply_predictor_transform(
136
1.79k
                    &mut buf[..image_size],
137
1.79k
                    width,
138
1.79k
                    self.height,
139
1.79k
                    *size_bits,
140
1.79k
                    predictor_data,
141
0
                )?,
142
                TransformType::ColorTransform {
143
0
                    size_bits,
144
0
                    transform_data,
145
0
                } => {
146
0
                    apply_color_transform(
147
0
                        &mut buf[..image_size],
148
0
                        width,
149
0
                        *size_bits,
150
0
                        transform_data,
151
0
                    );
152
0
                }
153
1.79k
                TransformType::SubtractGreen => {
154
1.79k
                    apply_subtract_green_transform(&mut buf[..image_size]);
155
1.79k
                }
156
                TransformType::ColorIndexingTransform {
157
0
                    table_size,
158
0
                    table_data,
159
0
                } => {
160
0
                    width = self.width;
161
0
                    image_size = usize::from(width) * usize::from(self.height) * 4;
162
0
                    apply_color_indexing_transform(
163
0
                        buf,
164
0
                        width,
165
0
                        self.height,
166
0
                        *table_size,
167
0
                        table_data,
168
0
                    );
169
0
                }
170
            }
171
        }
172
173
1.79k
        Ok(())
174
1.79k
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
175
176
    /// Reads Image data from the bitstream
177
    ///
178
    /// Can be in any of the 5 roles described in the Specification. ARGB Image role has different
179
    /// behaviour to the other 4. xsize and ysize describe the size of the blocks where each block
180
    /// has its own entropy code
181
5.28k
    fn decode_image_stream(
182
5.28k
        &mut self,
183
5.28k
        xsize: u16,
184
5.28k
        ysize: u16,
185
5.28k
        is_argb_img: bool,
186
5.28k
        data: &mut [u8],
187
5.28k
    ) -> Result<(), DecodingError> {
188
5.28k
        let color_cache_bits = self.read_color_cache()?;
189
5.27k
        let color_cache = color_cache_bits.map(|bits| ColorCache {
190
634
            color_cache_bits: bits,
191
634
            color_cache: vec![[0; 4]; 1 << bits],
192
634
        });
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
Line
Count
Source
190
295
            color_cache_bits: bits,
191
295
            color_cache: vec![[0; 4]; 1 << bits],
192
295
        });
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
Line
Count
Source
190
339
            color_cache_bits: bits,
191
339
            color_cache: vec![[0; 4]; 1 << bits],
192
339
        });
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::decode_image_stream::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
193
194
5.27k
        let huffman_info = self.read_huffman_codes(is_argb_img, xsize, ysize, color_cache)?;
195
4.89k
        self.decode_image_data(xsize, ysize, huffman_info, data)
196
5.28k
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
Line
Count
Source
181
621
    fn decode_image_stream(
182
621
        &mut self,
183
621
        xsize: u16,
184
621
        ysize: u16,
185
621
        is_argb_img: bool,
186
621
        data: &mut [u8],
187
621
    ) -> Result<(), DecodingError> {
188
621
        let color_cache_bits = self.read_color_cache()?;
189
621
        let color_cache = color_cache_bits.map(|bits| ColorCache {
190
            color_cache_bits: bits,
191
            color_cache: vec![[0; 4]; 1 << bits],
192
        });
193
194
621
        let huffman_info = self.read_huffman_codes(is_argb_img, xsize, ysize, color_cache)?;
195
473
        self.decode_image_data(xsize, ysize, huffman_info, data)
196
621
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
Line
Count
Source
181
1.06k
    fn decode_image_stream(
182
1.06k
        &mut self,
183
1.06k
        xsize: u16,
184
1.06k
        ysize: u16,
185
1.06k
        is_argb_img: bool,
186
1.06k
        data: &mut [u8],
187
1.06k
    ) -> Result<(), DecodingError> {
188
1.06k
        let color_cache_bits = self.read_color_cache()?;
189
1.05k
        let color_cache = color_cache_bits.map(|bits| ColorCache {
190
            color_cache_bits: bits,
191
            color_cache: vec![[0; 4]; 1 << bits],
192
        });
193
194
1.05k
        let huffman_info = self.read_huffman_codes(is_argb_img, xsize, ysize, color_cache)?;
195
830
        self.decode_image_data(xsize, ysize, huffman_info, data)
196
1.06k
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::decode_image_stream
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
Line
Count
Source
181
3.59k
    fn decode_image_stream(
182
3.59k
        &mut self,
183
3.59k
        xsize: u16,
184
3.59k
        ysize: u16,
185
3.59k
        is_argb_img: bool,
186
3.59k
        data: &mut [u8],
187
3.59k
    ) -> Result<(), DecodingError> {
188
3.59k
        let color_cache_bits = self.read_color_cache()?;
189
3.59k
        let color_cache = color_cache_bits.map(|bits| ColorCache {
190
            color_cache_bits: bits,
191
            color_cache: vec![[0; 4]; 1 << bits],
192
        });
193
194
3.59k
        let huffman_info = self.read_huffman_codes(is_argb_img, xsize, ysize, color_cache)?;
195
3.59k
        self.decode_image_data(xsize, ysize, huffman_info, data)
196
3.59k
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
197
198
    /// Reads transforms and their data from the bitstream
199
2.62k
    fn read_transforms(&mut self) -> Result<u16, DecodingError> {
200
2.62k
        let mut xsize = self.width;
201
202
6.94k
        while self.bit_reader.read_bits::<u8>(1)? == 1 {
203
4.49k
            let transform_type_val = self.bit_reader.read_bits::<u8>(2)?;
204
205
4.49k
            if self.transforms[usize::from(transform_type_val)].is_some() {
206
                //can only have one of each transform, error
207
3
                return Err(DecodingError::TransformError);
208
4.49k
            }
209
210
4.49k
            self.transform_order.push(transform_type_val);
211
212
4.49k
            let transform_type = match transform_type_val {
213
                0 => {
214
                    //predictor
215
216
2.25k
                    let size_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
217
218
2.25k
                    let block_xsize = subsample_size(xsize, size_bits);
219
2.25k
                    let block_ysize = subsample_size(self.height, size_bits);
220
221
2.25k
                    let mut predictor_data =
222
2.25k
                        vec![0; usize::from(block_xsize) * usize::from(block_ysize) * 4];
223
2.25k
                    self.decode_image_stream(block_xsize, block_ysize, false, &mut predictor_data)?;
224
225
2.13k
                    TransformType::PredictorTransform {
226
2.13k
                        size_bits,
227
2.13k
                        predictor_data,
228
2.13k
                    }
229
                }
230
                1 => {
231
                    //color transform
232
233
64
                    let size_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
234
235
63
                    let block_xsize = subsample_size(xsize, size_bits);
236
63
                    let block_ysize = subsample_size(self.height, size_bits);
237
238
63
                    let mut transform_data =
239
63
                        vec![0; usize::from(block_xsize) * usize::from(block_ysize) * 4];
240
63
                    self.decode_image_stream(block_xsize, block_ysize, false, &mut transform_data)?;
241
242
33
                    TransformType::ColorTransform {
243
33
                        size_bits,
244
33
                        transform_data,
245
33
                    }
246
                }
247
                2 => {
248
                    //subtract green
249
250
1.98k
                    TransformType::SubtractGreen
251
                }
252
                3 => {
253
197
                    let color_table_size = self.bit_reader.read_bits::<u16>(8)? + 1;
254
255
196
                    let mut color_map = vec![0; usize::from(color_table_size) * 4];
256
196
                    self.decode_image_stream(color_table_size, 1, false, &mut color_map)?;
257
258
166
                    let bits = if color_table_size <= 2 {
259
75
                        3
260
91
                    } else if color_table_size <= 4 {
261
14
                        2
262
77
                    } else if color_table_size <= 16 {
263
3
                        1
264
                    } else {
265
74
                        0
266
                    };
267
166
                    xsize = subsample_size(xsize, bits);
268
269
166
                    Self::adjust_color_map(&mut color_map);
270
271
166
                    TransformType::ColorIndexingTransform {
272
166
                        table_size: color_table_size,
273
166
                        table_data: color_map,
274
166
                    }
275
                }
276
0
                _ => unreachable!(),
277
            };
278
279
4.31k
            self.transforms[usize::from(transform_type_val)] = Some(transform_type);
280
        }
281
282
2.44k
        Ok(xsize)
283
2.62k
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
Line
Count
Source
199
310
    fn read_transforms(&mut self) -> Result<u16, DecodingError> {
200
310
        let mut xsize = self.width;
201
202
530
        while self.bit_reader.read_bits::<u8>(1)? == 1 {
203
231
            let transform_type_val = self.bit_reader.read_bits::<u8>(2)?;
204
205
231
            if self.transforms[usize::from(transform_type_val)].is_some() {
206
                //can only have one of each transform, error
207
1
                return Err(DecodingError::TransformError);
208
230
            }
209
210
230
            self.transform_order.push(transform_type_val);
211
212
230
            let transform_type = match transform_type_val {
213
                0 => {
214
                    //predictor
215
216
104
                    let size_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
217
218
104
                    let block_xsize = subsample_size(xsize, size_bits);
219
104
                    let block_ysize = subsample_size(self.height, size_bits);
220
221
104
                    let mut predictor_data =
222
104
                        vec![0; usize::from(block_xsize) * usize::from(block_ysize) * 4];
223
104
                    self.decode_image_stream(block_xsize, block_ysize, false, &mut predictor_data)?;
224
225
100
                    TransformType::PredictorTransform {
226
100
                        size_bits,
227
100
                        predictor_data,
228
100
                    }
229
                }
230
                1 => {
231
                    //color transform
232
233
25
                    let size_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
234
235
25
                    let block_xsize = subsample_size(xsize, size_bits);
236
25
                    let block_ysize = subsample_size(self.height, size_bits);
237
238
25
                    let mut transform_data =
239
25
                        vec![0; usize::from(block_xsize) * usize::from(block_ysize) * 4];
240
25
                    self.decode_image_stream(block_xsize, block_ysize, false, &mut transform_data)?;
241
242
23
                    TransformType::ColorTransform {
243
23
                        size_bits,
244
23
                        transform_data,
245
23
                    }
246
                }
247
                2 => {
248
                    //subtract green
249
250
60
                    TransformType::SubtractGreen
251
                }
252
                3 => {
253
41
                    let color_table_size = self.bit_reader.read_bits::<u16>(8)? + 1;
254
255
40
                    let mut color_map = vec![0; usize::from(color_table_size) * 4];
256
40
                    self.decode_image_stream(color_table_size, 1, false, &mut color_map)?;
257
258
37
                    let bits = if color_table_size <= 2 {
259
2
                        3
260
35
                    } else if color_table_size <= 4 {
261
0
                        2
262
35
                    } else if color_table_size <= 16 {
263
1
                        1
264
                    } else {
265
34
                        0
266
                    };
267
37
                    xsize = subsample_size(xsize, bits);
268
269
37
                    Self::adjust_color_map(&mut color_map);
270
271
37
                    TransformType::ColorIndexingTransform {
272
37
                        table_size: color_table_size,
273
37
                        table_data: color_map,
274
37
                    }
275
                }
276
0
                _ => unreachable!(),
277
            };
278
279
220
            self.transforms[usize::from(transform_type_val)] = Some(transform_type);
280
        }
281
282
299
        Ok(xsize)
283
310
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
Line
Count
Source
199
517
    fn read_transforms(&mut self) -> Result<u16, DecodingError> {
200
517
        let mut xsize = self.width;
201
202
1.01k
        while self.bit_reader.read_bits::<u8>(1)? == 1 {
203
674
            let transform_type_val = self.bit_reader.read_bits::<u8>(2)?;
204
205
674
            if self.transforms[usize::from(transform_type_val)].is_some() {
206
                //can only have one of each transform, error
207
2
                return Err(DecodingError::TransformError);
208
672
            }
209
210
672
            self.transform_order.push(transform_type_val);
211
212
672
            let transform_type = match transform_type_val {
213
                0 => {
214
                    //predictor
215
216
352
                    let size_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
217
218
351
                    let block_xsize = subsample_size(xsize, size_bits);
219
351
                    let block_ysize = subsample_size(self.height, size_bits);
220
221
351
                    let mut predictor_data =
222
351
                        vec![0; usize::from(block_xsize) * usize::from(block_ysize) * 4];
223
351
                    self.decode_image_stream(block_xsize, block_ysize, false, &mut predictor_data)?;
224
225
238
                    TransformType::PredictorTransform {
226
238
                        size_bits,
227
238
                        predictor_data,
228
238
                    }
229
                }
230
                1 => {
231
                    //color transform
232
233
39
                    let size_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
234
235
38
                    let block_xsize = subsample_size(xsize, size_bits);
236
38
                    let block_ysize = subsample_size(self.height, size_bits);
237
238
38
                    let mut transform_data =
239
38
                        vec![0; usize::from(block_xsize) * usize::from(block_ysize) * 4];
240
38
                    self.decode_image_stream(block_xsize, block_ysize, false, &mut transform_data)?;
241
242
10
                    TransformType::ColorTransform {
243
10
                        size_bits,
244
10
                        transform_data,
245
10
                    }
246
                }
247
                2 => {
248
                    //subtract green
249
250
125
                    TransformType::SubtractGreen
251
                }
252
                3 => {
253
156
                    let color_table_size = self.bit_reader.read_bits::<u16>(8)? + 1;
254
255
156
                    let mut color_map = vec![0; usize::from(color_table_size) * 4];
256
156
                    self.decode_image_stream(color_table_size, 1, false, &mut color_map)?;
257
258
129
                    let bits = if color_table_size <= 2 {
259
73
                        3
260
56
                    } else if color_table_size <= 4 {
261
14
                        2
262
42
                    } else if color_table_size <= 16 {
263
2
                        1
264
                    } else {
265
40
                        0
266
                    };
267
129
                    xsize = subsample_size(xsize, bits);
268
269
129
                    Self::adjust_color_map(&mut color_map);
270
271
129
                    TransformType::ColorIndexingTransform {
272
129
                        table_size: color_table_size,
273
129
                        table_data: color_map,
274
129
                    }
275
                }
276
0
                _ => unreachable!(),
277
            };
278
279
502
            self.transforms[usize::from(transform_type_val)] = Some(transform_type);
280
        }
281
282
345
        Ok(xsize)
283
517
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::read_transforms
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
Line
Count
Source
199
1.79k
    fn read_transforms(&mut self) -> Result<u16, DecodingError> {
200
1.79k
        let mut xsize = self.width;
201
202
5.39k
        while self.bit_reader.read_bits::<u8>(1)? == 1 {
203
3.59k
            let transform_type_val = self.bit_reader.read_bits::<u8>(2)?;
204
205
3.59k
            if self.transforms[usize::from(transform_type_val)].is_some() {
206
                //can only have one of each transform, error
207
0
                return Err(DecodingError::TransformError);
208
3.59k
            }
209
210
3.59k
            self.transform_order.push(transform_type_val);
211
212
3.59k
            let transform_type = match transform_type_val {
213
                0 => {
214
                    //predictor
215
216
1.79k
                    let size_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
217
218
1.79k
                    let block_xsize = subsample_size(xsize, size_bits);
219
1.79k
                    let block_ysize = subsample_size(self.height, size_bits);
220
221
1.79k
                    let mut predictor_data =
222
1.79k
                        vec![0; usize::from(block_xsize) * usize::from(block_ysize) * 4];
223
1.79k
                    self.decode_image_stream(block_xsize, block_ysize, false, &mut predictor_data)?;
224
225
1.79k
                    TransformType::PredictorTransform {
226
1.79k
                        size_bits,
227
1.79k
                        predictor_data,
228
1.79k
                    }
229
                }
230
                1 => {
231
                    //color transform
232
233
0
                    let size_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
234
235
0
                    let block_xsize = subsample_size(xsize, size_bits);
236
0
                    let block_ysize = subsample_size(self.height, size_bits);
237
238
0
                    let mut transform_data =
239
0
                        vec![0; usize::from(block_xsize) * usize::from(block_ysize) * 4];
240
0
                    self.decode_image_stream(block_xsize, block_ysize, false, &mut transform_data)?;
241
242
0
                    TransformType::ColorTransform {
243
0
                        size_bits,
244
0
                        transform_data,
245
0
                    }
246
                }
247
                2 => {
248
                    //subtract green
249
250
1.79k
                    TransformType::SubtractGreen
251
                }
252
                3 => {
253
0
                    let color_table_size = self.bit_reader.read_bits::<u16>(8)? + 1;
254
255
0
                    let mut color_map = vec![0; usize::from(color_table_size) * 4];
256
0
                    self.decode_image_stream(color_table_size, 1, false, &mut color_map)?;
257
258
0
                    let bits = if color_table_size <= 2 {
259
0
                        3
260
0
                    } else if color_table_size <= 4 {
261
0
                        2
262
0
                    } else if color_table_size <= 16 {
263
0
                        1
264
                    } else {
265
0
                        0
266
                    };
267
0
                    xsize = subsample_size(xsize, bits);
268
269
0
                    Self::adjust_color_map(&mut color_map);
270
271
0
                    TransformType::ColorIndexingTransform {
272
0
                        table_size: color_table_size,
273
0
                        table_data: color_map,
274
0
                    }
275
                }
276
0
                _ => unreachable!(),
277
            };
278
279
3.59k
            self.transforms[usize::from(transform_type_val)] = Some(transform_type);
280
        }
281
282
1.79k
        Ok(xsize)
283
1.79k
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
284
285
    /// Adjusts the color map since it's subtraction coded
286
166
    fn adjust_color_map(color_map: &mut [u8]) {
287
57.2k
        for i in 4..color_map.len() {
288
57.2k
            color_map[i] = color_map[i].wrapping_add(color_map[i - 4]);
289
57.2k
        }
290
166
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
Line
Count
Source
286
37
    fn adjust_color_map(color_map: &mut [u8]) {
287
23.6k
        for i in 4..color_map.len() {
288
23.6k
            color_map[i] = color_map[i].wrapping_add(color_map[i - 4]);
289
23.6k
        }
290
37
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
Line
Count
Source
286
129
    fn adjust_color_map(color_map: &mut [u8]) {
287
33.6k
        for i in 4..color_map.len() {
288
33.6k
            color_map[i] = color_map[i].wrapping_add(color_map[i - 4]);
289
33.6k
        }
290
129
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::adjust_color_map
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
291
292
    /// Reads huffman codes associated with an image
293
5.27k
    fn read_huffman_codes(
294
5.27k
        &mut self,
295
5.27k
        read_meta: bool,
296
5.27k
        xsize: u16,
297
5.27k
        ysize: u16,
298
5.27k
        color_cache: Option<ColorCache>,
299
5.27k
    ) -> Result<HuffmanInfo, DecodingError> {
300
5.27k
        let mut num_huff_groups = 1u32;
301
302
5.27k
        let mut huffman_bits = 0;
303
5.27k
        let mut huffman_xsize = 1;
304
5.27k
        let mut huffman_ysize = 1;
305
5.27k
        let mut entropy_image = Vec::new();
306
307
5.27k
        if read_meta && self.bit_reader.read_bits::<u8>(1)? == 1 {
308
            //meta huffman codes
309
332
            huffman_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
310
332
            huffman_xsize = subsample_size(xsize, huffman_bits);
311
332
            huffman_ysize = subsample_size(ysize, huffman_bits);
312
313
332
            let mut data = vec![0; usize::from(huffman_xsize) * usize::from(huffman_ysize) * 4];
314
332
            self.decode_image_stream(huffman_xsize, huffman_ysize, false, &mut data)?;
315
316
317
            entropy_image = data
317
317
                .chunks_exact(4)
318
1.69M
                .map(|pixel| {
319
1.69M
                    let meta_huff_code = (u16::from(pixel[0]) << 8) | u16::from(pixel[1]);
320
1.69M
                    if u32::from(meta_huff_code) >= num_huff_groups {
321
406
                        num_huff_groups = u32::from(meta_huff_code) + 1;
322
1.69M
                    }
323
1.69M
                    meta_huff_code
324
1.69M
                })
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
Line
Count
Source
318
1.64M
                .map(|pixel| {
319
1.64M
                    let meta_huff_code = (u16::from(pixel[0]) << 8) | u16::from(pixel[1]);
320
1.64M
                    if u32::from(meta_huff_code) >= num_huff_groups {
321
237
                        num_huff_groups = u32::from(meta_huff_code) + 1;
322
1.64M
                    }
323
1.64M
                    meta_huff_code
324
1.64M
                })
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
Line
Count
Source
318
44.0k
                .map(|pixel| {
319
44.0k
                    let meta_huff_code = (u16::from(pixel[0]) << 8) | u16::from(pixel[1]);
320
44.0k
                    if u32::from(meta_huff_code) >= num_huff_groups {
321
169
                        num_huff_groups = u32::from(meta_huff_code) + 1;
322
43.8k
                    }
323
44.0k
                    meta_huff_code
324
44.0k
                })
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::read_huffman_codes::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
325
317
                .collect::<Vec<u16>>();
326
4.93k
        }
327
328
5.25k
        let mut hufftree_groups = Vec::new();
329
330
21.3k
        for _i in 0..num_huff_groups {
331
21.3k
            let mut group: HuffmanCodeGroup = Default::default();
332
126k
            for j in 0..HUFFMAN_CODES_PER_META_CODE {
333
105k
                let mut alphabet_size = ALPHABET_SIZE[j];
334
105k
                if j == 0 {
335
21.3k
                    if let Some(color_cache) = color_cache.as_ref() {
336
12.1k
                        alphabet_size += 1 << color_cache.color_cache_bits;
337
12.1k
                    }
338
84.5k
                }
339
340
105k
                let tree = self.read_huffman_code(alphabet_size)?;
341
105k
                group[j] = tree;
342
            }
343
20.9k
            hufftree_groups.push(group);
344
        }
345
346
4.89k
        let huffman_mask = if huffman_bits == 0 {
347
4.76k
            !0
348
        } else {
349
129
            (1 << huffman_bits) - 1
350
        };
351
352
4.89k
        let info = HuffmanInfo {
353
4.89k
            xsize: huffman_xsize,
354
4.89k
            _ysize: huffman_ysize,
355
4.89k
            color_cache,
356
4.89k
            image: entropy_image,
357
4.89k
            bits: huffman_bits,
358
4.89k
            mask: huffman_mask,
359
4.89k
            huffman_code_groups: hufftree_groups,
360
4.89k
        };
361
362
4.89k
        Ok(info)
363
5.27k
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
Line
Count
Source
293
621
    fn read_huffman_codes(
294
621
        &mut self,
295
621
        read_meta: bool,
296
621
        xsize: u16,
297
621
        ysize: u16,
298
621
        color_cache: Option<ColorCache>,
299
621
    ) -> Result<HuffmanInfo, DecodingError> {
300
621
        let mut num_huff_groups = 1u32;
301
302
621
        let mut huffman_bits = 0;
303
621
        let mut huffman_xsize = 1;
304
621
        let mut huffman_ysize = 1;
305
621
        let mut entropy_image = Vec::new();
306
307
621
        if read_meta && self.bit_reader.read_bits::<u8>(1)? == 1 {
308
            //meta huffman codes
309
153
            huffman_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
310
153
            huffman_xsize = subsample_size(xsize, huffman_bits);
311
153
            huffman_ysize = subsample_size(ysize, huffman_bits);
312
313
153
            let mut data = vec![0; usize::from(huffman_xsize) * usize::from(huffman_ysize) * 4];
314
153
            self.decode_image_stream(huffman_xsize, huffman_ysize, false, &mut data)?;
315
316
147
            entropy_image = data
317
147
                .chunks_exact(4)
318
147
                .map(|pixel| {
319
                    let meta_huff_code = (u16::from(pixel[0]) << 8) | u16::from(pixel[1]);
320
                    if u32::from(meta_huff_code) >= num_huff_groups {
321
                        num_huff_groups = u32::from(meta_huff_code) + 1;
322
                    }
323
                    meta_huff_code
324
                })
325
147
                .collect::<Vec<u16>>();
326
468
        }
327
328
615
        let mut hufftree_groups = Vec::new();
329
330
13.3k
        for _i in 0..num_huff_groups {
331
13.3k
            let mut group: HuffmanCodeGroup = Default::default();
332
79.8k
            for j in 0..HUFFMAN_CODES_PER_META_CODE {
333
66.6k
                let mut alphabet_size = ALPHABET_SIZE[j];
334
66.6k
                if j == 0 {
335
13.3k
                    if let Some(color_cache) = color_cache.as_ref() {
336
11.4k
                        alphabet_size += 1 << color_cache.color_cache_bits;
337
11.4k
                    }
338
53.2k
                }
339
340
66.6k
                let tree = self.read_huffman_code(alphabet_size)?;
341
66.4k
                group[j] = tree;
342
            }
343
13.2k
            hufftree_groups.push(group);
344
        }
345
346
473
        let huffman_mask = if huffman_bits == 0 {
347
444
            !0
348
        } else {
349
29
            (1 << huffman_bits) - 1
350
        };
351
352
473
        let info = HuffmanInfo {
353
473
            xsize: huffman_xsize,
354
473
            _ysize: huffman_ysize,
355
473
            color_cache,
356
473
            image: entropy_image,
357
473
            bits: huffman_bits,
358
473
            mask: huffman_mask,
359
473
            huffman_code_groups: hufftree_groups,
360
473
        };
361
362
473
        Ok(info)
363
621
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
Line
Count
Source
293
1.05k
    fn read_huffman_codes(
294
1.05k
        &mut self,
295
1.05k
        read_meta: bool,
296
1.05k
        xsize: u16,
297
1.05k
        ysize: u16,
298
1.05k
        color_cache: Option<ColorCache>,
299
1.05k
    ) -> Result<HuffmanInfo, DecodingError> {
300
1.05k
        let mut num_huff_groups = 1u32;
301
302
1.05k
        let mut huffman_bits = 0;
303
1.05k
        let mut huffman_xsize = 1;
304
1.05k
        let mut huffman_ysize = 1;
305
1.05k
        let mut entropy_image = Vec::new();
306
307
1.05k
        if read_meta && self.bit_reader.read_bits::<u8>(1)? == 1 {
308
            //meta huffman codes
309
179
            huffman_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
310
179
            huffman_xsize = subsample_size(xsize, huffman_bits);
311
179
            huffman_ysize = subsample_size(ysize, huffman_bits);
312
313
179
            let mut data = vec![0; usize::from(huffman_xsize) * usize::from(huffman_ysize) * 4];
314
179
            self.decode_image_stream(huffman_xsize, huffman_ysize, false, &mut data)?;
315
316
170
            entropy_image = data
317
170
                .chunks_exact(4)
318
170
                .map(|pixel| {
319
                    let meta_huff_code = (u16::from(pixel[0]) << 8) | u16::from(pixel[1]);
320
                    if u32::from(meta_huff_code) >= num_huff_groups {
321
                        num_huff_groups = u32::from(meta_huff_code) + 1;
322
                    }
323
                    meta_huff_code
324
                })
325
170
                .collect::<Vec<u16>>();
326
876
        }
327
328
1.04k
        let mut hufftree_groups = Vec::new();
329
330
4.37k
        for _i in 0..num_huff_groups {
331
4.37k
            let mut group: HuffmanCodeGroup = Default::default();
332
25.4k
            for j in 0..HUFFMAN_CODES_PER_META_CODE {
333
21.2k
                let mut alphabet_size = ALPHABET_SIZE[j];
334
21.2k
                if j == 0 {
335
4.37k
                    if let Some(color_cache) = color_cache.as_ref() {
336
743
                        alphabet_size += 1 << color_cache.color_cache_bits;
337
3.62k
                    }
338
16.9k
                }
339
340
21.2k
                let tree = self.read_huffman_code(alphabet_size)?;
341
21.0k
                group[j] = tree;
342
            }
343
4.15k
            hufftree_groups.push(group);
344
        }
345
346
830
        let huffman_mask = if huffman_bits == 0 {
347
730
            !0
348
        } else {
349
100
            (1 << huffman_bits) - 1
350
        };
351
352
830
        let info = HuffmanInfo {
353
830
            xsize: huffman_xsize,
354
830
            _ysize: huffman_ysize,
355
830
            color_cache,
356
830
            image: entropy_image,
357
830
            bits: huffman_bits,
358
830
            mask: huffman_mask,
359
830
            huffman_code_groups: hufftree_groups,
360
830
        };
361
362
830
        Ok(info)
363
1.05k
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::read_huffman_codes
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
Line
Count
Source
293
3.59k
    fn read_huffman_codes(
294
3.59k
        &mut self,
295
3.59k
        read_meta: bool,
296
3.59k
        xsize: u16,
297
3.59k
        ysize: u16,
298
3.59k
        color_cache: Option<ColorCache>,
299
3.59k
    ) -> Result<HuffmanInfo, DecodingError> {
300
3.59k
        let mut num_huff_groups = 1u32;
301
302
3.59k
        let mut huffman_bits = 0;
303
3.59k
        let mut huffman_xsize = 1;
304
3.59k
        let mut huffman_ysize = 1;
305
3.59k
        let mut entropy_image = Vec::new();
306
307
3.59k
        if read_meta && self.bit_reader.read_bits::<u8>(1)? == 1 {
308
            //meta huffman codes
309
0
            huffman_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
310
0
            huffman_xsize = subsample_size(xsize, huffman_bits);
311
0
            huffman_ysize = subsample_size(ysize, huffman_bits);
312
313
0
            let mut data = vec![0; usize::from(huffman_xsize) * usize::from(huffman_ysize) * 4];
314
0
            self.decode_image_stream(huffman_xsize, huffman_ysize, false, &mut data)?;
315
316
0
            entropy_image = data
317
0
                .chunks_exact(4)
318
0
                .map(|pixel| {
319
                    let meta_huff_code = (u16::from(pixel[0]) << 8) | u16::from(pixel[1]);
320
                    if u32::from(meta_huff_code) >= num_huff_groups {
321
                        num_huff_groups = u32::from(meta_huff_code) + 1;
322
                    }
323
                    meta_huff_code
324
                })
325
0
                .collect::<Vec<u16>>();
326
3.59k
        }
327
328
3.59k
        let mut hufftree_groups = Vec::new();
329
330
3.59k
        for _i in 0..num_huff_groups {
331
3.59k
            let mut group: HuffmanCodeGroup = Default::default();
332
21.5k
            for j in 0..HUFFMAN_CODES_PER_META_CODE {
333
17.9k
                let mut alphabet_size = ALPHABET_SIZE[j];
334
17.9k
                if j == 0 {
335
3.59k
                    if let Some(color_cache) = color_cache.as_ref() {
336
0
                        alphabet_size += 1 << color_cache.color_cache_bits;
337
3.59k
                    }
338
14.3k
                }
339
340
17.9k
                let tree = self.read_huffman_code(alphabet_size)?;
341
17.9k
                group[j] = tree;
342
            }
343
3.59k
            hufftree_groups.push(group);
344
        }
345
346
3.59k
        let huffman_mask = if huffman_bits == 0 {
347
3.59k
            !0
348
        } else {
349
0
            (1 << huffman_bits) - 1
350
        };
351
352
3.59k
        let info = HuffmanInfo {
353
3.59k
            xsize: huffman_xsize,
354
3.59k
            _ysize: huffman_ysize,
355
3.59k
            color_cache,
356
3.59k
            image: entropy_image,
357
3.59k
            bits: huffman_bits,
358
3.59k
            mask: huffman_mask,
359
3.59k
            huffman_code_groups: hufftree_groups,
360
3.59k
        };
361
362
3.59k
        Ok(info)
363
3.59k
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
364
365
    /// Decodes and returns a single huffman tree
366
105k
    fn read_huffman_code(&mut self, alphabet_size: u16) -> Result<HuffmanTree, DecodingError> {
367
105k
        let simple = self.bit_reader.read_bits::<u8>(1)? == 1;
368
369
105k
        if simple {
370
94.8k
            let num_symbols = self.bit_reader.read_bits::<u8>(1)? + 1;
371
372
94.7k
            let is_first_8bits = self.bit_reader.read_bits::<u8>(1)?;
373
94.7k
            let zero_symbol = self.bit_reader.read_bits::<u16>(1 + 7 * is_first_8bits)?;
374
375
94.7k
            if zero_symbol >= alphabet_size {
376
8
                return Err(DecodingError::BitStreamError);
377
94.7k
            }
378
379
94.7k
            if num_symbols == 1 {
380
80.7k
                Ok(HuffmanTree::build_single_node(zero_symbol))
381
            } else {
382
14.0k
                let one_symbol = self.bit_reader.read_bits::<u16>(8)?;
383
13.9k
                if one_symbol >= alphabet_size {
384
8
                    return Err(DecodingError::BitStreamError);
385
13.9k
                }
386
13.9k
                Ok(HuffmanTree::build_two_node(zero_symbol, one_symbol))
387
            }
388
        } else {
389
11.0k
            let mut code_length_code_lengths = vec![0; CODE_LENGTH_CODES];
390
391
11.0k
            let num_code_lengths = 4 + self.bit_reader.read_bits::<usize>(4)?;
392
167k
            for i in 0..num_code_lengths {
393
166k
                code_length_code_lengths[CODE_LENGTH_CODE_ORDER[i]] =
394
167k
                    self.bit_reader.read_bits(3)?;
395
            }
396
397
10.8k
            let new_code_lengths =
398
11.0k
                self.read_huffman_code_lengths(code_length_code_lengths, alphabet_size)?;
399
400
10.8k
            HuffmanTree::build_implicit(new_code_lengths)
401
        }
402
105k
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
Line
Count
Source
366
66.6k
    fn read_huffman_code(&mut self, alphabet_size: u16) -> Result<HuffmanTree, DecodingError> {
367
66.6k
        let simple = self.bit_reader.read_bits::<u8>(1)? == 1;
368
369
66.6k
        if simple {
370
63.7k
            let num_symbols = self.bit_reader.read_bits::<u8>(1)? + 1;
371
372
63.7k
            let is_first_8bits = self.bit_reader.read_bits::<u8>(1)?;
373
63.7k
            let zero_symbol = self.bit_reader.read_bits::<u16>(1 + 7 * is_first_8bits)?;
374
375
63.7k
            if zero_symbol >= alphabet_size {
376
4
                return Err(DecodingError::BitStreamError);
377
63.7k
            }
378
379
63.7k
            if num_symbols == 1 {
380
51.7k
                Ok(HuffmanTree::build_single_node(zero_symbol))
381
            } else {
382
11.9k
                let one_symbol = self.bit_reader.read_bits::<u16>(8)?;
383
11.9k
                if one_symbol >= alphabet_size {
384
2
                    return Err(DecodingError::BitStreamError);
385
11.9k
                }
386
11.9k
                Ok(HuffmanTree::build_two_node(zero_symbol, one_symbol))
387
            }
388
        } else {
389
2.88k
            let mut code_length_code_lengths = vec![0; CODE_LENGTH_CODES];
390
391
2.88k
            let num_code_lengths = 4 + self.bit_reader.read_bits::<usize>(4)?;
392
26.9k
            for i in 0..num_code_lengths {
393
26.9k
                code_length_code_lengths[CODE_LENGTH_CODE_ORDER[i]] =
394
26.9k
                    self.bit_reader.read_bits(3)?;
395
            }
396
397
2.81k
            let new_code_lengths =
398
2.87k
                self.read_huffman_code_lengths(code_length_code_lengths, alphabet_size)?;
399
400
2.81k
            HuffmanTree::build_implicit(new_code_lengths)
401
        }
402
66.6k
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
Line
Count
Source
366
21.2k
    fn read_huffman_code(&mut self, alphabet_size: u16) -> Result<HuffmanTree, DecodingError> {
367
21.2k
        let simple = self.bit_reader.read_bits::<u8>(1)? == 1;
368
369
21.2k
        if simple {
370
19.8k
            let num_symbols = self.bit_reader.read_bits::<u8>(1)? + 1;
371
372
19.8k
            let is_first_8bits = self.bit_reader.read_bits::<u8>(1)?;
373
19.8k
            let zero_symbol = self.bit_reader.read_bits::<u16>(1 + 7 * is_first_8bits)?;
374
375
19.8k
            if zero_symbol >= alphabet_size {
376
4
                return Err(DecodingError::BitStreamError);
377
19.8k
            }
378
379
19.8k
            if num_symbols == 1 {
380
17.7k
                Ok(HuffmanTree::build_single_node(zero_symbol))
381
            } else {
382
2.06k
                let one_symbol = self.bit_reader.read_bits::<u16>(8)?;
383
2.05k
                if one_symbol >= alphabet_size {
384
6
                    return Err(DecodingError::BitStreamError);
385
2.05k
                }
386
2.05k
                Ok(HuffmanTree::build_two_node(zero_symbol, one_symbol))
387
            }
388
        } else {
389
1.41k
            let mut code_length_code_lengths = vec![0; CODE_LENGTH_CODES];
390
391
1.41k
            let num_code_lengths = 4 + self.bit_reader.read_bits::<usize>(4)?;
392
11.4k
            for i in 0..num_code_lengths {
393
11.3k
                code_length_code_lengths[CODE_LENGTH_CODE_ORDER[i]] =
394
11.4k
                    self.bit_reader.read_bits(3)?;
395
            }
396
397
1.25k
            let new_code_lengths =
398
1.38k
                self.read_huffman_code_lengths(code_length_code_lengths, alphabet_size)?;
399
400
1.25k
            HuffmanTree::build_implicit(new_code_lengths)
401
        }
402
21.2k
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::read_huffman_code
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
Line
Count
Source
366
17.9k
    fn read_huffman_code(&mut self, alphabet_size: u16) -> Result<HuffmanTree, DecodingError> {
367
17.9k
        let simple = self.bit_reader.read_bits::<u8>(1)? == 1;
368
369
17.9k
        if simple {
370
11.2k
            let num_symbols = self.bit_reader.read_bits::<u8>(1)? + 1;
371
372
11.2k
            let is_first_8bits = self.bit_reader.read_bits::<u8>(1)?;
373
11.2k
            let zero_symbol = self.bit_reader.read_bits::<u16>(1 + 7 * is_first_8bits)?;
374
375
11.2k
            if zero_symbol >= alphabet_size {
376
0
                return Err(DecodingError::BitStreamError);
377
11.2k
            }
378
379
11.2k
            if num_symbols == 1 {
380
11.2k
                Ok(HuffmanTree::build_single_node(zero_symbol))
381
            } else {
382
0
                let one_symbol = self.bit_reader.read_bits::<u16>(8)?;
383
0
                if one_symbol >= alphabet_size {
384
0
                    return Err(DecodingError::BitStreamError);
385
0
                }
386
0
                Ok(HuffmanTree::build_two_node(zero_symbol, one_symbol))
387
            }
388
        } else {
389
6.77k
            let mut code_length_code_lengths = vec![0; CODE_LENGTH_CODES];
390
391
6.77k
            let num_code_lengths = 4 + self.bit_reader.read_bits::<usize>(4)?;
392
128k
            for i in 0..num_code_lengths {
393
128k
                code_length_code_lengths[CODE_LENGTH_CODE_ORDER[i]] =
394
128k
                    self.bit_reader.read_bits(3)?;
395
            }
396
397
6.77k
            let new_code_lengths =
398
6.77k
                self.read_huffman_code_lengths(code_length_code_lengths, alphabet_size)?;
399
400
6.77k
            HuffmanTree::build_implicit(new_code_lengths)
401
        }
402
17.9k
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
403
404
    /// Reads huffman code lengths
405
11.0k
    fn read_huffman_code_lengths(
406
11.0k
        &mut self,
407
11.0k
        code_length_code_lengths: Vec<u16>,
408
11.0k
        num_symbols: u16,
409
11.0k
    ) -> Result<Vec<u16>, DecodingError> {
410
11.0k
        let table = HuffmanTree::build_implicit(code_length_code_lengths)?;
411
412
10.8k
        let mut max_symbol = if self.bit_reader.read_bits::<u8>(1)? == 1 {
413
7.17k
            let length_nbits = 2 + 2 * self.bit_reader.read_bits::<u8>(3)?;
414
7.17k
            let max_minus_two = self.bit_reader.read_bits::<u16>(length_nbits)?;
415
7.16k
            if max_minus_two > num_symbols - 2 {
416
0
                return Err(DecodingError::BitStreamError);
417
7.16k
            }
418
7.16k
            2 + max_minus_two
419
        } else {
420
3.71k
            num_symbols
421
        };
422
423
10.8k
        let mut code_lengths = vec![0; usize::from(num_symbols)];
424
10.8k
        let mut prev_code_len = 8; //default code length
425
426
10.8k
        let mut symbol = 0;
427
1.87M
        while symbol < num_symbols {
428
1.86M
            if max_symbol == 0 {
429
2.09k
                break;
430
1.86M
            }
431
1.86M
            max_symbol -= 1;
432
433
1.86M
            self.bit_reader.fill()?;
434
1.86M
            let code_len = table.read_symbol(&mut self.bit_reader)?;
435
436
1.86M
            if code_len < 16 {
437
1.83M
                code_lengths[usize::from(symbol)] = code_len;
438
1.83M
                symbol += 1;
439
1.83M
                if code_len != 0 {
440
873k
                    prev_code_len = code_len;
441
960k
                }
442
            } else {
443
26.0k
                let use_prev = code_len == 16;
444
26.0k
                let slot = code_len - 16;
445
26.0k
                let extra_bits = match slot {
446
15.7k
                    0 => 2,
447
4.41k
                    1 => 3,
448
5.94k
                    2 => 7,
449
0
                    _ => return Err(DecodingError::BitStreamError),
450
                };
451
26.0k
                let repeat_offset = match slot {
452
20.1k
                    0 | 1 => 3,
453
5.94k
                    2 => 11,
454
0
                    _ => return Err(DecodingError::BitStreamError),
455
                };
456
457
26.0k
                let mut repeat = self.bit_reader.read_bits::<u16>(extra_bits)? + repeat_offset;
458
459
26.0k
                if symbol + repeat > num_symbols {
460
16
                    return Err(DecodingError::BitStreamError);
461
26.0k
                }
462
463
26.0k
                let length = if use_prev { prev_code_len } else { 0 };
464
544k
                while repeat > 0 {
465
518k
                    repeat -= 1;
466
518k
                    code_lengths[usize::from(symbol)] = length;
467
518k
                    symbol += 1;
468
518k
                }
469
            }
470
        }
471
472
10.8k
        Ok(code_lengths)
473
11.0k
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
Line
Count
Source
405
2.87k
    fn read_huffman_code_lengths(
406
2.87k
        &mut self,
407
2.87k
        code_length_code_lengths: Vec<u16>,
408
2.87k
        num_symbols: u16,
409
2.87k
    ) -> Result<Vec<u16>, DecodingError> {
410
2.87k
        let table = HuffmanTree::build_implicit(code_length_code_lengths)?;
411
412
2.83k
        let mut max_symbol = if self.bit_reader.read_bits::<u8>(1)? == 1 {
413
1.52k
            let length_nbits = 2 + 2 * self.bit_reader.read_bits::<u8>(3)?;
414
1.52k
            let max_minus_two = self.bit_reader.read_bits::<u16>(length_nbits)?;
415
1.52k
            if max_minus_two > num_symbols - 2 {
416
0
                return Err(DecodingError::BitStreamError);
417
1.52k
            }
418
1.52k
            2 + max_minus_two
419
        } else {
420
1.31k
            num_symbols
421
        };
422
423
2.83k
        let mut code_lengths = vec![0; usize::from(num_symbols)];
424
2.83k
        let mut prev_code_len = 8; //default code length
425
426
2.83k
        let mut symbol = 0;
427
71.4k
        while symbol < num_symbols {
428
70.1k
            if max_symbol == 0 {
429
1.52k
                break;
430
68.6k
            }
431
68.6k
            max_symbol -= 1;
432
433
68.6k
            self.bit_reader.fill()?;
434
68.6k
            let code_len = table.read_symbol(&mut self.bit_reader)?;
435
436
68.6k
            if code_len < 16 {
437
48.2k
                code_lengths[usize::from(symbol)] = code_len;
438
48.2k
                symbol += 1;
439
48.2k
                if code_len != 0 {
440
44.4k
                    prev_code_len = code_len;
441
44.4k
                }
442
            } else {
443
20.3k
                let use_prev = code_len == 16;
444
20.3k
                let slot = code_len - 16;
445
20.3k
                let extra_bits = match slot {
446
13.1k
                    0 => 2,
447
3.40k
                    1 => 3,
448
3.83k
                    2 => 7,
449
0
                    _ => return Err(DecodingError::BitStreamError),
450
                };
451
20.3k
                let repeat_offset = match slot {
452
16.5k
                    0 | 1 => 3,
453
3.83k
                    2 => 11,
454
0
                    _ => return Err(DecodingError::BitStreamError),
455
                };
456
457
20.3k
                let mut repeat = self.bit_reader.read_bits::<u16>(extra_bits)? + repeat_offset;
458
459
20.3k
                if symbol + repeat > num_symbols {
460
10
                    return Err(DecodingError::BitStreamError);
461
20.3k
                }
462
463
20.3k
                let length = if use_prev { prev_code_len } else { 0 };
464
346k
                while repeat > 0 {
465
326k
                    repeat -= 1;
466
326k
                    code_lengths[usize::from(symbol)] = length;
467
326k
                    symbol += 1;
468
326k
                }
469
            }
470
        }
471
472
2.81k
        Ok(code_lengths)
473
2.87k
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
Line
Count
Source
405
1.38k
    fn read_huffman_code_lengths(
406
1.38k
        &mut self,
407
1.38k
        code_length_code_lengths: Vec<u16>,
408
1.38k
        num_symbols: u16,
409
1.38k
    ) -> Result<Vec<u16>, DecodingError> {
410
1.38k
        let table = HuffmanTree::build_implicit(code_length_code_lengths)?;
411
412
1.27k
        let mut max_symbol = if self.bit_reader.read_bits::<u8>(1)? == 1 {
413
576
            let length_nbits = 2 + 2 * self.bit_reader.read_bits::<u8>(3)?;
414
576
            let max_minus_two = self.bit_reader.read_bits::<u16>(length_nbits)?;
415
574
            if max_minus_two > num_symbols - 2 {
416
0
                return Err(DecodingError::BitStreamError);
417
574
            }
418
574
            2 + max_minus_two
419
        } else {
420
696
            num_symbols
421
        };
422
423
1.27k
        let mut code_lengths = vec![0; usize::from(num_symbols)];
424
1.27k
        let mut prev_code_len = 8; //default code length
425
426
1.27k
        let mut symbol = 0;
427
18.8k
        while symbol < num_symbols {
428
18.1k
            if max_symbol == 0 {
429
574
                break;
430
17.6k
            }
431
17.6k
            max_symbol -= 1;
432
433
17.6k
            self.bit_reader.fill()?;
434
17.6k
            let code_len = table.read_symbol(&mut self.bit_reader)?;
435
436
17.6k
            if code_len < 16 {
437
11.9k
                code_lengths[usize::from(symbol)] = code_len;
438
11.9k
                symbol += 1;
439
11.9k
                if code_len != 0 {
440
11.2k
                    prev_code_len = code_len;
441
11.2k
                }
442
            } else {
443
5.69k
                let use_prev = code_len == 16;
444
5.69k
                let slot = code_len - 16;
445
5.69k
                let extra_bits = match slot {
446
2.57k
                    0 => 2,
447
1.00k
                    1 => 3,
448
2.11k
                    2 => 7,
449
0
                    _ => return Err(DecodingError::BitStreamError),
450
                };
451
5.69k
                let repeat_offset = match slot {
452
3.58k
                    0 | 1 => 3,
453
2.11k
                    2 => 11,
454
0
                    _ => return Err(DecodingError::BitStreamError),
455
                };
456
457
5.69k
                let mut repeat = self.bit_reader.read_bits::<u16>(extra_bits)? + repeat_offset;
458
459
5.69k
                if symbol + repeat > num_symbols {
460
6
                    return Err(DecodingError::BitStreamError);
461
5.68k
                }
462
463
5.68k
                let length = if use_prev { prev_code_len } else { 0 };
464
198k
                while repeat > 0 {
465
192k
                    repeat -= 1;
466
192k
                    code_lengths[usize::from(symbol)] = length;
467
192k
                    symbol += 1;
468
192k
                }
469
            }
470
        }
471
472
1.25k
        Ok(code_lengths)
473
1.38k
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::read_huffman_code_lengths
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
Line
Count
Source
405
6.77k
    fn read_huffman_code_lengths(
406
6.77k
        &mut self,
407
6.77k
        code_length_code_lengths: Vec<u16>,
408
6.77k
        num_symbols: u16,
409
6.77k
    ) -> Result<Vec<u16>, DecodingError> {
410
6.77k
        let table = HuffmanTree::build_implicit(code_length_code_lengths)?;
411
412
6.77k
        let mut max_symbol = if self.bit_reader.read_bits::<u8>(1)? == 1 {
413
5.06k
            let length_nbits = 2 + 2 * self.bit_reader.read_bits::<u8>(3)?;
414
5.06k
            let max_minus_two = self.bit_reader.read_bits::<u16>(length_nbits)?;
415
5.06k
            if max_minus_two > num_symbols - 2 {
416
0
                return Err(DecodingError::BitStreamError);
417
5.06k
            }
418
5.06k
            2 + max_minus_two
419
        } else {
420
1.70k
            num_symbols
421
        };
422
423
6.77k
        let mut code_lengths = vec![0; usize::from(num_symbols)];
424
6.77k
        let mut prev_code_len = 8; //default code length
425
426
6.77k
        let mut symbol = 0;
427
1.78M
        while symbol < num_symbols {
428
1.77M
            if max_symbol == 0 {
429
0
                break;
430
1.77M
            }
431
1.77M
            max_symbol -= 1;
432
433
1.77M
            self.bit_reader.fill()?;
434
1.77M
            let code_len = table.read_symbol(&mut self.bit_reader)?;
435
436
1.77M
            if code_len < 16 {
437
1.77M
                code_lengths[usize::from(symbol)] = code_len;
438
1.77M
                symbol += 1;
439
1.77M
                if code_len != 0 {
440
818k
                    prev_code_len = code_len;
441
955k
                }
442
            } else {
443
0
                let use_prev = code_len == 16;
444
0
                let slot = code_len - 16;
445
0
                let extra_bits = match slot {
446
0
                    0 => 2,
447
0
                    1 => 3,
448
0
                    2 => 7,
449
0
                    _ => return Err(DecodingError::BitStreamError),
450
                };
451
0
                let repeat_offset = match slot {
452
0
                    0 | 1 => 3,
453
0
                    2 => 11,
454
0
                    _ => return Err(DecodingError::BitStreamError),
455
                };
456
457
0
                let mut repeat = self.bit_reader.read_bits::<u16>(extra_bits)? + repeat_offset;
458
459
0
                if symbol + repeat > num_symbols {
460
0
                    return Err(DecodingError::BitStreamError);
461
0
                }
462
463
0
                let length = if use_prev { prev_code_len } else { 0 };
464
0
                while repeat > 0 {
465
0
                    repeat -= 1;
466
0
                    code_lengths[usize::from(symbol)] = length;
467
0
                    symbol += 1;
468
0
                }
469
            }
470
        }
471
472
6.77k
        Ok(code_lengths)
473
6.77k
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
474
475
    /// Decodes the image data using the huffman trees and either of the 3 methods of decoding
476
4.89k
    fn decode_image_data(
477
4.89k
        &mut self,
478
4.89k
        width: u16,
479
4.89k
        height: u16,
480
4.89k
        mut huffman_info: HuffmanInfo,
481
4.89k
        data: &mut [u8],
482
4.89k
    ) -> Result<(), DecodingError> {
483
4.89k
        let num_values = usize::from(width) * usize::from(height);
484
485
4.89k
        let huff_index = huffman_info.get_huff_index(0, 0);
486
4.89k
        let mut tree = &huffman_info.huffman_code_groups[huff_index];
487
4.89k
        let mut index = 0;
488
489
4.89k
        let mut next_block_start = 0;
490
32.0M
        while index < num_values {
491
32.0M
            self.bit_reader.fill()?;
492
493
32.0M
            if index >= next_block_start {
494
1.80M
                let x = index % usize::from(width);
495
1.80M
                let y = index / usize::from(width);
496
1.80M
                next_block_start = (x | usize::from(huffman_info.mask)).min(usize::from(width - 1))
497
1.80M
                    + y * usize::from(width)
498
1.80M
                    + 1;
499
500
1.80M
                let huff_index = huffman_info.get_huff_index(x as u16, y as u16);
501
1.80M
                tree = &huffman_info.huffman_code_groups[huff_index];
502
503
                // Fast path: If all the codes each contain only a single
504
                // symbol, then the pixel data isn't written to the bitstream
505
                // and we can just fill the output buffer with the symbol
506
                // directly.
507
4.73M
                if tree[..4].iter().all(|t| t.is_single_node()) {
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data::{closure#0}
Line
Count
Source
507
3.99M
                if tree[..4].iter().all(|t| t.is_single_node()) {
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data::{closure#0}
Line
Count
Source
507
559k
                if tree[..4].iter().all(|t| t.is_single_node()) {
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::decode_image_data::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data::{closure#0}
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data::{closure#0}
Line
Count
Source
507
177k
                if tree[..4].iter().all(|t| t.is_single_node()) {
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data::{closure#0}
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data::{closure#0}
508
976k
                    let code = tree[GREEN].read_symbol(&mut self.bit_reader)?;
509
976k
                    if code < 256 {
510
976k
                        let n = if huffman_info.bits == 0 {
511
2.05k
                            num_values
512
                        } else {
513
974k
                            next_block_start - index
514
                        };
515
516
976k
                        let red = tree[RED].read_symbol(&mut self.bit_reader)?;
517
976k
                        let blue = tree[BLUE].read_symbol(&mut self.bit_reader)?;
518
976k
                        let alpha = tree[ALPHA].read_symbol(&mut self.bit_reader)?;
519
976k
                        let value = [red as u8, code as u8, blue as u8, alpha as u8];
520
521
118M
                        for i in 0..n {
522
118M
                            data[index * 4 + i * 4..][..4].copy_from_slice(&value);
523
118M
                        }
524
525
976k
                        if let Some(color_cache) = huffman_info.color_cache.as_mut() {
526
61
                            color_cache.insert(value);
527
976k
                        }
528
529
976k
                        index += n;
530
976k
                        continue;
531
0
                    }
532
825k
                }
533
30.2M
            }
534
535
31.0M
            let code = tree[GREEN].read_symbol(&mut self.bit_reader)?;
536
537
            //check code
538
31.0M
            if code < 256 {
539
                //literal, so just use huffman codes and read as argb
540
20.6M
                let green = code as u8;
541
20.6M
                let red = tree[RED].read_symbol(&mut self.bit_reader)? as u8;
542
20.6M
                let blue = tree[BLUE].read_symbol(&mut self.bit_reader)? as u8;
543
20.6M
                if self.bit_reader.nbits < 15 {
544
4.91k
                    self.bit_reader.fill()?;
545
20.6M
                }
546
20.6M
                let alpha = tree[ALPHA].read_symbol(&mut self.bit_reader)? as u8;
547
548
20.6M
                data[index * 4] = red;
549
20.6M
                data[index * 4 + 1] = green;
550
20.6M
                data[index * 4 + 2] = blue;
551
20.6M
                data[index * 4 + 3] = alpha;
552
553
20.6M
                if let Some(color_cache) = huffman_info.color_cache.as_mut() {
554
4.53M
                    color_cache.insert([red, green, blue, alpha]);
555
16.1M
                }
556
20.6M
                index += 1;
557
10.4M
            } else if code < 256 + 24 {
558
                //backward reference, so go back and use that to add image data
559
7.57M
                let length_symbol = code - 256;
560
7.57M
                let length = Self::get_copy_distance(&mut self.bit_reader, length_symbol)?;
561
562
7.57M
                let dist_symbol = tree[DIST].read_symbol(&mut self.bit_reader)?;
563
7.57M
                let dist_code = Self::get_copy_distance(&mut self.bit_reader, dist_symbol)?;
564
7.57M
                let dist = Self::plane_code_to_distance(width, dist_code);
565
566
7.57M
                if index < dist || num_values - index < length {
567
57
                    return Err(DecodingError::BitStreamError);
568
7.57M
                }
569
570
7.57M
                if dist == 1 {
571
3.95M
                    let value: [u8; 4] = data[(index - dist) * 4..][..4].try_into().unwrap();
572
1.90G
                    for i in 0..length {
573
1.90G
                        data[index * 4 + i * 4..][..4].copy_from_slice(&value);
574
1.90G
                    }
575
                } else {
576
3.61M
                    if index + length + 3 <= num_values {
577
3.61M
                        let start = (index - dist) * 4;
578
3.61M
                        data.copy_within(start..start + 16, index * 4);
579
580
3.61M
                        if length > 4 || dist < 4 {
581
250M
                            for i in (0..length * 4).step_by((dist * 4).min(16)).skip(1) {
582
250M
                                data.copy_within(start + i..start + i + 16, index * 4 + i);
583
250M
                            }
584
9.68k
                        }
585
                    } else {
586
64.3k
                        for i in 0..length * 4 {
587
64.3k
                            data[index * 4 + i] = data[index * 4 + i - dist * 4];
588
64.3k
                        }
589
                    }
590
591
3.61M
                    if let Some(color_cache) = huffman_info.color_cache.as_mut() {
592
1.00G
                        for pixel in data[index * 4..][..length * 4].chunks_exact(4) {
593
1.00G
                            color_cache.insert(pixel.try_into().unwrap());
594
1.00G
                        }
595
29.8k
                    }
596
                }
597
7.57M
                index += length;
598
            } else {
599
                //color cache, so use previously stored pixels to get this pixel
600
2.87M
                let color_cache = huffman_info
601
2.87M
                    .color_cache
602
2.87M
                    .as_mut()
603
2.87M
                    .ok_or(DecodingError::BitStreamError)?;
604
2.87M
                let color = color_cache.lookup((code - 280).into());
605
2.87M
                data[index * 4..][..4].copy_from_slice(&color);
606
2.87M
                index += 1;
607
608
2.87M
                if index < next_block_start {
609
2.87M
                    if let Some((bits, code)) = tree[GREEN].peek_symbol(&self.bit_reader) {
610
2.87M
                        if code >= 280 {
611
794k
                            self.bit_reader.consume(bits)?;
612
794k
                            data[index * 4..][..4]
613
794k
                                .copy_from_slice(&color_cache.lookup((code - 280).into()));
614
794k
                            index += 1;
615
2.07M
                        }
616
350
                    }
617
2.10k
                }
618
            }
619
        }
620
621
4.55k
        Ok(())
622
4.89k
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
Line
Count
Source
476
473
    fn decode_image_data(
477
473
        &mut self,
478
473
        width: u16,
479
473
        height: u16,
480
473
        mut huffman_info: HuffmanInfo,
481
473
        data: &mut [u8],
482
473
    ) -> Result<(), DecodingError> {
483
473
        let num_values = usize::from(width) * usize::from(height);
484
485
473
        let huff_index = huffman_info.get_huff_index(0, 0);
486
473
        let mut tree = &huffman_info.huffman_code_groups[huff_index];
487
473
        let mut index = 0;
488
489
473
        let mut next_block_start = 0;
490
2.51M
        while index < num_values {
491
2.51M
            self.bit_reader.fill()?;
492
493
2.51M
            if index >= next_block_start {
494
1.12M
                let x = index % usize::from(width);
495
1.12M
                let y = index / usize::from(width);
496
1.12M
                next_block_start = (x | usize::from(huffman_info.mask)).min(usize::from(width - 1))
497
1.12M
                    + y * usize::from(width)
498
1.12M
                    + 1;
499
500
1.12M
                let huff_index = huffman_info.get_huff_index(x as u16, y as u16);
501
1.12M
                tree = &huffman_info.huffman_code_groups[huff_index];
502
503
                // Fast path: If all the codes each contain only a single
504
                // symbol, then the pixel data isn't written to the bitstream
505
                // and we can just fill the output buffer with the symbol
506
                // directly.
507
1.12M
                if tree[..4].iter().all(|t| t.is_single_node()) {
508
959k
                    let code = tree[GREEN].read_symbol(&mut self.bit_reader)?;
509
959k
                    if code < 256 {
510
959k
                        let n = if huffman_info.bits == 0 {
511
36
                            num_values
512
                        } else {
513
959k
                            next_block_start - index
514
                        };
515
516
959k
                        let red = tree[RED].read_symbol(&mut self.bit_reader)?;
517
959k
                        let blue = tree[BLUE].read_symbol(&mut self.bit_reader)?;
518
959k
                        let alpha = tree[ALPHA].read_symbol(&mut self.bit_reader)?;
519
959k
                        let value = [red as u8, code as u8, blue as u8, alpha as u8];
520
521
84.7M
                        for i in 0..n {
522
84.7M
                            data[index * 4 + i * 4..][..4].copy_from_slice(&value);
523
84.7M
                        }
524
525
959k
                        if let Some(color_cache) = huffman_info.color_cache.as_mut() {
526
20
                            color_cache.insert(value);
527
959k
                        }
528
529
959k
                        index += n;
530
959k
                        continue;
531
0
                    }
532
162k
                }
533
1.38M
            }
534
535
1.55M
            let code = tree[GREEN].read_symbol(&mut self.bit_reader)?;
536
537
            //check code
538
1.55M
            if code < 256 {
539
                //literal, so just use huffman codes and read as argb
540
859k
                let green = code as u8;
541
859k
                let red = tree[RED].read_symbol(&mut self.bit_reader)? as u8;
542
859k
                let blue = tree[BLUE].read_symbol(&mut self.bit_reader)? as u8;
543
859k
                if self.bit_reader.nbits < 15 {
544
325
                    self.bit_reader.fill()?;
545
858k
                }
546
859k
                let alpha = tree[ALPHA].read_symbol(&mut self.bit_reader)? as u8;
547
548
859k
                data[index * 4] = red;
549
859k
                data[index * 4 + 1] = green;
550
859k
                data[index * 4 + 2] = blue;
551
859k
                data[index * 4 + 3] = alpha;
552
553
859k
                if let Some(color_cache) = huffman_info.color_cache.as_mut() {
554
772k
                    color_cache.insert([red, green, blue, alpha]);
555
772k
                }
556
859k
                index += 1;
557
691k
            } else if code < 256 + 24 {
558
                //backward reference, so go back and use that to add image data
559
646k
                let length_symbol = code - 256;
560
646k
                let length = Self::get_copy_distance(&mut self.bit_reader, length_symbol)?;
561
562
646k
                let dist_symbol = tree[DIST].read_symbol(&mut self.bit_reader)?;
563
646k
                let dist_code = Self::get_copy_distance(&mut self.bit_reader, dist_symbol)?;
564
646k
                let dist = Self::plane_code_to_distance(width, dist_code);
565
566
646k
                if index < dist || num_values - index < length {
567
26
                    return Err(DecodingError::BitStreamError);
568
646k
                }
569
570
646k
                if dist == 1 {
571
455k
                    let value: [u8; 4] = data[(index - dist) * 4..][..4].try_into().unwrap();
572
1.48G
                    for i in 0..length {
573
1.48G
                        data[index * 4 + i * 4..][..4].copy_from_slice(&value);
574
1.48G
                    }
575
                } else {
576
190k
                    if index + length + 3 <= num_values {
577
190k
                        let start = (index - dist) * 4;
578
190k
                        data.copy_within(start..start + 16, index * 4);
579
580
190k
                        if length > 4 || dist < 4 {
581
147M
                            for i in (0..length * 4).step_by((dist * 4).min(16)).skip(1) {
582
147M
                                data.copy_within(start + i..start + i + 16, index * 4 + i);
583
147M
                            }
584
7.66k
                        }
585
                    } else {
586
6.17k
                        for i in 0..length * 4 {
587
6.17k
                            data[index * 4 + i] = data[index * 4 + i - dist * 4];
588
6.17k
                        }
589
                    }
590
591
190k
                    if let Some(color_cache) = huffman_info.color_cache.as_mut() {
592
590M
                        for pixel in data[index * 4..][..length * 4].chunks_exact(4) {
593
590M
                            color_cache.insert(pixel.try_into().unwrap());
594
590M
                        }
595
3.75k
                    }
596
                }
597
646k
                index += length;
598
            } else {
599
                //color cache, so use previously stored pixels to get this pixel
600
44.9k
                let color_cache = huffman_info
601
44.9k
                    .color_cache
602
44.9k
                    .as_mut()
603
44.9k
                    .ok_or(DecodingError::BitStreamError)?;
604
44.9k
                let color = color_cache.lookup((code - 280).into());
605
44.9k
                data[index * 4..][..4].copy_from_slice(&color);
606
44.9k
                index += 1;
607
608
44.9k
                if index < next_block_start {
609
44.5k
                    if let Some((bits, code)) = tree[GREEN].peek_symbol(&self.bit_reader) {
610
44.2k
                        if code >= 280 {
611
26.2k
                            self.bit_reader.consume(bits)?;
612
26.2k
                            data[index * 4..][..4]
613
26.2k
                                .copy_from_slice(&color_cache.lookup((code - 280).into()));
614
26.2k
                            index += 1;
615
17.9k
                        }
616
340
                    }
617
397
                }
618
            }
619
        }
620
621
327
        Ok(())
622
473
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
Line
Count
Source
476
830
    fn decode_image_data(
477
830
        &mut self,
478
830
        width: u16,
479
830
        height: u16,
480
830
        mut huffman_info: HuffmanInfo,
481
830
        data: &mut [u8],
482
830
    ) -> Result<(), DecodingError> {
483
830
        let num_values = usize::from(width) * usize::from(height);
484
485
830
        let huff_index = huffman_info.get_huff_index(0, 0);
486
830
        let mut tree = &huffman_info.huffman_code_groups[huff_index];
487
830
        let mut index = 0;
488
489
830
        let mut next_block_start = 0;
490
13.5M
        while index < num_values {
491
13.5M
            self.bit_reader.fill()?;
492
493
13.5M
            if index >= next_block_start {
494
510k
                let x = index % usize::from(width);
495
510k
                let y = index / usize::from(width);
496
510k
                next_block_start = (x | usize::from(huffman_info.mask)).min(usize::from(width - 1))
497
510k
                    + y * usize::from(width)
498
510k
                    + 1;
499
500
510k
                let huff_index = huffman_info.get_huff_index(x as u16, y as u16);
501
510k
                tree = &huffman_info.huffman_code_groups[huff_index];
502
503
                // Fast path: If all the codes each contain only a single
504
                // symbol, then the pixel data isn't written to the bitstream
505
                // and we can just fill the output buffer with the symbol
506
                // directly.
507
510k
                if tree[..4].iter().all(|t| t.is_single_node()) {
508
15.6k
                    let code = tree[GREEN].read_symbol(&mut self.bit_reader)?;
509
15.6k
                    if code < 256 {
510
15.6k
                        let n = if huffman_info.bits == 0 {
511
185
                            num_values
512
                        } else {
513
15.4k
                            next_block_start - index
514
                        };
515
516
15.6k
                        let red = tree[RED].read_symbol(&mut self.bit_reader)?;
517
15.6k
                        let blue = tree[BLUE].read_symbol(&mut self.bit_reader)?;
518
15.6k
                        let alpha = tree[ALPHA].read_symbol(&mut self.bit_reader)?;
519
15.6k
                        let value = [red as u8, code as u8, blue as u8, alpha as u8];
520
521
33.3M
                        for i in 0..n {
522
33.3M
                            data[index * 4 + i * 4..][..4].copy_from_slice(&value);
523
33.3M
                        }
524
525
15.6k
                        if let Some(color_cache) = huffman_info.color_cache.as_mut() {
526
41
                            color_cache.insert(value);
527
15.6k
                        }
528
529
15.6k
                        index += n;
530
15.6k
                        continue;
531
0
                    }
532
494k
                }
533
13.0M
            }
534
535
13.4M
            let code = tree[GREEN].read_symbol(&mut self.bit_reader)?;
536
537
            //check code
538
13.4M
            if code < 256 {
539
                //literal, so just use huffman codes and read as argb
540
3.86M
                let green = code as u8;
541
3.86M
                let red = tree[RED].read_symbol(&mut self.bit_reader)? as u8;
542
3.86M
                let blue = tree[BLUE].read_symbol(&mut self.bit_reader)? as u8;
543
3.86M
                if self.bit_reader.nbits < 15 {
544
271
                    self.bit_reader.fill()?;
545
3.86M
                }
546
3.86M
                let alpha = tree[ALPHA].read_symbol(&mut self.bit_reader)? as u8;
547
548
3.86M
                data[index * 4] = red;
549
3.86M
                data[index * 4 + 1] = green;
550
3.86M
                data[index * 4 + 2] = blue;
551
3.86M
                data[index * 4 + 3] = alpha;
552
553
3.86M
                if let Some(color_cache) = huffman_info.color_cache.as_mut() {
554
3.75M
                    color_cache.insert([red, green, blue, alpha]);
555
3.75M
                }
556
3.86M
                index += 1;
557
9.63M
            } else if code < 256 + 24 {
558
                //backward reference, so go back and use that to add image data
559
6.79M
                let length_symbol = code - 256;
560
6.79M
                let length = Self::get_copy_distance(&mut self.bit_reader, length_symbol)?;
561
562
6.79M
                let dist_symbol = tree[DIST].read_symbol(&mut self.bit_reader)?;
563
6.79M
                let dist_code = Self::get_copy_distance(&mut self.bit_reader, dist_symbol)?;
564
6.79M
                let dist = Self::plane_code_to_distance(width, dist_code);
565
566
6.79M
                if index < dist || num_values - index < length {
567
31
                    return Err(DecodingError::BitStreamError);
568
6.79M
                }
569
570
6.79M
                if dist == 1 {
571
3.37M
                    let value: [u8; 4] = data[(index - dist) * 4..][..4].try_into().unwrap();
572
409M
                    for i in 0..length {
573
409M
                        data[index * 4 + i * 4..][..4].copy_from_slice(&value);
574
409M
                    }
575
                } else {
576
3.42M
                    if index + length + 3 <= num_values {
577
3.42M
                        let start = (index - dist) * 4;
578
3.42M
                        data.copy_within(start..start + 16, index * 4);
579
580
3.42M
                        if length > 4 || dist < 4 {
581
103M
                            for i in (0..length * 4).step_by((dist * 4).min(16)).skip(1) {
582
103M
                                data.copy_within(start + i..start + i + 16, index * 4 + i);
583
103M
                            }
584
2.02k
                        }
585
                    } else {
586
58.1k
                        for i in 0..length * 4 {
587
58.1k
                            data[index * 4 + i] = data[index * 4 + i - dist * 4];
588
58.1k
                        }
589
                    }
590
591
3.42M
                    if let Some(color_cache) = huffman_info.color_cache.as_mut() {
592
419M
                        for pixel in data[index * 4..][..length * 4].chunks_exact(4) {
593
419M
                            color_cache.insert(pixel.try_into().unwrap());
594
419M
                        }
595
26.1k
                    }
596
                }
597
6.79M
                index += length;
598
            } else {
599
                //color cache, so use previously stored pixels to get this pixel
600
2.83M
                let color_cache = huffman_info
601
2.83M
                    .color_cache
602
2.83M
                    .as_mut()
603
2.83M
                    .ok_or(DecodingError::BitStreamError)?;
604
2.83M
                let color = color_cache.lookup((code - 280).into());
605
2.83M
                data[index * 4..][..4].copy_from_slice(&color);
606
2.83M
                index += 1;
607
608
2.83M
                if index < next_block_start {
609
2.82M
                    if let Some((bits, code)) = tree[GREEN].peek_symbol(&self.bit_reader) {
610
2.82M
                        if code >= 280 {
611
768k
                            self.bit_reader.consume(bits)?;
612
768k
                            data[index * 4..][..4]
613
768k
                                .copy_from_slice(&color_cache.lookup((code - 280).into()));
614
768k
                            index += 1;
615
2.06M
                        }
616
10
                    }
617
1.70k
                }
618
            }
619
        }
620
621
632
        Ok(())
622
830
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::decode_image_data
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
Line
Count
Source
476
3.59k
    fn decode_image_data(
477
3.59k
        &mut self,
478
3.59k
        width: u16,
479
3.59k
        height: u16,
480
3.59k
        mut huffman_info: HuffmanInfo,
481
3.59k
        data: &mut [u8],
482
3.59k
    ) -> Result<(), DecodingError> {
483
3.59k
        let num_values = usize::from(width) * usize::from(height);
484
485
3.59k
        let huff_index = huffman_info.get_huff_index(0, 0);
486
3.59k
        let mut tree = &huffman_info.huffman_code_groups[huff_index];
487
3.59k
        let mut index = 0;
488
489
3.59k
        let mut next_block_start = 0;
490
16.0M
        while index < num_values {
491
16.0M
            self.bit_reader.fill()?;
492
493
16.0M
            if index >= next_block_start {
494
170k
                let x = index % usize::from(width);
495
170k
                let y = index / usize::from(width);
496
170k
                next_block_start = (x | usize::from(huffman_info.mask)).min(usize::from(width - 1))
497
170k
                    + y * usize::from(width)
498
170k
                    + 1;
499
500
170k
                let huff_index = huffman_info.get_huff_index(x as u16, y as u16);
501
170k
                tree = &huffman_info.huffman_code_groups[huff_index];
502
503
                // Fast path: If all the codes each contain only a single
504
                // symbol, then the pixel data isn't written to the bitstream
505
                // and we can just fill the output buffer with the symbol
506
                // directly.
507
170k
                if tree[..4].iter().all(|t| t.is_single_node()) {
508
1.83k
                    let code = tree[GREEN].read_symbol(&mut self.bit_reader)?;
509
1.83k
                    if code < 256 {
510
1.83k
                        let n = if huffman_info.bits == 0 {
511
1.83k
                            num_values
512
                        } else {
513
0
                            next_block_start - index
514
                        };
515
516
1.83k
                        let red = tree[RED].read_symbol(&mut self.bit_reader)?;
517
1.83k
                        let blue = tree[BLUE].read_symbol(&mut self.bit_reader)?;
518
1.83k
                        let alpha = tree[ALPHA].read_symbol(&mut self.bit_reader)?;
519
1.83k
                        let value = [red as u8, code as u8, blue as u8, alpha as u8];
520
521
1.83k
                        for i in 0..n {
522
1.83k
                            data[index * 4 + i * 4..][..4].copy_from_slice(&value);
523
1.83k
                        }
524
525
1.83k
                        if let Some(color_cache) = huffman_info.color_cache.as_mut() {
526
0
                            color_cache.insert(value);
527
1.83k
                        }
528
529
1.83k
                        index += n;
530
1.83k
                        continue;
531
0
                    }
532
168k
                }
533
15.8M
            }
534
535
16.0M
            let code = tree[GREEN].read_symbol(&mut self.bit_reader)?;
536
537
            //check code
538
16.0M
            if code < 256 {
539
                //literal, so just use huffman codes and read as argb
540
15.9M
                let green = code as u8;
541
15.9M
                let red = tree[RED].read_symbol(&mut self.bit_reader)? as u8;
542
15.9M
                let blue = tree[BLUE].read_symbol(&mut self.bit_reader)? as u8;
543
15.9M
                if self.bit_reader.nbits < 15 {
544
4.31k
                    self.bit_reader.fill()?;
545
15.9M
                }
546
15.9M
                let alpha = tree[ALPHA].read_symbol(&mut self.bit_reader)? as u8;
547
548
15.9M
                data[index * 4] = red;
549
15.9M
                data[index * 4 + 1] = green;
550
15.9M
                data[index * 4 + 2] = blue;
551
15.9M
                data[index * 4 + 3] = alpha;
552
553
15.9M
                if let Some(color_cache) = huffman_info.color_cache.as_mut() {
554
0
                    color_cache.insert([red, green, blue, alpha]);
555
15.9M
                }
556
15.9M
                index += 1;
557
127k
            } else if code < 256 + 24 {
558
                //backward reference, so go back and use that to add image data
559
127k
                let length_symbol = code - 256;
560
127k
                let length = Self::get_copy_distance(&mut self.bit_reader, length_symbol)?;
561
562
127k
                let dist_symbol = tree[DIST].read_symbol(&mut self.bit_reader)?;
563
127k
                let dist_code = Self::get_copy_distance(&mut self.bit_reader, dist_symbol)?;
564
127k
                let dist = Self::plane_code_to_distance(width, dist_code);
565
566
127k
                if index < dist || num_values - index < length {
567
0
                    return Err(DecodingError::BitStreamError);
568
127k
                }
569
570
127k
                if dist == 1 {
571
127k
                    let value: [u8; 4] = data[(index - dist) * 4..][..4].try_into().unwrap();
572
1.35M
                    for i in 0..length {
573
1.35M
                        data[index * 4 + i * 4..][..4].copy_from_slice(&value);
574
1.35M
                    }
575
                } else {
576
0
                    if index + length + 3 <= num_values {
577
0
                        let start = (index - dist) * 4;
578
0
                        data.copy_within(start..start + 16, index * 4);
579
580
0
                        if length > 4 || dist < 4 {
581
0
                            for i in (0..length * 4).step_by((dist * 4).min(16)).skip(1) {
582
0
                                data.copy_within(start + i..start + i + 16, index * 4 + i);
583
0
                            }
584
0
                        }
585
                    } else {
586
0
                        for i in 0..length * 4 {
587
0
                            data[index * 4 + i] = data[index * 4 + i - dist * 4];
588
0
                        }
589
                    }
590
591
0
                    if let Some(color_cache) = huffman_info.color_cache.as_mut() {
592
0
                        for pixel in data[index * 4..][..length * 4].chunks_exact(4) {
593
0
                            color_cache.insert(pixel.try_into().unwrap());
594
0
                        }
595
0
                    }
596
                }
597
127k
                index += length;
598
            } else {
599
                //color cache, so use previously stored pixels to get this pixel
600
0
                let color_cache = huffman_info
601
0
                    .color_cache
602
0
                    .as_mut()
603
0
                    .ok_or(DecodingError::BitStreamError)?;
604
0
                let color = color_cache.lookup((code - 280).into());
605
0
                data[index * 4..][..4].copy_from_slice(&color);
606
0
                index += 1;
607
608
0
                if index < next_block_start {
609
0
                    if let Some((bits, code)) = tree[GREEN].peek_symbol(&self.bit_reader) {
610
0
                        if code >= 280 {
611
0
                            self.bit_reader.consume(bits)?;
612
0
                            data[index * 4..][..4]
613
0
                                .copy_from_slice(&color_cache.lookup((code - 280).into()));
614
0
                            index += 1;
615
0
                        }
616
0
                    }
617
0
                }
618
            }
619
        }
620
621
3.59k
        Ok(())
622
3.59k
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
623
624
    /// Reads color cache data from the bitstream
625
5.28k
    fn read_color_cache(&mut self) -> Result<Option<u8>, DecodingError> {
626
5.28k
        if self.bit_reader.read_bits::<u8>(1)? == 1 {
627
648
            let code_bits = self.bit_reader.read_bits::<u8>(4)?;
628
629
647
            if !(1..=11).contains(&code_bits) {
630
13
                return Err(DecodingError::InvalidColorCacheBits(code_bits));
631
634
            }
632
633
634
            Ok(Some(code_bits))
634
        } else {
635
4.63k
            Ok(None)
636
        }
637
5.28k
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
Line
Count
Source
625
621
    fn read_color_cache(&mut self) -> Result<Option<u8>, DecodingError> {
626
621
        if self.bit_reader.read_bits::<u8>(1)? == 1 {
627
295
            let code_bits = self.bit_reader.read_bits::<u8>(4)?;
628
629
295
            if !(1..=11).contains(&code_bits) {
630
0
                return Err(DecodingError::InvalidColorCacheBits(code_bits));
631
295
            }
632
633
295
            Ok(Some(code_bits))
634
        } else {
635
326
            Ok(None)
636
        }
637
621
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
Line
Count
Source
625
1.06k
    fn read_color_cache(&mut self) -> Result<Option<u8>, DecodingError> {
626
1.06k
        if self.bit_reader.read_bits::<u8>(1)? == 1 {
627
353
            let code_bits = self.bit_reader.read_bits::<u8>(4)?;
628
629
352
            if !(1..=11).contains(&code_bits) {
630
13
                return Err(DecodingError::InvalidColorCacheBits(code_bits));
631
339
            }
632
633
339
            Ok(Some(code_bits))
634
        } else {
635
716
            Ok(None)
636
        }
637
1.06k
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::read_color_cache
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
Line
Count
Source
625
3.59k
    fn read_color_cache(&mut self) -> Result<Option<u8>, DecodingError> {
626
3.59k
        if self.bit_reader.read_bits::<u8>(1)? == 1 {
627
0
            let code_bits = self.bit_reader.read_bits::<u8>(4)?;
628
629
0
            if !(1..=11).contains(&code_bits) {
630
0
                return Err(DecodingError::InvalidColorCacheBits(code_bits));
631
0
            }
632
633
0
            Ok(Some(code_bits))
634
        } else {
635
3.59k
            Ok(None)
636
        }
637
3.59k
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
638
639
    /// Gets the copy distance from the prefix code and bitstream
640
15.1M
    fn get_copy_distance(
641
15.1M
        bit_reader: &mut BitReader<R>,
642
15.1M
        prefix_code: u16,
643
15.1M
    ) -> Result<usize, DecodingError> {
644
15.1M
        if prefix_code < 4 {
645
4.29M
            return Ok(usize::from(prefix_code + 1));
646
10.8M
        }
647
10.8M
        let extra_bits: u8 = ((prefix_code - 2) >> 1).try_into().unwrap();
648
10.8M
        let offset = (2 + (usize::from(prefix_code) & 1)) << extra_bits;
649
650
10.8M
        let bits = bit_reader.peek(extra_bits) as usize;
651
10.8M
        bit_reader.consume(extra_bits)?;
652
653
10.8M
        Ok(offset + bits + 1)
654
15.1M
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
Line
Count
Source
640
1.29M
    fn get_copy_distance(
641
1.29M
        bit_reader: &mut BitReader<R>,
642
1.29M
        prefix_code: u16,
643
1.29M
    ) -> Result<usize, DecodingError> {
644
1.29M
        if prefix_code < 4 {
645
479k
            return Ok(usize::from(prefix_code + 1));
646
813k
        }
647
813k
        let extra_bits: u8 = ((prefix_code - 2) >> 1).try_into().unwrap();
648
813k
        let offset = (2 + (usize::from(prefix_code) & 1)) << extra_bits;
649
650
813k
        let bits = bit_reader.peek(extra_bits) as usize;
651
813k
        bit_reader.consume(extra_bits)?;
652
653
813k
        Ok(offset + bits + 1)
654
1.29M
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
Line
Count
Source
640
13.5M
    fn get_copy_distance(
641
13.5M
        bit_reader: &mut BitReader<R>,
642
13.5M
        prefix_code: u16,
643
13.5M
    ) -> Result<usize, DecodingError> {
644
13.5M
        if prefix_code < 4 {
645
3.58M
            return Ok(usize::from(prefix_code + 1));
646
10.0M
        }
647
10.0M
        let extra_bits: u8 = ((prefix_code - 2) >> 1).try_into().unwrap();
648
10.0M
        let offset = (2 + (usize::from(prefix_code) & 1)) << extra_bits;
649
650
10.0M
        let bits = bit_reader.peek(extra_bits) as usize;
651
10.0M
        bit_reader.consume(extra_bits)?;
652
653
10.0M
        Ok(offset + bits + 1)
654
13.5M
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::get_copy_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
Line
Count
Source
640
254k
    fn get_copy_distance(
641
254k
        bit_reader: &mut BitReader<R>,
642
254k
        prefix_code: u16,
643
254k
    ) -> Result<usize, DecodingError> {
644
254k
        if prefix_code < 4 {
645
223k
            return Ok(usize::from(prefix_code + 1));
646
31.8k
        }
647
31.8k
        let extra_bits: u8 = ((prefix_code - 2) >> 1).try_into().unwrap();
648
31.8k
        let offset = (2 + (usize::from(prefix_code) & 1)) << extra_bits;
649
650
31.8k
        let bits = bit_reader.peek(extra_bits) as usize;
651
31.8k
        bit_reader.consume(extra_bits)?;
652
653
31.8k
        Ok(offset + bits + 1)
654
254k
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
655
656
    /// Gets distance to pixel
657
7.57M
    fn plane_code_to_distance(xsize: u16, plane_code: usize) -> usize {
658
7.57M
        if plane_code > 120 {
659
3.39M
            plane_code - 120
660
        } else {
661
4.17M
            let (xoffset, yoffset) = DISTANCE_MAP[plane_code - 1];
662
663
4.17M
            let dist = i32::from(xoffset) + i32::from(yoffset) * i32::from(xsize);
664
4.17M
            if dist < 1 {
665
0
                return 1;
666
4.17M
            }
667
4.17M
            dist.try_into().unwrap()
668
        }
669
7.57M
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
Line
Count
Source
657
646k
    fn plane_code_to_distance(xsize: u16, plane_code: usize) -> usize {
658
646k
        if plane_code > 120 {
659
186k
            plane_code - 120
660
        } else {
661
460k
            let (xoffset, yoffset) = DISTANCE_MAP[plane_code - 1];
662
663
460k
            let dist = i32::from(xoffset) + i32::from(yoffset) * i32::from(xsize);
664
460k
            if dist < 1 {
665
0
                return 1;
666
460k
            }
667
460k
            dist.try_into().unwrap()
668
        }
669
646k
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
Line
Count
Source
657
6.79M
    fn plane_code_to_distance(xsize: u16, plane_code: usize) -> usize {
658
6.79M
        if plane_code > 120 {
659
3.21M
            plane_code - 120
660
        } else {
661
3.58M
            let (xoffset, yoffset) = DISTANCE_MAP[plane_code - 1];
662
663
3.58M
            let dist = i32::from(xoffset) + i32::from(yoffset) * i32::from(xsize);
664
3.58M
            if dist < 1 {
665
0
                return 1;
666
3.58M
            }
667
3.58M
            dist.try_into().unwrap()
668
        }
669
6.79M
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::plane_code_to_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
Line
Count
Source
657
127k
    fn plane_code_to_distance(xsize: u16, plane_code: usize) -> usize {
658
127k
        if plane_code > 120 {
659
0
            plane_code - 120
660
        } else {
661
127k
            let (xoffset, yoffset) = DISTANCE_MAP[plane_code - 1];
662
663
127k
            let dist = i32::from(xoffset) + i32::from(yoffset) * i32::from(xsize);
664
127k
            if dist < 1 {
665
0
                return 1;
666
127k
            }
667
127k
            dist.try_into().unwrap()
668
        }
669
127k
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
670
}
671
672
#[derive(Debug, Clone)]
673
struct HuffmanInfo {
674
    xsize: u16,
675
    _ysize: u16,
676
    color_cache: Option<ColorCache>,
677
    image: Vec<u16>,
678
    bits: u8,
679
    mask: u16,
680
    huffman_code_groups: Vec<HuffmanCodeGroup>,
681
}
682
683
impl HuffmanInfo {
684
1.80M
    fn get_huff_index(&self, x: u16, y: u16) -> usize {
685
1.80M
        if self.bits == 0 {
686
813k
            return 0;
687
993k
        }
688
993k
        let position =
689
993k
            usize::from(y >> self.bits) * usize::from(self.xsize) + usize::from(x >> self.bits);
690
993k
        let meta_huff_code: usize = usize::from(self.image[position]);
691
993k
        meta_huff_code
692
1.80M
    }
693
}
694
695
#[derive(Debug, Clone)]
696
struct ColorCache {
697
    color_cache_bits: u8,
698
    color_cache: Vec<[u8; 4]>,
699
}
700
701
impl ColorCache {
702
    #[inline(always)]
703
1.01G
    fn insert(&mut self, color: [u8; 4]) {
704
1.01G
        let [r, g, b, a] = color;
705
1.01G
        let color_u32 =
706
1.01G
            (u32::from(r) << 16) | (u32::from(g) << 8) | (u32::from(b)) | (u32::from(a) << 24);
707
1.01G
        let index = (0x1e35a7bdu32.wrapping_mul(color_u32)) >> (32 - self.color_cache_bits);
708
1.01G
        self.color_cache[index as usize] = color;
709
1.01G
    }
710
711
    #[inline(always)]
712
3.67M
    fn lookup(&self, index: usize) -> [u8; 4] {
713
3.67M
        self.color_cache[index]
714
3.67M
    }
715
}
716
717
#[derive(Debug, Clone)]
718
pub(crate) struct BitReader<R> {
719
    reader: R,
720
    buffer: u64,
721
    nbits: u8,
722
}
723
724
impl<R: BufRead> BitReader<R> {
725
2.63k
    const fn new(reader: R) -> Self {
726
2.63k
        Self {
727
2.63k
            reader,
728
2.63k
            buffer: 0,
729
2.63k
            nbits: 0,
730
2.63k
        }
731
2.63k
    }
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Line
Count
Source
725
318
    const fn new(reader: R) -> Self {
726
318
        Self {
727
318
            reader,
728
318
            buffer: 0,
729
318
            nbits: 0,
730
318
        }
731
318
    }
<image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Line
Count
Source
725
517
    const fn new(reader: R) -> Self {
726
517
        Self {
727
517
            reader,
728
517
            buffer: 0,
729
517
            nbits: 0,
730
517
        }
731
517
    }
Unexecuted instantiation: <image_webp::lossless::BitReader<_>>::new
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Line
Count
Source
725
1.79k
    const fn new(reader: R) -> Self {
726
1.79k
        Self {
727
1.79k
            reader,
728
1.79k
            buffer: 0,
729
1.79k
            nbits: 0,
730
1.79k
        }
731
1.79k
    }
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
732
733
    /// Fills the buffer with bits from the input stream.
734
    ///
735
    /// After this function, the internal buffer will contain 64-bits or have reached the end of
736
    /// the input stream.
737
33.9M
    pub(crate) fn fill(&mut self) -> Result<(), DecodingError> {
738
33.9M
        debug_assert!(self.nbits < 64);
739
740
33.9M
        let mut buf = self.reader.fill_buf()?;
741
33.9M
        if buf.len() >= 8 {
742
33.8M
            let lookahead = u64::from_le_bytes(buf[..8].try_into().unwrap());
743
33.8M
            self.reader.consume(usize::from((63 - self.nbits) / 8));
744
33.8M
            self.buffer |= lookahead << self.nbits;
745
33.8M
            self.nbits |= 56;
746
33.8M
        } else {
747
69.1k
            while !buf.is_empty() && self.nbits < 56 {
748
14.7k
                self.buffer |= u64::from(buf[0]) << self.nbits;
749
14.7k
                self.nbits += 8;
750
14.7k
                self.reader.consume(1);
751
14.7k
                buf = self.reader.fill_buf()?;
752
            }
753
        }
754
755
33.9M
        Ok(())
756
33.9M
    }
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
Line
Count
Source
737
2.58M
    pub(crate) fn fill(&mut self) -> Result<(), DecodingError> {
738
2.58M
        debug_assert!(self.nbits < 64);
739
740
2.58M
        let mut buf = self.reader.fill_buf()?;
741
2.58M
        if buf.len() >= 8 {
742
2.57M
            let lookahead = u64::from_le_bytes(buf[..8].try_into().unwrap());
743
2.57M
            self.reader.consume(usize::from((63 - self.nbits) / 8));
744
2.57M
            self.buffer |= lookahead << self.nbits;
745
2.57M
            self.nbits |= 56;
746
2.57M
        } else {
747
9.03k
            while !buf.is_empty() && self.nbits < 56 {
748
1.28k
                self.buffer |= u64::from(buf[0]) << self.nbits;
749
1.28k
                self.nbits += 8;
750
1.28k
                self.reader.consume(1);
751
1.28k
                buf = self.reader.fill_buf()?;
752
            }
753
        }
754
755
2.58M
        Ok(())
756
2.58M
    }
<image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
Line
Count
Source
737
13.5M
    pub(crate) fn fill(&mut self) -> Result<(), DecodingError> {
738
13.5M
        debug_assert!(self.nbits < 64);
739
740
13.5M
        let mut buf = self.reader.fill_buf()?;
741
13.5M
        if buf.len() >= 8 {
742
13.5M
            let lookahead = u64::from_le_bytes(buf[..8].try_into().unwrap());
743
13.5M
            self.reader.consume(usize::from((63 - self.nbits) / 8));
744
13.5M
            self.buffer |= lookahead << self.nbits;
745
13.5M
            self.nbits |= 56;
746
13.5M
        } else {
747
21.5k
            while !buf.is_empty() && self.nbits < 56 {
748
2.78k
                self.buffer |= u64::from(buf[0]) << self.nbits;
749
2.78k
                self.nbits += 8;
750
2.78k
                self.reader.consume(1);
751
2.78k
                buf = self.reader.fill_buf()?;
752
            }
753
        }
754
755
13.5M
        Ok(())
756
13.5M
    }
Unexecuted instantiation: <image_webp::lossless::BitReader<_>>::fill
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
Line
Count
Source
737
17.8M
    pub(crate) fn fill(&mut self) -> Result<(), DecodingError> {
738
17.8M
        debug_assert!(self.nbits < 64);
739
740
17.8M
        let mut buf = self.reader.fill_buf()?;
741
17.8M
        if buf.len() >= 8 {
742
17.8M
            let lookahead = u64::from_le_bytes(buf[..8].try_into().unwrap());
743
17.8M
            self.reader.consume(usize::from((63 - self.nbits) / 8));
744
17.8M
            self.buffer |= lookahead << self.nbits;
745
17.8M
            self.nbits |= 56;
746
17.8M
        } else {
747
38.5k
            while !buf.is_empty() && self.nbits < 56 {
748
10.7k
                self.buffer |= u64::from(buf[0]) << self.nbits;
749
10.7k
                self.nbits += 8;
750
10.7k
                self.reader.consume(1);
751
10.7k
                buf = self.reader.fill_buf()?;
752
            }
753
        }
754
755
17.8M
        Ok(())
756
17.8M
    }
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
757
758
    /// Peeks at the next `num` bits in the buffer.
759
11.5M
    pub(crate) const fn peek(&self, num: u8) -> u64 {
760
11.5M
        self.buffer & ((1 << num) - 1)
761
11.5M
    }
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
Line
Count
Source
759
1.14M
    pub(crate) const fn peek(&self, num: u8) -> u64 {
760
1.14M
        self.buffer & ((1 << num) - 1)
761
1.14M
    }
<image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
Line
Count
Source
759
10.1M
    pub(crate) const fn peek(&self, num: u8) -> u64 {
760
10.1M
        self.buffer & ((1 << num) - 1)
761
10.1M
    }
Unexecuted instantiation: <image_webp::lossless::BitReader<_>>::peek
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
Line
Count
Source
759
260k
    pub(crate) const fn peek(&self, num: u8) -> u64 {
760
260k
        self.buffer & ((1 << num) - 1)
761
260k
    }
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
762
763
    /// Peeks at the full buffer.
764
96.8M
    pub(crate) const fn peek_full(&self) -> u64 {
765
96.8M
        self.buffer
766
96.8M
    }
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
Line
Count
Source
764
4.56M
    pub(crate) const fn peek_full(&self) -> u64 {
765
4.56M
        self.buffer
766
4.56M
    }
<image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
Line
Count
Source
764
26.8M
    pub(crate) const fn peek_full(&self) -> u64 {
765
26.8M
        self.buffer
766
26.8M
    }
Unexecuted instantiation: <image_webp::lossless::BitReader<_>>::peek_full
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
Line
Count
Source
764
65.5M
    pub(crate) const fn peek_full(&self) -> u64 {
765
65.5M
        self.buffer
766
65.5M
    }
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
767
768
    /// Consumes `num` bits from the buffer returning an error if there are not enough bits.
769
106M
    pub(crate) fn consume(&mut self, num: u8) -> Result<(), DecodingError> {
770
106M
        if self.nbits < num {
771
437
            return Err(DecodingError::BitStreamError);
772
106M
        }
773
774
106M
        self.buffer >>= num;
775
106M
        self.nbits -= num;
776
106M
        Ok(())
777
106M
    }
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
Line
Count
Source
769
5.69M
    pub(crate) fn consume(&mut self, num: u8) -> Result<(), DecodingError> {
770
5.69M
        if self.nbits < num {
771
191
            return Err(DecodingError::BitStreamError);
772
5.69M
        }
773
774
5.69M
        self.buffer >>= num;
775
5.69M
        self.nbits -= num;
776
5.69M
        Ok(())
777
5.69M
    }
<image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
Line
Count
Source
769
34.8M
    pub(crate) fn consume(&mut self, num: u8) -> Result<(), DecodingError> {
770
34.8M
        if self.nbits < num {
771
246
            return Err(DecodingError::BitStreamError);
772
34.8M
        }
773
774
34.8M
        self.buffer >>= num;
775
34.8M
        self.nbits -= num;
776
34.8M
        Ok(())
777
34.8M
    }
Unexecuted instantiation: <image_webp::lossless::BitReader<_>>::consume
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
Line
Count
Source
769
65.7M
    pub(crate) fn consume(&mut self, num: u8) -> Result<(), DecodingError> {
770
65.7M
        if self.nbits < num {
771
0
            return Err(DecodingError::BitStreamError);
772
65.7M
        }
773
774
65.7M
        self.buffer >>= num;
775
65.7M
        self.nbits -= num;
776
65.7M
        Ok(())
777
65.7M
    }
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
778
779
    /// Convenience function to read a number of bits and convert them to a type.
780
666k
    pub(crate) fn read_bits<T: TryFrom<u32>>(&mut self, num: u8) -> Result<T, DecodingError> {
781
666k
        debug_assert!(num as usize <= 8 * mem::size_of::<T>());
782
666k
        debug_assert!(num <= 32);
783
784
666k
        if self.nbits < num {
785
20.3k
            self.fill()?;
786
646k
        }
787
666k
        let value = self.peek(num) as u32;
788
666k
        self.consume(num)?;
789
790
666k
        value.try_into().map_err(|_| {
791
0
            debug_assert!(false, "Value too large to fit in type");
792
0
            DecodingError::BitStreamError
793
0
        })
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<_>>::read_bits::<_>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>::{closure#0}
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>::{closure#0}
794
666k
    }
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Line
Count
Source
780
201k
    pub(crate) fn read_bits<T: TryFrom<u32>>(&mut self, num: u8) -> Result<T, DecodingError> {
781
201k
        debug_assert!(num as usize <= 8 * mem::size_of::<T>());
782
201k
        debug_assert!(num <= 32);
783
784
201k
        if self.nbits < num {
785
4.08k
            self.fill()?;
786
197k
        }
787
201k
        let value = self.peek(num) as u32;
788
201k
        self.consume(num)?;
789
790
201k
        value.try_into().map_err(|_| {
791
            debug_assert!(false, "Value too large to fit in type");
792
            DecodingError::BitStreamError
793
        })
794
201k
    }
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Line
Count
Source
780
2.88k
    pub(crate) fn read_bits<T: TryFrom<u32>>(&mut self, num: u8) -> Result<T, DecodingError> {
781
2.88k
        debug_assert!(num as usize <= 8 * mem::size_of::<T>());
782
2.88k
        debug_assert!(num <= 32);
783
784
2.88k
        if self.nbits < num {
785
57
            self.fill()?;
786
2.82k
        }
787
2.88k
        let value = self.peek(num) as u32;
788
2.88k
        self.consume(num)?;
789
790
2.88k
        value.try_into().map_err(|_| {
791
            debug_assert!(false, "Value too large to fit in type");
792
            DecodingError::BitStreamError
793
        })
794
2.88k
    }
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
Line
Count
Source
780
125k
    pub(crate) fn read_bits<T: TryFrom<u32>>(&mut self, num: u8) -> Result<T, DecodingError> {
781
125k
        debug_assert!(num as usize <= 8 * mem::size_of::<T>());
782
125k
        debug_assert!(num <= 32);
783
784
125k
        if self.nbits < num {
785
3.59k
            self.fill()?;
786
121k
        }
787
125k
        let value = self.peek(num) as u32;
788
125k
        self.consume(num)?;
789
790
125k
        value.try_into().map_err(|_| {
791
            debug_assert!(false, "Value too large to fit in type");
792
            DecodingError::BitStreamError
793
        })
794
125k
    }
<image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Line
Count
Source
780
66.8k
    pub(crate) fn read_bits<T: TryFrom<u32>>(&mut self, num: u8) -> Result<T, DecodingError> {
781
66.8k
        debug_assert!(num as usize <= 8 * mem::size_of::<T>());
782
66.8k
        debug_assert!(num <= 32);
783
784
66.8k
        if self.nbits < num {
785
1.42k
            self.fill()?;
786
65.4k
        }
787
66.8k
        let value = self.peek(num) as u32;
788
66.8k
        self.consume(num)?;
789
790
66.8k
        value.try_into().map_err(|_| {
791
            debug_assert!(false, "Value too large to fit in type");
792
            DecodingError::BitStreamError
793
        })
794
66.8k
    }
<image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Line
Count
Source
780
1.41k
    pub(crate) fn read_bits<T: TryFrom<u32>>(&mut self, num: u8) -> Result<T, DecodingError> {
781
1.41k
        debug_assert!(num as usize <= 8 * mem::size_of::<T>());
782
1.41k
        debug_assert!(num <= 32);
783
784
1.41k
        if self.nbits < num {
785
0
            self.fill()?;
786
1.41k
        }
787
1.41k
        let value = self.peek(num) as u32;
788
1.41k
        self.consume(num)?;
789
790
1.41k
        value.try_into().map_err(|_| {
791
            debug_assert!(false, "Value too large to fit in type");
792
            DecodingError::BitStreamError
793
        })
794
1.41k
    }
<image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
Line
Count
Source
780
39.7k
    pub(crate) fn read_bits<T: TryFrom<u32>>(&mut self, num: u8) -> Result<T, DecodingError> {
781
39.7k
        debug_assert!(num as usize <= 8 * mem::size_of::<T>());
782
39.7k
        debug_assert!(num <= 32);
783
784
39.7k
        if self.nbits < num {
785
842
            self.fill()?;
786
38.9k
        }
787
39.7k
        let value = self.peek(num) as u32;
788
39.7k
        self.consume(num)?;
789
790
39.6k
        value.try_into().map_err(|_| {
791
            debug_assert!(false, "Value too large to fit in type");
792
            DecodingError::BitStreamError
793
        })
794
39.7k
    }
Unexecuted instantiation: <image_webp::lossless::BitReader<_>>::read_bits::<_>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Line
Count
Source
780
73.7k
    pub(crate) fn read_bits<T: TryFrom<u32>>(&mut self, num: u8) -> Result<T, DecodingError> {
781
73.7k
        debug_assert!(num as usize <= 8 * mem::size_of::<T>());
782
73.7k
        debug_assert!(num <= 32);
783
784
73.7k
        if self.nbits < num {
785
2.06k
            self.fill()?;
786
71.7k
        }
787
73.7k
        let value = self.peek(num) as u32;
788
73.7k
        self.consume(num)?;
789
790
73.7k
        value.try_into().map_err(|_| {
791
            debug_assert!(false, "Value too large to fit in type");
792
            DecodingError::BitStreamError
793
        })
794
73.7k
    }
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Line
Count
Source
780
6.77k
    pub(crate) fn read_bits<T: TryFrom<u32>>(&mut self, num: u8) -> Result<T, DecodingError> {
781
6.77k
        debug_assert!(num as usize <= 8 * mem::size_of::<T>());
782
6.77k
        debug_assert!(num <= 32);
783
784
6.77k
        if self.nbits < num {
785
0
            self.fill()?;
786
6.77k
        }
787
6.77k
        let value = self.peek(num) as u32;
788
6.77k
        self.consume(num)?;
789
790
6.77k
        value.try_into().map_err(|_| {
791
            debug_assert!(false, "Value too large to fit in type");
792
            DecodingError::BitStreamError
793
        })
794
6.77k
    }
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
Line
Count
Source
780
148k
    pub(crate) fn read_bits<T: TryFrom<u32>>(&mut self, num: u8) -> Result<T, DecodingError> {
781
148k
        debug_assert!(num as usize <= 8 * mem::size_of::<T>());
782
148k
        debug_assert!(num <= 32);
783
784
148k
        if self.nbits < num {
785
8.29k
            self.fill()?;
786
140k
        }
787
148k
        let value = self.peek(num) as u32;
788
148k
        self.consume(num)?;
789
790
148k
        value.try_into().map_err(|_| {
791
            debug_assert!(false, "Value too large to fit in type");
792
            DecodingError::BitStreamError
793
        })
794
148k
    }
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Unexecuted instantiation: <image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Unexecuted instantiation: <image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
795
}
796
797
#[cfg(test)]
798
mod test {
799
800
    use std::io::Cursor;
801
802
    use super::BitReader;
803
804
    #[test]
805
    fn bit_read_test() {
806
        //10011100 01000001 11100001
807
        let mut bit_reader = BitReader::new(Cursor::new(vec![0x9C, 0x41, 0xE1]));
808
809
        assert_eq!(bit_reader.read_bits::<u8>(3).unwrap(), 4); //100
810
        assert_eq!(bit_reader.read_bits::<u8>(2).unwrap(), 3); //11
811
        assert_eq!(bit_reader.read_bits::<u8>(6).unwrap(), 12); //001100
812
        assert_eq!(bit_reader.read_bits::<u16>(10).unwrap(), 40); //0000101000
813
        assert_eq!(bit_reader.read_bits::<u8>(3).unwrap(), 7); //111
814
    }
815
816
    #[test]
817
    fn bit_read_error_test() {
818
        //01101010
819
        let mut bit_reader = BitReader::new(Cursor::new(vec![0x6A]));
820
821
        assert_eq!(bit_reader.read_bits::<u8>(3).unwrap(), 2); //010
822
        assert_eq!(bit_reader.read_bits::<u8>(5).unwrap(), 13); //01101
823
        assert!(bit_reader.read_bits::<u8>(4).is_err()); //error
824
    }
825
}