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