xref: /aosp_15_r20/external/brotli/c/enc/entropy_encode.h (revision f4ee7fba7774faf2a30f13154332c0a06550dbc4)
1*f4ee7fbaSAndroid Build Coastguard Worker /* Copyright 2010 Google Inc. All Rights Reserved.
2*f4ee7fbaSAndroid Build Coastguard Worker 
3*f4ee7fbaSAndroid Build Coastguard Worker    Distributed under MIT license.
4*f4ee7fbaSAndroid Build Coastguard Worker    See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
5*f4ee7fbaSAndroid Build Coastguard Worker */
6*f4ee7fbaSAndroid Build Coastguard Worker 
7*f4ee7fbaSAndroid Build Coastguard Worker /* Entropy encoding (Huffman) utilities. */
8*f4ee7fbaSAndroid Build Coastguard Worker 
9*f4ee7fbaSAndroid Build Coastguard Worker #ifndef BROTLI_ENC_ENTROPY_ENCODE_H_
10*f4ee7fbaSAndroid Build Coastguard Worker #define BROTLI_ENC_ENTROPY_ENCODE_H_
11*f4ee7fbaSAndroid Build Coastguard Worker 
12*f4ee7fbaSAndroid Build Coastguard Worker #include "../common/platform.h"
13*f4ee7fbaSAndroid Build Coastguard Worker #include <brotli/types.h>
14*f4ee7fbaSAndroid Build Coastguard Worker 
15*f4ee7fbaSAndroid Build Coastguard Worker #if defined(__cplusplus) || defined(c_plusplus)
16*f4ee7fbaSAndroid Build Coastguard Worker extern "C" {
17*f4ee7fbaSAndroid Build Coastguard Worker #endif
18*f4ee7fbaSAndroid Build Coastguard Worker 
19*f4ee7fbaSAndroid Build Coastguard Worker /* A node of a Huffman tree. */
20*f4ee7fbaSAndroid Build Coastguard Worker typedef struct HuffmanTree {
21*f4ee7fbaSAndroid Build Coastguard Worker   uint32_t total_count_;
22*f4ee7fbaSAndroid Build Coastguard Worker   int16_t index_left_;
23*f4ee7fbaSAndroid Build Coastguard Worker   int16_t index_right_or_value_;
24*f4ee7fbaSAndroid Build Coastguard Worker } HuffmanTree;
25*f4ee7fbaSAndroid Build Coastguard Worker 
InitHuffmanTree(HuffmanTree * self,uint32_t count,int16_t left,int16_t right)26*f4ee7fbaSAndroid Build Coastguard Worker static BROTLI_INLINE void InitHuffmanTree(HuffmanTree* self, uint32_t count,
27*f4ee7fbaSAndroid Build Coastguard Worker     int16_t left, int16_t right) {
28*f4ee7fbaSAndroid Build Coastguard Worker   self->total_count_ = count;
29*f4ee7fbaSAndroid Build Coastguard Worker   self->index_left_ = left;
30*f4ee7fbaSAndroid Build Coastguard Worker   self->index_right_or_value_ = right;
31*f4ee7fbaSAndroid Build Coastguard Worker }
32*f4ee7fbaSAndroid Build Coastguard Worker 
33*f4ee7fbaSAndroid Build Coastguard Worker /* Returns 1 is assignment of depths succeeded, otherwise 0. */
34*f4ee7fbaSAndroid Build Coastguard Worker BROTLI_INTERNAL BROTLI_BOOL BrotliSetDepth(
35*f4ee7fbaSAndroid Build Coastguard Worker     int p, HuffmanTree* pool, uint8_t* depth, int max_depth);
36*f4ee7fbaSAndroid Build Coastguard Worker 
37*f4ee7fbaSAndroid Build Coastguard Worker /* This function will create a Huffman tree.
38*f4ee7fbaSAndroid Build Coastguard Worker 
39*f4ee7fbaSAndroid Build Coastguard Worker    The (data,length) contains the population counts.
40*f4ee7fbaSAndroid Build Coastguard Worker    The tree_limit is the maximum bit depth of the Huffman codes.
41*f4ee7fbaSAndroid Build Coastguard Worker 
42*f4ee7fbaSAndroid Build Coastguard Worker    The depth contains the tree, i.e., how many bits are used for
43*f4ee7fbaSAndroid Build Coastguard Worker    the symbol.
44*f4ee7fbaSAndroid Build Coastguard Worker 
45*f4ee7fbaSAndroid Build Coastguard Worker    The actual Huffman tree is constructed in the tree[] array, which has to
46*f4ee7fbaSAndroid Build Coastguard Worker    be at least 2 * length + 1 long.
47*f4ee7fbaSAndroid Build Coastguard Worker 
48*f4ee7fbaSAndroid Build Coastguard Worker    See http://en.wikipedia.org/wiki/Huffman_coding */
49*f4ee7fbaSAndroid Build Coastguard Worker BROTLI_INTERNAL void BrotliCreateHuffmanTree(const uint32_t* data,
50*f4ee7fbaSAndroid Build Coastguard Worker                                              const size_t length,
51*f4ee7fbaSAndroid Build Coastguard Worker                                              const int tree_limit,
52*f4ee7fbaSAndroid Build Coastguard Worker                                              HuffmanTree* tree,
53*f4ee7fbaSAndroid Build Coastguard Worker                                              uint8_t* depth);
54*f4ee7fbaSAndroid Build Coastguard Worker 
55*f4ee7fbaSAndroid Build Coastguard Worker /* Change the population counts in a way that the consequent
56*f4ee7fbaSAndroid Build Coastguard Worker    Huffman tree compression, especially its RLE-part will be more
57*f4ee7fbaSAndroid Build Coastguard Worker    likely to compress this data more efficiently.
58*f4ee7fbaSAndroid Build Coastguard Worker 
59*f4ee7fbaSAndroid Build Coastguard Worker    length contains the size of the histogram.
60*f4ee7fbaSAndroid Build Coastguard Worker    counts contains the population counts.
61*f4ee7fbaSAndroid Build Coastguard Worker    good_for_rle is a buffer of at least length size */
62*f4ee7fbaSAndroid Build Coastguard Worker BROTLI_INTERNAL void BrotliOptimizeHuffmanCountsForRle(
63*f4ee7fbaSAndroid Build Coastguard Worker     size_t length, uint32_t* counts, uint8_t* good_for_rle);
64*f4ee7fbaSAndroid Build Coastguard Worker 
65*f4ee7fbaSAndroid Build Coastguard Worker /* Write a Huffman tree from bit depths into the bit-stream representation
66*f4ee7fbaSAndroid Build Coastguard Worker    of a Huffman tree. The generated Huffman tree is to be compressed once
67*f4ee7fbaSAndroid Build Coastguard Worker    more using a Huffman tree */
68*f4ee7fbaSAndroid Build Coastguard Worker BROTLI_INTERNAL void BrotliWriteHuffmanTree(const uint8_t* depth,
69*f4ee7fbaSAndroid Build Coastguard Worker                                             size_t num,
70*f4ee7fbaSAndroid Build Coastguard Worker                                             size_t* tree_size,
71*f4ee7fbaSAndroid Build Coastguard Worker                                             uint8_t* tree,
72*f4ee7fbaSAndroid Build Coastguard Worker                                             uint8_t* extra_bits_data);
73*f4ee7fbaSAndroid Build Coastguard Worker 
74*f4ee7fbaSAndroid Build Coastguard Worker /* Get the actual bit values for a tree of bit depths. */
75*f4ee7fbaSAndroid Build Coastguard Worker BROTLI_INTERNAL void BrotliConvertBitDepthsToSymbols(const uint8_t* depth,
76*f4ee7fbaSAndroid Build Coastguard Worker                                                      size_t len,
77*f4ee7fbaSAndroid Build Coastguard Worker                                                      uint16_t* bits);
78*f4ee7fbaSAndroid Build Coastguard Worker 
79*f4ee7fbaSAndroid Build Coastguard Worker BROTLI_INTERNAL extern const size_t kBrotliShellGaps[6];
80*f4ee7fbaSAndroid Build Coastguard Worker /* Input size optimized Shell sort. */
81*f4ee7fbaSAndroid Build Coastguard Worker typedef BROTLI_BOOL (*HuffmanTreeComparator)(
82*f4ee7fbaSAndroid Build Coastguard Worker     const HuffmanTree*, const HuffmanTree*);
SortHuffmanTreeItems(HuffmanTree * items,const size_t n,HuffmanTreeComparator comparator)83*f4ee7fbaSAndroid Build Coastguard Worker static BROTLI_INLINE void SortHuffmanTreeItems(HuffmanTree* items,
84*f4ee7fbaSAndroid Build Coastguard Worker     const size_t n, HuffmanTreeComparator comparator) {
85*f4ee7fbaSAndroid Build Coastguard Worker   if (n < 13) {
86*f4ee7fbaSAndroid Build Coastguard Worker     /* Insertion sort. */
87*f4ee7fbaSAndroid Build Coastguard Worker     size_t i;
88*f4ee7fbaSAndroid Build Coastguard Worker     for (i = 1; i < n; ++i) {
89*f4ee7fbaSAndroid Build Coastguard Worker       HuffmanTree tmp = items[i];
90*f4ee7fbaSAndroid Build Coastguard Worker       size_t k = i;
91*f4ee7fbaSAndroid Build Coastguard Worker       size_t j = i - 1;
92*f4ee7fbaSAndroid Build Coastguard Worker       while (comparator(&tmp, &items[j])) {
93*f4ee7fbaSAndroid Build Coastguard Worker         items[k] = items[j];
94*f4ee7fbaSAndroid Build Coastguard Worker         k = j;
95*f4ee7fbaSAndroid Build Coastguard Worker         if (!j--) break;
96*f4ee7fbaSAndroid Build Coastguard Worker       }
97*f4ee7fbaSAndroid Build Coastguard Worker       items[k] = tmp;
98*f4ee7fbaSAndroid Build Coastguard Worker     }
99*f4ee7fbaSAndroid Build Coastguard Worker     return;
100*f4ee7fbaSAndroid Build Coastguard Worker   } else {
101*f4ee7fbaSAndroid Build Coastguard Worker     /* Shell sort. */
102*f4ee7fbaSAndroid Build Coastguard Worker     int g = n < 57 ? 2 : 0;
103*f4ee7fbaSAndroid Build Coastguard Worker     for (; g < 6; ++g) {
104*f4ee7fbaSAndroid Build Coastguard Worker       size_t gap = kBrotliShellGaps[g];
105*f4ee7fbaSAndroid Build Coastguard Worker       size_t i;
106*f4ee7fbaSAndroid Build Coastguard Worker       for (i = gap; i < n; ++i) {
107*f4ee7fbaSAndroid Build Coastguard Worker         size_t j = i;
108*f4ee7fbaSAndroid Build Coastguard Worker         HuffmanTree tmp = items[i];
109*f4ee7fbaSAndroid Build Coastguard Worker         for (; j >= gap && comparator(&tmp, &items[j - gap]); j -= gap) {
110*f4ee7fbaSAndroid Build Coastguard Worker           items[j] = items[j - gap];
111*f4ee7fbaSAndroid Build Coastguard Worker         }
112*f4ee7fbaSAndroid Build Coastguard Worker         items[j] = tmp;
113*f4ee7fbaSAndroid Build Coastguard Worker       }
114*f4ee7fbaSAndroid Build Coastguard Worker     }
115*f4ee7fbaSAndroid Build Coastguard Worker   }
116*f4ee7fbaSAndroid Build Coastguard Worker }
117*f4ee7fbaSAndroid Build Coastguard Worker 
118*f4ee7fbaSAndroid Build Coastguard Worker #if defined(__cplusplus) || defined(c_plusplus)
119*f4ee7fbaSAndroid Build Coastguard Worker }  /* extern "C" */
120*f4ee7fbaSAndroid Build Coastguard Worker #endif
121*f4ee7fbaSAndroid Build Coastguard Worker 
122*f4ee7fbaSAndroid Build Coastguard Worker #endif  /* BROTLI_ENC_ENTROPY_ENCODE_H_ */
123