/rust/registry/src/index.crates.io-1949cf8c6b5b557f/zune-jpeg-0.4.21/src/huffman.rs
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2023. |
3 | | * |
4 | | * This software is free software; |
5 | | * |
6 | | * You can redistribute it or modify it under terms of the MIT, Apache License or Zlib license |
7 | | */ |
8 | | |
9 | | //! This file contains a single struct `HuffmanTable` that |
10 | | //! stores Huffman tables needed during `BitStream` decoding. |
11 | | #![allow(clippy::similar_names, clippy::module_name_repetitions)] |
12 | | |
13 | | use alloc::string::ToString; |
14 | | |
15 | | use crate::errors::DecodeErrors; |
16 | | |
17 | | /// Determines how many bits of lookahead we have for our bitstream decoder. |
18 | | |
19 | | pub const HUFF_LOOKAHEAD: u8 = 9; |
20 | | |
21 | | /// A struct which contains necessary tables for decoding a JPEG |
22 | | /// huffman encoded bitstream |
23 | | |
24 | | pub struct HuffmanTable { |
25 | | // element `[0]` of each array is unused |
26 | | /// largest code of length k |
27 | | pub(crate) maxcode: [i32; 18], |
28 | | /// offset for codes of length k |
29 | | /// Answers the question, where do code-lengths of length k end |
30 | | /// Element 0 is unused |
31 | | pub(crate) offset: [i32; 18], |
32 | | /// lookup table for fast decoding |
33 | | /// |
34 | | /// top bits above HUFF_LOOKAHEAD contain the code length. |
35 | | /// |
36 | | /// Lower (8) bits contain the symbol in order of increasing code length. |
37 | | pub(crate) lookup: [i32; 1 << HUFF_LOOKAHEAD], |
38 | | |
39 | | /// A table which can be used to decode small AC coefficients and |
40 | | /// do an equivalent of receive_extend |
41 | | pub(crate) ac_lookup: Option<[i16; 1 << HUFF_LOOKAHEAD]>, |
42 | | |
43 | | /// Directly represent contents of a JPEG DHT marker |
44 | | /// |
45 | | /// \# number of symbols with codes of length `k` bits |
46 | | // bits[0] is unused |
47 | | /// Symbols in order of increasing code length |
48 | | pub(crate) values: [u8; 256] |
49 | | } |
50 | | |
51 | | impl HuffmanTable { |
52 | 45.2k | pub fn new( |
53 | 45.2k | codes: &[u8; 17], values: [u8; 256], is_dc: bool, is_progressive: bool |
54 | 45.2k | ) -> Result<HuffmanTable, DecodeErrors> { |
55 | 45.2k | let too_long_code = (i32::from(HUFF_LOOKAHEAD) + 1) << HUFF_LOOKAHEAD; |
56 | 45.2k | let mut p = HuffmanTable { |
57 | 45.2k | maxcode: [0; 18], |
58 | 45.2k | offset: [0; 18], |
59 | 45.2k | lookup: [too_long_code; 1 << HUFF_LOOKAHEAD], |
60 | 45.2k | values, |
61 | 45.2k | ac_lookup: None |
62 | 45.2k | }; |
63 | | |
64 | 45.2k | p.make_derived_table(is_dc, is_progressive, codes)?; |
65 | | |
66 | 44.9k | Ok(p) |
67 | 45.2k | } |
68 | | |
69 | | /// Create a new huffman tables with values that aren't fixed |
70 | | /// used by fill_mjpeg_tables |
71 | 3.41k | pub fn new_unfilled( |
72 | 3.41k | codes: &[u8; 17], values: &[u8], is_dc: bool, is_progressive: bool |
73 | 3.41k | ) -> Result<HuffmanTable, DecodeErrors> { |
74 | 3.41k | let mut buf = [0; 256]; |
75 | 3.41k | buf[..values.len()].copy_from_slice(values); |
76 | 3.41k | HuffmanTable::new(codes, buf, is_dc, is_progressive) |
77 | 3.41k | } |
78 | | |
79 | | /// Compute derived values for a Huffman table |
80 | | /// |
81 | | /// This routine performs some validation checks on the table |
82 | | #[allow( |
83 | | clippy::cast_possible_truncation, |
84 | | clippy::cast_possible_wrap, |
85 | | clippy::cast_sign_loss, |
86 | | clippy::too_many_lines, |
87 | | clippy::needless_range_loop |
88 | | )] |
89 | 45.2k | fn make_derived_table( |
90 | 45.2k | &mut self, is_dc: bool, _is_progressive: bool, bits: &[u8; 17] |
91 | 45.2k | ) -> Result<(), DecodeErrors> { |
92 | | // build a list of code size |
93 | 45.2k | let mut huff_size = [0; 257]; |
94 | | // Huffman code lengths |
95 | 45.2k | let mut huff_code: [u32; 257] = [0; 257]; |
96 | | // figure C.1 make table of Huffman code length for each symbol |
97 | 45.2k | let mut p = 0; |
98 | | |
99 | 769k | for l in 1..=16 { |
100 | 724k | let mut i = i32::from(bits[l]); |
101 | | // table overrun is checked before ,so we dont need to check |
102 | 1.67M | while i != 0 { |
103 | 954k | huff_size[p] = l as u8; |
104 | 954k | p += 1; |
105 | 954k | i -= 1; |
106 | 954k | } |
107 | | } |
108 | | |
109 | 45.2k | huff_size[p] = 0; |
110 | | |
111 | 45.2k | let num_symbols = p; |
112 | | // Generate the codes themselves |
113 | | // We also validate that the counts represent a legal Huffman code tree |
114 | 45.2k | let mut code = 0; |
115 | 45.2k | let mut si = i32::from(huff_size[0]); |
116 | | |
117 | 45.2k | p = 0; |
118 | | |
119 | 422k | while huff_size[p] != 0 { |
120 | 1.32M | while i32::from(huff_size[p]) == si { |
121 | 951k | huff_code[p] = code; |
122 | 951k | code += 1; |
123 | 951k | p += 1; |
124 | 951k | } |
125 | | // maximum code of length si, pre-shifted by 16-k bits |
126 | 376k | self.maxcode[si as usize] = (code << (16 - si)) as i32; |
127 | | // code is now 1 more than the last code used for code-length si; but |
128 | | // it must still fit in si bits, since no code is allowed to be all ones. |
129 | 376k | if (code as i32) >= (1 << si) { |
130 | 101 | return Err(DecodeErrors::HuffmanDecode("Bad Huffman Table".to_string())); |
131 | 376k | } |
132 | | |
133 | 376k | code <<= 1; |
134 | 376k | si += 1; |
135 | | } |
136 | | |
137 | | // Figure F.15 generate decoding tables for bit-sequential decoding |
138 | 45.1k | p = 0; |
139 | | |
140 | 812k | for l in 0..=16 { |
141 | 767k | if bits[l] == 0 { |
142 | 489k | // -1 if no codes of this length |
143 | 489k | self.maxcode[l] = -1; |
144 | 489k | } else { |
145 | 277k | // offset[l]=codes[index of 1st symbol of code length l |
146 | 277k | // minus minimum code of length l] |
147 | 277k | self.offset[l] = (p as i32) - (huff_code[p]) as i32; |
148 | 277k | p += usize::from(bits[l]); |
149 | 277k | } |
150 | | } |
151 | | |
152 | 45.1k | self.offset[17] = 0; |
153 | | // we ensure that decode terminates |
154 | 45.1k | self.maxcode[17] = 0x000F_FFFF; |
155 | | |
156 | | /* |
157 | | * Compute lookahead tables to speed up decoding. |
158 | | * First we set all the table entries to 0(left justified), indicating "too long"; |
159 | | * (Note too long was set during initialization) |
160 | | * then we iterate through the Huffman codes that are short enough and |
161 | | * fill in all the entries that correspond to bit sequences starting |
162 | | * with that code. |
163 | | */ |
164 | | |
165 | 45.1k | p = 0; |
166 | | |
167 | 451k | for l in 1..=HUFF_LOOKAHEAD { |
168 | 406k | for _ in 1..=i32::from(bits[usize::from(l)]) { |
169 | | // l -> Current code length, |
170 | | // p => Its index in self.code and self.values |
171 | | // Generate left justified code followed by all possible bit sequences |
172 | 489k | let mut look_bits = (huff_code[p] as usize) << (HUFF_LOOKAHEAD - l); |
173 | | |
174 | 16.6M | for _ in 0..1 << (HUFF_LOOKAHEAD - l) { |
175 | 16.6M | self.lookup[look_bits] = |
176 | 16.6M | (i32::from(l) << HUFF_LOOKAHEAD) | i32::from(self.values[p]); |
177 | 16.6M | look_bits += 1; |
178 | 16.6M | } |
179 | | |
180 | 489k | p += 1; |
181 | | } |
182 | | } |
183 | | // build an ac table that does an equivalent of decode and receive_extend |
184 | 45.1k | if !is_dc { |
185 | 18.8k | let mut fast = [255; 1 << HUFF_LOOKAHEAD]; |
186 | | // Iterate over number of symbols |
187 | 693k | for i in 0..num_symbols { |
188 | | // get code size for an item |
189 | 693k | let s = huff_size[i]; |
190 | | |
191 | 693k | if s <= HUFF_LOOKAHEAD { |
192 | | // if it's lower than what we need for our lookup table create the table |
193 | 358k | let c = (huff_code[i] << (HUFF_LOOKAHEAD - s)) as usize; |
194 | 358k | let m = (1 << (HUFF_LOOKAHEAD - s)) as usize; |
195 | | |
196 | 9.05M | for j in 0..m { |
197 | 9.05M | fast[c + j] = i as i16; |
198 | 9.05M | } |
199 | 334k | } |
200 | | } |
201 | | |
202 | | // build a table that decodes both magnitude and value of small ACs in |
203 | | // one go. |
204 | 18.8k | let mut fast_ac = [0; 1 << HUFF_LOOKAHEAD]; |
205 | | |
206 | 9.65M | for i in 0..(1 << HUFF_LOOKAHEAD) { |
207 | 9.65M | let fast_v = fast[i]; |
208 | | |
209 | 9.65M | if fast_v < 255 { |
210 | | // get symbol value from AC table |
211 | 9.05M | let rs = self.values[fast_v as usize]; |
212 | | // shift by 4 to get run length |
213 | 9.05M | let run = i16::from((rs >> 4) & 15); |
214 | | // get magnitude bits stored at the lower 3 bits |
215 | 9.05M | let mag_bits = i16::from(rs & 15); |
216 | | // length of the bit we've read |
217 | 9.05M | let len = i16::from(huff_size[fast_v as usize]); |
218 | | |
219 | 9.05M | if mag_bits != 0 && (len + mag_bits) <= i16::from(HUFF_LOOKAHEAD) { |
220 | | // magnitude code followed by receive_extend code |
221 | 6.13M | let mut k = (((i as i16) << len) & ((1 << HUFF_LOOKAHEAD) - 1)) |
222 | 6.13M | >> (i16::from(HUFF_LOOKAHEAD) - mag_bits); |
223 | 6.13M | let m = 1 << (mag_bits - 1); |
224 | | |
225 | 6.13M | if k < m { |
226 | 3.06M | k += (!0_i16 << mag_bits) + 1; |
227 | 3.06M | }; |
228 | | |
229 | | // if result is small enough fit into fast ac table |
230 | 6.13M | if (-128..=127).contains(&k) { |
231 | 6.13M | fast_ac[i] = (k << 8) + (run << 4) + (len + mag_bits); |
232 | 6.13M | } |
233 | 2.92M | } |
234 | 602k | } |
235 | | } |
236 | 18.8k | self.ac_lookup = Some(fast_ac); |
237 | 26.2k | } |
238 | | |
239 | | // Validate symbols as being reasonable |
240 | | // For AC tables, we make no check, but accept all byte values 0..255 |
241 | | // For DC tables, we require symbols to be in range 0..15 |
242 | 45.1k | if is_dc { |
243 | 233k | for i in 0..num_symbols { |
244 | 233k | let sym = self.values[i]; |
245 | | |
246 | 233k | if sym > 15 { |
247 | 184 | return Err(DecodeErrors::HuffmanDecode("Bad Huffman Table".to_string())); |
248 | 233k | } |
249 | | } |
250 | 18.8k | } |
251 | | |
252 | 44.9k | Ok(()) |
253 | 45.2k | } |
254 | | } |