Coverage Report

Created: 2026-09-28 06:47

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