Coverage Report

Created: 2026-09-14 07:37

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.30M
static int ValuesShouldBeCollapsedToStrideAverage(int a, int b) {
32
2.30M
  return abs(a - b) < 4;
33
2.30M
}
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
155k
                                      counts) {
42
  // 1) Let's make the Huffman code more compatible with rle encoding.
43
155k
  int i;
44
17.3M
  for (; length >= 0; --length) {
45
17.3M
    if (length == 0) {
46
9.57k
      return;  // All zeros.
47
9.57k
    }
48
17.3M
    if (counts[length - 1] != 0) {
49
      // Now counts[0..length - 1] does not have trailing zeros.
50
146k
      break;
51
146k
    }
52
17.3M
  }
53
  // 2) Let's mark all population counts that already can be encoded
54
  // with an rle code.
55
146k
  {
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
146k
    uint32_t symbol = counts[0];
60
146k
    int stride = 0;
61
11.3M
    for (i = 0; i < length + 1; ++i) {
62
11.1M
      if (i == length || counts[i] != symbol) {
63
2.27M
        if ((symbol == 0 && stride >= 5) || (symbol != 0 && stride >= 7)) {
64
194k
          int k;
65
8.72M
          for (k = 0; k < stride; ++k) {
66
8.53M
            good_for_rle[i - k - 1] = 1;
67
8.53M
          }
68
194k
        }
69
2.27M
        stride = 1;
70
2.27M
        if (i != length) {
71
2.13M
          symbol = counts[i];
72
2.13M
        }
73
8.89M
      } else {
74
8.89M
        ++stride;
75
8.89M
      }
76
11.1M
    }
77
146k
  }
78
  // 3) Let's replace those population counts that lead to more rle codes.
79
146k
  {
80
146k
    uint32_t stride = 0;
81
146k
    uint32_t limit = counts[0];
82
146k
    uint32_t sum = 0;
83
11.3M
    for (i = 0; i < length + 1; ++i) {
84
11.1M
      if (i == length || good_for_rle[i] || (i != 0 && good_for_rle[i - 1]) ||
85
9.84M
          !ValuesShouldBeCollapsedToStrideAverage(counts[i], limit)) {
86
9.84M
        if (stride >= 4 || (stride >= 3 && sum == 0)) {
87
153k
          uint32_t k;
88
          // The stride must end, collapse what we have, if we have enough (4).
89
153k
          uint32_t count = (sum + stride / 2) / stride;
90
153k
          if (count < 1) {
91
31.6k
            count = 1;
92
31.6k
          }
93
153k
          if (sum == 0) {
94
            // Don't make an all zeros stride to be upgraded to ones.
95
17.5k
            count = 0;
96
17.5k
          }
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
153k
        }
103
9.84M
        stride = 0;
104
9.84M
        sum = 0;
105
9.84M
        if (i < length - 3) {
106
          // All interesting strides have a count of at least 4,
107
          // at least when non-zeros.
108
9.52M
          limit =
109
9.52M
              (counts[i] + counts[i + 1] + counts[i + 2] + counts[i + 3] + 2) /
110
9.52M
              4;
111
9.52M
        } else if (i < length) {
112
176k
          limit = counts[i];
113
176k
        } else {
114
146k
          limit = 0;
115
146k
        }
116
9.84M
      }
117
11.1M
      ++stride;
118
11.1M
      if (i != length) {
119
11.0M
        sum += counts[i];
120
11.0M
        if (stride >= 4) {
121
673k
          limit = (sum + stride / 2) / stride;
122
673k
        }
123
11.0M
      }
124
11.1M
    }
125
146k
  }
126
146k
}
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
10.8M
static int CompareHuffmanTrees(const void* ptr1, const void* ptr2) {
131
10.8M
  const HuffmanTree* const t1 = (const HuffmanTree*)ptr1;
132
10.8M
  const HuffmanTree* const t2 = (const HuffmanTree*)ptr2;
133
10.8M
  if (t1->total_count > t2->total_count) {
134
2.82M
    return -1;
135
8.00M
  } else if (t1->total_count < t2->total_count) {
136
4.14M
    return 1;
137
4.14M
  } else {
138
3.85M
    assert(t1->value != t2->value);
139
3.85M
    return (t1->value < t2->value) ? -1 : 1;
140
3.85M
  }
141
10.8M
}
142
143
static void SetBitDepths(const HuffmanTree* const tree,
144
                         const HuffmanTree* WEBP_BIDI_INDEXABLE const pool,
145
4.84M
                         uint8_t* WEBP_INDEXABLE const bit_depths, int level) {
146
4.84M
  if (tree->pool_index_left >= 0) {
147
2.38M
    SetBitDepths(&pool[tree->pool_index_left], pool, bit_depths, level + 1);
148
2.38M
    SetBitDepths(&pool[tree->pool_index_right], pool, bit_depths, level + 1);
149
2.45M
  } else {
150
2.45M
    bit_depths[tree->value] = level;
151
2.45M
  }
152
4.84M
}
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
155k
    uint8_t* WEBP_COUNTED_BY(histogram_size) const bit_depths) {
178
155k
  uint32_t count_min;
179
155k
  HuffmanTree* WEBP_BIDI_INDEXABLE tree_pool;
180
155k
  int tree_size_orig = 0;
181
155k
  int i;
182
183
28.3M
  for (i = 0; i < histogram_size; ++i) {
184
28.2M
    if (histogram[i] != 0) {
185
2.34M
      ++tree_size_orig;
186
2.34M
    }
187
28.2M
  }
188
189
155k
  if (tree_size_orig == 0) {  // pretty optimal already!
190
9.57k
    return;
191
9.57k
  }
192
193
146k
  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
146k
  assert(tree_size_orig <= (1 << (tree_depth_limit - 1)));
200
148k
  for (count_min = 1;; count_min *= 2) {
201
148k
    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
148k
    int idx = 0;
205
148k
    int j;
206
27.8M
    for (j = 0; j < histogram_size; ++j) {
207
27.6M
      if (histogram[j] != 0) {
208
2.53M
        const uint32_t count =
209
2.53M
            (histogram[j] < count_min) ? count_min : histogram[j];
210
2.53M
        tree[idx].total_count = count;
211
2.53M
        tree[idx].value = j;
212
2.53M
        tree[idx].pool_index_left = -1;
213
2.53M
        tree[idx].pool_index_right = -1;
214
2.53M
        ++idx;
215
2.53M
      }
216
27.6M
    }
217
218
    // Build the Huffman tree.
219
148k
    qsort(tree, tree_size, sizeof(*tree), CompareHuffmanTrees);
220
221
148k
    if (tree_size > 1) {  // Normal case.
222
68.1k
      int tree_pool_size = 0;
223
2.45M
      while (tree_size > 1) {  // Finish when we have only one root.
224
2.38M
        uint32_t count;
225
2.38M
        tree_pool[tree_pool_size++] = tree[tree_size - 1];
226
2.38M
        tree_pool[tree_pool_size++] = tree[tree_size - 2];
227
2.38M
        count = tree_pool[tree_pool_size - 1].total_count +
228
2.38M
                tree_pool[tree_pool_size - 2].total_count;
229
2.38M
        tree_size -= 2;
230
2.38M
        {
231
          // Search for the insertion point.
232
2.38M
          int k;
233
70.9M
          for (k = 0; k < tree_size; ++k) {
234
70.8M
            if (tree[k].total_count <= count) {
235
2.30M
              break;
236
2.30M
            }
237
70.8M
          }
238
2.38M
          memmove(tree + (k + 1), tree + k, (tree_size - k) * sizeof(*tree));
239
2.38M
          tree[k].total_count = count;
240
2.38M
          tree[k].value = -1;
241
242
2.38M
          tree[k].pool_index_left = tree_pool_size - 1;
243
2.38M
          tree[k].pool_index_right = tree_pool_size - 2;
244
2.38M
          tree_size = tree_size + 1;
245
2.38M
        }
246
2.38M
      }
247
68.1k
      SetBitDepths(&tree[0], tree_pool, bit_depths, 0);
248
79.8k
    } else if (tree_size == 1) {  // Trivial case: only one element.
249
79.8k
      bit_depths[tree[0].value] = 1;
250
79.8k
    }
251
252
148k
    {
253
      // Test if this Huffman tree satisfies our 'tree_depth_limit' criteria.
254
148k
      int max_depth = bit_depths[0];
255
27.6M
      for (j = 1; j < histogram_size; ++j) {
256
27.5M
        if (max_depth < bit_depths[j]) {
257
116k
          max_depth = bit_depths[j];
258
116k
        }
259
27.5M
      }
260
148k
      if (max_depth <= tree_depth_limit) {
261
146k
        break;
262
146k
      }
263
148k
    }
264
148k
  }
265
146k
}
266
267
// -----------------------------------------------------------------------------
268
// Coding of the Huffman tree values
269
270
static HuffmanTreeToken* WEBP_INDEXABLE
271
CodeRepeatedValues(int repetitions, HuffmanTreeToken* WEBP_INDEXABLE tokens,
272
839k
                   int value, int prev_value) {
273
839k
  assert(value <= MAX_ALLOWED_CODE_LENGTH);
274
839k
  if (value != prev_value) {
275
726k
    tokens->code = value;
276
726k
    tokens->extra_bits = 0;
277
726k
    ++tokens;
278
726k
    --repetitions;
279
726k
  }
280
940k
  while (repetitions >= 1) {
281
388k
    if (repetitions < 3) {
282
195k
      int i;
283
422k
      for (i = 0; i < repetitions; ++i) {
284
227k
        tokens->code = value;
285
227k
        tokens->extra_bits = 0;
286
227k
        ++tokens;
287
227k
      }
288
195k
      break;
289
195k
    } else if (repetitions < 7) {
290
91.9k
      tokens->code = 16;
291
91.9k
      tokens->extra_bits = repetitions - 3;
292
91.9k
      ++tokens;
293
91.9k
      break;
294
101k
    } else {
295
101k
      tokens->code = 16;
296
101k
      tokens->extra_bits = 3;
297
101k
      ++tokens;
298
101k
      repetitions -= 6;
299
101k
    }
300
388k
  }
301
839k
  return tokens;
302
839k
}
303
304
static HuffmanTreeToken* WEBP_INDEXABLE
305
298k
CodeRepeatedZeros(int repetitions, HuffmanTreeToken* WEBP_INDEXABLE tokens) {
306
307k
  while (repetitions >= 1) {
307
307k
    if (repetitions < 3) {
308
111k
      int i;
309
247k
      for (i = 0; i < repetitions; ++i) {
310
135k
        tokens->code = 0;  // 0-value
311
135k
        tokens->extra_bits = 0;
312
135k
        ++tokens;
313
135k
      }
314
111k
      break;
315
195k
    } else if (repetitions < 11) {
316
102k
      tokens->code = 17;
317
102k
      tokens->extra_bits = repetitions - 3;
318
102k
      ++tokens;
319
102k
      break;
320
102k
    } else if (repetitions < 139) {
321
84.7k
      tokens->code = 18;
322
84.7k
      tokens->extra_bits = repetitions - 11;
323
84.7k
      ++tokens;
324
84.7k
      break;
325
84.7k
    } else {
326
8.58k
      tokens->code = 18;
327
8.58k
      tokens->extra_bits = 0x7f;  // 138 repeated 0s
328
8.58k
      ++tokens;
329
8.58k
      repetitions -= 138;
330
8.58k
    }
331
307k
  }
332
298k
  return tokens;
333
298k
}
334
335
int VP8LCreateCompressedHuffmanTree(
336
    const HuffmanTreeCode* const tree,
337
29.5k
    HuffmanTreeToken* WEBP_COUNTED_BY(max_tokens) tokens, int max_tokens) {
338
29.5k
  HuffmanTreeToken* WEBP_INDEXABLE current_token = tokens;
339
29.5k
  HuffmanTreeToken* const starting_token = tokens;
340
29.5k
  HuffmanTreeToken* const ending_token = tokens + max_tokens;
341
29.5k
  const int depth_size = tree->num_symbols;
342
29.5k
  int prev_value = 8;  // 8 is the initial value for rle.
343
29.5k
  int i = 0;
344
29.5k
  assert(tokens != NULL);
345
1.16M
  while (i < depth_size) {
346
1.13M
    const int value = tree->code_lengths[i];
347
1.13M
    int k = i + 1;
348
1.13M
    int runs;
349
6.56M
    while (k < depth_size && tree->code_lengths[k] == value) ++k;
350
1.13M
    runs = k - i;
351
1.13M
    if (value == 0) {
352
298k
      current_token = CodeRepeatedZeros(runs, current_token);
353
839k
    } else {
354
839k
      current_token =
355
839k
          CodeRepeatedValues(runs, current_token, value, prev_value);
356
839k
      prev_value = value;
357
839k
    }
358
1.13M
    i += runs;
359
1.13M
    assert(current_token <= ending_token);
360
1.13M
  }
361
29.5k
  (void)ending_token;  // suppress 'unused variable' warning
362
29.5k
  return (int)(current_token - starting_token);
363
29.5k
}
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
28.2M
static uint32_t ReverseBits(int num_bits, uint32_t bits) {
373
28.2M
  uint32_t retval = 0;
374
28.2M
  int i = 0;
375
33.2M
  while (i < num_bits) {
376
5.06M
    i += 4;
377
5.06M
    retval |= kReversedBits[bits & 0xf] << (MAX_ALLOWED_CODE_LENGTH + 1 - i);
378
5.06M
    bits >>= 4;
379
5.06M
  }
380
28.2M
  retval >>= (MAX_ALLOWED_CODE_LENGTH + 1 - num_bits);
381
28.2M
  return retval;
382
28.2M
}
383
384
// Get the actual bit values for a tree of bit depths.
385
155k
static void ConvertBitDepthsToSymbols(HuffmanTreeCode* const tree) {
386
  // 0 bit-depth means that the symbol does not exist.
387
155k
  int i;
388
155k
  int len;
389
155k
  uint32_t next_code[MAX_ALLOWED_CODE_LENGTH + 1];
390
155k
  int depth_count[MAX_ALLOWED_CODE_LENGTH + 1] = {0};
391
392
155k
  assert(tree != NULL);
393
155k
  len = tree->num_symbols;
394
28.3M
  for (i = 0; i < len; ++i) {
395
28.2M
    const int code_length = tree->code_lengths[i];
396
28.2M
    assert(code_length <= MAX_ALLOWED_CODE_LENGTH);
397
28.2M
    ++depth_count[code_length];
398
28.2M
  }
399
155k
  depth_count[0] = 0;  // ignore unused symbol
400
155k
  next_code[0] = 0;
401
155k
  {
402
155k
    uint32_t code = 0;
403
2.49M
    for (i = 1; i <= MAX_ALLOWED_CODE_LENGTH; ++i) {
404
2.33M
      code = (code + depth_count[i - 1]) << 1;
405
2.33M
      next_code[i] = code;
406
2.33M
    }
407
155k
  }
408
28.3M
  for (i = 0; i < len; ++i) {
409
28.2M
    const int code_length = tree->code_lengths[i];
410
28.2M
    tree->codes[i] = ReverseBits(code_length, next_code[code_length]++);
411
28.2M
  }
412
155k
}
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
155k
                           HuffmanTreeCode* const huff_code) {
420
155k
  const int num_symbols = huff_code->num_symbols;
421
155k
  uint32_t* const WEBP_BIDI_INDEXABLE bounded_histogram =
422
155k
      WEBP_UNSAFE_FORGE_BIDI_INDEXABLE(
423
155k
          uint32_t*, histogram, (size_t)num_symbols * sizeof(*histogram));
424
155k
  uint8_t* const WEBP_BIDI_INDEXABLE bounded_buf_rle =
425
155k
      WEBP_UNSAFE_FORGE_BIDI_INDEXABLE(uint8_t*, buf_rle,
426
155k
                                       (size_t)num_symbols * sizeof(*buf_rle));
427
428
155k
  memset(bounded_buf_rle, 0, num_symbols * sizeof(*buf_rle));
429
155k
  OptimizeHuffmanForRle(num_symbols, bounded_buf_rle, bounded_histogram);
430
155k
  GenerateOptimalTree(
431
155k
      bounded_histogram, num_symbols,
432
155k
      WEBP_UNSAFE_FORGE_BIDI_INDEXABLE(HuffmanTree*, huff_tree,
433
155k
                                       3 * num_symbols * sizeof(*huff_tree)),
434
155k
      tree_depth_limit, huff_code->code_lengths);
435
  // Create the actual bit codes for the bit lengths.
436
155k
  ConvertBitDepthsToSymbols(huff_code);
437
155k
}