Coverage Report

Created: 2026-03-12 07:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libjxl/lib/jpegli/huffman.cc
Line
Count
Source
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/jpegli/huffman.h"
7
8
#include <algorithm>
9
#include <cstddef>
10
#include <cstdint>
11
#include <cstring>
12
#include <limits>
13
#include <vector>
14
15
#include "lib/jpegli/common.h"
16
#include "lib/jpegli/common_internal.h"
17
#include "lib/jpegli/error.h"
18
#include "lib/jxl/base/compiler_specific.h"
19
#include "lib/jxl/base/status.h"
20
21
namespace jpegli {
22
23
// Returns the table width of the next 2nd level table, count is the histogram
24
// of bit lengths for the remaining symbols, len is the code length of the next
25
// processed symbol.
26
29.1k
static inline int NextTableBitSize(const int* count, int len) {
27
29.1k
  int left = 1 << (len - kJpegHuffmanRootTableBits);
28
65.5k
  while (len < static_cast<int>(kJpegHuffmanMaxBitLength)) {
29
60.4k
    left -= count[len];
30
60.4k
    if (left <= 0) break;
31
36.3k
    ++len;
32
36.3k
    left <<= 1;
33
36.3k
  }
34
29.1k
  return len - kJpegHuffmanRootTableBits;
35
29.1k
}
36
37
void BuildJpegHuffmanTable(const uint32_t* count, const uint32_t* symbols,
38
10.1k
                           HuffmanTableEntry* lut) {
39
10.1k
  HuffmanTableEntry code;    // current table entry
40
10.1k
  HuffmanTableEntry* table;  // next available space in table
41
10.1k
  int len;                   // current code length
42
10.1k
  int idx;                   // symbol index
43
10.1k
  int key;                   // prefix code
44
10.1k
  int reps;                  // number of replicate key values in current table
45
10.1k
  int low;                   // low bits for current root entry
46
10.1k
  int table_bits;            // key length of current table
47
10.1k
  int table_size;            // size of current table
48
49
  // Make a local copy of the input bit length histogram.
50
10.1k
  int tmp_count[kJpegHuffmanMaxBitLength + 1] = {0};
51
10.1k
  int total_count = 0;
52
172k
  for (len = 1; len <= static_cast<int>(kJpegHuffmanMaxBitLength); ++len) {
53
162k
    tmp_count[len] = count[len];
54
162k
    total_count += tmp_count[len];
55
162k
  }
56
57
10.1k
  table = lut;
58
10.1k
  table_bits = kJpegHuffmanRootTableBits;
59
10.1k
  table_size = 1 << table_bits;
60
61
  // Special case code with only one value.
62
10.1k
  if (total_count == 1) {
63
60
    code.bits = 0;
64
60
    code.value = symbols[0];
65
15.4k
    for (key = 0; key < table_size; ++key) {
66
15.3k
      table[key] = code;
67
15.3k
    }
68
60
    return;
69
60
  }
70
71
  // Fill in root table.
72
10.0k
  key = 0;
73
10.0k
  idx = 0;
74
90.8k
  for (len = 1; len <= kJpegHuffmanRootTableBits; ++len) {
75
216k
    for (; tmp_count[len] > 0; --tmp_count[len]) {
76
135k
      code.bits = len;
77
135k
      code.value = symbols[idx++];
78
135k
      reps = 1 << (kJpegHuffmanRootTableBits - len);
79
2.61M
      while (reps--) {
80
2.48M
        table[key++] = code;
81
2.48M
      }
82
135k
    }
83
80.7k
  }
84
85
  // Fill in 2nd level tables and add pointers to root table.
86
10.0k
  table += table_size;
87
10.0k
  table_size = 0;
88
10.0k
  low = 0;
89
10.0k
  for (len = kJpegHuffmanRootTableBits + 1;
90
90.8k
       len <= static_cast<int>(kJpegHuffmanMaxBitLength); ++len) {
91
758k
    for (; tmp_count[len] > 0; --tmp_count[len]) {
92
      // Start a new sub-table if the previous one is full.
93
677k
      if (low >= table_size) {
94
29.1k
        table += table_size;
95
29.1k
        table_bits = NextTableBitSize(tmp_count, len);
96
29.1k
        table_size = 1 << table_bits;
97
29.1k
        low = 0;
98
29.1k
        lut[key].bits = table_bits + kJpegHuffmanRootTableBits;
99
29.1k
        lut[key].value = (table - lut) - key;
100
29.1k
        ++key;
101
29.1k
      }
102
677k
      code.bits = len - kJpegHuffmanRootTableBits;
103
677k
      code.value = symbols[idx++];
104
677k
      reps = 1 << (table_bits - code.bits);
105
1.99M
      while (reps--) {
106
1.31M
        table[low++] = code;
107
1.31M
      }
108
677k
    }
109
80.7k
  }
110
10.0k
}
111
112
// A node of a Huffman tree.
113
struct HuffmanTree {
114
  HuffmanTree(uint32_t count, int16_t left, int16_t right)
115
0
      : total_count(count), index_left(left), index_right_or_value(right) {}
116
  uint32_t total_count;
117
  int16_t index_left;
118
  int16_t index_right_or_value;
119
};
120
121
void SetDepth(const HuffmanTree& p, HuffmanTree* pool, uint8_t* depth,
122
0
              uint8_t level) {
123
0
  if (p.index_left >= 0) {
124
0
    ++level;
125
0
    SetDepth(pool[p.index_left], pool, depth, level);
126
0
    SetDepth(pool[p.index_right_or_value], pool, depth, level);
127
0
  } else {
128
0
    depth[p.index_right_or_value] = level;
129
0
  }
130
0
}
131
132
// Compare the root nodes, least popular first; indices are in decreasing order
133
// before sorting is applied.
134
0
static JXL_INLINE bool Compare(const HuffmanTree& v0, const HuffmanTree& v1) {
135
0
  return v0.total_count != v1.total_count
136
0
             ? v0.total_count < v1.total_count
137
0
             : v0.index_right_or_value > v1.index_right_or_value;
138
0
}
139
140
// This function will create a Huffman tree.
141
//
142
// The catch here is that the tree cannot be arbitrarily deep.
143
// Brotli specifies a maximum depth of 15 bits for "code trees"
144
// and 7 bits for "code length code trees."
145
//
146
// count_limit is the value that is to be faked as the minimum value
147
// and this minimum value is raised until the tree matches the
148
// maximum length requirement.
149
//
150
// This algorithm is not of excellent performance for very long data blocks,
151
// especially when population counts are longer than 2**tree_limit, but
152
// we are not planning to use this with extremely long blocks.
153
//
154
// See http://en.wikipedia.org/wiki/Huffman_coding
155
void CreateHuffmanTree(const uint32_t* data, const size_t length,
156
0
                       const int tree_limit, uint8_t* depth) {
157
  // For block sizes below 64 kB, we never need to do a second iteration
158
  // of this loop. Probably all of our block sizes will be smaller than
159
  // that, so this loop is mostly of academic interest. If we actually
160
  // would need this, we would be better off with the Katajainen algorithm.
161
0
  for (uint32_t count_limit = 1;; count_limit *= 2) {
162
0
    std::vector<HuffmanTree> tree;
163
0
    tree.reserve(2 * length + 1);
164
165
0
    for (size_t i = length; i != 0;) {
166
0
      --i;
167
0
      if (data[i]) {
168
0
        const uint32_t count = std::max(data[i], count_limit - 1);
169
0
        tree.emplace_back(count, -1, static_cast<int16_t>(i));
170
0
      }
171
0
    }
172
173
0
    const size_t n = tree.size();
174
0
    if (n == 1) {
175
      // Fake value; will be fixed on upper level.
176
0
      depth[tree[0].index_right_or_value] = 1;
177
0
      break;
178
0
    }
179
180
0
    std::sort(tree.begin(), tree.end(), Compare);
181
182
    // The nodes are:
183
    // [0, n): the sorted leaf nodes that we start with.
184
    // [n]: we add a sentinel here.
185
    // [n + 1, 2n): new parent nodes are added here, starting from
186
    //              (n+1). These are naturally in ascending order.
187
    // [2n]: we add a sentinel at the end as well.
188
    // There will be (2n+1) elements at the end.
189
0
    const HuffmanTree sentinel(std::numeric_limits<uint32_t>::max(), -1, -1);
190
0
    tree.push_back(sentinel);
191
0
    tree.push_back(sentinel);
192
193
0
    size_t i = 0;      // Points to the next leaf node.
194
0
    size_t j = n + 1;  // Points to the next non-leaf node.
195
0
    for (size_t k = n - 1; k != 0; --k) {
196
0
      size_t left;
197
0
      size_t right;
198
0
      if (tree[i].total_count <= tree[j].total_count) {
199
0
        left = i;
200
0
        ++i;
201
0
      } else {
202
0
        left = j;
203
0
        ++j;
204
0
      }
205
0
      if (tree[i].total_count <= tree[j].total_count) {
206
0
        right = i;
207
0
        ++i;
208
0
      } else {
209
0
        right = j;
210
0
        ++j;
211
0
      }
212
213
      // The sentinel node becomes the parent node.
214
0
      size_t j_end = tree.size() - 1;
215
0
      tree[j_end].total_count =
216
0
          tree[left].total_count + tree[right].total_count;
217
0
      tree[j_end].index_left = static_cast<int16_t>(left);
218
0
      tree[j_end].index_right_or_value = static_cast<int16_t>(right);
219
220
      // Add back the last sentinel node.
221
0
      tree.push_back(sentinel);
222
0
    }
223
0
    JXL_DASSERT(tree.size() == 2 * n + 1);
224
0
    SetDepth(tree[2 * n - 1], tree.data(), depth, 0);
225
226
    // We need to pack the Huffman tree in tree_limit bits.
227
    // If this was not successful, add fake entities to the lowest values
228
    // and retry.
229
0
    if (*std::max_element(&depth[0], &depth[length]) <= tree_limit) {
230
0
      break;
231
0
    }
232
0
  }
233
0
}
234
235
void ValidateHuffmanTable(j_common_ptr cinfo, const JHUFF_TBL* table,
236
12.5k
                          bool is_dc) {
237
12.5k
  size_t total_symbols = 0;
238
12.5k
  size_t total_p = 0;
239
12.5k
  size_t max_depth = 0;
240
212k
  for (size_t d = 1; d <= kJpegHuffmanMaxBitLength; ++d) {
241
200k
    uint8_t count = table->bits[d];
242
200k
    if (count) {
243
140k
      total_symbols += count;
244
140k
      total_p += (1u << (kJpegHuffmanMaxBitLength - d)) * count;
245
140k
      max_depth = d;
246
140k
    }
247
200k
  }
248
12.5k
  total_p += 1u << (kJpegHuffmanMaxBitLength - max_depth);  // sentinel symbol
249
12.5k
  if (total_symbols == 0) {
250
0
    JPEGLI_ERROR("Empty Huffman table");
251
0
  }
252
12.5k
  if (total_symbols > kJpegHuffmanAlphabetSize) {
253
0
    JPEGLI_ERROR("Too many symbols in Huffman table");
254
0
  }
255
12.5k
  if (total_p != (1u << kJpegHuffmanMaxBitLength)) {
256
0
    JPEGLI_ERROR("Invalid bit length distribution");
257
0
  }
258
12.5k
  uint8_t symbol_seen[kJpegHuffmanAlphabetSize] = {};
259
1.08M
  for (size_t i = 0; i < total_symbols; ++i) {
260
1.06M
    uint8_t symbol = table->huffval[i];
261
1.06M
    if (symbol_seen[symbol]) {
262
0
      JPEGLI_ERROR("Duplicate symbol %d in Huffman table", symbol);
263
0
    }
264
1.06M
    symbol_seen[symbol] = 1;
265
1.06M
  }
266
12.5k
}
267
268
11.6k
void AddStandardHuffmanTables(j_common_ptr cinfo, bool is_dc) {
269
  // Huffman tables from the JPEG standard.
270
11.6k
  static constexpr JHUFF_TBL kStandardDCTables[2] = {
271
      // DC luma
272
11.6k
      {{0, 0, 1, 5, 1, 1, 1, 1, 1, 1},
273
11.6k
       {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
274
11.6k
       FALSE},
275
      // DC chroma
276
11.6k
      {{0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1},
277
11.6k
       {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
278
11.6k
       FALSE}};
279
11.6k
  static constexpr JHUFF_TBL kStandardACTables[2] = {
280
      // AC luma
281
11.6k
      {{0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125},
282
11.6k
       {0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06,
283
11.6k
        0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
284
11.6k
        0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72,
285
11.6k
        0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
286
11.6k
        0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45,
287
11.6k
        0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
288
11.6k
        0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75,
289
11.6k
        0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
290
11.6k
        0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3,
291
11.6k
        0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
292
11.6k
        0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
293
11.6k
        0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
294
11.6k
        0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4,
295
11.6k
        0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa},
296
11.6k
       FALSE},
297
      // AC chroma
298
11.6k
      {{0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119},
299
11.6k
       {0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41,
300
11.6k
        0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
301
11.6k
        0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1,
302
11.6k
        0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
303
11.6k
        0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44,
304
11.6k
        0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
305
11.6k
        0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74,
306
11.6k
        0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
307
11.6k
        0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a,
308
11.6k
        0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
309
11.6k
        0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
310
11.6k
        0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
311
11.6k
        0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4,
312
11.6k
        0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa},
313
11.6k
       FALSE}};
314
11.6k
  const JHUFF_TBL* std_tables = is_dc ? kStandardDCTables : kStandardACTables;
315
11.6k
  JHUFF_TBL** tables;
316
11.6k
  if (cinfo->is_decompressor) {
317
11.6k
    j_decompress_ptr cinfo_d = reinterpret_cast<j_decompress_ptr>(cinfo);
318
11.6k
    tables = is_dc ? cinfo_d->dc_huff_tbl_ptrs : cinfo_d->ac_huff_tbl_ptrs;
319
11.6k
  } else {
320
0
    j_compress_ptr cinfo_c = reinterpret_cast<j_compress_ptr>(cinfo);
321
0
    tables = is_dc ? cinfo_c->dc_huff_tbl_ptrs : cinfo_c->ac_huff_tbl_ptrs;
322
0
  }
323
35.0k
  for (int i = 0; i < 2; ++i) {
324
23.3k
    if (tables[i] == nullptr) {
325
12.5k
      tables[i] = jpegli_alloc_huff_table(cinfo);
326
12.5k
      memcpy(tables[i], &std_tables[i], sizeof(JHUFF_TBL));
327
12.5k
      ValidateHuffmanTable(cinfo, tables[i], is_dc);
328
12.5k
    }
329
23.3k
  }
330
11.6k
}
331
332
}  // namespace jpegli