/src/libjxl/lib/jxl/dec_huffman.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) the JPEG XL Project Authors. All rights reserved. |
2 | | // |
3 | | // Use of this source code is governed by a BSD-style |
4 | | // license that can be found in the LICENSE file. |
5 | | |
6 | | #include "lib/jxl/dec_huffman.h" |
7 | | |
8 | | #include <jxl/types.h> |
9 | | #include <string.h> /* for memset */ |
10 | | |
11 | | #include <vector> |
12 | | |
13 | | #include "lib/jxl/ans_params.h" |
14 | | #include "lib/jxl/base/bits.h" |
15 | | #include "lib/jxl/huffman_table.h" |
16 | | |
17 | | namespace jxl { |
18 | | |
19 | | static const int kCodeLengthCodes = 18; |
20 | | static const uint8_t kCodeLengthCodeOrder[kCodeLengthCodes] = { |
21 | | 1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15, |
22 | | }; |
23 | | static const uint8_t kDefaultCodeLength = 8; |
24 | | static const uint8_t kCodeLengthRepeatCode = 16; |
25 | | |
26 | | JXL_BOOL ReadHuffmanCodeLengths(const uint8_t* code_length_code_lengths, |
27 | | int num_symbols, uint8_t* code_lengths, |
28 | 4.75k | BitReader* br) { |
29 | 4.75k | int symbol = 0; |
30 | 4.75k | uint8_t prev_code_len = kDefaultCodeLength; |
31 | 4.75k | int repeat = 0; |
32 | 4.75k | uint8_t repeat_code_len = 0; |
33 | 4.75k | int space = 32768; |
34 | 4.75k | HuffmanCode table[32]; |
35 | | |
36 | 4.75k | uint16_t counts[16] = {0}; |
37 | 90.3k | for (int i = 0; i < kCodeLengthCodes; ++i) { |
38 | 85.6k | ++counts[code_length_code_lengths[i]]; |
39 | 85.6k | } |
40 | 4.75k | if (!BuildHuffmanTable(table, 5, code_length_code_lengths, kCodeLengthCodes, |
41 | 4.75k | &counts[0])) { |
42 | 0 | return JXL_FALSE; |
43 | 0 | } |
44 | | |
45 | 99.4k | while (symbol < num_symbols && space > 0) { |
46 | 94.7k | const HuffmanCode* p = table; |
47 | 94.7k | uint8_t code_len; |
48 | 94.7k | br->Refill(); |
49 | 94.7k | p += br->PeekFixedBits<5>(); |
50 | 94.7k | br->Consume(p->bits); |
51 | 94.7k | code_len = static_cast<uint8_t>(p->value); |
52 | 94.7k | if (code_len < kCodeLengthRepeatCode) { |
53 | 88.2k | repeat = 0; |
54 | 88.2k | code_lengths[symbol++] = code_len; |
55 | 88.2k | if (code_len != 0) { |
56 | 62.5k | prev_code_len = code_len; |
57 | 62.5k | space -= 32768u >> code_len; |
58 | 62.5k | } |
59 | 88.2k | } else { |
60 | 6.48k | const int extra_bits = code_len - 14; |
61 | 6.48k | int old_repeat; |
62 | 6.48k | int repeat_delta; |
63 | 6.48k | uint8_t new_len = 0; |
64 | 6.48k | if (code_len == kCodeLengthRepeatCode) { |
65 | 242 | new_len = prev_code_len; |
66 | 242 | } |
67 | 6.48k | if (repeat_code_len != new_len) { |
68 | 250 | repeat = 0; |
69 | 250 | repeat_code_len = new_len; |
70 | 250 | } |
71 | 6.48k | old_repeat = repeat; |
72 | 6.48k | if (repeat > 0) { |
73 | 4.10k | repeat -= 2; |
74 | 4.10k | repeat <<= extra_bits; |
75 | 4.10k | } |
76 | 6.48k | repeat += static_cast<int>(br->ReadBits(extra_bits) + 3); |
77 | 6.48k | repeat_delta = repeat - old_repeat; |
78 | 6.48k | if (symbol + repeat_delta > num_symbols) { |
79 | 0 | return 0; |
80 | 0 | } |
81 | 6.48k | memset(&code_lengths[symbol], repeat_code_len, |
82 | 6.48k | static_cast<size_t>(repeat_delta)); |
83 | 6.48k | symbol += repeat_delta; |
84 | 6.48k | if (repeat_code_len != 0) { |
85 | 242 | space -= repeat_delta << (15 - repeat_code_len); |
86 | 242 | } |
87 | 6.48k | } |
88 | 94.7k | } |
89 | 4.75k | if (space != 0) { |
90 | 132 | return JXL_FALSE; |
91 | 132 | } |
92 | 4.62k | memset(&code_lengths[symbol], 0, static_cast<size_t>(num_symbols - symbol)); |
93 | 4.62k | return JXL_TRUE; |
94 | 4.75k | } |
95 | | |
96 | | static JXL_INLINE bool ReadSimpleCode(size_t alphabet_size, BitReader* br, |
97 | 8.36k | HuffmanCode* table) { |
98 | 8.36k | size_t max_bits = |
99 | 8.36k | (alphabet_size > 1u) ? FloorLog2Nonzero(alphabet_size - 1u) + 1 : 0; |
100 | | |
101 | 8.36k | size_t num_symbols = br->ReadFixedBits<2>() + 1; |
102 | | |
103 | 8.36k | uint16_t symbols[4] = {0}; |
104 | 31.8k | for (size_t i = 0; i < num_symbols; ++i) { |
105 | 23.4k | uint16_t symbol = br->ReadBits(max_bits); |
106 | 23.4k | if (symbol >= alphabet_size) { |
107 | 2 | return false; |
108 | 2 | } |
109 | 23.4k | symbols[i] = symbol; |
110 | 23.4k | } |
111 | | |
112 | 22.9k | for (size_t i = 0; i < num_symbols - 1; ++i) { |
113 | 37.0k | for (size_t j = i + 1; j < num_symbols; ++j) { |
114 | 22.5k | if (symbols[i] == symbols[j]) return false; |
115 | 22.5k | } |
116 | 14.8k | } |
117 | | |
118 | | // 4 symbols have to option to encode. |
119 | 8.07k | if (num_symbols == 4) num_symbols += br->ReadFixedBits<1>(); |
120 | | |
121 | 8.07k | const auto swap_symbols = [&symbols](size_t i, size_t j) { |
122 | 7.46k | uint16_t t = symbols[j]; |
123 | 7.46k | symbols[j] = symbols[i]; |
124 | 7.46k | symbols[i] = t; |
125 | 7.46k | }; |
126 | | |
127 | 8.07k | size_t table_size = 1; |
128 | 8.07k | switch (num_symbols) { |
129 | 557 | case 1: |
130 | 557 | table[0] = {0, symbols[0]}; |
131 | 557 | break; |
132 | 1.11k | case 2: |
133 | 1.11k | if (symbols[0] > symbols[1]) swap_symbols(0, 1); |
134 | 1.11k | table[0] = {1, symbols[0]}; |
135 | 1.11k | table[1] = {1, symbols[1]}; |
136 | 1.11k | table_size = 2; |
137 | 1.11k | break; |
138 | 6.06k | case 3: |
139 | 6.06k | if (symbols[1] > symbols[2]) swap_symbols(1, 2); |
140 | 6.06k | table[0] = {1, symbols[0]}; |
141 | 6.06k | table[2] = {1, symbols[0]}; |
142 | 6.06k | table[1] = {2, symbols[1]}; |
143 | 6.06k | table[3] = {2, symbols[2]}; |
144 | 6.06k | table_size = 4; |
145 | 6.06k | break; |
146 | 331 | case 4: { |
147 | 1.32k | for (size_t i = 0; i < 3; ++i) { |
148 | 2.97k | for (size_t j = i + 1; j < 4; ++j) { |
149 | 1.98k | if (symbols[i] > symbols[j]) swap_symbols(i, j); |
150 | 1.98k | } |
151 | 993 | } |
152 | 331 | table[0] = {2, symbols[0]}; |
153 | 331 | table[2] = {2, symbols[1]}; |
154 | 331 | table[1] = {2, symbols[2]}; |
155 | 331 | table[3] = {2, symbols[3]}; |
156 | 331 | table_size = 4; |
157 | 331 | break; |
158 | 0 | } |
159 | 0 | case 5: { |
160 | 0 | if (symbols[2] > symbols[3]) swap_symbols(2, 3); |
161 | 0 | table[0] = {1, symbols[0]}; |
162 | 0 | table[1] = {2, symbols[1]}; |
163 | 0 | table[2] = {1, symbols[0]}; |
164 | 0 | table[3] = {3, symbols[2]}; |
165 | 0 | table[4] = {1, symbols[0]}; |
166 | 0 | table[5] = {2, symbols[1]}; |
167 | 0 | table[6] = {1, symbols[0]}; |
168 | 0 | table[7] = {3, symbols[3]}; |
169 | 0 | table_size = 8; |
170 | 0 | break; |
171 | 0 | } |
172 | 0 | default: { |
173 | | // Unreachable. |
174 | 0 | return false; |
175 | 0 | } |
176 | 8.07k | } |
177 | | |
178 | 8.07k | const uint32_t goal_size = 1u << kHuffmanTableBits; |
179 | 58.7k | while (table_size != goal_size) { |
180 | 50.6k | memcpy(&table[table_size], &table[0], |
181 | 50.6k | static_cast<size_t>(table_size) * sizeof(table[0])); |
182 | 50.6k | table_size <<= 1; |
183 | 50.6k | } |
184 | | |
185 | 8.07k | return true; |
186 | 8.07k | } |
187 | | |
188 | | bool HuffmanDecodingData::ReadFromBitStream(size_t alphabet_size, |
189 | 13.1k | BitReader* br) { |
190 | 13.1k | if (alphabet_size > (1 << PREFIX_MAX_BITS)) return false; |
191 | | |
192 | | /* simple_code_or_skip is used as follows: |
193 | | 1 for simple code; |
194 | | 0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */ |
195 | 13.1k | uint32_t simple_code_or_skip = br->ReadFixedBits<2>(); |
196 | 13.1k | if (simple_code_or_skip == 1u) { |
197 | 8.36k | table_.resize(1u << kHuffmanTableBits); |
198 | 8.36k | return ReadSimpleCode(alphabet_size, br, table_.data()); |
199 | 8.36k | } |
200 | | |
201 | 4.78k | std::vector<uint8_t> code_lengths(alphabet_size, 0); |
202 | 4.78k | uint8_t code_length_code_lengths[kCodeLengthCodes] = {0}; |
203 | 4.78k | int space = 32; |
204 | 4.78k | int num_codes = 0; |
205 | | /* Static Huffman code for the code length code lengths */ |
206 | 4.78k | static const HuffmanCode huff[16] = { |
207 | 4.78k | {2, 0}, {2, 4}, {2, 3}, {3, 2}, {2, 0}, {2, 4}, {2, 3}, {4, 1}, |
208 | 4.78k | {2, 0}, {2, 4}, {2, 3}, {3, 2}, {2, 0}, {2, 4}, {2, 3}, {4, 5}, |
209 | 4.78k | }; |
210 | 50.8k | for (size_t i = simple_code_or_skip; i < kCodeLengthCodes && space > 0; ++i) { |
211 | 46.0k | const int code_len_idx = kCodeLengthCodeOrder[i]; |
212 | 46.0k | const HuffmanCode* p = huff; |
213 | 46.0k | uint8_t v; |
214 | 46.0k | br->Refill(); |
215 | 46.0k | p += br->PeekFixedBits<4>(); |
216 | 46.0k | br->Consume(p->bits); |
217 | 46.0k | v = static_cast<uint8_t>(p->value); |
218 | 46.0k | code_length_code_lengths[code_len_idx] = v; |
219 | 46.0k | if (v != 0) { |
220 | 33.8k | space -= (32u >> v); |
221 | 33.8k | ++num_codes; |
222 | 33.8k | } |
223 | 46.0k | } |
224 | 4.78k | bool ok = |
225 | 4.78k | (num_codes == 1 || space == 0) && |
226 | 4.78k | FROM_JXL_BOOL(ReadHuffmanCodeLengths( |
227 | 4.78k | code_length_code_lengths, alphabet_size, code_lengths.data(), br)); |
228 | | |
229 | 4.78k | if (!ok) return false; |
230 | 4.62k | uint16_t counts[16] = {0}; |
231 | 2.01M | for (size_t i = 0; i < alphabet_size; ++i) { |
232 | 2.01M | ++counts[code_lengths[i]]; |
233 | 2.01M | } |
234 | 4.62k | table_.resize(alphabet_size + 376); |
235 | 4.62k | uint32_t table_size = |
236 | 4.62k | BuildHuffmanTable(table_.data(), kHuffmanTableBits, code_lengths.data(), |
237 | 4.62k | alphabet_size, &counts[0]); |
238 | 4.62k | table_.resize(table_size); |
239 | 4.62k | return (table_size > 0); |
240 | 4.78k | } |
241 | | |
242 | | // Decodes the next Huffman coded symbol from the bit-stream. |
243 | 69.5M | uint16_t HuffmanDecodingData::ReadSymbol(BitReader* br) const { |
244 | 69.5M | size_t n_bits; |
245 | 69.5M | const HuffmanCode* table = table_.data(); |
246 | 69.5M | table += br->PeekBits(kHuffmanTableBits); |
247 | 69.5M | n_bits = table->bits; |
248 | 69.5M | if (n_bits > kHuffmanTableBits) { |
249 | 196k | br->Consume(kHuffmanTableBits); |
250 | 196k | n_bits -= kHuffmanTableBits; |
251 | 196k | table += table->value; |
252 | 196k | table += br->PeekBits(n_bits); |
253 | 196k | } |
254 | 69.5M | br->Consume(table->bits); |
255 | 69.5M | return table->value; |
256 | 69.5M | } |
257 | | |
258 | | } // namespace jxl |