Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(755)

Side by Side Diff: third_party/brotli/enc/entropy_encode.c

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

Powered by Google App Engine
This is Rietveld 408576698