1use core::cmp::max;
9
10#[derive(Clone, Copy, Default)]
11pub struct HuffmanTree {
12 pub total_count_: u32,
13 pub index_left_: i16,
14 pub index_right_or_value_: i16,
15}
16
17impl HuffmanTree {
18 pub fn new(count: u32, left: i16, right: i16) -> Self {
19 Self {
20 total_count_: count,
21 index_left_: left,
22 index_right_or_value_: right,
23 }
24 }
25}
26
27pub fn BrotliSetDepth(p0: i32, pool: &mut [HuffmanTree], depth: &mut [u8], max_depth: i32) -> bool {
28 let mut stack: [i32; 16] = [0; 16];
29 let mut level: i32 = 0i32;
30 let mut p: i32 = p0;
31 stack[0] = -1i32;
32 loop {
33 if (pool[(p as usize)]).index_left_ as i32 >= 0i32 {
34 level += 1;
35 if level > max_depth {
36 return false;
37 }
38 stack[level as usize] = (pool[(p as usize)]).index_right_or_value_ as i32;
39 p = (pool[(p as usize)]).index_left_ as i32;
40 {
41 continue;
42 }
43 } else {
44 let pp = pool[(p as usize)];
45 depth[((pp).index_right_or_value_ as usize)] = level as u8;
46 }
47 while level >= 0i32 && (stack[level as usize] == -1i32) {
48 level -= 1;
49 }
50 if level < 0i32 {
51 return true;
52 }
53 p = stack[level as usize];
54 stack[level as usize] = -1i32;
55 }
56}
57
58pub trait HuffmanComparator {
59 fn Cmp(&self, a: &HuffmanTree, b: &HuffmanTree) -> bool;
60}
61pub struct SortHuffmanTree {}
62impl HuffmanComparator for SortHuffmanTree {
63 fn Cmp(&self, v0: &HuffmanTree, v1: &HuffmanTree) -> bool {
64 if v0.total_count_ != v1.total_count_ {
65 v0.total_count_ < v1.total_count_
66 } else {
67 v0.index_right_or_value_ > v1.index_right_or_value_
68 }
69 }
70}
71pub fn SortHuffmanTreeItems<Comparator: HuffmanComparator>(
72 items: &mut [HuffmanTree],
73 n: usize,
74 comparator: Comparator,
75) {
76 static gaps: [usize; 6] = [132, 57, 23, 10, 4, 1];
77 if n < 13 {
78 for i in 1..n {
79 let mut tmp: HuffmanTree = items[i];
80 let mut k: usize = i;
81 let mut j: usize = i.wrapping_sub(1);
82 while comparator.Cmp(&mut tmp, &mut items[j]) {
83 items[k] = items[j];
84 k = j;
85 if {
86 let _old = j;
87 j = j.wrapping_sub(1);
88 _old
89 } == 0
90 {
91 break;
92 }
93 }
94 items[k] = tmp;
95 }
96 } else {
97 let mut g: i32 = if n < 57usize { 2i32 } else { 0i32 };
98 while g < 6i32 {
99 {
100 let gap: usize = gaps[g as usize];
101 for i in gap..n {
102 let mut j: usize = i;
103 let mut tmp: HuffmanTree = items[i];
104 while j >= gap && (comparator.Cmp(&mut tmp, &mut items[j.wrapping_sub(gap)])) {
105 {
106 items[j] = items[j.wrapping_sub(gap)];
107 }
108 j = j.wrapping_sub(gap);
109 }
110 items[j] = tmp;
111 }
112 }
113 g += 1;
114 }
115 }
116}
117
118pub fn BrotliCreateHuffmanTree(
134 data: &[u32],
135 length: usize,
136 tree_limit: i32,
137 tree: &mut [HuffmanTree],
138 depth: &mut [u8],
139) {
140 let sentinel = HuffmanTree::new(u32::MAX, -1, -1);
141 let mut count_limit = 1u32;
142 'break1: loop {
143 {
144 let mut n: usize = 0usize;
145 let mut i: usize;
146 let mut j: usize;
147 let mut k: usize;
148 i = length;
149 while i != 0usize {
150 i = i.wrapping_sub(1);
151 if data[i] != 0 {
152 let count: u32 = max(data[i], count_limit);
153 tree[n] = HuffmanTree::new(count, -1, i as i16);
154 n = n.wrapping_add(1);
155 }
156 }
157 if n == 1 {
158 depth[((tree[0]).index_right_or_value_ as usize)] = 1u8;
159 {
160 break 'break1;
161 }
162 }
163 SortHuffmanTreeItems(tree, n, SortHuffmanTree {});
164 tree[n] = sentinel;
165 tree[n.wrapping_add(1)] = sentinel;
166 i = 0usize;
167 j = n.wrapping_add(1);
168 k = n.wrapping_sub(1);
169 while k != 0usize {
170 {
171 let left: usize;
172 let right: usize;
173 if (tree[i]).total_count_ <= (tree[j]).total_count_ {
174 left = i;
175 i = i.wrapping_add(1);
176 } else {
177 left = j;
178 j = j.wrapping_add(1);
179 }
180 if (tree[i]).total_count_ <= (tree[j]).total_count_ {
181 right = i;
182 i = i.wrapping_add(1);
183 } else {
184 right = j;
185 j = j.wrapping_add(1);
186 }
187 {
188 let j_end: usize = (2usize).wrapping_mul(n).wrapping_sub(k);
189 (tree[j_end]).total_count_ = (tree[left])
190 .total_count_
191 .wrapping_add((tree[right]).total_count_);
192 (tree[j_end]).index_left_ = left as i16;
193 (tree[j_end]).index_right_or_value_ = right as i16;
194 tree[j_end.wrapping_add(1)] = sentinel;
195 }
196 }
197 k = k.wrapping_sub(1);
198 }
199 if BrotliSetDepth(
200 (2usize).wrapping_mul(n).wrapping_sub(1) as i32,
201 tree,
202 depth,
203 tree_limit,
204 ) {
205 break 'break1;
206 }
207 }
208 count_limit = count_limit.wrapping_mul(2);
209 }
210}
211pub fn BrotliOptimizeHuffmanCountsForRle(
212 mut length: usize,
213 counts: &mut [u32],
214 good_for_rle: &mut [u8],
215) {
216 let mut nonzero_count: usize = 0usize;
217 let mut stride: usize;
218 let mut limit: usize;
219 let mut sum: usize;
220 let streak_limit: usize = 1240usize;
221 for i in 0usize..length {
222 if counts[i] != 0 {
223 nonzero_count = nonzero_count.wrapping_add(1);
224 }
225 }
226 if nonzero_count < 16usize {
227 return;
228 }
229 while length != 0usize && (counts[length.wrapping_sub(1)] == 0u32) {
230 length = length.wrapping_sub(1);
231 }
232 if length == 0usize {
233 return;
234 }
235 {
236 let mut nonzeros: usize = 0usize;
237 let mut smallest_nonzero: u32 = (1i32 << 30) as u32;
238 for i in 0usize..length {
239 if counts[i] != 0u32 {
240 nonzeros = nonzeros.wrapping_add(1);
241 if smallest_nonzero > counts[i] {
242 smallest_nonzero = counts[i];
243 }
244 }
245 }
246 if nonzeros < 5usize {
247 return;
248 }
249 if smallest_nonzero < 4u32 {
250 let zeros: usize = length.wrapping_sub(nonzeros);
251 if zeros < 6 {
252 for i in 1..length.wrapping_sub(1) {
253 if counts[i - 1] != 0 && counts[i] == 0 && counts[i + 1] != 0 {
254 counts[i] = 1;
255 }
256 }
257 }
258 }
259 if nonzeros < 28usize {
260 return;
261 }
262 }
263 for rle_item in good_for_rle.iter_mut() {
264 *rle_item = 0;
265 }
266 {
267 let mut symbol: u32 = counts[0];
268 let mut step: usize = 0usize;
269 for i in 0..=length {
270 if i == length || counts[i] != symbol {
271 if symbol == 0u32 && (step >= 5usize) || symbol != 0u32 && (step >= 7usize) {
272 for k in 0usize..step {
273 good_for_rle[i.wrapping_sub(k).wrapping_sub(1)] = 1u8;
274 }
275 }
276 step = 1;
277 if i != length {
278 symbol = counts[i];
279 }
280 } else {
281 step = step.wrapping_add(1);
282 }
283 }
284 }
285 stride = 0usize;
286 limit = (256u32)
287 .wrapping_mul((counts[0]).wrapping_add(counts[1]).wrapping_add(counts[2]))
288 .wrapping_div(3)
289 .wrapping_add(420) as usize;
290 sum = 0usize;
291 for i in 0..=length {
292 if i == length
293 || good_for_rle[i] != 0
294 || i != 0usize && (good_for_rle[i.wrapping_sub(1)] != 0)
295 || ((256u32).wrapping_mul(counts[i]) as usize)
296 .wrapping_sub(limit)
297 .wrapping_add(streak_limit)
298 >= (2usize).wrapping_mul(streak_limit)
299 {
300 if stride >= 4usize || stride >= 3usize && (sum == 0usize) {
301 let mut count: usize = sum
302 .wrapping_add(stride.wrapping_div(2))
303 .wrapping_div(stride);
304 if count == 0usize {
305 count = 1;
306 }
307 if sum == 0usize {
308 count = 0usize;
309 }
310 for k in 0usize..stride {
311 counts[i.wrapping_sub(k).wrapping_sub(1)] = count as u32;
312 }
313 }
314 stride = 0usize;
315 sum = 0usize;
316 if i < length.wrapping_sub(2) {
317 limit = (256u32)
318 .wrapping_mul(
319 (counts[i])
320 .wrapping_add(counts[i.wrapping_add(1)])
321 .wrapping_add(counts[i.wrapping_add(2)]),
322 )
323 .wrapping_div(3)
324 .wrapping_add(420) as usize;
325 } else if i < length {
326 limit = (256u32).wrapping_mul(counts[i]) as usize;
327 } else {
328 limit = 0usize;
329 }
330 }
331 stride = stride.wrapping_add(1);
332 if i != length {
333 sum = sum.wrapping_add(counts[i] as usize);
334 if stride >= 4usize {
335 limit = (256usize)
336 .wrapping_mul(sum)
337 .wrapping_add(stride.wrapping_div(2))
338 .wrapping_div(stride);
339 }
340 if stride == 4usize {
341 limit = limit.wrapping_add(120);
342 }
343 }
344 }
345}
346
347pub(crate) fn decide_over_rle_use(depth: &[u8], length: usize) -> (bool, bool) {
348 let mut total_reps_zero: usize = 0usize;
349 let mut total_reps_non_zero: usize = 0usize;
350 let mut count_reps_zero: usize = 1;
351 let mut count_reps_non_zero: usize = 1;
352 let mut i: usize;
353 i = 0usize;
354 while i < length {
355 let value: u8 = depth[i];
356 let mut reps: usize = 1;
357 let mut k: usize;
358 k = i.wrapping_add(1);
359 while k < length && (depth[k] as i32 == value as i32) {
360 {
361 reps = reps.wrapping_add(1);
362 }
363 k = k.wrapping_add(1);
364 }
365 if reps >= 3usize && (value as i32 == 0i32) {
366 total_reps_zero = total_reps_zero.wrapping_add(reps);
367 count_reps_zero = count_reps_zero.wrapping_add(1);
368 }
369 if reps >= 4usize && (value as i32 != 0i32) {
370 total_reps_non_zero = total_reps_non_zero.wrapping_add(reps);
371 count_reps_non_zero = count_reps_non_zero.wrapping_add(1);
372 }
373 i = i.wrapping_add(reps);
374 }
375 let use_rle_for_non_zero = total_reps_non_zero > count_reps_non_zero.wrapping_mul(2);
376 let use_rle_for_zero = total_reps_zero > count_reps_zero.wrapping_mul(2);
377
378 (use_rle_for_non_zero, use_rle_for_zero)
379}
380
381fn Reverse(v: &mut [u8], mut start: usize, mut end: usize) {
382 end = end.wrapping_sub(1);
383 while start < end {
384 v.swap(start, end);
385 start = start.wrapping_add(1);
386 end = end.wrapping_sub(1);
387 }
388}
389
390fn BrotliWriteHuffmanTreeRepetitions(
391 previous_value: u8,
392 value: u8,
393 mut repetitions: usize,
394 tree_size: &mut usize,
395 tree: &mut [u8],
396 extra_bits_data: &mut [u8],
397) {
398 if previous_value as i32 != value as i32 {
399 tree[*tree_size] = value;
400 extra_bits_data[*tree_size] = 0u8;
401 *tree_size = tree_size.wrapping_add(1);
402 repetitions = repetitions.wrapping_sub(1);
403 }
404 if repetitions == 7usize {
405 tree[*tree_size] = value;
406 extra_bits_data[*tree_size] = 0u8;
407 *tree_size = tree_size.wrapping_add(1);
408 repetitions = repetitions.wrapping_sub(1);
409 }
410 if repetitions < 3usize {
411 for _i in 0usize..repetitions {
412 tree[*tree_size] = value;
413 extra_bits_data[*tree_size] = 0u8;
414 *tree_size = tree_size.wrapping_add(1);
415 }
416 } else {
417 let start: usize = *tree_size;
418 repetitions = repetitions.wrapping_sub(3);
419 loop {
420 tree[*tree_size] = 16u8;
421 extra_bits_data[*tree_size] = (repetitions & 0x03) as u8;
422 *tree_size = tree_size.wrapping_add(1);
423 repetitions >>= 2i32;
424 if repetitions == 0usize {
425 break;
426 }
427 repetitions = repetitions.wrapping_sub(1);
428 }
429 Reverse(tree, start, *tree_size);
430 Reverse(extra_bits_data, start, *tree_size);
431 }
432}
433
434fn BrotliWriteHuffmanTreeRepetitionsZeros(
435 mut repetitions: usize,
436 tree_size: &mut usize,
437 tree: &mut [u8],
438 extra_bits_data: &mut [u8],
439) {
440 if repetitions == 11 {
441 tree[*tree_size] = 0u8;
442 extra_bits_data[*tree_size] = 0u8;
443 *tree_size = tree_size.wrapping_add(1);
444 repetitions = repetitions.wrapping_sub(1);
445 }
446 if repetitions < 3usize {
447 for _i in 0usize..repetitions {
448 tree[*tree_size] = 0u8;
449 extra_bits_data[*tree_size] = 0u8;
450 *tree_size = tree_size.wrapping_add(1);
451 }
452 } else {
453 let start: usize = *tree_size;
454 repetitions = repetitions.wrapping_sub(3);
455 loop {
456 tree[*tree_size] = 17u8;
457 extra_bits_data[*tree_size] = (repetitions & 0x7usize) as u8;
458 *tree_size = tree_size.wrapping_add(1);
459 repetitions >>= 3i32;
460 if repetitions == 0usize {
461 break;
462 }
463 repetitions = repetitions.wrapping_sub(1);
464 }
465 Reverse(tree, start, *tree_size);
466 Reverse(extra_bits_data, start, *tree_size);
467 }
468}
469
470pub fn BrotliWriteHuffmanTree(
471 depth: &[u8],
472 length: usize,
473 tree_size: &mut usize,
474 tree: &mut [u8],
475 extra_bits_data: &mut [u8],
476) {
477 let mut previous_value: u8 = 8u8;
478 let mut i: usize;
479 let mut use_rle_for_non_zero = false;
480 let mut use_rle_for_zero = false;
481 let mut new_length: usize = length;
482 i = 0usize;
483 'break27: while i < length {
484 {
485 if depth[length.wrapping_sub(i).wrapping_sub(1)] as i32 == 0i32 {
486 new_length = new_length.wrapping_sub(1);
487 } else {
488 break 'break27;
489 }
490 }
491 i = i.wrapping_add(1);
492 }
493 if length > 50 {
494 (use_rle_for_non_zero, use_rle_for_zero) = decide_over_rle_use(depth, new_length);
495 }
496 i = 0usize;
497 while i < new_length {
498 let value: u8 = depth[i];
499 let mut reps: usize = 1;
500 if value != 0 && use_rle_for_non_zero || value == 0 && use_rle_for_zero {
501 let mut k: usize;
502 k = i.wrapping_add(1);
503 while k < new_length && (depth[k] as i32 == value as i32) {
504 {
505 reps = reps.wrapping_add(1);
506 }
507 k = k.wrapping_add(1);
508 }
509 }
510 if value as i32 == 0i32 {
511 BrotliWriteHuffmanTreeRepetitionsZeros(reps, tree_size, tree, extra_bits_data);
512 } else {
513 BrotliWriteHuffmanTreeRepetitions(
514 previous_value,
515 value,
516 reps,
517 tree_size,
518 tree,
519 extra_bits_data,
520 );
521 previous_value = value;
522 }
523 i = i.wrapping_add(reps);
524 }
525}
526
527fn BrotliReverseBits(num_bits: usize, mut bits: u16) -> u16 {
528 static kLut: [usize; 16] = [
529 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf,
530 ];
531 let mut retval: usize = kLut[(bits as i32 & 0xfi32) as usize];
532 let mut i: usize;
533 i = 4usize;
534 while i < num_bits {
535 {
536 retval <<= 4i32;
537 bits = (bits as i32 >> 4) as u16;
538 retval |= kLut[(bits as i32 & 0xfi32) as usize];
539 }
540 i = i.wrapping_add(4);
541 }
542 retval >>= (0usize.wrapping_sub(num_bits) & 0x3usize);
543 retval as u16
544}
545const MAX_HUFFMAN_BITS: usize = 16;
546pub fn BrotliConvertBitDepthsToSymbols(depth: &[u8], len: usize, bits: &mut [u16]) {
547 let mut bl_count: [u16; MAX_HUFFMAN_BITS] = [0; MAX_HUFFMAN_BITS];
551 let mut next_code: [u16; MAX_HUFFMAN_BITS] = [0; MAX_HUFFMAN_BITS];
552 let mut code: i32 = 0i32;
553 for i in 0usize..len {
554 let _rhs = 1;
555 let _lhs = &mut bl_count[depth[i] as usize];
556 *_lhs = (*_lhs as i32 + _rhs) as u16;
557 }
558 bl_count[0] = 0u16;
559 next_code[0] = 0u16;
560 for i in 1..MAX_HUFFMAN_BITS {
561 code = (code + bl_count[i - 1] as i32) << 1;
562 next_code[i] = code as u16;
563 }
564 for i in 0usize..len {
565 if depth[i] != 0 {
566 bits[i] = BrotliReverseBits(depth[i] as usize, {
567 let _rhs = 1;
568 let _lhs = &mut next_code[depth[i] as usize];
569 let _old = *_lhs;
570 *_lhs = (*_lhs as i32 + _rhs) as u16;
571 _old
572 });
573 }
574 }
575}