Coverage Report

Created: 2026-11-12 07:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libwebp/src/utils/huffman_encode_utils.c
Line
Count
Source
1
// Copyright 2011 Google Inc. All Rights Reserved.
2
//
3
// Use of this source code is governed by a BSD-style license
4
// that can be found in the COPYING file in the root of the source
5
// tree. An additional intellectual property rights grant can be found
6
// in the file PATENTS. All contributing project authors may
7
// be found in the AUTHORS file in the root of the source tree.
8
// -----------------------------------------------------------------------------
9
//
10
// Author: Jyrki Alakuijala (jyrki@google.com)
11
//
12
// Entropy encoding (Huffman) for webp lossless.
13
14
#include "src/utils/huffman_encode_utils.h"
15
16
#include <assert.h>
17
#include <stdlib.h>
18
#include <string.h>
19
20
#include "src/utils/bounds_safety.h"
21
#include "src/utils/utils.h"
22
#include "src/webp/format_constants.h"
23
#include "src/webp/types.h"
24
25
WEBP_ASSUME_UNSAFE_INDEXABLE_ABI
26
27
// -----------------------------------------------------------------------------
28
// Util function to optimize the symbol map for RLE coding
29
30
// Heuristics for selecting the stride ranges to collapse.
31
2.49M
static int ValuesShouldBeCollapsedToStrideAverage(int a, int b) {
32
2.49M
  return abs(a - b) < 4;
33
2.49M
}
34
35
// Change the population counts in a way that the consequent
36
// Huffman tree compression, especially its RLE-part, give smaller output.
37
static void OptimizeHuffmanForRle(int length,
38
                                  uint8_t* const WEBP_COUNTED_BY(length)
39
                                      good_for_rle,
40
                                  uint32_t* const WEBP_COUNTED_BY(length)
41
117k
                                      counts) {
42
  // 1) Let's make the Huffman code more compatible with rle encoding.
43
117k
  int i;
44
11.4M
  for (; length >= 0; --length) {
45
11.4M
    if (length == 0) {
46
8.82k
      return;  // All zeros.
47
8.82k
    }
48
11.4M
    if (counts[length - 1] != 0) {
49
      // Now counts[0..length - 1] does not have trailing zeros.
50
108k
      break;
51
108k
    }
52
11.4M
  }
53
  // 2) Let's mark all population counts that already can be encoded
54
  // with an rle code.
55
108k
  {
56
    // Let's not spoil any of the existing good rle codes.
57
    // Mark any seq of 0's that is longer as 5 as a good_for_rle.
58
    // Mark any seq of non-0's that is longer as 7 as a good_for_rle.
59
108k
    uint32_t symbol = counts[0];
60
108k
    int stride = 0;
61
9.93M
    for (i = 0; i < length + 1; ++i) {
62
9.82M
      if (i == length || counts[i] != symbol) {
63
2.39M
        if ((symbol == 0 && stride >= 5) || (symbol != 0 && stride >= 7)) {
64
156k
          int k;
65
7.22M
          for (k = 0; k < stride; ++k) {
66
7.06M
            good_for_rle[i - k - 1] = 1;
67
7.06M
          }
68
156k
        }
69
2.39M
        stride = 1;
70
2.39M
        if (i != length) {
71
2.28M
          symbol = counts[i];
72
2.28M
        }
73
7.42M
      } else {
74
7.42M
        ++stride;
75
7.42M
      }
76
9.82M
    }
77
108k
  }
78
  // 3) Let's replace those population counts that lead to more rle codes.
79
108k
  {
80
108k
    uint32_t stride = 0;
81
108k
    uint32_t limit = counts[0];
82
108k
    uint32_t sum = 0;
83
9.93M
    for (i = 0; i < length + 1; ++i) {
84
9.82M
      if (i == length || good_for_rle[i] || (i != 0 && good_for_rle[i - 1]) ||
85
8.51M
          !ValuesShouldBeCollapsedToStrideAverage(counts[i], limit)) {
86
8.51M
        if (stride >= 4 || (stride >= 3 && sum == 0)) {
87
149k
          uint32_t k;
88
          // The stride must end, collapse what we have, if we have enough (4).
89
149k
          uint32_t count = (sum + stride / 2) / stride;
90
149k
          if (count < 1) {
91
24.8k
            count = 1;
92
24.8k
          }
93
149k
          if (sum == 0) {
94
            // Don't make an all zeros stride to be upgraded to ones.
95
11.3k
            count = 0;
96
11.3k
          }
97
1.28M
          for (k = 0; k < stride; ++k) {
98
            // We don't want to change value at counts[i],
99
            // that is already belonging to the next stride. Thus - 1.
100
1.13M
            counts[i - k - 1] = count;
101
1.13M
          }
102
149k
        }
103
8.51M
        stride = 0;
104
8.51M
        sum = 0;
105
8.51M
        if (i < length - 3) {
106
          // All interesting strides have a count of at least 4,
107
          // at least when non-zeros.
108
8.25M
          limit =
109
8.25M
              (counts[i] + counts[i + 1] + counts[i + 2] + counts[i + 3] + 2) /
110
8.25M
              4;
111
8.25M
        } else if (i < length) {
112
149k
          limit = counts[i];
113
149k
        } else {
114
108k
          limit = 0;
115
108k
        }
116
8.51M
      }
117
9.82M
      ++stride;
118
9.82M
      if (i != length) {
119
9.71M
        sum += counts[i];
120
9.71M
        if (stride >= 4) {
121
683k
          limit = (sum + stride / 2) / stride;
122
683k
        }
123
9.71M
      }
124
9.82M
    }
125
108k
  }
126
108k
}
127
128
// A comparer function for two Huffman trees: sorts first by 'total count'
129
// (more comes first), and then by 'value' (more comes first).
130
13.4M
static int CompareHuffmanTrees(const void* ptr1, const void* ptr2) {
131
13.4M
  const HuffmanTree* const t1 = (const HuffmanTree*)ptr1;
132
13.4M
  const HuffmanTree* const t2 = (const HuffmanTree*)ptr2;
133
13.4M
  if (t1->total_count > t2->total_count) {
134
3.54M
    return -1;
135
9.93M
  } else if (t1->total_count < t2->total_count) {
136
5.07M
    return 1;
137
5.07M
  } else {
138
4.85M
    assert(t1->value != t2->value);
139
4.85M
    return (t1->value < t2->value) ? -1 : 1;
140
4.85M
  }
141
13.4M
}
142
143
static void SetBitDepths(const HuffmanTree* const tree,
144
                         const HuffmanTree* WEBP_BIDI_INDEXABLE const pool,
145
5.43M
                         uint8_t* WEBP_INDEXABLE const bit_depths, int level) {
146
5.43M
  if (tree->pool_index_left >= 0) {
147
2.68M
    SetBitDepths(&pool[tree->pool_index_left], pool, bit_depths, level + 1);
148
2.68M
    SetBitDepths(&pool[tree->pool_index_right], pool, bit_depths, level + 1);
149
2.74M
  } else {
150
2.74M
    bit_depths[tree->value] = level;
151
2.74M
  }
152
5.43M
}
153
154
// Create an optimal Huffman tree.
155
//
156
// (data,length): population counts.
157
// tree_limit: maximum bit depth (inclusive) of the codes.
158
// bit_depths[]: how many bits are used for the symbol.
159
//
160
// Returns 0 when an error has occurred.
161
//
162
// The catch here is that the tree cannot be arbitrarily deep
163
//
164
// count_limit is the value that is to be faked as the minimum value
165
// and this minimum value is raised until the tree matches the
166
// maximum length requirement.
167
//
168
// This algorithm is not of excellent performance for very long data blocks,
169
// especially when population counts are longer than 2**tree_limit, but
170
// we are not planning to use this with extremely long blocks.
171
//
172
// See https://en.wikipedia.org/wiki/Huffman_coding
173
static void GenerateOptimalTree(
174
    const uint32_t* const WEBP_COUNTED_BY(histogram_size) histogram,
175
    int histogram_size, HuffmanTree* WEBP_BIDI_INDEXABLE tree,
176
    int tree_depth_limit,
177
117k
    uint8_t* WEBP_COUNTED_BY(histogram_size) const bit_depths) {
178
117k
  uint32_t count_min;
179
117k
  HuffmanTree* WEBP_BIDI_INDEXABLE tree_pool;
180
117k
  int tree_size_orig = 0;
181
117k
  int i;
182
183
21.1M
  for (i = 0; i < histogram_size; ++i) {
184
21.0M
    if (histogram[i] != 0) {
185
2.53M
      ++tree_size_orig;
186
2.53M
    }
187
21.0M
  }
188
189
117k
  if (tree_size_orig == 0) {  // pretty optimal already!
190
8.82k
    return;
191
8.82k
  }
192
193
108k
  tree_pool = tree + tree_size_orig;
194
195
  // For block sizes with less than 64k symbols we never need to do a
196
  // second iteration of this loop.
197
  // If we actually start running inside this loop a lot, we would perhaps
198
  // be better off with the Katajainen algorithm.
199
108k
  assert(tree_size_orig <= (1 << (tree_depth_limit - 1)));
200
112k
  for (count_min = 1;; count_min *= 2) {
201
112k
    int tree_size = tree_size_orig;
202
    // We need to pack the Huffman tree in tree_depth_limit bits.
203
    // So, we try by faking histogram entries to be at least 'count_min'.
204
112k
    int idx = 0;
205
112k
    int j;
206
20.3M
    for (j = 0; j < histogram_size; ++j) {
207
20.2M
      if (histogram[j] != 0) {
208
2.79M
        const uint32_t count =
209
2.79M
            (histogram[j] < count_min) ? count_min : histogram[j];
210
2.79M
        tree[idx].total_count = count;
211
2.79M
        tree[idx].value = j;
212
2.79M
        tree[idx].pool_index_left = -1;
213
2.79M
        tree[idx].pool_index_right = -1;
214
2.79M
        ++idx;
215
2.79M
      }
216
20.2M
    }
217
218
    // Build the Huffman tree.
219
112k
    qsort(tree, tree_size, sizeof(*tree), CompareHuffmanTrees);
220
221
112k
    if (tree_size > 1) {  // Normal case.
222
64.1k
      int tree_pool_size = 0;
223
2.74M
      while (tree_size > 1) {  // Finish when we have only one root.
224
2.68M
        uint32_t count;
225
2.68M
        tree_pool[tree_pool_size++] = tree[tree_size - 1];
226
2.68M
        tree_pool[tree_pool_size++] = tree[tree_size - 2];
227
2.68M
        count = tree_pool[tree_pool_size - 1].total_count +
228
2.68M
                tree_pool[tree_pool_size - 2].total_count;
229
2.68M
        tree_size -= 2;
230
2.68M
        {
231
          // Search for the insertion point.
232
2.68M
          int k;
233
113M
          for (k = 0; k < tree_size; ++k) {
234
113M
            if (tree[k].total_count <= count) {
235
2.60M
              break;
236
2.60M
            }
237
113M
          }
238
2.68M
          memmove(tree + (k + 1), tree + k, (tree_size - k) * sizeof(*tree));
239
2.68M
          tree[k].total_count = count;
240
2.68M
          tree[k].value = -1;
241
242
2.68M
          tree[k].pool_index_left = tree_pool_size - 1;
243
2.68M
          tree[k].pool_index_right = tree_pool_size - 2;
244
2.68M
          tree_size = tree_size + 1;
245
2.68M
        }
246
2.68M
      }
247
64.1k
      SetBitDepths(&tree[0], tree_pool, bit_depths, 0);
248
64.1k
    } else if (tree_size == 1) {  // Trivial case: only one element.
249
48.4k
      bit_depths[tree[0].value] = 1;
250
48.4k
    }
251
252
112k
    {
253
      // Test if this Huffman tree satisfies our 'tree_depth_limit' criteria.
254
112k
      int max_depth = bit_depths[0];
255
20.2M
      for (j = 1; j < histogram_size; ++j) {
256
20.1M
        if (max_depth < bit_depths[j]) {
257
100k
          max_depth = bit_depths[j];
258
100k
        }
259
20.1M
      }
260
112k
      if (max_depth <= tree_depth_limit) {
261
108k
        break;
262
108k
      }
263
112k
    }
264
112k
  }
265
108k
}
266
267
// -----------------------------------------------------------------------------
268
// Coding of the Huffman tree values
269
270
static HuffmanTreeToken* WEBP_INDEXABLE
271
CodeRepeatedValues(int repetitions, HuffmanTreeToken* WEBP_INDEXABLE tokens,
272
971k
                   int value, int prev_value) {
273
971k
  assert(value <= MAX_ALLOWED_CODE_LENGTH);
274
971k
  if (value != prev_value) {
275
874k
    tokens->code = value;
276
874k
    tokens->extra_bits = 0;
277
874k
    ++tokens;
278
874k
    --repetitions;
279
874k
  }
280
1.07M
  while (repetitions >= 1) {
281
440k
    if (repetitions < 3) {
282
232k
      int i;
283
510k
      for (i = 0; i < repetitions; ++i) {
284
277k
        tokens->code = value;
285
277k
        tokens->extra_bits = 0;
286
277k
        ++tokens;
287
277k
      }
288
232k
      break;
289
232k
    } else if (repetitions < 7) {
290
101k
      tokens->code = 16;
291
101k
      tokens->extra_bits = repetitions - 3;
292
101k
      ++tokens;
293
101k
      break;
294
105k
    } else {
295
105k
      tokens->code = 16;
296
105k
      tokens->extra_bits = 3;
297
105k
      ++tokens;
298
105k
      repetitions -= 6;
299
105k
    }
300
440k
  }
301
971k
  return tokens;
302
971k
}
303
304
static HuffmanTreeToken* WEBP_INDEXABLE
305
253k
CodeRepeatedZeros(int repetitions, HuffmanTreeToken* WEBP_INDEXABLE tokens) {
306
266k
  while (repetitions >= 1) {
307
266k
    if (repetitions < 3) {
308
103k
      int i;
309
229k
      for (i = 0; i < repetitions; ++i) {
310
126k
        tokens->code = 0;  // 0-value
311
126k
        tokens->extra_bits = 0;
312
126k
        ++tokens;
313
126k
      }
314
103k
      break;
315
163k
    } else if (repetitions < 11) {
316
88.3k
      tokens->code = 17;
317
88.3k
      tokens->extra_bits = repetitions - 3;
318
88.3k
      ++tokens;
319
88.3k
      break;
320
88.3k
    } else if (repetitions < 139) {
321
62.1k
      tokens->code = 18;
322
62.1k
      tokens->extra_bits = repetitions - 11;
323
62.1k
      ++tokens;
324
62.1k
      break;
325
62.1k
    } else {
326
12.5k
      tokens->code = 18;
327
12.5k
      tokens->extra_bits = 0x7f;  // 138 repeated 0s
328
12.5k
      ++tokens;
329
12.5k
      repetitions -= 138;
330
12.5k
    }
331
266k
  }
332
253k
  return tokens;
333
253k
}
334
335
int VP8LCreateCompressedHuffmanTree(
336
    const HuffmanTreeCode* const tree,
337
27.8k
    HuffmanTreeToken* WEBP_COUNTED_BY(max_tokens) tokens, int max_tokens) {
338
27.8k
  HuffmanTreeToken* WEBP_INDEXABLE current_token = tokens;
339
27.8k
  HuffmanTreeToken* const starting_token = tokens;
340
27.8k
  HuffmanTreeToken* const ending_token = tokens + max_tokens;
341
27.8k
  const int depth_size = tree->num_symbols;
342
27.8k
  int prev_value = 8;  // 8 is the initial value for rle.
343
27.8k
  int i = 0;
344
27.8k
  assert(tokens != NULL);
345
1.25M
  while (i < depth_size) {
346
1.22M
    const int value = tree->code_lengths[i];
347
1.22M
    int k = i + 1;
348
1.22M
    int runs;
349
7.30M
    while (k < depth_size && tree->code_lengths[k] == value) ++k;
350
1.22M
    runs = k - i;
351
1.22M
    if (value == 0) {
352
253k
      current_token = CodeRepeatedZeros(runs, current_token);
353
971k
    } else {
354
971k
      current_token =
355
971k
          CodeRepeatedValues(runs, current_token, value, prev_value);
356
971k
      prev_value = value;
357
971k
    }
358
1.22M
    i += runs;
359
1.22M
    assert(current_token <= ending_token);
360
1.22M
  }
361
27.8k
  (void)ending_token;  // suppress 'unused variable' warning
362
27.8k
  return (int)(current_token - starting_token);
363
27.8k
}
364
365
// -----------------------------------------------------------------------------
366
367
// Pre-reversed 4-bit values.
368
static const uint8_t kReversedBits[16] = {0x0, 0x8, 0x4, 0xc, 0x2, 0xa,
369
                                          0x6, 0xe, 0x1, 0x9, 0x5, 0xd,
370
                                          0x3, 0xb, 0x7, 0xf};
