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 #include "./entropy_encode.h"
10*f4ee7fbaSAndroid Build Coastguard Worker
11*f4ee7fbaSAndroid Build Coastguard Worker #include <string.h> /* memset */
12*f4ee7fbaSAndroid Build Coastguard Worker
13*f4ee7fbaSAndroid Build Coastguard Worker #include "../common/constants.h"
14*f4ee7fbaSAndroid Build Coastguard Worker #include "../common/platform.h"
15*f4ee7fbaSAndroid Build Coastguard Worker #include <brotli/types.h>
16*f4ee7fbaSAndroid Build Coastguard Worker
17*f4ee7fbaSAndroid Build Coastguard Worker #if defined(__cplusplus) || defined(c_plusplus)
18*f4ee7fbaSAndroid Build Coastguard Worker extern "C" {
19*f4ee7fbaSAndroid Build Coastguard Worker #endif
20*f4ee7fbaSAndroid Build Coastguard Worker
21*f4ee7fbaSAndroid Build Coastguard Worker const size_t kBrotliShellGaps[] = {132, 57, 23, 10, 4, 1};
22*f4ee7fbaSAndroid Build Coastguard Worker
BrotliSetDepth(int p0,HuffmanTree * pool,uint8_t * depth,int max_depth)23*f4ee7fbaSAndroid Build Coastguard Worker BROTLI_BOOL BrotliSetDepth(
24*f4ee7fbaSAndroid Build Coastguard Worker int p0, HuffmanTree* pool, uint8_t* depth, int max_depth) {
25*f4ee7fbaSAndroid Build Coastguard Worker int stack[16];
26*f4ee7fbaSAndroid Build Coastguard Worker int level = 0;
27*f4ee7fbaSAndroid Build Coastguard Worker int p = p0;
28*f4ee7fbaSAndroid Build Coastguard Worker BROTLI_DCHECK(max_depth <= 15);
29*f4ee7fbaSAndroid Build Coastguard Worker stack[0] = -1;
30*f4ee7fbaSAndroid Build Coastguard Worker while (BROTLI_TRUE) {
31*f4ee7fbaSAndroid Build Coastguard Worker if (pool[p].index_left_ >= 0) {
32*f4ee7fbaSAndroid Build Coastguard Worker level++;
33*f4ee7fbaSAndroid Build Coastguard Worker if (level > max_depth) return BROTLI_FALSE;
34*f4ee7fbaSAndroid Build Coastguard Worker stack[level] = pool[p].index_right_or_value_;
35*f4ee7fbaSAndroid Build Coastguard Worker p = pool[p].index_left_;
36*f4ee7fbaSAndroid Build Coastguard Worker continue;
37*f4ee7fbaSAndroid Build Coastguard Worker } else {
38*f4ee7fbaSAndroid Build Coastguard Worker depth[pool[p].index_right_or_value_] = (uint8_t)level;
39*f4ee7fbaSAndroid Build Coastguard Worker }
40*f4ee7fbaSAndroid Build Coastguard Worker while (level >= 0 && stack[level] == -1) level--;
41*f4ee7fbaSAndroid Build Coastguard Worker if (level < 0) return BROTLI_TRUE;
42*f4ee7fbaSAndroid Build Coastguard Worker p = stack[level];
43*f4ee7fbaSAndroid Build Coastguard Worker stack[level] = -1;
44*f4ee7fbaSAndroid Build Coastguard Worker }
45*f4ee7fbaSAndroid Build Coastguard Worker }
46*f4ee7fbaSAndroid Build Coastguard Worker
47*f4ee7fbaSAndroid Build Coastguard Worker /* Sort the root nodes, least popular first. */
SortHuffmanTree(const HuffmanTree * v0,const HuffmanTree * v1)48*f4ee7fbaSAndroid Build Coastguard Worker static BROTLI_INLINE BROTLI_BOOL SortHuffmanTree(
49*f4ee7fbaSAndroid Build Coastguard Worker const HuffmanTree* v0, const HuffmanTree* v1) {
50*f4ee7fbaSAndroid Build Coastguard Worker if (v0->total_count_ != v1->total_count_) {
51*f4ee7fbaSAndroid Build Coastguard Worker return TO_BROTLI_BOOL(v0->total_count_ < v1->total_count_);
52*f4ee7fbaSAndroid Build Coastguard Worker }
53*f4ee7fbaSAndroid Build Coastguard Worker return TO_BROTLI_BOOL(v0->index_right_or_value_ > v1->index_right_or_value_);
54*f4ee7fbaSAndroid Build Coastguard Worker }
55*f4ee7fbaSAndroid Build Coastguard Worker
56*f4ee7fbaSAndroid Build Coastguard Worker /* This function will create a Huffman tree.
57*f4ee7fbaSAndroid Build Coastguard Worker
58*f4ee7fbaSAndroid Build Coastguard Worker The catch here is that the tree cannot be arbitrarily deep.
59*f4ee7fbaSAndroid Build Coastguard Worker Brotli specifies a maximum depth of 15 bits for "code trees"
60*f4ee7fbaSAndroid Build Coastguard Worker and 7 bits for "code length code trees."
61*f4ee7fbaSAndroid Build Coastguard Worker
62*f4ee7fbaSAndroid Build Coastguard Worker count_limit is the value that is to be faked as the minimum value
63*f4ee7fbaSAndroid Build Coastguard Worker and this minimum value is raised until the tree matches the
64*f4ee7fbaSAndroid Build Coastguard Worker maximum length requirement.
65*f4ee7fbaSAndroid Build Coastguard Worker
66*f4ee7fbaSAndroid Build Coastguard Worker This algorithm is not of excellent performance for very long data blocks,
67*f4ee7fbaSAndroid Build Coastguard Worker especially when population counts are longer than 2**tree_limit, but
68*f4ee7fbaSAndroid Build Coastguard Worker we are not planning to use this with extremely long blocks.
69*f4ee7fbaSAndroid Build Coastguard Worker
70*f4ee7fbaSAndroid Build Coastguard Worker See http://en.wikipedia.org/wiki/Huffman_coding */
BrotliCreateHuffmanTree(const uint32_t * data,const size_t length,const int tree_limit,HuffmanTree * tree,uint8_t * depth)71*f4ee7fbaSAndroid Build Coastguard Worker void BrotliCreateHuffmanTree(const uint32_t* data,
72*f4ee7fbaSAndroid Build Coastguard Worker const size_t length,
73*f4ee7fbaSAndroid Build Coastguard Worker const int tree_limit,
74*f4ee7fbaSAndroid Build Coastguard Worker HuffmanTree* tree,
75*f4ee7fbaSAndroid Build Coastguard Worker uint8_t* depth) {
76*f4ee7fbaSAndroid Build Coastguard Worker uint32_t count_limit;
77*f4ee7fbaSAndroid Build Coastguard Worker HuffmanTree sentinel;
78*f4ee7fbaSAndroid Build Coastguard Worker InitHuffmanTree(&sentinel, BROTLI_UINT32_MAX, -1, -1);
79*f4ee7fbaSAndroid Build Coastguard Worker /* For block sizes below 64 kB, we never need to do a second iteration
80*f4ee7fbaSAndroid Build Coastguard Worker of this loop. Probably all of our block sizes will be smaller than
81*f4ee7fbaSAndroid Build Coastguard Worker that, so this loop is mostly of academic interest. If we actually
82*f4ee7fbaSAndroid Build Coastguard Worker would need this, we would be better off with the Katajainen algorithm. */
83*f4ee7fbaSAndroid Build Coastguard Worker for (count_limit = 1; ; count_limit *= 2) {
84*f4ee7fbaSAndroid Build Coastguard Worker size_t n = 0;
85*f4ee7fbaSAndroid Build Coastguard Worker size_t i;
86*f4ee7fbaSAndroid Build Coastguard Worker size_t j;
87*f4ee7fbaSAndroid Build Coastguard Worker size_t k;
88*f4ee7fbaSAndroid Build Coastguard Worker for (i = length; i != 0;) {
89*f4ee7fbaSAndroid Build Coastguard Worker --i;
90*f4ee7fbaSAndroid Build Coastguard Worker if (data[i]) {
91*f4ee7fbaSAndroid Build Coastguard Worker const uint32_t count = BROTLI_MAX(uint32_t, data[i], count_limit);
92*f4ee7fbaSAndroid Build Coastguard Worker InitHuffmanTree(&tree[n++], count, -1, (int16_t)i);
93*f4ee7fbaSAndroid Build Coastguard Worker }
94*f4ee7fbaSAndroid Build Coastguard Worker }
95*f4ee7fbaSAndroid Build Coastguard Worker
96*f4ee7fbaSAndroid Build Coastguard Worker if (n == 1) {
97*f4ee7fbaSAndroid Build Coastguard Worker depth[tree[0].index_right_or_value_] = 1; /* Only one element. */
98*f4ee7fbaSAndroid Build Coastguard Worker break;
99*f4ee7fbaSAndroid Build Coastguard Worker }
100*f4ee7fbaSAndroid Build Coastguard Worker
101*f4ee7fbaSAndroid Build Coastguard Worker SortHuffmanTreeItems(tree, n, SortHuffmanTree);
102*f4ee7fbaSAndroid Build Coastguard Worker
103*f4ee7fbaSAndroid Build Coastguard Worker /* The nodes are:
104*f4ee7fbaSAndroid Build Coastguard Worker [0, n): the sorted leaf nodes that we start with.
105*f4ee7fbaSAndroid Build Coastguard Worker [n]: we add a sentinel here.
106*f4ee7fbaSAndroid Build Coastguard Worker [n + 1, 2n): new parent nodes are added here, starting from
107*f4ee7fbaSAndroid Build Coastguard Worker (n+1). These are naturally in ascending order.
108*f4ee7fbaSAndroid Build Coastguard Worker [2n]: we add a sentinel at the end as well.
109*f4ee7fbaSAndroid Build Coastguard Worker There will be (2n+1) elements at the end. */
110*f4ee7fbaSAndroid Build Coastguard Worker tree[n] = sentinel;
111*f4ee7fbaSAndroid Build Coastguard Worker tree[n + 1] = sentinel;
112*f4ee7fbaSAndroid Build Coastguard Worker
113*f4ee7fbaSAndroid Build Coastguard Worker i = 0; /* Points to the next leaf node. */
114*f4ee7fbaSAndroid Build Coastguard Worker j = n + 1; /* Points to the next non-leaf node. */
115*f4ee7fbaSAndroid Build Coastguard Worker for (k = n - 1; k != 0; --k) {
116*f4ee7fbaSAndroid Build Coastguard Worker size_t left, right;
117*f4ee7fbaSAndroid Build Coastguard Worker if (tree[i].total_count_ <= tree[j].total_count_) {
118*f4ee7fbaSAndroid Build Coastguard Worker left = i;
119*f4ee7fbaSAndroid Build Coastguard Worker ++i;
120*f4ee7fbaSAndroid Build Coastguard Worker } else {
121*f4ee7fbaSAndroid Build Coastguard Worker left = j;
122*f4ee7fbaSAndroid Build Coastguard Worker ++j;
123*f4ee7fbaSAndroid Build Coastguard Worker }
124*f4ee7fbaSAndroid Build Coastguard Worker if (tree[i].total_count_ <= tree[j].total_count_) {
125*f4ee7fbaSAndroid Build Coastguard Worker right = i;
126*f4ee7fbaSAndroid Build Coastguard Worker ++i;
127*f4ee7fbaSAndroid Build Coastguard Worker } else {
128*f4ee7fbaSAndroid Build Coastguard Worker right = j;
129*f4ee7fbaSAndroid Build Coastguard Worker ++j;
130*f4ee7fbaSAndroid Build Coastguard Worker }
131*f4ee7fbaSAndroid Build Coastguard Worker
132*f4ee7fbaSAndroid Build Coastguard Worker {
133*f4ee7fbaSAndroid Build Coastguard Worker /* The sentinel node becomes the parent node. */
134*f4ee7fbaSAndroid Build Coastguard Worker size_t j_end = 2 * n - k;
135*f4ee7fbaSAndroid Build Coastguard Worker tree[j_end].total_count_ =
136*f4ee7fbaSAndroid Build Coastguard Worker tree[left].total_count_ + tree[right].total_count_;
137*f4ee7fbaSAndroid Build Coastguard Worker tree[j_end].index_left_ = (int16_t)left;
138*f4ee7fbaSAndroid Build Coastguard Worker tree[j_end].index_right_or_value_ = (int16_t)right;
139*f4ee7fbaSAndroid Build Coastguard Worker
140*f4ee7fbaSAndroid Build Coastguard Worker /* Add back the last sentinel node. */
141*f4ee7fbaSAndroid Build Coastguard Worker tree[j_end + 1] = sentinel;
142*f4ee7fbaSAndroid Build Coastguard Worker }
143*f4ee7fbaSAndroid Build Coastguard Worker }
144*f4ee7fbaSAndroid Build Coastguard Worker if (BrotliSetDepth((int)(2 * n - 1), &tree[0], depth, tree_limit)) {
145*f4ee7fbaSAndroid Build Coastguard Worker /* We need to pack the Huffman tree in tree_limit bits. If this was not
146*f4ee7fbaSAndroid Build Coastguard Worker successful, add fake entities to the lowest values and retry. */
147*f4ee7fbaSAndroid Build Coastguard Worker break;
148*f4ee7fbaSAndroid Build Coastguard Worker }
149*f4ee7fbaSAndroid Build Coastguard Worker }
150*f4ee7fbaSAndroid Build Coastguard Worker }
151*f4ee7fbaSAndroid Build Coastguard Worker
Reverse(uint8_t * v,size_t start,size_t end)152*f4ee7fbaSAndroid Build Coastguard Worker static void Reverse(uint8_t* v, size_t start, size_t end) {
153*f4ee7fbaSAndroid Build Coastguard Worker --end;
154*f4ee7fbaSAndroid Build Coastguard Worker while (start < end) {
155*f4ee7fbaSAndroid Build Coastguard Worker uint8_t tmp = v[start];
156*f4ee7fbaSAndroid Build Coastguard Worker v[start] = v[end];
157*f4ee7fbaSAndroid Build Coastguard Worker v[end] = tmp;
158*f4ee7fbaSAndroid Build Coastguard Worker ++start;
159*f4ee7fbaSAndroid Build Coastguard Worker --end;
160*f4ee7fbaSAndroid Build Coastguard Worker }
161*f4ee7fbaSAndroid Build Coastguard Worker }
162*f4ee7fbaSAndroid Build Coastguard Worker
BrotliWriteHuffmanTreeRepetitions(const uint8_t previous_value,const uint8_t value,size_t repetitions,size_t * tree_size,uint8_t * tree,uint8_t * extra_bits_data)163*f4ee7fbaSAndroid Build Coastguard Worker static void BrotliWriteHuffmanTreeRepetitions(
164*f4ee7fbaSAndroid Build Coastguard Worker const uint8_t previous_value,
165*f4ee7fbaSAndroid Build Coastguard Worker const uint8_t value,
166*f4ee7fbaSAndroid Build Coastguard Worker size_t repetitions,
167*f4ee7fbaSAndroid Build Coastguard Worker size_t* tree_size,
168*f4ee7fbaSAndroid Build Coastguard Worker uint8_t* tree,
169*f4ee7fbaSAndroid Build Coastguard Worker uint8_t* extra_bits_data) {
170*f4ee7fbaSAndroid Build Coastguard Worker BROTLI_DCHECK(repetitions > 0);
171*f4ee7fbaSAndroid Build Coastguard Worker if (previous_value != value) {
172*f4ee7fbaSAndroid Build Coastguard Worker tree[*tree_size] = value;
173*f4ee7fbaSAndroid Build Coastguard Worker extra_bits_data[*tree_size] = 0;
174*f4ee7fbaSAndroid Build Coastguard Worker ++(*tree_size);
175*f4ee7fbaSAndroid Build Coastguard Worker --repetitions;
176*f4ee7fbaSAndroid Build Coastguard Worker }
177*f4ee7fbaSAndroid Build Coastguard Worker if (repetitions == 7) {
178*f4ee7fbaSAndroid Build Coastguard Worker tree[*tree_size] = value;
179*f4ee7fbaSAndroid Build Coastguard Worker extra_bits_data[*tree_size] = 0;
180*f4ee7fbaSAndroid Build Coastguard Worker ++(*tree_size);
181*f4ee7fbaSAndroid Build Coastguard Worker --repetitions;
182*f4ee7fbaSAndroid Build Coastguard Worker }
183*f4ee7fbaSAndroid Build Coastguard Worker if (repetitions < 3) {
184*f4ee7fbaSAndroid Build Coastguard Worker size_t i;
185*f4ee7fbaSAndroid Build Coastguard Worker for (i = 0; i < repetitions; ++i) {
186*f4ee7fbaSAndroid Build Coastguard Worker tree[*tree_size] = value;
187*f4ee7fbaSAndroid Build Coastguard Worker extra_bits_data[*tree_size] = 0;
188*f4ee7fbaSAndroid Build Coastguard Worker ++(*tree_size);
189*f4ee7fbaSAndroid Build Coastguard Worker }
190*f4ee7fbaSAndroid Build Coastguard Worker } else {
191*f4ee7fbaSAndroid Build Coastguard Worker size_t start = *tree_size;
192*f4ee7fbaSAndroid Build Coastguard Worker repetitions -= 3;
193*f4ee7fbaSAndroid Build Coastguard Worker while (BROTLI_TRUE) {
194*f4ee7fbaSAndroid Build Coastguard Worker tree[*tree_size] = BROTLI_REPEAT_PREVIOUS_CODE_LENGTH;
195*f4ee7fbaSAndroid Build Coastguard Worker extra_bits_data[*tree_size] = repetitions & 0x3;
196*f4ee7fbaSAndroid Build Coastguard Worker ++(*tree_size);
197*f4ee7fbaSAndroid Build Coastguard Worker repetitions >>= 2;
198*f4ee7fbaSAndroid Build Coastguard Worker if (repetitions == 0) {
199*f4ee7fbaSAndroid Build Coastguard Worker break;
200*f4ee7fbaSAndroid Build Coastguard Worker }
201*f4ee7fbaSAndroid Build Coastguard Worker --repetitions;
202*f4ee7fbaSAndroid Build Coastguard Worker }
203*f4ee7fbaSAndroid Build Coastguard Worker Reverse(tree, start, *tree_size);
204*f4ee7fbaSAndroid Build Coastguard Worker Reverse(extra_bits_data, start, *tree_size);
205*f4ee7fbaSAndroid Build Coastguard Worker }
206*f4ee7fbaSAndroid Build Coastguard Worker }
207*f4ee7fbaSAndroid Build Coastguard Worker
BrotliWriteHuffmanTreeRepetitionsZeros(size_t repetitions,size_t * tree_size,uint8_t * tree,uint8_t * extra_bits_data)208*f4ee7fbaSAndroid Build Coastguard Worker static void BrotliWriteHuffmanTreeRepetitionsZeros(
209*f4ee7fbaSAndroid Build Coastguard Worker size_t repetitions,
210*f4ee7fbaSAndroid Build Coastguard Worker size_t* tree_size,
211*f4ee7fbaSAndroid Build Coastguard Worker uint8_t* tree,
212*f4ee7fbaSAndroid Build Coastguard Worker uint8_t* extra_bits_data) {
213*f4ee7fbaSAndroid Build Coastguard Worker if (repetitions == 11) {
214*f4ee7fbaSAndroid Build Coastguard Worker tree[*tree_size] = 0;
215*f4ee7fbaSAndroid Build Coastguard Worker extra_bits_data[*tree_size] = 0;
216*f4ee7fbaSAndroid Build Coastguard Worker ++(*tree_size);
217*f4ee7fbaSAndroid Build Coastguard Worker --repetitions;
218*f4ee7fbaSAndroid Build Coastguard Worker }
219*f4ee7fbaSAndroid Build Coastguard Worker if (repetitions < 3) {
220*f4ee7fbaSAndroid Build Coastguard Worker size_t i;
221*f4ee7fbaSAndroid Build Coastguard Worker for (i = 0; i < repetitions; ++i) {
222*f4ee7fbaSAndroid Build Coastguard Worker tree[*tree_size] = 0;
223*f4ee7fbaSAndroid Build Coastguard Worker extra_bits_data[*tree_size] = 0;
224*f4ee7fbaSAndroid Build Coastguard Worker ++(*tree_size);
225*f4ee7fbaSAndroid Build Coastguard Worker }
226*f4ee7fbaSAndroid Build Coastguard Worker } else {
227*f4ee7fbaSAndroid Build Coastguard Worker size_t start = *tree_size;
228*f4ee7fbaSAndroid Build Coastguard Worker repetitions -= 3;
229*f4ee7fbaSAndroid Build Coastguard Worker while (BROTLI_TRUE) {
230*f4ee7fbaSAndroid Build Coastguard Worker tree[*tree_size] = BROTLI_REPEAT_ZERO_CODE_LENGTH;
231*f4ee7fbaSAndroid Build Coastguard Worker extra_bits_data[*tree_size] = repetitions & 0x7;
232*f4ee7fbaSAndroid Build Coastguard Worker ++(*tree_size);
233*f4ee7fbaSAndroid Build Coastguard Worker repetitions >>= 3;
234*f4ee7fbaSAndroid Build Coastguard Worker if (repetitions == 0) {
235*f4ee7fbaSAndroid Build Coastguard Worker break;
236*f4ee7fbaSAndroid Build Coastguard Worker }
237*f4ee7fbaSAndroid Build Coastguard Worker --repetitions;
238*f4ee7fbaSAndroid Build Coastguard Worker }
239*f4ee7fbaSAndroid Build Coastguard Worker Reverse(tree, start, *tree_size);
240*f4ee7fbaSAndroid Build Coastguard Worker Reverse(extra_bits_data, start, *tree_size);
241*f4ee7fbaSAndroid Build Coastguard Worker }
242*f4ee7fbaSAndroid Build Coastguard Worker }
243*f4ee7fbaSAndroid Build Coastguard Worker
BrotliOptimizeHuffmanCountsForRle(size_t length,uint32_t * counts,uint8_t * good_for_rle)244*f4ee7fbaSAndroid Build Coastguard Worker void BrotliOptimizeHuffmanCountsForRle(size_t length, uint32_t* counts,
245*f4ee7fbaSAndroid Build Coastguard Worker uint8_t* good_for_rle) {
246*f4ee7fbaSAndroid Build Coastguard Worker size_t nonzero_count = 0;
247*f4ee7fbaSAndroid Build Coastguard Worker size_t stride;
248*f4ee7fbaSAndroid Build Coastguard Worker size_t limit;
249*f4ee7fbaSAndroid Build Coastguard Worker size_t sum;
250*f4ee7fbaSAndroid Build Coastguard Worker const size_t streak_limit = 1240;
251*f4ee7fbaSAndroid Build Coastguard Worker /* Let's make the Huffman code more compatible with RLE encoding. */
252*f4ee7fbaSAndroid Build Coastguard Worker size_t i;
253*f4ee7fbaSAndroid Build Coastguard Worker for (i = 0; i < length; i++) {
254*f4ee7fbaSAndroid Build Coastguard Worker if (counts[i]) {
255*f4ee7fbaSAndroid Build Coastguard Worker ++nonzero_count;
256*f4ee7fbaSAndroid Build Coastguard Worker }
257*f4ee7fbaSAndroid Build Coastguard Worker }
258*f4ee7fbaSAndroid Build Coastguard Worker if (nonzero_count < 16) {
259*f4ee7fbaSAndroid Build Coastguard Worker return;
260*f4ee7fbaSAndroid Build Coastguard Worker }
261*f4ee7fbaSAndroid Build Coastguard Worker while (length != 0 && counts[length - 1] == 0) {
262*f4ee7fbaSAndroid Build Coastguard Worker --length;
263*f4ee7fbaSAndroid Build Coastguard Worker }
264*f4ee7fbaSAndroid Build Coastguard Worker if (length == 0) {
265*f4ee7fbaSAndroid Build Coastguard Worker return; /* All zeros. */
266*f4ee7fbaSAndroid Build Coastguard Worker }
267*f4ee7fbaSAndroid Build Coastguard Worker /* Now counts[0..length - 1] does not have trailing zeros. */
268*f4ee7fbaSAndroid Build Coastguard Worker {
269*f4ee7fbaSAndroid Build Coastguard Worker size_t nonzeros = 0;
270*f4ee7fbaSAndroid Build Coastguard Worker uint32_t smallest_nonzero = 1 << 30;
271*f4ee7fbaSAndroid Build Coastguard Worker for (i = 0; i < length; ++i) {
272*f4ee7fbaSAndroid Build Coastguard Worker if (counts[i] != 0) {
273*f4ee7fbaSAndroid Build Coastguard Worker ++nonzeros;
274*f4ee7fbaSAndroid Build Coastguard Worker if (smallest_nonzero > counts[i]) {
275*f4ee7fbaSAndroid Build Coastguard Worker smallest_nonzero = counts[i];
276*f4ee7fbaSAndroid Build Coastguard Worker }
277*f4ee7fbaSAndroid Build Coastguard Worker }
278*f4ee7fbaSAndroid Build Coastguard Worker }
279*f4ee7fbaSAndroid Build Coastguard Worker if (nonzeros < 5) {
280*f4ee7fbaSAndroid Build Coastguard Worker /* Small histogram will model it well. */
281*f4ee7fbaSAndroid Build Coastguard Worker return;
282*f4ee7fbaSAndroid Build Coastguard Worker }
283*f4ee7fbaSAndroid Build Coastguard Worker if (smallest_nonzero < 4) {
284*f4ee7fbaSAndroid Build Coastguard Worker size_t zeros = length - nonzeros;
285*f4ee7fbaSAndroid Build Coastguard Worker if (zeros < 6) {
286*f4ee7fbaSAndroid Build Coastguard Worker for (i = 1; i < length - 1; ++i) {
287*f4ee7fbaSAndroid Build Coastguard Worker if (counts[i - 1] != 0 && counts[i] == 0 && counts[i + 1] != 0) {
288*f4ee7fbaSAndroid Build Coastguard Worker counts[i] = 1;
289*f4ee7fbaSAndroid Build Coastguard Worker }
290*f4ee7fbaSAndroid Build Coastguard Worker }
291*f4ee7fbaSAndroid Build Coastguard Worker }
292*f4ee7fbaSAndroid Build Coastguard Worker }
293*f4ee7fbaSAndroid Build Coastguard Worker if (nonzeros < 28) {
294*f4ee7fbaSAndroid Build Coastguard Worker return;
295*f4ee7fbaSAndroid Build Coastguard Worker }
296*f4ee7fbaSAndroid Build Coastguard Worker }
297*f4ee7fbaSAndroid Build Coastguard Worker /* 2) Let's mark all population counts that already can be encoded
298*f4ee7fbaSAndroid Build Coastguard Worker with an RLE code. */
299*f4ee7fbaSAndroid Build Coastguard Worker memset(good_for_rle, 0, length);
300*f4ee7fbaSAndroid Build Coastguard Worker {
301*f4ee7fbaSAndroid Build Coastguard Worker /* Let's not spoil any of the existing good RLE codes.
302*f4ee7fbaSAndroid Build Coastguard Worker Mark any seq of 0's that is longer as 5 as a good_for_rle.
303*f4ee7fbaSAndroid Build Coastguard Worker Mark any seq of non-0's that is longer as 7 as a good_for_rle. */
304*f4ee7fbaSAndroid Build Coastguard Worker uint32_t symbol = counts[0];
305*f4ee7fbaSAndroid Build Coastguard Worker size_t step = 0;
306*f4ee7fbaSAndroid Build Coastguard Worker for (i = 0; i <= length; ++i) {
307*f4ee7fbaSAndroid Build Coastguard Worker if (i == length || counts[i] != symbol) {
308*f4ee7fbaSAndroid Build Coastguard Worker if ((symbol == 0 && step >= 5) ||
309*f4ee7fbaSAndroid Build Coastguard Worker (symbol != 0 && step >= 7)) {
310*f4ee7fbaSAndroid Build Coastguard Worker size_t k;
311*f4ee7fbaSAndroid Build Coastguard Worker for (k = 0; k < step; ++k) {
312*f4ee7fbaSAndroid Build Coastguard Worker good_for_rle[i - k - 1] = 1;
313*f4ee7fbaSAndroid Build Coastguard Worker }
314*f4ee7fbaSAndroid Build Coastguard Worker }
315*f4ee7fbaSAndroid Build Coastguard Worker step = 1;
316*f4ee7fbaSAndroid Build Coastguard Worker if (i != length) {
317*f4ee7fbaSAndroid Build Coastguard Worker symbol = counts[i];
318*f4ee7fbaSAndroid Build Coastguard Worker }
319*f4ee7fbaSAndroid Build Coastguard Worker } else {
320*f4ee7fbaSAndroid Build Coastguard Worker ++step;
321*f4ee7fbaSAndroid Build Coastguard Worker }
322*f4ee7fbaSAndroid Build Coastguard Worker }
323*f4ee7fbaSAndroid Build Coastguard Worker }
324*f4ee7fbaSAndroid Build Coastguard Worker /* 3) Let's replace those population counts that lead to more RLE codes.
325*f4ee7fbaSAndroid Build Coastguard Worker Math here is in 24.8 fixed point representation. */
326*f4ee7fbaSAndroid Build Coastguard Worker stride = 0;
327*f4ee7fbaSAndroid Build Coastguard Worker limit = 256 * (counts[0] + counts[1] + counts[2]) / 3 + 420;
328*f4ee7fbaSAndroid Build Coastguard Worker sum = 0;
329*f4ee7fbaSAndroid Build Coastguard Worker for (i = 0; i <= length; ++i) {
330*f4ee7fbaSAndroid Build Coastguard Worker if (i == length || good_for_rle[i] ||
331*f4ee7fbaSAndroid Build Coastguard Worker (i != 0 && good_for_rle[i - 1]) ||
332*f4ee7fbaSAndroid Build Coastguard Worker (256 * counts[i] - limit + streak_limit) >= 2 * streak_limit) {
333*f4ee7fbaSAndroid Build Coastguard Worker if (stride >= 4 || (stride >= 3 && sum == 0)) {
334*f4ee7fbaSAndroid Build Coastguard Worker size_t k;
335*f4ee7fbaSAndroid Build Coastguard Worker /* The stride must end, collapse what we have, if we have enough (4). */
336*f4ee7fbaSAndroid Build Coastguard Worker size_t count = (sum + stride / 2) / stride;
337*f4ee7fbaSAndroid Build Coastguard Worker if (count == 0) {
338*f4ee7fbaSAndroid Build Coastguard Worker count = 1;
339*f4ee7fbaSAndroid Build Coastguard Worker }
340*f4ee7fbaSAndroid Build Coastguard Worker if (sum == 0) {
341*f4ee7fbaSAndroid Build Coastguard Worker /* Don't make an all zeros stride to be upgraded to ones. */
342*f4ee7fbaSAndroid Build Coastguard Worker count = 0;
343*f4ee7fbaSAndroid Build Coastguard Worker }
344*f4ee7fbaSAndroid Build Coastguard Worker for (k = 0; k < stride; ++k) {
345*f4ee7fbaSAndroid Build Coastguard Worker /* We don't want to change value at counts[i],
346*f4ee7fbaSAndroid Build Coastguard Worker that is already belonging to the next stride. Thus - 1. */
347*f4ee7fbaSAndroid Build Coastguard Worker counts[i - k - 1] = (uint32_t)count;
348*f4ee7fbaSAndroid Build Coastguard Worker }
349*f4ee7fbaSAndroid Build Coastguard Worker }
350*f4ee7fbaSAndroid Build Coastguard Worker stride = 0;
351*f4ee7fbaSAndroid Build Coastguard Worker sum = 0;
352*f4ee7fbaSAndroid Build Coastguard Worker if (i < length - 2) {
353*f4ee7fbaSAndroid Build Coastguard Worker /* All interesting strides have a count of at least 4, */
354*f4ee7fbaSAndroid Build Coastguard Worker /* at least when non-zeros. */
355*f4ee7fbaSAndroid Build Coastguard Worker limit = 256 * (counts[i] + counts[i + 1] + counts[i + 2]) / 3 + 420;
356*f4ee7fbaSAndroid Build Coastguard Worker } else if (i < length) {
357*f4ee7fbaSAndroid Build Coastguard Worker limit = 256 * counts[i];
358*f4ee7fbaSAndroid Build Coastguard Worker } else {
359*f4ee7fbaSAndroid Build Coastguard Worker limit = 0;
360*f4ee7fbaSAndroid Build Coastguard Worker }
361*f4ee7fbaSAndroid Build Coastguard Worker }
362*f4ee7fbaSAndroid Build Coastguard Worker ++stride;
363*f4ee7fbaSAndroid Build Coastguard Worker if (i != length) {
364*f4ee7fbaSAndroid Build Coastguard Worker sum += counts[i];
365*f4ee7fbaSAndroid Build Coastguard Worker if (stride >= 4) {
366*f4ee7fbaSAndroid Build Coastguard Worker limit = (256 * sum + stride / 2) / stride;
367*f4ee7fbaSAndroid Build Coastguard Worker }
368*f4ee7fbaSAndroid Build Coastguard Worker if (stride == 4) {
369*f4ee7fbaSAndroid Build Coastguard Worker limit += 120;
370*f4ee7fbaSAndroid Build Coastguard Worker }
371*f4ee7fbaSAndroid Build Coastguard Worker }
372*f4ee7fbaSAndroid Build Coastguard Worker }
373*f4ee7fbaSAndroid Build Coastguard Worker }
374*f4ee7fbaSAndroid Build Coastguard Worker
DecideOverRleUse(const uint8_t * depth,const size_t length,BROTLI_BOOL * use_rle_for_non_zero,BROTLI_BOOL * use_rle_for_zero)375*f4ee7fbaSAndroid Build Coastguard Worker static void DecideOverRleUse(const uint8_t* depth, const size_t length,
376*f4ee7fbaSAndroid Build Coastguard Worker BROTLI_BOOL* use_rle_for_non_zero,
377*f4ee7fbaSAndroid Build Coastguard Worker BROTLI_BOOL* use_rle_for_zero) {
378*f4ee7fbaSAndroid Build Coastguard Worker size_t total_reps_zero = 0;
379*f4ee7fbaSAndroid Build Coastguard Worker size_t total_reps_non_zero = 0;
380*f4ee7fbaSAndroid Build Coastguard Worker size_t count_reps_zero = 1;
381*f4ee7fbaSAndroid Build Coastguard Worker size_t count_reps_non_zero = 1;
382*f4ee7fbaSAndroid Build Coastguard Worker size_t i;
383*f4ee7fbaSAndroid Build Coastguard Worker for (i = 0; i < length;) {
384*f4ee7fbaSAndroid Build Coastguard Worker const uint8_t value = depth[i];
385*f4ee7fbaSAndroid Build Coastguard Worker size_t reps = 1;
386*f4ee7fbaSAndroid Build Coastguard Worker size_t k;
387*f4ee7fbaSAndroid Build Coastguard Worker for (k = i + 1; k < length && depth[k] == value; ++k) {
388*f4ee7fbaSAndroid Build Coastguard Worker ++reps;
389*f4ee7fbaSAndroid Build Coastguard Worker }
390*f4ee7fbaSAndroid Build Coastguard Worker if (reps >= 3 && value == 0) {
391*f4ee7fbaSAndroid Build Coastguard Worker total_reps_zero += reps;
392*f4ee7fbaSAndroid Build Coastguard Worker ++count_reps_zero;
393*f4ee7fbaSAndroid Build Coastguard Worker }
394*f4ee7fbaSAndroid Build Coastguard Worker if (reps >= 4 && value != 0) {
395*f4ee7fbaSAndroid Build Coastguard Worker total_reps_non_zero += reps;
396*f4ee7fbaSAndroid Build Coastguard Worker ++count_reps_non_zero;
397*f4ee7fbaSAndroid Build Coastguard Worker }
398*f4ee7fbaSAndroid Build Coastguard Worker i += reps;
399*f4ee7fbaSAndroid Build Coastguard Worker }
400*f4ee7fbaSAndroid Build Coastguard Worker *use_rle_for_non_zero =
401*f4ee7fbaSAndroid Build Coastguard Worker TO_BROTLI_BOOL(total_reps_non_zero > count_reps_non_zero * 2);
402*f4ee7fbaSAndroid Build Coastguard Worker *use_rle_for_zero = TO_BROTLI_BOOL(total_reps_zero > count_reps_zero * 2);
403*f4ee7fbaSAndroid Build Coastguard Worker }
404*f4ee7fbaSAndroid Build Coastguard Worker
BrotliWriteHuffmanTree(const uint8_t * depth,size_t length,size_t * tree_size,uint8_t * tree,uint8_t * extra_bits_data)405*f4ee7fbaSAndroid Build Coastguard Worker void BrotliWriteHuffmanTree(const uint8_t* depth,
406*f4ee7fbaSAndroid Build Coastguard Worker size_t length,
407*f4ee7fbaSAndroid Build Coastguard Worker size_t* tree_size,
408*f4ee7fbaSAndroid Build Coastguard Worker uint8_t* tree,
409*f4ee7fbaSAndroid Build Coastguard Worker uint8_t* extra_bits_data) {
410*f4ee7fbaSAndroid Build Coastguard Worker uint8_t previous_value = BROTLI_INITIAL_REPEATED_CODE_LENGTH;
411*f4ee7fbaSAndroid Build Coastguard Worker size_t i;
412*f4ee7fbaSAndroid Build Coastguard Worker BROTLI_BOOL use_rle_for_non_zero = BROTLI_FALSE;
413*f4ee7fbaSAndroid Build Coastguard Worker BROTLI_BOOL use_rle_for_zero = BROTLI_FALSE;
414*f4ee7fbaSAndroid Build Coastguard Worker
415*f4ee7fbaSAndroid Build Coastguard Worker /* Throw away trailing zeros. */
416*f4ee7fbaSAndroid Build Coastguard Worker size_t new_length = length;
417*f4ee7fbaSAndroid Build Coastguard Worker for (i = 0; i < length; ++i) {
418*f4ee7fbaSAndroid Build Coastguard Worker if (depth[length - i - 1] == 0) {
419*f4ee7fbaSAndroid Build Coastguard Worker --new_length;
420*f4ee7fbaSAndroid Build Coastguard Worker } else {
421*f4ee7fbaSAndroid Build Coastguard Worker break;
422*f4ee7fbaSAndroid Build Coastguard Worker }
423*f4ee7fbaSAndroid Build Coastguard Worker }
424*f4ee7fbaSAndroid Build Coastguard Worker
425*f4ee7fbaSAndroid Build Coastguard Worker /* First gather statistics on if it is a good idea to do RLE. */
426*f4ee7fbaSAndroid Build Coastguard Worker if (length > 50) {
427*f4ee7fbaSAndroid Build Coastguard Worker /* Find RLE coding for longer codes.
428*f4ee7fbaSAndroid Build Coastguard Worker Shorter codes seem not to benefit from RLE. */
429*f4ee7fbaSAndroid Build Coastguard Worker DecideOverRleUse(depth, new_length,
430*f4ee7fbaSAndroid Build Coastguard Worker &use_rle_for_non_zero, &use_rle_for_zero);
431*f4ee7fbaSAndroid Build Coastguard Worker }
432*f4ee7fbaSAndroid Build Coastguard Worker
433*f4ee7fbaSAndroid Build Coastguard Worker /* Actual RLE coding. */
434*f4ee7fbaSAndroid Build Coastguard Worker for (i = 0; i < new_length;) {
435*f4ee7fbaSAndroid Build Coastguard Worker const uint8_t value = depth[i];
436*f4ee7fbaSAndroid Build Coastguard Worker size_t reps = 1;
437*f4ee7fbaSAndroid Build Coastguard Worker if ((value != 0 && use_rle_for_non_zero) ||
438*f4ee7fbaSAndroid Build Coastguard Worker (value == 0 && use_rle_for_zero)) {
439*f4ee7fbaSAndroid Build Coastguard Worker size_t k;
440*f4ee7fbaSAndroid Build Coastguard Worker for (k = i + 1; k < new_length && depth[k] == value; ++k) {
441*f4ee7fbaSAndroid Build Coastguard Worker ++reps;
442*f4ee7fbaSAndroid Build Coastguard Worker }
443*f4ee7fbaSAndroid Build Coastguard Worker }
444*f4ee7fbaSAndroid Build Coastguard Worker if (value == 0) {
445*f4ee7fbaSAndroid Build Coastguard Worker BrotliWriteHuffmanTreeRepetitionsZeros(
446*f4ee7fbaSAndroid Build Coastguard Worker reps, tree_size, tree, extra_bits_data);
447*f4ee7fbaSAndroid Build Coastguard Worker } else {
448*f4ee7fbaSAndroid Build Coastguard Worker BrotliWriteHuffmanTreeRepetitions(previous_value,
449*f4ee7fbaSAndroid Build Coastguard Worker value, reps, tree_size,
450*f4ee7fbaSAndroid Build Coastguard Worker tree, extra_bits_data);
451*f4ee7fbaSAndroid Build Coastguard Worker previous_value = value;
452*f4ee7fbaSAndroid Build Coastguard Worker }
453*f4ee7fbaSAndroid Build Coastguard Worker i += reps;
454*f4ee7fbaSAndroid Build Coastguard Worker }
455*f4ee7fbaSAndroid Build Coastguard Worker }
456*f4ee7fbaSAndroid Build Coastguard Worker
BrotliReverseBits(size_t num_bits,uint16_t bits)457*f4ee7fbaSAndroid Build Coastguard Worker static uint16_t BrotliReverseBits(size_t num_bits, uint16_t bits) {
458*f4ee7fbaSAndroid Build Coastguard Worker static const size_t kLut[16] = { /* Pre-reversed 4-bit values. */
459*f4ee7fbaSAndroid Build Coastguard Worker 0x00, 0x08, 0x04, 0x0C, 0x02, 0x0A, 0x06, 0x0E,
460*f4ee7fbaSAndroid Build Coastguard Worker 0x01, 0x09, 0x05, 0x0D, 0x03, 0x0B, 0x07, 0x0F
461*f4ee7fbaSAndroid Build Coastguard Worker };
462*f4ee7fbaSAndroid Build Coastguard Worker size_t retval = kLut[bits & 0x0F];
463*f4ee7fbaSAndroid Build Coastguard Worker size_t i;
464*f4ee7fbaSAndroid Build Coastguard Worker for (i = 4; i < num_bits; i += 4) {
465*f4ee7fbaSAndroid Build Coastguard Worker retval <<= 4;
466*f4ee7fbaSAndroid Build Coastguard Worker bits = (uint16_t)(bits >> 4);
467*f4ee7fbaSAndroid Build Coastguard Worker retval |= kLut[bits & 0x0F];
468*f4ee7fbaSAndroid Build Coastguard Worker }
469*f4ee7fbaSAndroid Build Coastguard Worker retval >>= ((0 - num_bits) & 0x03);
470*f4ee7fbaSAndroid Build Coastguard Worker return (uint16_t)retval;
471*f4ee7fbaSAndroid Build Coastguard Worker }
472*f4ee7fbaSAndroid Build Coastguard Worker
473*f4ee7fbaSAndroid Build Coastguard Worker /* 0..15 are values for bits */
474*f4ee7fbaSAndroid Build Coastguard Worker #define MAX_HUFFMAN_BITS 16
475*f4ee7fbaSAndroid Build Coastguard Worker
BrotliConvertBitDepthsToSymbols(const uint8_t * depth,size_t len,uint16_t * bits)476*f4ee7fbaSAndroid Build Coastguard Worker void BrotliConvertBitDepthsToSymbols(const uint8_t* depth,
477*f4ee7fbaSAndroid Build Coastguard Worker size_t len,
478*f4ee7fbaSAndroid Build Coastguard Worker uint16_t* bits) {
479*f4ee7fbaSAndroid Build Coastguard Worker /* In Brotli, all bit depths are [1..15]
480*f4ee7fbaSAndroid Build Coastguard Worker 0 bit depth means that the symbol does not exist. */
481*f4ee7fbaSAndroid Build Coastguard Worker uint16_t bl_count[MAX_HUFFMAN_BITS] = { 0 };
482*f4ee7fbaSAndroid Build Coastguard Worker uint16_t next_code[MAX_HUFFMAN_BITS];
483*f4ee7fbaSAndroid Build Coastguard Worker size_t i;
484*f4ee7fbaSAndroid Build Coastguard Worker int code = 0;
485*f4ee7fbaSAndroid Build Coastguard Worker for (i = 0; i < len; ++i) {
486*f4ee7fbaSAndroid Build Coastguard Worker ++bl_count[depth[i]];
487*f4ee7fbaSAndroid Build Coastguard Worker }
488*f4ee7fbaSAndroid Build Coastguard Worker bl_count[0] = 0;
489*f4ee7fbaSAndroid Build Coastguard Worker next_code[0] = 0;
490*f4ee7fbaSAndroid Build Coastguard Worker for (i = 1; i < MAX_HUFFMAN_BITS; ++i) {
491*f4ee7fbaSAndroid Build Coastguard Worker code = (code + bl_count[i - 1]) << 1;
492*f4ee7fbaSAndroid Build Coastguard Worker next_code[i] = (uint16_t)code;
493*f4ee7fbaSAndroid Build Coastguard Worker }
494*f4ee7fbaSAndroid Build Coastguard Worker for (i = 0; i < len; ++i) {
495*f4ee7fbaSAndroid Build Coastguard Worker if (depth[i]) {
496*f4ee7fbaSAndroid Build Coastguard Worker bits[i] = BrotliReverseBits(depth[i], next_code[depth[i]]++);
497*f4ee7fbaSAndroid Build Coastguard Worker }
498*f4ee7fbaSAndroid Build Coastguard Worker }
499*f4ee7fbaSAndroid Build Coastguard Worker }
500*f4ee7fbaSAndroid Build Coastguard Worker
501*f4ee7fbaSAndroid Build Coastguard Worker #if defined(__cplusplus) || defined(c_plusplus)
502*f4ee7fbaSAndroid Build Coastguard Worker } /* extern "C" */
503*f4ee7fbaSAndroid Build Coastguard Worker #endif
504