Coverage Report

Created: 2025-12-11 07:11

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
8.08k
pub(crate) fn subsample_size(size: u16, bits: u8) -> u16 {
55
8.08k
    ((u32::from(size) + (1u32 << bits) - 1) >> bits)
56
8.08k
        .try_into()
57
8.08k
        .unwrap()
58
8.08k
}
image_webp::lossless::subsample_size
Line
Count
Source
54
6.21k
pub(crate) fn subsample_size(size: u16, bits: u8) -> u16 {
55
6.21k
    ((u32::from(size) + (1u32 << bits) - 1) >> bits)
56
6.21k
        .try_into()
57
6.21k
        .unwrap()
58
6.21k
}
image_webp::lossless::subsample_size
Line
Count
Source
54
1.87k
pub(crate) fn subsample_size(size: u16, bits: u8) -> u16 {
55
1.87k
    ((u32::from(size) + (1u32 << bits) - 1) >> bits)
56
1.87k
        .try_into()
57
1.87k
        .unwrap()
58
1.87k
}
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
3.03k
    pub(crate) const fn new(r: R) -> Self {
75
3.03k
        Self {
76
3.03k
            bit_reader: BitReader::new(r),
77
3.03k
            transforms: [None, None, None, None],
78
3.03k
            transform_order: Vec::new(),
79
3.03k
            width: 0,
80
3.03k
            height: 0,
81
3.03k
        }
82
3.03k
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Line
Count
Source
74
2.35k
    pub(crate) const fn new(r: R) -> Self {
75
2.35k
        Self {
76
2.35k
            bit_reader: BitReader::new(r),
77
2.35k
            transforms: [None, None, None, None],
78
2.35k
            transform_order: Vec::new(),
79
2.35k
            width: 0,
80
2.35k
            height: 0,
81
2.35k
        }
82
2.35k
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Line
Count
Source
74
674
    pub(crate) const fn new(r: R) -> Self {
75
674
        Self {
76
674
            bit_reader: BitReader::new(r),
77
674
            transforms: [None, None, None, None],
78
674
            transform_order: Vec::new(),
79
674
            width: 0,
80
674
            height: 0,
81
674
        }
82
674
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::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
3.03k
    pub(crate) fn decode_frame(
90
3.03k
        &mut self,
91
3.03k
        width: u32,
92
3.03k
        height: u32,
93
3.03k
        implicit_dimensions: bool,
94
3.03k
        buf: &mut [u8],
95
3.03k
    ) -> Result<(), DecodingError> {
96
3.03k
        if implicit_dimensions {
97
674
            self.width = width as u16;
98
674
            self.height = height as u16;
99
674
        } else {
100
2.35k
            let signature = self.bit_reader.read_bits::<u8>(8)?;
101
2.35k
            if signature != 0x2f {
102
0
                return Err(DecodingError::LosslessSignatureInvalid(signature));
103
2.35k
            }
104
105
2.35k
            self.width = self.bit_reader.read_bits::<u16>(14)? + 1;
106
2.35k
            self.height = self.bit_reader.read_bits::<u16>(14)? + 1;
107
2.35k
            if u32::from(self.width) != width || u32::from(self.height) != height {
108
1
                return Err(DecodingError::InconsistentImageSizes);
109
2.35k
            }
110
111
2.35k
            let _alpha_used = self.bit_reader.read_bits::<u8>(1)?;
112
2.35k
            let version_num = self.bit_reader.read_bits::<u8>(3)?;
113
2.35k
            if version_num != 0 {
114
0
                return Err(DecodingError::VersionNumberInvalid(version_num));
115
2.35k
            }
116
        }
117
118
3.02k
        let transformed_width = self.read_transforms()?;
119
2.85k
        let transformed_size = usize::from(transformed_width) * usize::from(self.height) * 4;
120
2.85k
        self.decode_image_stream(
121
2.85k
            transformed_width,
122
2.85k
            self.height,
123
            true,
124
2.85k
            &mut buf[..transformed_size],
125
853
        )?;
126
127
2.00k
        let mut image_size = transformed_size;
128
2.00k
        let mut width = transformed_width;
129
3.76k
        for &trans_index in self.transform_order.iter().rev() {
130
3.76k
            let transform = self.transforms[usize::from(trans_index)].as_ref().unwrap();
131
3.76k
            match transform {
132
                TransformType::PredictorTransform {
133
1.85k
                    size_bits,
134
1.85k
                    predictor_data,
135
1.85k
                } => apply_predictor_transform(
136
1.85k
                    &mut buf[..image_size],
137
1.85k
                    width,
138
1.85k
                    self.height,
139
1.85k
                    *size_bits,
140
1.85k
                    predictor_data,
141
0
                )?,
142
                TransformType::ColorTransform {
143
11
                    size_bits,
144
11
                    transform_data,
145
11
                } => {
146
11
                    apply_color_transform(
147
11
                        &mut buf[..image_size],
148
11
                        width,
149
11
                        *size_bits,
150
11
                        transform_data,
151
11
                    );
152
11
                }
153
1.78k
                TransformType::SubtractGreen => {
154
1.78k
                    apply_subtract_green_transform(&mut buf[..image_size]);
155
1.78k
                }
156
                TransformType::ColorIndexingTransform {
157
107
                    table_size,
158
107
                    table_data,
159
107
                } => {
160
107
                    width = self.width;
161
107
                    image_size = usize::from(width) * usize::from(self.height) * 4;
162
107
                    apply_color_indexing_transform(
163
107
                        buf,
164
107
                        width,
165
107
                        self.height,
166
107
                        *table_size,
167
107
                        table_data,
168
107
                    );
169
107
                }
170
            }
171
        }
172
173
2.00k
        Ok(())
174
3.03k
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
Line
Count
Source
89
2.35k
    pub(crate) fn decode_frame(
90
2.35k
        &mut self,
91
2.35k
        width: u32,
92
2.35k
        height: u32,
93
2.35k
        implicit_dimensions: bool,
94
2.35k
        buf: &mut [u8],
95
2.35k
    ) -> Result<(), DecodingError> {
96
2.35k
        if implicit_dimensions {
97
0
            self.width = width as u16;
98
0
            self.height = height as u16;
99
0
        } else {
100
2.35k
            let signature = self.bit_reader.read_bits::<u8>(8)?;
101
2.35k
            if signature != 0x2f {
102
0
                return Err(DecodingError::LosslessSignatureInvalid(signature));
103
2.35k
            }
104
105
2.35k
            self.width = self.bit_reader.read_bits::<u16>(14)? + 1;
106
2.35k
            self.height = self.bit_reader.read_bits::<u16>(14)? + 1;
107
2.35k
            if u32::from(self.width) != width || u32::from(self.height) != height {
108
1
                return Err(DecodingError::InconsistentImageSizes);
109
2.35k
            }
110
111
2.35k
            let _alpha_used = self.bit_reader.read_bits::<u8>(1)?;
112
2.35k
            let version_num = self.bit_reader.read_bits::<u8>(3)?;
113
2.35k
            if version_num != 0 {
114
0
                return Err(DecodingError::VersionNumberInvalid(version_num));
115
2.35k
            }
116
        }
117
118
2.35k
        let transformed_width = self.read_transforms()?;
119
2.32k
        let transformed_size = usize::from(transformed_width) * usize::from(self.height) * 4;
120
2.32k
        self.decode_image_stream(
121
2.32k
            transformed_width,
122
2.32k
            self.height,
123
            true,
124
2.32k
            &mut buf[..transformed_size],
125
456
        )?;
126
127
1.87k
        let mut image_size = transformed_size;
128
1.87k
        let mut width = transformed_width;
129
3.63k
        for &trans_index in self.transform_order.iter().rev() {
130
3.63k
            let transform = self.transforms[usize::from(trans_index)].as_ref().unwrap();
131
3.63k
            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
6
                    size_bits,
144
6
                    transform_data,
145
6
                } => {
146
6
                    apply_color_transform(
147
6
                        &mut buf[..image_size],
148
6
                        width,
149
6
                        *size_bits,
150
6
                        transform_data,
151
6
                    );
152
6
                }
153
1.78k
                TransformType::SubtractGreen => {
154
1.78k
                    apply_subtract_green_transform(&mut buf[..image_size]);
155
1.78k
                }
156
                TransformType::ColorIndexingTransform {
157
57
                    table_size,
158
57
                    table_data,
159
57
                } => {
160
57
                    width = self.width;
161
57
                    image_size = usize::from(width) * usize::from(self.height) * 4;
162
57
                    apply_color_indexing_transform(
163
57
                        buf,
164
57
                        width,
165
57
                        self.height,
166
57
                        *table_size,
167
57
                        table_data,
168
57
                    );
169
57
                }
170
            }
171
        }
172
173
1.87k
        Ok(())
174
2.35k
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_frame
Line
Count
Source
89
674
    pub(crate) fn decode_frame(
90
674
        &mut self,
91
674
        width: u32,
92
674
        height: u32,
93
674
        implicit_dimensions: bool,
94
674
        buf: &mut [u8],
95
674
    ) -> Result<(), DecodingError> {
96
674
        if implicit_dimensions {
97
674
            self.width = width as u16;
98
674
            self.height = height as u16;
99
674
        } 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
674
        let transformed_width = self.read_transforms()?;
119
531
        let transformed_size = usize::from(transformed_width) * usize::from(self.height) * 4;
120
531
        self.decode_image_stream(
121
531
            transformed_width,
122
531
            self.height,
123
            true,
124
531
            &mut buf[..transformed_size],
125
397
        )?;
126
127
134
        let mut image_size = transformed_size;
128
134
        let mut width = transformed_width;
129
134
        for &trans_index in self.transform_order.iter().rev() {
130
124
            let transform = self.transforms[usize::from(trans_index)].as_ref().unwrap();
131
124
            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
4
                TransformType::SubtractGreen => {
154
4
                    apply_subtract_green_transform(&mut buf[..image_size]);
155
4
                }
156
                TransformType::ColorIndexingTransform {
157
50
                    table_size,
158
50
                    table_data,
159
50
                } => {
160
50
                    width = self.width;
161
50
                    image_size = usize::from(width) * usize::from(self.height) * 4;
162
50
                    apply_color_indexing_transform(
163
50
                        buf,
164
50
                        width,
165
50
                        self.height,
166
50
                        *table_size,
167
50
                        table_data,
168
50
                    );
169
50
                }
170
            }
171
        }
172
173
134
        Ok(())
174
674
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::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
6.18k
    fn decode_image_stream(
182
6.18k
        &mut self,
183
6.18k
        xsize: u16,
184
6.18k
        ysize: u16,
185
6.18k
        is_argb_img: bool,
186
6.18k
        data: &mut [u8],
187
6.18k
    ) -> Result<(), DecodingError> {
188
6.18k
        let color_cache_bits = self.read_color_cache()?;
189
6.17k
        let color_cache = color_cache_bits.map(|bits| ColorCache {
190
811
            color_cache_bits: bits,
191
811
            color_cache: vec![[0; 4]; 1 << bits],
192
811
        });
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
Line
Count
Source
190
471
            color_cache_bits: bits,
191
471
            color_cache: vec![[0; 4]; 1 << bits],
192
471
        });
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream::{closure#0}
Line
Count
Source
190
340
            color_cache_bits: bits,
191
340
            color_cache: vec![[0; 4]; 1 << bits],
192
340
        });
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::decode_image_stream::{closure#0}
193
194
6.17k
        let huffman_info = self.read_huffman_codes(is_argb_img, xsize, ysize, color_cache)?;
195
5.61k
        self.decode_image_data(xsize, ysize, huffman_info, data)
196
6.18k
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
Line
Count
Source
181
4.75k
    fn decode_image_stream(
182
4.75k
        &mut self,
183
4.75k
        xsize: u16,
184
4.75k
        ysize: u16,
185
4.75k
        is_argb_img: bool,
186
4.75k
        data: &mut [u8],
187
4.75k
    ) -> Result<(), DecodingError> {
188
4.75k
        let color_cache_bits = self.read_color_cache()?;
189
4.74k
        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
4.74k
        let huffman_info = self.read_huffman_codes(is_argb_img, xsize, ysize, color_cache)?;
195
4.48k
        self.decode_image_data(xsize, ysize, huffman_info, data)
196
4.75k
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_stream
Line
Count
Source
181
1.42k
    fn decode_image_stream(
182
1.42k
        &mut self,
183
1.42k
        xsize: u16,
184
1.42k
        ysize: u16,
185
1.42k
        is_argb_img: bool,
186
1.42k
        data: &mut [u8],
187
1.42k
    ) -> Result<(), DecodingError> {
188
1.42k
        let color_cache_bits = self.read_color_cache()?;
189
1.42k
        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.42k
        let huffman_info = self.read_huffman_codes(is_argb_img, xsize, ysize, color_cache)?;
195
1.13k
        self.decode_image_data(xsize, ysize, huffman_info, data)
196
1.42k
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::decode_image_stream
197
198
    /// Reads transforms and their data from the bitstream
199
3.02k
    fn read_transforms(&mut self) -> Result<u16, DecodingError> {
200
3.02k
        let mut xsize = self.width;
201
202
7.67k
        while self.bit_reader.read_bits::<u8>(1)? == 1 {
203
4.82k
            let transform_type_val = self.bit_reader.read_bits::<u8>(2)?;
204
205
4.82k
            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.81k
            }
209
210
4.81k
            self.transform_order.push(transform_type_val);
211
212
4.81k
            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.15k
                    TransformType::PredictorTransform {
226
2.15k
                        size_bits,
227
2.15k
                        predictor_data,
228
2.15k
                    }
229
                }
230
                1 => {
231
                    //color transform
232
233
132
                    let size_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
234
235
132
                    let block_xsize = subsample_size(xsize, size_bits);
236
132
                    let block_ysize = subsample_size(self.height, size_bits);
237
238
132
                    let mut transform_data =
239
132
                        vec![0; usize::from(block_xsize) * usize::from(block_ysize) * 4];
240
132
                    self.decode_image_stream(block_xsize, block_ysize, false, &mut transform_data)?;
241
242
107
                    TransformType::ColorTransform {
243
107
                        size_bits,
244
107
                        transform_data,
245
107
                    }
246
                }
247
                2 => {
248
                    //subtract green
249
250
2.03k
                    TransformType::SubtractGreen
251
                }
252
                3 => {
253
397
                    let color_table_size = self.bit_reader.read_bits::<u16>(8)? + 1;
254
255
394
                    let mut color_map = vec![0; usize::from(color_table_size) * 4];
256
394
                    self.decode_image_stream(color_table_size, 1, false, &mut color_map)?;
257
258
356
                    let bits = if color_table_size <= 2 {
259
89
                        3
260
267
                    } else if color_table_size <= 4 {
261
42
                        2
262
225
                    } else if color_table_size <= 16 {
263
15
                        1
264
                    } else {
265
210
                        0
266
                    };
267
356
                    xsize = subsample_size(xsize, bits);
268
269
356
                    Self::adjust_color_map(&mut color_map);
270
271
356
                    TransformType::ColorIndexingTransform {
272
356
                        table_size: color_table_size,
273
356
                        table_data: color_map,
274
356
                    }
275
                }
276
0
                _ => unreachable!(),
277
            };
278
279
4.65k
            self.transforms[usize::from(transform_type_val)] = Some(transform_type);
280
        }
281
282
2.85k
        Ok(xsize)
283
3.02k
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
Line
Count
Source
199
2.35k
    fn read_transforms(&mut self) -> Result<u16, DecodingError> {
200
2.35k
        let mut xsize = self.width;
201
202
6.37k
        while self.bit_reader.read_bits::<u8>(1)? == 1 {
203
4.05k
            let transform_type_val = self.bit_reader.read_bits::<u8>(2)?;
204
205
4.05k
            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
4.04k
            }
209
210
4.04k
            self.transform_order.push(transform_type_val);
211
212
4.04k
            let transform_type = match transform_type_val {
213
                0 => {
214
                    //predictor
215
216
1.93k
                    let size_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
217
218
1.93k
                    let block_xsize = subsample_size(xsize, size_bits);
219
1.93k
                    let block_ysize = subsample_size(self.height, size_bits);
220
221
1.93k
                    let mut predictor_data =
222
1.93k
                        vec![0; usize::from(block_xsize) * usize::from(block_ysize) * 4];
223
1.93k
                    self.decode_image_stream(block_xsize, block_ysize, false, &mut predictor_data)?;
224
225
1.92k
                    TransformType::PredictorTransform {
226
1.92k
                        size_bits,
227
1.92k
                        predictor_data,
228
1.92k
                    }
229
                }
230
                1 => {
231
                    //color transform
232
233
100
                    let size_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
234
235
100
                    let block_xsize = subsample_size(xsize, size_bits);
236
100
                    let block_ysize = subsample_size(self.height, size_bits);
237
238
100
                    let mut transform_data =
239
100
                        vec![0; usize::from(block_xsize) * usize::from(block_ysize) * 4];
240
100
                    self.decode_image_stream(block_xsize, block_ysize, false, &mut transform_data)?;
241
242
95
                    TransformType::ColorTransform {
243
95
                        size_bits,
244
95
                        transform_data,
245
95
                    }
246
                }
247
                2 => {
248
                    //subtract green
249
250
1.90k
                    TransformType::SubtractGreen
251
                }
252
                3 => {
253
106
                    let color_table_size = self.bit_reader.read_bits::<u16>(8)? + 1;
254
255
104
                    let mut color_map = vec![0; usize::from(color_table_size) * 4];
256
104
                    self.decode_image_stream(color_table_size, 1, false, &mut color_map)?;
257
258
94
                    let bits = if color_table_size <= 2 {
259
5
                        3
260
89
                    } else if color_table_size <= 4 {
261
4
                        2
262
85
                    } else if color_table_size <= 16 {
263
10
                        1
264
                    } else {
265
75
                        0
266
                    };
267
94
                    xsize = subsample_size(xsize, bits);
268
269
94
                    Self::adjust_color_map(&mut color_map);
270
271
94
                    TransformType::ColorIndexingTransform {
272
94
                        table_size: color_table_size,
273
94
                        table_data: color_map,
274
94
                    }
275
                }
276
0
                _ => unreachable!(),
277
            };
278
279
4.02k
            self.transforms[usize::from(transform_type_val)] = Some(transform_type);
280
        }
281
282
2.32k
        Ok(xsize)
283
2.35k
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_transforms
Line
Count
Source
199
674
    fn read_transforms(&mut self) -> Result<u16, DecodingError> {
200
674
        let mut xsize = self.width;
201
202
1.30k
        while self.bit_reader.read_bits::<u8>(1)? == 1 {
203
769
            let transform_type_val = self.bit_reader.read_bits::<u8>(2)?;
204
205
769
            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
768
            }
209
210
768
            self.transform_order.push(transform_type_val);
211
212
768
            let transform_type = match transform_type_val {
213
                0 => {
214
                    //predictor
215
216
318
                    let size_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
217
218
318
                    let block_xsize = subsample_size(xsize, size_bits);
219
318
                    let block_ysize = subsample_size(self.height, size_bits);
220
221
318
                    let mut predictor_data =
222
318
                        vec![0; usize::from(block_xsize) * usize::from(block_ysize) * 4];
223
318
                    self.decode_image_stream(block_xsize, block_ysize, false, &mut predictor_data)?;
224
225
225
                    TransformType::PredictorTransform {
226
225
                        size_bits,
227
225
                        predictor_data,
228
225
                    }
229
                }
230
                1 => {
231
                    //color transform
232
233
32
                    let size_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
234
235
32
                    let block_xsize = subsample_size(xsize, size_bits);
236
32
                    let block_ysize = subsample_size(self.height, size_bits);
237
238
32
                    let mut transform_data =
239
32
                        vec![0; usize::from(block_xsize) * usize::from(block_ysize) * 4];
240
32
                    self.decode_image_stream(block_xsize, block_ysize, false, &mut transform_data)?;
241
242
12
                    TransformType::ColorTransform {
243
12
                        size_bits,
244
12
                        transform_data,
245
12
                    }
246
                }
247
                2 => {
248
                    //subtract green
249
250
127
                    TransformType::SubtractGreen
251
                }
252
                3 => {
253
291
                    let color_table_size = self.bit_reader.read_bits::<u16>(8)? + 1;
254
255
290
                    let mut color_map = vec![0; usize::from(color_table_size) * 4];
256
290
                    self.decode_image_stream(color_table_size, 1, false, &mut color_map)?;
257
258
262
                    let bits = if color_table_size <= 2 {
259
84
                        3
260
178
                    } else if color_table_size <= 4 {
261
38
                        2
262
140
                    } else if color_table_size <= 16 {
263
5
                        1
264
                    } else {
265
135
                        0
266
                    };
267
262
                    xsize = subsample_size(xsize, bits);
268
269
262
                    Self::adjust_color_map(&mut color_map);
270
271
262
                    TransformType::ColorIndexingTransform {
272
262
                        table_size: color_table_size,
273
262
                        table_data: color_map,
274
262
                    }
275
                }
276
0
                _ => unreachable!(),
277
            };
278
279
626
            self.transforms[usize::from(transform_type_val)] = Some(transform_type);
280
        }
281
282
531
        Ok(xsize)
283
674
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::read_transforms
284
285
    /// Adjusts the color map since it's subtraction coded
286
356
    fn adjust_color_map(color_map: &mut [u8]) {
287
112k
        for i in 4..color_map.len() {
288
112k
            color_map[i] = color_map[i].wrapping_add(color_map[i - 4]);
289
112k
        }
290
356
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
Line
Count
Source
286
94
    fn adjust_color_map(color_map: &mut [u8]) {
287
55.5k
        for i in 4..color_map.len() {
288
55.5k
            color_map[i] = color_map[i].wrapping_add(color_map[i - 4]);
289
55.5k
        }
290
94
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::adjust_color_map
Line
Count
Source
286
262
    fn adjust_color_map(color_map: &mut [u8]) {
287
57.1k
        for i in 4..color_map.len() {
288
57.1k
            color_map[i] = color_map[i].wrapping_add(color_map[i - 4]);
289
57.1k
        }
290
262
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::adjust_color_map
291
292
    /// Reads huffman codes associated with an image
293
6.17k
    fn read_huffman_codes(
294
6.17k
        &mut self,
295
6.17k
        read_meta: bool,
296
6.17k
        xsize: u16,
297
6.17k
        ysize: u16,
298
6.17k
        color_cache: Option<ColorCache>,
299
6.17k
    ) -> Result<HuffmanInfo, DecodingError> {
300
6.17k
        let mut num_huff_groups = 1u32;
301
302
6.17k
        let mut huffman_bits = 0;
303
6.17k
        let mut huffman_xsize = 1;
304
6.17k
        let mut huffman_ysize = 1;
305
6.17k
        let mut entropy_image = Vec::new();
306
307
6.17k
        if read_meta && self.bit_reader.read_bits::<u8>(1)? == 1 {
308
            //meta huffman codes
309
545
            huffman_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
310
545
            huffman_xsize = subsample_size(xsize, huffman_bits);
311
545
            huffman_ysize = subsample_size(ysize, huffman_bits);
312
313
545
            let mut data = vec![0; usize::from(huffman_xsize) * usize::from(huffman_ysize) * 4];
314
545
            self.decode_image_stream(huffman_xsize, huffman_ysize, false, &mut data)?;
315
316
511
            entropy_image = data
317
511
                .chunks_exact(4)
318
2.01M
                .map(|pixel| {
319
2.01M
                    let meta_huff_code = (u16::from(pixel[0]) << 8) | u16::from(pixel[1]);
320
2.01M
                    if u32::from(meta_huff_code) >= num_huff_groups {
321
904
                        num_huff_groups = u32::from(meta_huff_code) + 1;
322
2.01M
                    }
323
2.01M
                    meta_huff_code
324
2.01M
                })
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
Line
Count
Source
318
1.94M
                .map(|pixel| {
319
1.94M
                    let meta_huff_code = (u16::from(pixel[0]) << 8) | u16::from(pixel[1]);
320
1.94M
                    if u32::from(meta_huff_code) >= num_huff_groups {
321
447
                        num_huff_groups = u32::from(meta_huff_code) + 1;
322
1.94M
                    }
323
1.94M
                    meta_huff_code
324
1.94M
                })
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes::{closure#0}
Line
Count
Source
318
74.2k
                .map(|pixel| {
319
74.2k
                    let meta_huff_code = (u16::from(pixel[0]) << 8) | u16::from(pixel[1]);
320
74.2k
                    if u32::from(meta_huff_code) >= num_huff_groups {
321
457
                        num_huff_groups = u32::from(meta_huff_code) + 1;
322
73.7k
                    }
323
74.2k
                    meta_huff_code
324
74.2k
                })
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::read_huffman_codes::{closure#0}
325
511
                .collect::<Vec<u16>>();
326
5.62k
        }
327
328
6.13k
        let mut hufftree_groups = Vec::new();
329
330
32.7k
        for _i in 0..num_huff_groups {
331
32.7k
            let mut group: HuffmanCodeGroup = Default::default();
332
195k
            for j in 0..HUFFMAN_CODES_PER_META_CODE {
333
162k
                let mut alphabet_size = ALPHABET_SIZE[j];
334
162k
                if j == 0 {
335
32.7k
                    if let Some(color_cache) = color_cache.as_ref() {
336
8.33k
                        alphabet_size += 1 << color_cache.color_cache_bits;
337
24.4k
                    }
338
129k
                }
339
340
162k
                let tree = self.read_huffman_code(alphabet_size)?;
341
162k
                group[j] = tree;
342
            }
343
32.2k
            hufftree_groups.push(group);
344
        }
345
346
5.61k
        let huffman_mask = if huffman_bits == 0 {
347
5.41k
            !0
348
        } else {
349
200
            (1 << huffman_bits) - 1
350
        };
351
352
5.61k
        let info = HuffmanInfo {
353
5.61k
            xsize: huffman_xsize,
354
5.61k
            _ysize: huffman_ysize,
355
5.61k
            color_cache,
356
5.61k
            image: entropy_image,
357
5.61k
            bits: huffman_bits,
358
5.61k
            mask: huffman_mask,
359
5.61k
            huffman_code_groups: hufftree_groups,
360
5.61k
        };
361
362
5.61k
        Ok(info)
363
6.17k
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
Line
Count
Source
293
4.74k
    fn read_huffman_codes(
294
4.74k
        &mut self,
295
4.74k
        read_meta: bool,
296
4.74k
        xsize: u16,
297
4.74k
        ysize: u16,
298
4.74k
        color_cache: Option<ColorCache>,
299
4.74k
    ) -> Result<HuffmanInfo, DecodingError> {
300
4.74k
        let mut num_huff_groups = 1u32;
301
302
4.74k
        let mut huffman_bits = 0;
303
4.74k
        let mut huffman_xsize = 1;
304
4.74k
        let mut huffman_ysize = 1;
305
4.74k
        let mut entropy_image = Vec::new();
306
307
4.74k
        if read_meta && self.bit_reader.read_bits::<u8>(1)? == 1 {
308
            //meta huffman codes
309
287
            huffman_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
310
287
            huffman_xsize = subsample_size(xsize, huffman_bits);
311
287
            huffman_ysize = subsample_size(ysize, huffman_bits);
312
313
287
            let mut data = vec![0; usize::from(huffman_xsize) * usize::from(huffman_ysize) * 4];
314
287
            self.decode_image_stream(huffman_xsize, huffman_ysize, false, &mut data)?;
315
316
275
            entropy_image = data
317
275
                .chunks_exact(4)
318
275
                .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
275
                .collect::<Vec<u16>>();
326
4.46k
        }
327
328
4.73k
        let mut hufftree_groups = Vec::new();
329
330
24.7k
        for _i in 0..num_huff_groups {
331
24.7k
            let mut group: HuffmanCodeGroup = Default::default();
332
147k
            for j in 0..HUFFMAN_CODES_PER_META_CODE {
333
123k
                let mut alphabet_size = ALPHABET_SIZE[j];
334
123k
                if j == 0 {
335
24.7k
                    if let Some(color_cache) = color_cache.as_ref() {
336
7.60k
                        alphabet_size += 1 << color_cache.color_cache_bits;
337
17.1k
                    }
338
98.6k
                }
339
340
123k
                let tree = self.read_huffman_code(alphabet_size)?;
341
123k
                group[j] = tree;
342
            }
343
24.5k
            hufftree_groups.push(group);
344
        }
345
346
4.48k
        let huffman_mask = if huffman_bits == 0 {
347
4.42k
            !0
348
        } else {
349
58
            (1 << huffman_bits) - 1
350
        };
351
352
4.48k
        let info = HuffmanInfo {
353
4.48k
            xsize: huffman_xsize,
354
4.48k
            _ysize: huffman_ysize,
355
4.48k
            color_cache,
356
4.48k
            image: entropy_image,
357
4.48k
            bits: huffman_bits,
358
4.48k
            mask: huffman_mask,
359
4.48k
            huffman_code_groups: hufftree_groups,
360
4.48k
        };
361
362
4.48k
        Ok(info)
363
4.74k
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_codes
Line
Count
Source
293
1.42k
    fn read_huffman_codes(
294
1.42k
        &mut self,
295
1.42k
        read_meta: bool,
296
1.42k
        xsize: u16,
297
1.42k
        ysize: u16,
298
1.42k
        color_cache: Option<ColorCache>,
299
1.42k
    ) -> Result<HuffmanInfo, DecodingError> {
300
1.42k
        let mut num_huff_groups = 1u32;
301
302
1.42k
        let mut huffman_bits = 0;
303
1.42k
        let mut huffman_xsize = 1;
304
1.42k
        let mut huffman_ysize = 1;
305
1.42k
        let mut entropy_image = Vec::new();
306
307
1.42k
        if read_meta && self.bit_reader.read_bits::<u8>(1)? == 1 {
308
            //meta huffman codes
309
258
            huffman_bits = self.bit_reader.read_bits::<u8>(3)? + 2;
310
258
            huffman_xsize = subsample_size(xsize, huffman_bits);
311
258
            huffman_ysize = subsample_size(ysize, huffman_bits);
312
313
258
            let mut data = vec![0; usize::from(huffman_xsize) * usize::from(huffman_ysize) * 4];
314
258
            self.decode_image_stream(huffman_xsize, huffman_ysize, false, &mut data)?;
315
316
236
            entropy_image = data
317
236
                .chunks_exact(4)
318
236
                .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
236
                .collect::<Vec<u16>>();
326
1.16k
        }
327
328
1.39k
        let mut hufftree_groups = Vec::new();
329
330
8.01k
        for _i in 0..num_huff_groups {
331
8.01k
            let mut group: HuffmanCodeGroup = Default::default();
332
47.1k
            for j in 0..HUFFMAN_CODES_PER_META_CODE {
333
39.3k
                let mut alphabet_size = ALPHABET_SIZE[j];
334
39.3k
                if j == 0 {
335
8.01k
                    if let Some(color_cache) = color_cache.as_ref() {
336
730
                        alphabet_size += 1 << color_cache.color_cache_bits;
337
7.28k
                    }
338
31.3k
                }
339
340
39.3k
                let tree = self.read_huffman_code(alphabet_size)?;
341
39.1k
                group[j] = tree;
342
            }
343
7.74k
            hufftree_groups.push(group);
344
        }
345
346
1.13k
        let huffman_mask = if huffman_bits == 0 {
347
991
            !0
348
        } else {
349
142
            (1 << huffman_bits) - 1
350
        };
351
352
1.13k
        let info = HuffmanInfo {
353
1.13k
            xsize: huffman_xsize,
354
1.13k
            _ysize: huffman_ysize,
355
1.13k
            color_cache,
356
1.13k
            image: entropy_image,
357
1.13k
            bits: huffman_bits,
358
1.13k
            mask: huffman_mask,
359
1.13k
            huffman_code_groups: hufftree_groups,
360
1.13k
        };
361
362
1.13k
        Ok(info)
363
1.42k
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::read_huffman_codes
364
365
    /// Decodes and returns a single huffman tree
366
162k
    fn read_huffman_code(&mut self, alphabet_size: u16) -> Result<HuffmanTree, DecodingError> {
367
162k
        let simple = self.bit_reader.read_bits::<u8>(1)? == 1;
368
369
162k
        if simple {
370
148k
            let num_symbols = self.bit_reader.read_bits::<u8>(1)? + 1;
371
372
148k
            let is_first_8bits = self.bit_reader.read_bits::<u8>(1)?;
373
148k
            let zero_symbol = self.bit_reader.read_bits::<u16>(1 + 7 * is_first_8bits)?;
374
375
148k
            if zero_symbol >= alphabet_size {
376
9
                return Err(DecodingError::BitStreamError);
377
148k
            }
378
379
148k
            if num_symbols == 1 {
380
140k
                Ok(HuffmanTree::build_single_node(zero_symbol))
381
            } else {
382
8.06k
                let one_symbol = self.bit_reader.read_bits::<u16>(8)?;
383
8.04k
                if one_symbol >= alphabet_size {
384
14
                    return Err(DecodingError::BitStreamError);
385
8.03k
                }
386
8.03k
                Ok(HuffmanTree::build_two_node(zero_symbol, one_symbol))
387
            }
388
        } else {
389
14.4k
            let mut code_length_code_lengths = vec![0; CODE_LENGTH_CODES];
390
391
14.4k
            let num_code_lengths = 4 + self.bit_reader.read_bits::<usize>(4)?;
392
192k
            for i in 0..num_code_lengths {
393
192k
                code_length_code_lengths[CODE_LENGTH_CODE_ORDER[i]] =
394
192k
                    self.bit_reader.read_bits(3)?;
395
            }
396
397
14.0k
            let new_code_lengths =
398
14.3k
                self.read_huffman_code_lengths(code_length_code_lengths, alphabet_size)?;
399
400
14.0k
            HuffmanTree::build_implicit(new_code_lengths)
401
        }
402
162k
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
Line
Count
Source
366
123k
    fn read_huffman_code(&mut self, alphabet_size: u16) -> Result<HuffmanTree, DecodingError> {
367
123k
        let simple = self.bit_reader.read_bits::<u8>(1)? == 1;
368
369
123k
        if simple {
370
110k
            let num_symbols = self.bit_reader.read_bits::<u8>(1)? + 1;
371
372
110k
            let is_first_8bits = self.bit_reader.read_bits::<u8>(1)?;
373
110k
            let zero_symbol = self.bit_reader.read_bits::<u16>(1 + 7 * is_first_8bits)?;
374
375
110k
            if zero_symbol >= alphabet_size {
376
5
                return Err(DecodingError::BitStreamError);
377
110k
            }
378
379
110k
            if num_symbols == 1 {
380
104k
                Ok(HuffmanTree::build_single_node(zero_symbol))
381
            } else {
382
5.93k
                let one_symbol = self.bit_reader.read_bits::<u16>(8)?;
383
5.92k
                if one_symbol >= alphabet_size {
384
3
                    return Err(DecodingError::BitStreamError);
385
5.91k
                }
386
5.91k
                Ok(HuffmanTree::build_two_node(zero_symbol, one_symbol))
387
            }
388
        } else {
389
12.6k
            let mut code_length_code_lengths = vec![0; CODE_LENGTH_CODES];
390
391
12.6k
            let num_code_lengths = 4 + self.bit_reader.read_bits::<usize>(4)?;
392
176k
            for i in 0..num_code_lengths {
393
176k
                code_length_code_lengths[CODE_LENGTH_CODE_ORDER[i]] =
394
176k
                    self.bit_reader.read_bits(3)?;
395
            }
396
397
12.5k
            let new_code_lengths =
398
12.6k
                self.read_huffman_code_lengths(code_length_code_lengths, alphabet_size)?;
399
400
12.5k
            HuffmanTree::build_implicit(new_code_lengths)
401
        }
402
123k
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code
Line
Count
Source
366
39.3k
    fn read_huffman_code(&mut self, alphabet_size: u16) -> Result<HuffmanTree, DecodingError> {
367
39.3k
        let simple = self.bit_reader.read_bits::<u8>(1)? == 1;
368
369
39.3k
        if simple {
370
37.5k
            let num_symbols = self.bit_reader.read_bits::<u8>(1)? + 1;
371
372
37.5k
            let is_first_8bits = self.bit_reader.read_bits::<u8>(1)?;
373
37.5k
            let zero_symbol = self.bit_reader.read_bits::<u16>(1 + 7 * is_first_8bits)?;
374
375
37.5k
            if zero_symbol >= alphabet_size {
376
4
                return Err(DecodingError::BitStreamError);
377
37.5k
            }
378
379
37.5k
            if num_symbols == 1 {
380
35.4k
                Ok(HuffmanTree::build_single_node(zero_symbol))
381
            } else {
382
2.13k
                let one_symbol = self.bit_reader.read_bits::<u16>(8)?;
383
2.12k
                if one_symbol >= alphabet_size {
384
11
                    return Err(DecodingError::BitStreamError);
385
2.11k
                }
386
2.11k
                Ok(HuffmanTree::build_two_node(zero_symbol, one_symbol))
387
            }
388
        } else {
389
1.78k
            let mut code_length_code_lengths = vec![0; CODE_LENGTH_CODES];
390
391
1.78k
            let num_code_lengths = 4 + self.bit_reader.read_bits::<usize>(4)?;
392
15.9k
            for i in 0..num_code_lengths {
393
15.8k
                code_length_code_lengths[CODE_LENGTH_CODE_ORDER[i]] =
394
15.9k
                    self.bit_reader.read_bits(3)?;
395
            }
396
397
1.59k
            let new_code_lengths =
398
1.76k
                self.read_huffman_code_lengths(code_length_code_lengths, alphabet_size)?;
399
400
1.59k
            HuffmanTree::build_implicit(new_code_lengths)
401
        }
402
39.3k
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::read_huffman_code
403
404
    /// Reads huffman code lengths
405
14.3k
    fn read_huffman_code_lengths(
406
14.3k
        &mut self,
407
14.3k
        code_length_code_lengths: Vec<u16>,
408
14.3k
        num_symbols: u16,
409
14.3k
    ) -> Result<Vec<u16>, DecodingError> {
410
14.3k
        let table = HuffmanTree::build_implicit(code_length_code_lengths)?;
411
412
14.1k
        let mut max_symbol = if self.bit_reader.read_bits::<u8>(1)? == 1 {
413
9.14k
            let length_nbits = 2 + 2 * self.bit_reader.read_bits::<u8>(3)?;
414
9.13k
            let max_minus_two = self.bit_reader.read_bits::<u16>(length_nbits)?;
415
9.13k
            if max_minus_two > num_symbols - 2 {
416
0
                return Err(DecodingError::BitStreamError);
417
9.13k
            }
418
9.13k
            2 + max_minus_two
419
        } else {
420
5.01k
            num_symbols
421
        };
422
423
14.1k
        let mut code_lengths = vec![0; usize::from(num_symbols)];
424
14.1k
        let mut prev_code_len = 8; //default code length
425
426
14.1k
        let mut symbol = 0;
427
1.88M
        while symbol < num_symbols {
428
1.87M
            if max_symbol == 0 {
429
4.26k
                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.81M
                code_lengths[usize::from(symbol)] = code_len;
438
1.81M
                symbol += 1;
439
1.81M
                if code_len != 0 {
440
890k
                    prev_code_len = code_len;
441
927k
                }
442
            } else {
443
48.5k
                let use_prev = code_len == 16;
444
48.5k
                let slot = code_len - 16;
445
48.5k
                let extra_bits = match slot {
446
27.5k
                    0 => 2,
447
6.90k
                    1 => 3,
448
14.1k
                    2 => 7,
449
0
                    _ => return Err(DecodingError::BitStreamError),
450
                };
451
48.5k
                let repeat_offset = match slot {
452
34.4k
                    0 | 1 => 3,
453
14.1k
                    2 => 11,
454
0
                    _ => return Err(DecodingError::BitStreamError),
455
                };
456
457
48.5k
                let mut repeat = self.bit_reader.read_bits::<u16>(extra_bits)? + repeat_offset;
458
459
48.5k
                if symbol + repeat > num_symbols {
460
35
                    return Err(DecodingError::BitStreamError);
461
48.4k
                }
462
463
48.4k
                let length = if use_prev { prev_code_len } else { 0 };
464
1.15M
                while repeat > 0 {
465
1.10M
                    repeat -= 1;
466
1.10M
                    code_lengths[usize::from(symbol)] = length;
467
1.10M
                    symbol += 1;
468
1.10M
                }
469
            }
470
        }
471
472
14.0k
        Ok(code_lengths)
473
14.3k
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
Line
Count
Source
405
12.6k
    fn read_huffman_code_lengths(
406
12.6k
        &mut self,
407
12.6k
        code_length_code_lengths: Vec<u16>,
408
12.6k
        num_symbols: u16,
409
12.6k
    ) -> Result<Vec<u16>, DecodingError> {
410
12.6k
        let table = HuffmanTree::build_implicit(code_length_code_lengths)?;
411
412
12.5k
        let mut max_symbol = if self.bit_reader.read_bits::<u8>(1)? == 1 {
413
8.52k
            let length_nbits = 2 + 2 * self.bit_reader.read_bits::<u8>(3)?;
414
8.52k
            let max_minus_two = self.bit_reader.read_bits::<u16>(length_nbits)?;
415
8.52k
            if max_minus_two > num_symbols - 2 {
416
0
                return Err(DecodingError::BitStreamError);
417
8.52k
            }
418
8.52k
            2 + max_minus_two
419
        } else {
420
4.01k
            num_symbols
421
        };
422
423
12.5k
        let mut code_lengths = vec![0; usize::from(num_symbols)];
424
12.5k
        let mut prev_code_len = 8; //default code length
425
426
12.5k
        let mut symbol = 0;
427
1.84M
        while symbol < num_symbols {
428
1.83M
            if max_symbol == 0 {
429
3.64k
                break;
430
1.83M
            }
431
1.83M
            max_symbol -= 1;
432
433
1.83M
            self.bit_reader.fill()?;
434
1.83M
            let code_len = table.read_symbol(&mut self.bit_reader)?;
435
436
1.83M
            if code_len < 16 {
437
1.79M
                code_lengths[usize::from(symbol)] = code_len;
438
1.79M
                symbol += 1;
439
1.79M
                if code_len != 0 {
440
868k
                    prev_code_len = code_len;
441
925k
                }
442
            } else {
443
40.4k
                let use_prev = code_len == 16;
444
40.4k
                let slot = code_len - 16;
445
40.4k
                let extra_bits = match slot {
446
23.9k
                    0 => 2,
447
5.61k
                    1 => 3,
448
10.9k
                    2 => 7,
449
0
                    _ => return Err(DecodingError::BitStreamError),
450
                };
451
40.4k
                let repeat_offset = match slot {
452
29.5k
                    0 | 1 => 3,
453
10.9k
                    2 => 11,
454
0
                    _ => return Err(DecodingError::BitStreamError),
455
                };
456
457
40.4k
                let mut repeat = self.bit_reader.read_bits::<u16>(extra_bits)? + repeat_offset;
458
459
40.4k
                if symbol + repeat > num_symbols {
460
19
                    return Err(DecodingError::BitStreamError);
461
40.4k
                }
462
463
40.4k
                let length = if use_prev { prev_code_len } else { 0 };
464
883k
                while repeat > 0 {
465
842k
                    repeat -= 1;
466
842k
                    code_lengths[usize::from(symbol)] = length;
467
842k
                    symbol += 1;
468
842k
                }
469
            }
470
        }
471
472
12.5k
        Ok(code_lengths)
473
12.6k
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_huffman_code_lengths
Line
Count
Source
405
1.76k
    fn read_huffman_code_lengths(
406
1.76k
        &mut self,
407
1.76k
        code_length_code_lengths: Vec<u16>,
408
1.76k
        num_symbols: u16,
409
1.76k
    ) -> Result<Vec<u16>, DecodingError> {
410
1.76k
        let table = HuffmanTree::build_implicit(code_length_code_lengths)?;
411
412
1.62k
        let mut max_symbol = if self.bit_reader.read_bits::<u8>(1)? == 1 {
413
617
            let length_nbits = 2 + 2 * self.bit_reader.read_bits::<u8>(3)?;
414
617
            let max_minus_two = self.bit_reader.read_bits::<u16>(length_nbits)?;
415
615
            if max_minus_two > num_symbols - 2 {
416
0
                return Err(DecodingError::BitStreamError);
417
615
            }
418
615
            2 + max_minus_two
419
        } else {
420
1.00k
            num_symbols
421
        };
422
423
1.62k
        let mut code_lengths = vec![0; usize::from(num_symbols)];
424
1.62k
        let mut prev_code_len = 8; //default code length
425
426
1.62k
        let mut symbol = 0;
427
34.3k
        while symbol < num_symbols {
428
33.3k
            if max_symbol == 0 {
429
614
                break;
430
32.7k
            }
431
32.7k
            max_symbol -= 1;
432
433
32.7k
            self.bit_reader.fill()?;
434
32.7k
            let code_len = table.read_symbol(&mut self.bit_reader)?;
435
436
32.7k
            if code_len < 16 {
437
24.7k
                code_lengths[usize::from(symbol)] = code_len;
438
24.7k
                symbol += 1;
439
24.7k
                if code_len != 0 {
440
22.4k
                    prev_code_len = code_len;
441
22.4k
                }
442
            } else {
443
8.05k
                let use_prev = code_len == 16;
444
8.05k
                let slot = code_len - 16;
445
8.05k
                let extra_bits = match slot {
446
3.58k
                    0 => 2,
447
1.29k
                    1 => 3,
448
3.18k
                    2 => 7,
449
0
                    _ => return Err(DecodingError::BitStreamError),
450
                };
451
8.05k
                let repeat_offset = match slot {
452
4.87k
                    0 | 1 => 3,
453
3.18k
                    2 => 11,
454
0
                    _ => return Err(DecodingError::BitStreamError),
455
                };
456
457
8.05k
                let mut repeat = self.bit_reader.read_bits::<u16>(extra_bits)? + repeat_offset;
458
459
8.05k
                if symbol + repeat > num_symbols {
460
16
                    return Err(DecodingError::BitStreamError);
461
8.03k
                }
462
463
8.03k
                let length = if use_prev { prev_code_len } else { 0 };
464
273k
                while repeat > 0 {
465
265k
                    repeat -= 1;
466
265k
                    code_lengths[usize::from(symbol)] = length;
467
265k
                    symbol += 1;
468
265k
                }
469
            }
470
        }
471
472
1.59k
        Ok(code_lengths)
473
1.76k
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::read_huffman_code_lengths
474
475
    /// Decodes the image data using the huffman trees and either of the 3 methods of decoding
476
5.61k
    fn decode_image_data(
477
5.61k
        &mut self,
478
5.61k
        width: u16,
479
5.61k
        height: u16,
480
5.61k
        mut huffman_info: HuffmanInfo,
481
5.61k
        data: &mut [u8],
482
5.61k
    ) -> Result<(), DecodingError> {
483
5.61k
        let num_values = usize::from(width) * usize::from(height);
484
485
5.61k
        let huff_index = huffman_info.get_huff_index(0, 0);
486
5.61k
        let mut tree = &huffman_info.huffman_code_groups[huff_index];
487
5.61k
        let mut index = 0;
488
489
5.61k
        let mut next_block_start = 0;
490
35.5M
        while index < num_values {
491
35.5M
            self.bit_reader.fill()?;
492
493
35.5M
            if index >= next_block_start {
494
1.56M
                let x = index % usize::from(width);
495
1.56M
                let y = index / usize::from(width);
496
1.56M
                next_block_start = (x | usize::from(huffman_info.mask)).min(usize::from(width - 1))
497
1.56M
                    + y * usize::from(width)
498
1.56M
                    + 1;
499
500
1.56M
                let huff_index = huffman_info.get_huff_index(x as u16, y as u16);
501
1.56M
                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
3.62M
                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
2.74M
                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
883k
                if tree[..4].iter().all(|t| t.is_single_node()) {
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::decode_image_data::{closure#0}
508
679k
                    let code = tree[GREEN].read_symbol(&mut self.bit_reader)?;
509
679k
                    if code < 256 {
510
679k
                        let n = if huffman_info.bits == 0 {
511
2.11k
                            num_values
512
                        } else {
513
677k
                            next_block_start - index
514
                        };
515
516
679k
                        let red = tree[RED].read_symbol(&mut self.bit_reader)?;
517
679k
                        let blue = tree[BLUE].read_symbol(&mut self.bit_reader)?;
518
679k
                        let alpha = tree[ALPHA].read_symbol(&mut self.bit_reader)?;
519
679k
                        let value = [red as u8, code as u8, blue as u8, alpha as u8];
520
521
125M
                        for i in 0..n {
522
125M
                            data[index * 4 + i * 4..][..4].copy_from_slice(&value);
523
125M
                        }
524
525
679k
                        if let Some(color_cache) = huffman_info.color_cache.as_mut() {
526
143k
                            color_cache.insert(value);
527
535k
                        }
528
529
679k
                        index += n;
530
679k
                        continue;
531
0
                    }
532
882k
                }
533
34.0M
            }
534
535
34.9M
            let code = tree[GREEN].read_symbol(&mut self.bit_reader)?;
536
537
            //check code
538
34.9M
            if code < 256 {
539
                //literal, so just use huffman codes and read as argb
540
22.5M
                let green = code as u8;
541
22.5M
                let red = tree[RED].read_symbol(&mut self.bit_reader)? as u8;
542
22.5M
                let blue = tree[BLUE].read_symbol(&mut self.bit_reader)? as u8;
543
22.5M
                if self.bit_reader.nbits < 15 {
544
5.16k
                    self.bit_reader.fill()?;
545
22.5M
                }
546
22.5M
                let alpha = tree[ALPHA].read_symbol(&mut self.bit_reader)? as u8;
547
548
22.5M
                data[index * 4] = red;
549
22.5M
                data[index * 4 + 1] = green;
550
22.5M
                data[index * 4 + 2] = blue;
551
22.5M
                data[index * 4 + 3] = alpha;
552
553
22.5M
                if let Some(color_cache) = huffman_info.color_cache.as_mut() {
554
6.81M
                    color_cache.insert([red, green, blue, alpha]);
555
15.7M
                }
556
22.5M
                index += 1;
557
12.3M
            } else if code < 256 + 24 {
558
                //backward reference, so go back and use that to add image data
559
8.12M
                let length_symbol = code - 256;
560
8.12M
                let length = Self::get_copy_distance(&mut self.bit_reader, length_symbol)?;
561
562
8.12M
                let dist_symbol = tree[DIST].read_symbol(&mut self.bit_reader)?;
563
8.12M
                let dist_code = Self::get_copy_distance(&mut self.bit_reader, dist_symbol)?;
564
8.12M
                let dist = Self::plane_code_to_distance(width, dist_code);
565
566
8.12M
                if index < dist || num_values - index < length {
567
124
                    return Err(DecodingError::BitStreamError);
568
8.12M
                }
569
570
8.12M
                if dist == 1 {
571
4.23M
                    let value: [u8; 4] = data[(index - dist) * 4..][..4].try_into().unwrap();
572
2.17G
                    for i in 0..length {
573
2.17G
                        data[index * 4 + i * 4..][..4].copy_from_slice(&value);
574
2.17G
                    }
575
                } else {
576
3.89M
                    if index + length + 3 <= num_values {
577
3.89M
                        let start = (index - dist) * 4;
578
3.89M
                        data.copy_within(start..start + 16, index * 4);
579
580
3.89M
                        if length > 4 || dist < 4 {
581
280M
                            for i in (0..length * 4).step_by((dist * 4).min(16)).skip(1) {
582
280M
                                data.copy_within(start + i..start + i + 16, index * 4 + i);
583
280M
                            }
584
11.8k
                        }
585
                    } else {
586
74.7k
                        for i in 0..length * 4 {
587
74.7k
                            data[index * 4 + i] = data[index * 4 + i - dist * 4];
588
74.7k
                        }
589
                    }
590
591
3.89M
                    if let Some(color_cache) = huffman_info.color_cache.as_mut() {
592
1.12G
                        for pixel in data[index * 4..][..length * 4].chunks_exact(4) {
593
1.12G
                            color_cache.insert(pixel.try_into().unwrap());
594
1.12G
                        }
595
35.5k
                    }
596
                }
597
8.12M
                index += length;
598
            } else {
599
                //color cache, so use previously stored pixels to get this pixel
600
4.25M
                let color_cache = huffman_info
601
4.25M
                    .color_cache
602
4.25M
                    .as_mut()
603
4.25M
                    .ok_or(DecodingError::BitStreamError)?;
604
4.25M
                let color = color_cache.lookup((code - 280).into());
605
4.25M
                data[index * 4..][..4].copy_from_slice(&color);
606
4.25M
                index += 1;
607
608
4.25M
                if index < next_block_start {
609
4.25M
                    if let Some((bits, code)) = tree[GREEN].peek_symbol(&self.bit_reader) {
610
4.25M
                        if code >= 280 {
611
1.47M
                            self.bit_reader.consume(bits)?;
612
1.47M
                            data[index * 4..][..4]
613
1.47M
                                .copy_from_slice(&color_cache.lookup((code - 280).into()));
614
1.47M
                            index += 1;
615
2.78M
                        }
616
584
                    }
617
4.75k
                }
618
            }
619
        }
620
621
5.13k
        Ok(())
622
5.61k
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
Line
Count
Source
476
4.48k
    fn decode_image_data(
477
4.48k
        &mut self,
478
4.48k
        width: u16,
479
4.48k
        height: u16,
480
4.48k
        mut huffman_info: HuffmanInfo,
481
4.48k
        data: &mut [u8],
482
4.48k
    ) -> Result<(), DecodingError> {
483
4.48k
        let num_values = usize::from(width) * usize::from(height);
484
485
4.48k
        let huff_index = huffman_info.get_huff_index(0, 0);
486
4.48k
        let mut tree = &huffman_info.huffman_code_groups[huff_index];
487
4.48k
        let mut index = 0;
488
489
4.48k
        let mut next_block_start = 0;
490
22.4M
        while index < num_values {
491
22.4M
            self.bit_reader.fill()?;
492
493
22.4M
            if index >= next_block_start {
494
971k
                let x = index % usize::from(width);
495
971k
                let y = index / usize::from(width);
496
971k
                next_block_start = (x | usize::from(huffman_info.mask)).min(usize::from(width - 1))
497
971k
                    + y * usize::from(width)
498
971k
                    + 1;
499
500
971k
                let huff_index = huffman_info.get_huff_index(x as u16, y as u16);
501
971k
                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
971k
                if tree[..4].iter().all(|t| t.is_single_node()) {
508
590k
                    let code = tree[GREEN].read_symbol(&mut self.bit_reader)?;
509
590k
                    if code < 256 {
510
590k
                        let n = if huffman_info.bits == 0 {
511
1.94k
                            num_values
512
                        } else {
513
588k
                            next_block_start - index
514
                        };
515
516
590k
                        let red = tree[RED].read_symbol(&mut self.bit_reader)?;
517
590k
                        let blue = tree[BLUE].read_symbol(&mut self.bit_reader)?;
518
590k
                        let alpha = tree[ALPHA].read_symbol(&mut self.bit_reader)?;
519
590k
                        let value = [red as u8, code as u8, blue as u8, alpha as u8];
520
521
91.9M
                        for i in 0..n {
522
91.9M
                            data[index * 4 + i * 4..][..4].copy_from_slice(&value);
523
91.9M
                        }
524
525
590k
                        if let Some(color_cache) = huffman_info.color_cache.as_mut() {
526
143k
                            color_cache.insert(value);
527
447k
                        }
528
529
590k
                        index += n;
530
590k
                        continue;
531
0
                    }
532
381k
                }
533
21.5M
            }
534
535
21.9M
            let code = tree[GREEN].read_symbol(&mut self.bit_reader)?;
536
537
            //check code
538
21.9M
            if code < 256 {
539
                //literal, so just use huffman codes and read as argb
540
18.7M
                let green = code as u8;
541
18.7M
                let red = tree[RED].read_symbol(&mut self.bit_reader)? as u8;
542
18.7M
                let blue = tree[BLUE].read_symbol(&mut self.bit_reader)? as u8;
543
18.7M
                if self.bit_reader.nbits < 15 {
544
4.85k
                    self.bit_reader.fill()?;
545
18.7M
                }
546
18.7M
                let alpha = tree[ALPHA].read_symbol(&mut self.bit_reader)? as u8;
547
548
18.7M
                data[index * 4] = red;
549
18.7M
                data[index * 4 + 1] = green;
550
18.7M
                data[index * 4 + 2] = blue;
551
18.7M
                data[index * 4 + 3] = alpha;
552
553
18.7M
                if let Some(color_cache) = huffman_info.color_cache.as_mut() {
554
3.25M
                    color_cache.insert([red, green, blue, alpha]);
555
15.4M
                }
556
18.7M
                index += 1;
557
3.16M
            } else if code < 256 + 24 {
558
                //backward reference, so go back and use that to add image data
559
1.61M
                let length_symbol = code - 256;
560
1.61M
                let length = Self::get_copy_distance(&mut self.bit_reader, length_symbol)?;
561
562
1.61M
                let dist_symbol = tree[DIST].read_symbol(&mut self.bit_reader)?;
563
1.61M
                let dist_code = Self::get_copy_distance(&mut self.bit_reader, dist_symbol)?;
564
1.61M
                let dist = Self::plane_code_to_distance(width, dist_code);
565
566
1.61M
                if index < dist || num_values - index < length {
567
27
                    return Err(DecodingError::BitStreamError);
568
1.61M
                }
569
570
1.61M
                if dist == 1 {
571
986k
                    let value: [u8; 4] = data[(index - dist) * 4..][..4].try_into().unwrap();
572
1.78G
                    for i in 0..length {
573
1.78G
                        data[index * 4 + i * 4..][..4].copy_from_slice(&value);
574
1.78G
                    }
575
                } else {
576
625k
                    if index + length + 3 <= num_values {
577
625k
                        let start = (index - dist) * 4;
578
625k
                        data.copy_within(start..start + 16, index * 4);
579
580
625k
                        if length > 4 || dist < 4 {
581
182M
                            for i in (0..length * 4).step_by((dist * 4).min(16)).skip(1) {
582
182M
                                data.copy_within(start + i..start + i + 16, index * 4 + i);
583
182M
                            }
584
9.39k
                        }
585
                    } else {
586
16.9k
                        for i in 0..length * 4 {
587
16.9k
                            data[index * 4 + i] = data[index * 4 + i - dist * 4];
588
16.9k
                        }
589
                    }
590
591
625k
                    if let Some(color_cache) = huffman_info.color_cache.as_mut() {
592
729M
                        for pixel in data[index * 4..][..length * 4].chunks_exact(4) {
593
729M
                            color_cache.insert(pixel.try_into().unwrap());
594
729M
                        }
595
7.86k
                    }
596
                }
597
1.61M
                index += length;
598
            } else {
599
                //color cache, so use previously stored pixels to get this pixel
600
1.55M
                let color_cache = huffman_info
601
1.55M
                    .color_cache
602
1.55M
                    .as_mut()
603
1.55M
                    .ok_or(DecodingError::BitStreamError)?;
604
1.55M
                let color = color_cache.lookup((code - 280).into());
605
1.55M
                data[index * 4..][..4].copy_from_slice(&color);
606
1.55M
                index += 1;
607
608
1.55M
                if index < next_block_start {
609
1.55M
                    if let Some((bits, code)) = tree[GREEN].peek_symbol(&self.bit_reader) {
610
1.55M
                        if code >= 280 {
611
736k
                            self.bit_reader.consume(bits)?;
612
736k
                            data[index * 4..][..4]
613
736k
                                .copy_from_slice(&color_cache.lookup((code - 280).into()));
614
736k
                            index += 1;
615
814k
                        }
616
562
                    }
617
3.09k
                }
618
            }
619
        }
620
621
4.26k
        Ok(())
622
4.48k
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::decode_image_data
Line
Count
Source
476
1.13k
    fn decode_image_data(
477
1.13k
        &mut self,
478
1.13k
        width: u16,
479
1.13k
        height: u16,
480
1.13k
        mut huffman_info: HuffmanInfo,
481
1.13k
        data: &mut [u8],
482
1.13k
    ) -> Result<(), DecodingError> {
483
1.13k
        let num_values = usize::from(width) * usize::from(height);
484
485
1.13k
        let huff_index = huffman_info.get_huff_index(0, 0);
486
1.13k
        let mut tree = &huffman_info.huffman_code_groups[huff_index];
487
1.13k
        let mut index = 0;
488
489
1.13k
        let mut next_block_start = 0;
490
13.0M
        while index < num_values {
491
13.0M
            self.bit_reader.fill()?;
492
493
13.0M
            if index >= next_block_start {
494
590k
                let x = index % usize::from(width);
495
590k
                let y = index / usize::from(width);
496
590k
                next_block_start = (x | usize::from(huffman_info.mask)).min(usize::from(width - 1))
497
590k
                    + y * usize::from(width)
498
590k
                    + 1;
499
500
590k
                let huff_index = huffman_info.get_huff_index(x as u16, y as u16);
501
590k
                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
590k
                if tree[..4].iter().all(|t| t.is_single_node()) {
508
88.8k
                    let code = tree[GREEN].read_symbol(&mut self.bit_reader)?;
509
88.8k
                    if code < 256 {
510
88.8k
                        let n = if huffman_info.bits == 0 {
511
178
                            num_values
512
                        } else {
513
88.6k
                            next_block_start - index
514
                        };
515
516
88.8k
                        let red = tree[RED].read_symbol(&mut self.bit_reader)?;
517
88.8k
                        let blue = tree[BLUE].read_symbol(&mut self.bit_reader)?;
518
88.8k
                        let alpha = tree[ALPHA].read_symbol(&mut self.bit_reader)?;
519
88.8k
                        let value = [red as u8, code as u8, blue as u8, alpha as u8];
520
521
33.8M
                        for i in 0..n {
522
33.8M
                            data[index * 4 + i * 4..][..4].copy_from_slice(&value);
523
33.8M
                        }
524
525
88.8k
                        if let Some(color_cache) = huffman_info.color_cache.as_mut() {
526
46
                            color_cache.insert(value);
527
88.7k
                        }
528
529
88.8k
                        index += n;
530
88.8k
                        continue;
531
0
                    }
532
501k
                }
533
12.5M
            }
534
535
13.0M
            let code = tree[GREEN].read_symbol(&mut self.bit_reader)?;
536
537
            //check code
538
13.0M
            if code < 256 {
539
                //literal, so just use huffman codes and read as argb
540
3.78M
                let green = code as u8;
541
3.78M
                let red = tree[RED].read_symbol(&mut self.bit_reader)? as u8;
542
3.78M
                let blue = tree[BLUE].read_symbol(&mut self.bit_reader)? as u8;
543
3.78M
                if self.bit_reader.nbits < 15 {
544
306
                    self.bit_reader.fill()?;
545
3.78M
                }
546
3.78M
                let alpha = tree[ALPHA].read_symbol(&mut self.bit_reader)? as u8;
547
548
3.78M
                data[index * 4] = red;
549
3.78M
                data[index * 4 + 1] = green;
550
3.78M
                data[index * 4 + 2] = blue;
551
3.78M
                data[index * 4 + 3] = alpha;
552
553
3.78M
                if let Some(color_cache) = huffman_info.color_cache.as_mut() {
554
3.55M
                    color_cache.insert([red, green, blue, alpha]);
555
3.55M
                }
556
3.78M
                index += 1;
557
9.21M
            } else if code < 256 + 24 {
558
                //backward reference, so go back and use that to add image data
559
6.51M
                let length_symbol = code - 256;
560
6.51M
                let length = Self::get_copy_distance(&mut self.bit_reader, length_symbol)?;
561
562
6.51M
                let dist_symbol = tree[DIST].read_symbol(&mut self.bit_reader)?;
563
6.51M
                let dist_code = Self::get_copy_distance(&mut self.bit_reader, dist_symbol)?;
564
6.51M
                let dist = Self::plane_code_to_distance(width, dist_code);
565
566
6.51M
                if index < dist || num_values - index < length {
567
97
                    return Err(DecodingError::BitStreamError);
568
6.51M
                }
569
570
6.51M
                if dist == 1 {
571
3.24M
                    let value: [u8; 4] = data[(index - dist) * 4..][..4].try_into().unwrap();
572
395M
                    for i in 0..length {
573
395M
                        data[index * 4 + i * 4..][..4].copy_from_slice(&value);
574
395M
                    }
575
                } else {
576
3.27M
                    if index + length + 3 <= num_values {
577
3.27M
                        let start = (index - dist) * 4;
578
3.27M
                        data.copy_within(start..start + 16, index * 4);
579
580
3.27M
                        if length > 4 || dist < 4 {
581
98.2M
                            for i in (0..length * 4).step_by((dist * 4).min(16)).skip(1) {
582
98.2M
                                data.copy_within(start + i..start + i + 16, index * 4 + i);
583
98.2M
                            }
584
2.42k
                        }
585
                    } else {
586
57.8k
                        for i in 0..length * 4 {
587
57.8k
                            data[index * 4 + i] = data[index * 4 + i - dist * 4];
588
57.8k
                        }
589
                    }
590
591
3.27M
                    if let Some(color_cache) = huffman_info.color_cache.as_mut() {
592
399M
                        for pixel in data[index * 4..][..length * 4].chunks_exact(4) {
593
399M
                            color_cache.insert(pixel.try_into().unwrap());
594
399M
                        }
595
27.6k
                    }
596
                }
597
6.51M
                index += length;
598
            } else {
599
                //color cache, so use previously stored pixels to get this pixel
600
2.70M
                let color_cache = huffman_info
601
2.70M
                    .color_cache
602
2.70M
                    .as_mut()
603
2.70M
                    .ok_or(DecodingError::BitStreamError)?;
604
2.70M
                let color = color_cache.lookup((code - 280).into());
605
2.70M
                data[index * 4..][..4].copy_from_slice(&color);
606
2.70M
                index += 1;
607
608
2.70M
                if index < next_block_start {
609
2.70M
                    if let Some((bits, code)) = tree[GREEN].peek_symbol(&self.bit_reader) {
610
2.70M
                        if code >= 280 {
611
733k
                            self.bit_reader.consume(bits)?;
612
733k
                            data[index * 4..][..4]
613
733k
                                .copy_from_slice(&color_cache.lookup((code - 280).into()));
614
733k
                            index += 1;
615
1.96M
                        }
616
22
                    }
617
1.66k
                }
618
            }
619
        }
620
621
869
        Ok(())
622
1.13k
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::decode_image_data
623
624
    /// Reads color cache data from the bitstream
625
6.18k
    fn read_color_cache(&mut self) -> Result<Option<u8>, DecodingError> {
626
6.18k
        if self.bit_reader.read_bits::<u8>(1)? == 1 {
627
821
            let code_bits = self.bit_reader.read_bits::<u8>(4)?;
628
629
820
            if !(1..=11).contains(&code_bits) {
630
9
                return Err(DecodingError::InvalidColorCacheBits(code_bits));
631
811
            }
632
633
811
            Ok(Some(code_bits))
634
        } else {
635
5.35k
            Ok(None)
636
        }
637
6.18k
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
Line
Count
Source
625
4.75k
    fn read_color_cache(&mut self) -> Result<Option<u8>, DecodingError> {
626
4.75k
        if self.bit_reader.read_bits::<u8>(1)? == 1 {
627
475
            let code_bits = self.bit_reader.read_bits::<u8>(4)?;
628
629
475
            if !(1..=11).contains(&code_bits) {
630
4
                return Err(DecodingError::InvalidColorCacheBits(code_bits));
631
471
            }
632
633
471
            Ok(Some(code_bits))
634
        } else {
635
4.27k
            Ok(None)
636
        }
637
4.75k
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_color_cache
Line
Count
Source
625
1.42k
    fn read_color_cache(&mut self) -> Result<Option<u8>, DecodingError> {
626
1.42k
        if self.bit_reader.read_bits::<u8>(1)? == 1 {
627
346
            let code_bits = self.bit_reader.read_bits::<u8>(4)?;
628
629
345
            if !(1..=11).contains(&code_bits) {
630
5
                return Err(DecodingError::InvalidColorCacheBits(code_bits));
631
340
            }
632
633
340
            Ok(Some(code_bits))
634
        } else {
635
1.08k
            Ok(None)
636
        }
637
1.42k
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::read_color_cache
638
639
    /// Gets the copy distance from the prefix code and bitstream
640
16.2M
    fn get_copy_distance(
641
16.2M
        bit_reader: &mut BitReader<R>,
642
16.2M
        prefix_code: u16,
643
16.2M
    ) -> Result<usize, DecodingError> {
644
16.2M
        if prefix_code < 4 {
645
4.60M
            return Ok(usize::from(prefix_code + 1));
646
11.6M
        }
647
11.6M
        let extra_bits: u8 = ((prefix_code - 2) >> 1).try_into().unwrap();
648
11.6M
        let offset = (2 + (usize::from(prefix_code) & 1)) << extra_bits;
649
650
11.6M
        let bits = bit_reader.peek(extra_bits) as usize;
651
11.6M
        bit_reader.consume(extra_bits)?;
652
653
11.6M
        Ok(offset + bits + 1)
654
16.2M
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
Line
Count
Source
640
3.22M
    fn get_copy_distance(
641
3.22M
        bit_reader: &mut BitReader<R>,
642
3.22M
        prefix_code: u16,
643
3.22M
    ) -> Result<usize, DecodingError> {
644
3.22M
        if prefix_code < 4 {
645
1.11M
            return Ok(usize::from(prefix_code + 1));
646
2.10M
        }
647
2.10M
        let extra_bits: u8 = ((prefix_code - 2) >> 1).try_into().unwrap();
648
2.10M
        let offset = (2 + (usize::from(prefix_code) & 1)) << extra_bits;
649
650
2.10M
        let bits = bit_reader.peek(extra_bits) as usize;
651
2.10M
        bit_reader.consume(extra_bits)?;
652
653
2.10M
        Ok(offset + bits + 1)
654
3.22M
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::get_copy_distance
Line
Count
Source
640
13.0M
    fn get_copy_distance(
641
13.0M
        bit_reader: &mut BitReader<R>,
642
13.0M
        prefix_code: u16,
643
13.0M
    ) -> Result<usize, DecodingError> {
644
13.0M
        if prefix_code < 4 {
645
3.48M
            return Ok(usize::from(prefix_code + 1));
646
9.54M
        }
647
9.54M
        let extra_bits: u8 = ((prefix_code - 2) >> 1).try_into().unwrap();
648
9.54M
        let offset = (2 + (usize::from(prefix_code) & 1)) << extra_bits;
649
650
9.54M
        let bits = bit_reader.peek(extra_bits) as usize;
651
9.54M
        bit_reader.consume(extra_bits)?;
652
653
9.54M
        Ok(offset + bits + 1)
654
13.0M
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::get_copy_distance
655
656
    /// Gets distance to pixel
657
8.12M
    fn plane_code_to_distance(xsize: u16, plane_code: usize) -> usize {
658
8.12M
        if plane_code > 120 {
659
3.65M
            plane_code - 120
660
        } else {
661
4.47M
            let (xoffset, yoffset) = DISTANCE_MAP[plane_code - 1];
662
663
4.47M
            let dist = i32::from(xoffset) + i32::from(yoffset) * i32::from(xsize);
664
4.47M
            if dist < 1 {
665
0
                return 1;
666
4.47M
            }
667
4.47M
            dist.try_into().unwrap()
668
        }
669
8.12M
    }
<image_webp::lossless::LosslessDecoder<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
Line
Count
Source
657
1.61M
    fn plane_code_to_distance(xsize: u16, plane_code: usize) -> usize {
658
1.61M
        if plane_code > 120 {
659
616k
            plane_code - 120
660
        } else {
661
995k
            let (xoffset, yoffset) = DISTANCE_MAP[plane_code - 1];
662
663
995k
            let dist = i32::from(xoffset) + i32::from(yoffset) * i32::from(xsize);
664
995k
            if dist < 1 {
665
0
                return 1;
666
995k
            }
667
995k
            dist.try_into().unwrap()
668
        }
669
1.61M
    }
<image_webp::lossless::LosslessDecoder<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::plane_code_to_distance
Line
Count
Source
657
6.51M
    fn plane_code_to_distance(xsize: u16, plane_code: usize) -> usize {
658
6.51M
        if plane_code > 120 {
659
3.03M
            plane_code - 120
660
        } else {
661
3.48M
            let (xoffset, yoffset) = DISTANCE_MAP[plane_code - 1];
662
663
3.48M
            let dist = i32::from(xoffset) + i32::from(yoffset) * i32::from(xsize);
664
3.48M
            if dist < 1 {
665
0
                return 1;
666
3.48M
            }
667
3.48M
            dist.try_into().unwrap()
668
        }
669
6.51M
    }
Unexecuted instantiation: <image_webp::lossless::LosslessDecoder<_>>::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.56M
    fn get_huff_index(&self, x: u16, y: u16) -> usize {
685
1.56M
        if self.bits == 0 {
686
852k
            return 0;
687
715k
        }
688
715k
        let position =
689
715k
            usize::from(y >> self.bits) * usize::from(self.xsize) + usize::from(x >> self.bits);
690
715k
        let meta_huff_code: usize = usize::from(self.image[position]);
691
715k
        meta_huff_code
692
1.56M
    }
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.13G
    fn insert(&mut self, color: [u8; 4]) {
704
1.13G
        let [r, g, b, a] = color;
705
1.13G
        let color_u32 =
706
1.13G
            (u32::from(r) << 16) | (u32::from(g) << 8) | (u32::from(b)) | (u32::from(a) << 24);
707
1.13G
        let index = (0x1e35a7bdu32.wrapping_mul(color_u32)) >> (32 - self.color_cache_bits);
708
1.13G
        self.color_cache[index as usize] = color;
709
1.13G
    }
710
711
    #[inline(always)]
712
5.72M
    fn lookup(&self, index: usize) -> [u8; 4] {
713
5.72M
        self.color_cache[index]
714
5.72M
    }
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
3.03k
    const fn new(reader: R) -> Self {
726
3.03k
        Self {
727
3.03k
            reader,
728
3.03k
            buffer: 0,
729
3.03k
            nbits: 0,
730
3.03k
        }
731
3.03k
    }
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Line
Count
Source
725
2.35k
    const fn new(reader: R) -> Self {
726
2.35k
        Self {
727
2.35k
            reader,
728
2.35k
            buffer: 0,
729
2.35k
            nbits: 0,
730
2.35k
        }
731
2.35k
    }
<image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::new
Line
Count
Source
725
674
    const fn new(reader: R) -> Self {
726
674
        Self {
727
674
            reader,
728
674
            buffer: 0,
729
674
            nbits: 0,
730
674
        }
731
674
    }
Unexecuted instantiation: <image_webp::lossless::BitReader<_>>::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
37.4M
    pub(crate) fn fill(&mut self) -> Result<(), DecodingError> {
738
37.4M
        debug_assert!(self.nbits < 64);
739
740
37.4M
        let mut buf = self.reader.fill_buf()?;
741
37.4M
        if buf.len() >= 8 {
742
37.2M
            let lookahead = u64::from_le_bytes(buf[..8].try_into().unwrap());
743
37.2M
            self.reader.consume(usize::from((63 - self.nbits) / 8));
744
37.2M
            self.buffer |= lookahead << self.nbits;
745
37.2M
            self.nbits |= 56;
746
37.2M
        } else {
747
218k
            while !buf.is_empty() && self.nbits < 56 {
748
15.5k
                self.buffer |= u64::from(buf[0]) << self.nbits;
749
15.5k
                self.nbits += 8;
750
15.5k
                self.reader.consume(1);
751
15.5k
                buf = self.reader.fill_buf()?;
752
            }
753
        }
754
755
37.4M
        Ok(())
756
37.4M
    }
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
Line
Count
Source
737
24.3M
    pub(crate) fn fill(&mut self) -> Result<(), DecodingError> {
738
24.3M
        debug_assert!(self.nbits < 64);
739
740
24.3M
        let mut buf = self.reader.fill_buf()?;
741
24.3M
        if buf.len() >= 8 {
742
24.1M
            let lookahead = u64::from_le_bytes(buf[..8].try_into().unwrap());
743
24.1M
            self.reader.consume(usize::from((63 - self.nbits) / 8));
744
24.1M
            self.buffer |= lookahead << self.nbits;
745
24.1M
            self.nbits |= 56;
746
24.1M
        } else {
747
193k
            while !buf.is_empty() && self.nbits < 56 {
748
12.6k
                self.buffer |= u64::from(buf[0]) << self.nbits;
749
12.6k
                self.nbits += 8;
750
12.6k
                self.reader.consume(1);
751
12.6k
                buf = self.reader.fill_buf()?;
752
            }
753
        }
754
755
24.3M
        Ok(())
756
24.3M
    }
<image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::fill
Line
Count
Source
737
13.1M
    pub(crate) fn fill(&mut self) -> Result<(), DecodingError> {
738
13.1M
        debug_assert!(self.nbits < 64);
739
740
13.1M
        let mut buf = self.reader.fill_buf()?;
741
13.1M
        if buf.len() >= 8 {
742
13.1M
            let lookahead = u64::from_le_bytes(buf[..8].try_into().unwrap());
743
13.1M
            self.reader.consume(usize::from((63 - self.nbits) / 8));
744
13.1M
            self.buffer |= lookahead << self.nbits;
745
13.1M
            self.nbits |= 56;
746
13.1M
        } else {
747
24.8k
            while !buf.is_empty() && self.nbits < 56 {
748
2.88k
                self.buffer |= u64::from(buf[0]) << self.nbits;
749
2.88k
                self.nbits += 8;
750
2.88k
                self.reader.consume(1);
751
2.88k
                buf = self.reader.fill_buf()?;
752
            }
753
        }
754
755
13.1M
        Ok(())
756
13.1M
    }
Unexecuted instantiation: <image_webp::lossless::BitReader<_>>::fill
757
758
    /// Peeks at the next `num` bits in the buffer.
759
12.5M
    pub(crate) const fn peek(&self, num: u8) -> u64 {
760
12.5M
        self.buffer & ((1 << num) - 1)
761
12.5M
    }
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
Line
Count
Source
759
2.85M
    pub(crate) const fn peek(&self, num: u8) -> u64 {
760
2.85M
        self.buffer & ((1 << num) - 1)
761
2.85M
    }
<image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek
Line
Count
Source
759
9.73M
    pub(crate) const fn peek(&self, num: u8) -> u64 {
760
9.73M
        self.buffer & ((1 << num) - 1)
761
9.73M
    }
Unexecuted instantiation: <image_webp::lossless::BitReader<_>>::peek
762
763
    /// Peeks at the full buffer.
764
107M
    pub(crate) const fn peek_full(&self) -> u64 {
765
107M
        self.buffer
766
107M
    }
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
Line
Count
Source
764
81.5M
    pub(crate) const fn peek_full(&self) -> u64 {
765
81.5M
        self.buffer
766
81.5M
    }
<image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::peek_full
Line
Count
Source
764
25.7M
    pub(crate) const fn peek_full(&self) -> u64 {
765
25.7M
        self.buffer
766
25.7M
    }
Unexecuted instantiation: <image_webp::lossless::BitReader<_>>::peek_full
767
768
    /// Consumes `num` bits from the buffer returning an error if there are not enough bits.
769
117M
    pub(crate) fn consume(&mut self, num: u8) -> Result<(), DecodingError> {
770
117M
        if self.nbits < num {
771
541
            return Err(DecodingError::BitStreamError);
772
117M
        }
773
774
117M
        self.buffer >>= num;
775
117M
        self.nbits -= num;
776
117M
        Ok(())
777
117M
    }
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
Line
Count
Source
769
83.5M
    pub(crate) fn consume(&mut self, num: u8) -> Result<(), DecodingError> {
770
83.5M
        if self.nbits < num {
771
296
            return Err(DecodingError::BitStreamError);
772
83.5M
        }
773
774
83.5M
        self.buffer >>= num;
775
83.5M
        self.nbits -= num;
776
83.5M
        Ok(())
777
83.5M
    }
<image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::consume
Line
Count
Source
769
33.4M
    pub(crate) fn consume(&mut self, num: u8) -> Result<(), DecodingError> {
770
33.4M
        if self.nbits < num {
771
245
            return Err(DecodingError::BitStreamError);
772
33.4M
        }
773
774
33.4M
        self.buffer >>= num;
775
33.4M
        self.nbits -= num;
776
33.4M
        Ok(())
777
33.4M
    }
Unexecuted instantiation: <image_webp::lossless::BitReader<_>>::consume
778
779
    /// Convenience function to read a number of bits and convert them to a type.
780
940k
    pub(crate) fn read_bits<T: TryFrom<u32>>(&mut self, num: u8) -> Result<T, DecodingError> {
781
940k
        debug_assert!(num as usize <= 8 * mem::size_of::<T>());
782
940k
        debug_assert!(num <= 32);
783
784
940k
        if self.nbits < num {
785
25.0k
            self.fill()?;
786
915k
        }
787
940k
        let value = self.peek(num) as u32;
788
940k
        self.consume(num)?;
789
790
940k
        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}
794
940k
    }
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Line
Count
Source
780
393k
    pub(crate) fn read_bits<T: TryFrom<u32>>(&mut self, num: u8) -> Result<T, DecodingError> {
781
393k
        debug_assert!(num as usize <= 8 * mem::size_of::<T>());
782
393k
        debug_assert!(num <= 32);
783
784
393k
        if self.nbits < num {
785
8.23k
            self.fill()?;
786
385k
        }
787
393k
        let value = self.peek(num) as u32;
788
393k
        self.consume(num)?;
789
790
393k
        value.try_into().map_err(|_| {
791
            debug_assert!(false, "Value too large to fit in type");
792
            DecodingError::BitStreamError
793
        })
794
393k
    }
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Line
Count
Source
780
12.6k
    pub(crate) fn read_bits<T: TryFrom<u32>>(&mut self, num: u8) -> Result<T, DecodingError> {
781
12.6k
        debug_assert!(num as usize <= 8 * mem::size_of::<T>());
782
12.6k
        debug_assert!(num <= 32);
783
784
12.6k
        if self.nbits < num {
785
126
            self.fill()?;
786
12.5k
        }
787
12.6k
        let value = self.peek(num) as u32;
788
12.6k
        self.consume(num)?;
789
790
12.6k
        value.try_into().map_err(|_| {
791
            debug_assert!(false, "Value too large to fit in type");
792
            DecodingError::BitStreamError
793
        })
794
12.6k
    }
<image_webp::lossless::BitReader<std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
Line
Count
Source
780
346k
    pub(crate) fn read_bits<T: TryFrom<u32>>(&mut self, num: u8) -> Result<T, DecodingError> {
781
346k
        debug_assert!(num as usize <= 8 * mem::size_of::<T>());
782
346k
        debug_assert!(num <= 32);
783
784
346k
        if self.nbits < num {
785
12.9k
            self.fill()?;
786
333k
        }
787
346k
        let value = self.peek(num) as u32;
788
346k
        self.consume(num)?;
789
790
346k
        value.try_into().map_err(|_| {
791
            debug_assert!(false, "Value too large to fit in type");
792
            DecodingError::BitStreamError
793
        })
794
346k
    }
<image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u8>
Line
Count
Source
780
121k
    pub(crate) fn read_bits<T: TryFrom<u32>>(&mut self, num: u8) -> Result<T, DecodingError> {
781
121k
        debug_assert!(num as usize <= 8 * mem::size_of::<T>());
782
121k
        debug_assert!(num <= 32);
783
784
121k
        if self.nbits < num {
785
2.79k
            self.fill()?;
786
118k
        }
787
121k
        let value = self.peek(num) as u32;
788
121k
        self.consume(num)?;
789
790
121k
        value.try_into().map_err(|_| {
791
            debug_assert!(false, "Value too large to fit in type");
792
            DecodingError::BitStreamError
793
        })
794
121k
    }
<image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<usize>
Line
Count
Source
780
1.78k
    pub(crate) fn read_bits<T: TryFrom<u32>>(&mut self, num: u8) -> Result<T, DecodingError> {
781
1.78k
        debug_assert!(num as usize <= 8 * mem::size_of::<T>());
782
1.78k
        debug_assert!(num <= 32);
783
784
1.78k
        if self.nbits < num {
785
3
            self.fill()?;
786
1.78k
        }
787
1.78k
        let value = self.peek(num) as u32;
788
1.78k
        self.consume(num)?;
789
790
1.78k
        value.try_into().map_err(|_| {
791
            debug_assert!(false, "Value too large to fit in type");
792
            DecodingError::BitStreamError
793
        })
794
1.78k
    }
<image_webp::lossless::BitReader<&mut std::io::Take<&mut std::io::cursor::Cursor<&[u8]>>>>::read_bits::<u16>
Line
Count
Source
780
64.5k
    pub(crate) fn read_bits<T: TryFrom<u32>>(&mut self, num: u8) -> Result<T, DecodingError> {
781
64.5k
        debug_assert!(num as usize <= 8 * mem::size_of::<T>());
782
64.5k
        debug_assert!(num <= 32);
783
784
64.5k
        if self.nbits < num {
785
946
            self.fill()?;
786
63.6k
        }
787
64.5k
        let value = self.peek(num) as u32;
788
64.5k
        self.consume(num)?;
789
790
64.5k
        value.try_into().map_err(|_| {
791
            debug_assert!(false, "Value too large to fit in type");
792
            DecodingError::BitStreamError
793
        })
794
64.5k
    }
Unexecuted instantiation: <image_webp::lossless::BitReader<_>>::read_bits::<_>
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
}