371
372
21.0M
static uint32_t ReverseBits(int num_bits, uint32_t bits) {
373
21.0M
  uint32_t retval = 0;
374
21.0M
  int i = 0;
375
27.2M
  while (i < num_bits) {
376
6.24M
    i += 4;
377
6.24M
    retval |= kReversedBits[bits & 0xf] << (MAX_ALLOWED_CODE_LENGTH + 1 - i);
378
6.24M
    bits >>= 4;
379
6.24M
  }
380
21.0M
  retval >>= (MAX_ALLOWED_CODE_LENGTH + 1 - num_bits);
381
21.0M
  return retval;
382
21.0M
}
383
384
// Get the actual bit values for a tree of bit depths.
385
117k
static void ConvertBitDepthsToSymbols(HuffmanTreeCode* const tree) {
386
  // 0 bit-depth means that the symbol does not exist.
387
117k
  int i;
388
117k
  int len;
389
117k
  uint32_t next_code[MAX_ALLOWED_CODE_LENGTH + 1];
390
117k
  int depth_count[MAX_ALLOWED_CODE_LENGTH + 1] = {0};
391
392
117k
  assert(tree != NULL);
393
117k
  len = tree->num_symbols;
394
21.1M
  for (i = 0; i < len; ++i) {
395
21.0M
    const int code_length = tree->code_lengths[i];
396
21.0M
    assert(code_length <= MAX_ALLOWED_CODE_LENGTH);
397
21.0M
    ++depth_count[code_length];
398
21.0M
  }
399
117k
  depth_count[0] = 0;  // ignore unused symbol
400
117k
  next_code[0] = 0;
401
117k
  {
402
117k
    uint32_t code = 0;
403
1.88M
    for (i = 1; i <= MAX_ALLOWED_CODE_LENGTH; ++i) {
404
1.76M
      code = (code + depth_count[i - 1]) << 1;
405
1.76M
      next_code[i] = code;
406
1.76M
    }
407
117k
  }
408
21.1M
  for (i = 0; i < len; ++i) {
409
21.0M
    const int code_length = tree->code_lengths[i];
410
21.0M
    tree->codes[i] = ReverseBits(code_length, next_code[code_length]++);
411
21.0M
  }
412
117k
}
413
414
// -----------------------------------------------------------------------------
415
// Main entry point
416
417
void VP8LCreateHuffmanTree(uint32_t* const histogram, int tree_depth_limit,
418
                           uint8_t* const buf_rle, HuffmanTree* const huff_tree,
419
117k
                           HuffmanTreeCode* const huff_code) {
420
117k
  const int num_symbols = huff_code->num_symbols;
421
117k
  uint32_t* const WEBP_BIDI_INDEXABLE bounded_histogram =
422
117k
      WEBP_UNSAFE_FORGE_BIDI_INDEXABLE(
423
117k
          uint32_t*, histogram, (size_t)num_symbols * sizeof(*histogram));
424
117k
  uint8_t* const WEBP_BIDI_INDEXABLE bounded_buf_rle =
425
117k
      WEBP_UNSAFE_FORGE_BIDI_INDEXABLE(uint8_t*, buf_rle,
426
117k
                                       (size_t)num_symbols * sizeof(*buf_rle));
427
428
117k
  memset(bounded_buf_rle, 0, num_symbols * sizeof(*buf_rle));
429
117k
  OptimizeHuffmanForRle(num_symbols, bounded_buf_rle, bounded_histogram);
430
117k
  GenerateOptimalTree(
431
117k
      bounded_histogram, num_symbols,
432
117k
      WEBP_UNSAFE_FORGE_BIDI_INDEXABLE(HuffmanTree*, huff_tree,
433
117k
                                       3 * num_symbols * sizeof(*huff_tree)),
434
117k
      tree_depth_limit, huff_code->code_lengths);
435
  // Create the actual bit codes for the bit lengths.
436
117k
  ConvertBitDepthsToSymbols(huff_code);
437
117k
}