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