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