1#![allow(dead_code)]
2use super::backward_references::BrotliEncoderParams;
3use super::vectorization::{sum8i, v256, v256i, Mem256f};
4
5use super::super::alloc;
6use super::super::alloc::{Allocator, SliceWrapper, SliceWrapperMut};
7use super::bit_cost::BrotliPopulationCost;
8use super::block_split::BlockSplit;
9use super::cluster::{BrotliHistogramBitCostDistance, BrotliHistogramCombine, HistogramPair};
10use super::command::Command;
11use super::histogram::{
12 ClearHistograms, CostAccessors, HistogramAddHistogram, HistogramAddItem, HistogramAddVector,
13 HistogramClear, HistogramCommand, HistogramDistance, HistogramLiteral,
14};
15use super::util::{brotli_max_uint8_t, brotli_min_size_t, FastLog2};
16use core;
17#[cfg(feature = "simd")]
18use core::simd::prelude::{SimdFloat, SimdPartialOrd};
19
20static kMaxLiteralHistograms: usize = 100usize;
21
22static kMaxCommandHistograms: usize = 50usize;
23
24static kLiteralBlockSwitchCost: super::util::floatX = 28.1 as super::util::floatX;
25
26static kCommandBlockSwitchCost: super::util::floatX = 13.5 as super::util::floatX;
27
28static kDistanceBlockSwitchCost: super::util::floatX = 14.6 as super::util::floatX;
29
30static kLiteralStrideLength: usize = 70usize;
31
32static kCommandStrideLength: usize = 40usize;
33
34static kSymbolsPerLiteralHistogram: usize = 544usize;
35
36static kSymbolsPerCommandHistogram: usize = 530usize;
37
38static kSymbolsPerDistanceHistogram: usize = 544usize;
39
40static kMinLengthForBlockSplitting: usize = 128usize;
41
42static kIterMulForRefining: usize = 2usize;
43
44static kMinItersForRefining: usize = 100usize;
45
46#[inline(always)]
47fn update_cost_and_signal(
48 num_histograms32: u32,
49 ix: usize,
50 min_cost: super::util::floatX,
51 block_switch_cost: super::util::floatX,
52 cost: &mut [Mem256f],
53 switch_signal: &mut [u8],
54) {
55 if (false) {
56 for k in 0..((num_histograms32 as usize + 7) >> 3 << 3) {
58 cost[k >> 3][k & 7] -= min_cost;
59 if (cost[k >> 3][k & 7] >= block_switch_cost) {
60 let mask = (1_u8 << (k & 7));
61 cost[k >> 3][k & 7] = block_switch_cost;
62 switch_signal[ix + (k >> 3)] |= mask;
63 }
64 }
65 return;
66 }
67 if (false) {
68 for k in 0..((num_histograms32 as usize + 7) >> 3 << 3) {
71 cost[k >> 3][k & 7] -= min_cost;
72 let cmpge = if (cost[k >> 3][k & 7] >= block_switch_cost) {
73 0xff
74 } else {
75 0
76 };
77 let mask = (1_u8 << (k & 7));
78 let bits = cmpge & mask;
79 if block_switch_cost < cost[k >> 3][k & 7] {
80 cost[k >> 3][k & 7] = block_switch_cost;
81 }
82 switch_signal[ix + (k >> 3)] |= bits;
83 }
87 return;
88 }
89 let ymm_min_cost = v256::splat(min_cost);
90 let ymm_block_switch_cost = v256::splat(block_switch_cost);
91 let ymm_and_mask = v256i::from([
92 1 << 0,
93 1 << 1,
94 1 << 2,
95 1 << 3,
96 1 << 4,
97 1 << 5,
98 1 << 6,
99 1 << 7,
100 ]);
101
102 for (index, cost_it) in cost[..((num_histograms32 as usize + 7) >> 3)]
103 .iter_mut()
104 .enumerate()
105 {
106 let mut ymm_cost = *cost_it;
107 let costk_minus_min_cost = ymm_cost - ymm_min_cost;
108 let ymm_cmpge: v256i = costk_minus_min_cost.simd_ge(ymm_block_switch_cost).to_int();
109 let ymm_bits = ymm_cmpge & ymm_and_mask;
110 let result = sum8i(ymm_bits);
111 switch_signal[ix + index] |= result as u8;
113 ymm_cost = costk_minus_min_cost.simd_min(ymm_block_switch_cost);
114 *cost_it = Mem256f::from(ymm_cost);
115 }
117}
118fn CountLiterals(cmds: &[Command], num_commands: usize) -> usize {
119 let mut total_length: usize = 0usize;
120 let mut i: usize;
121 i = 0usize;
122 while i < num_commands {
123 {
124 total_length = total_length.wrapping_add((cmds[i]).insert_len_ as usize);
125 }
126 i = i.wrapping_add(1);
127 }
128 total_length
129}
130
131fn CommandCopyLen(xself: &Command) -> u32 {
132 xself.copy_len_ & 0xffffffu32
133}
134
135fn CopyLiteralsToByteArray(
136 cmds: &[Command],
137 num_commands: usize,
138 data: &[u8],
139 offset: usize,
140 mask: usize,
141 literals: &mut [u8],
142) {
143 let mut pos: usize = 0usize;
144 let mut from_pos: usize = offset & mask;
145 let mut i: usize;
146 i = 0usize;
147 while i < num_commands {
148 {
149 let mut insert_len: usize = (cmds[i]).insert_len_ as usize;
150 if from_pos.wrapping_add(insert_len) > mask {
151 let head_size: usize = mask.wrapping_add(1).wrapping_sub(from_pos);
152 literals[pos..(pos + head_size)]
153 .clone_from_slice(&data[from_pos..(from_pos + head_size)]);
154 from_pos = 0usize;
155 pos = pos.wrapping_add(head_size);
156 insert_len = insert_len.wrapping_sub(head_size);
157 }
158 if insert_len > 0usize {
159 literals[pos..(pos + insert_len)]
160 .clone_from_slice(&data[from_pos..(from_pos + insert_len)]);
161 pos = pos.wrapping_add(insert_len);
162 }
163 from_pos = from_pos
164 .wrapping_add(insert_len)
165 .wrapping_add(CommandCopyLen(&cmds[i]) as usize)
166 & mask;
167 }
168 i = i.wrapping_add(1);
169 }
170}
171
172fn MyRand(seed: &mut u32) -> u32 {
173 *seed = seed.wrapping_mul(16807);
174 if *seed == 0u32 {
175 *seed = 1u32;
176 }
177 *seed
178}
179
180fn InitialEntropyCodes<
181 HistogramType: SliceWrapper<u32> + SliceWrapperMut<u32> + CostAccessors,
182 IntegerType: Sized + Clone,
183>(
184 data: &[IntegerType],
185 length: usize,
186 stride: usize,
187 num_histograms: usize,
188 histograms: &mut [HistogramType],
189) where
190 u64: core::convert::From<IntegerType>,
191{
192 let mut seed: u32 = 7u32;
193 let block_length: usize = length.wrapping_div(num_histograms);
194 let mut i: usize;
195 ClearHistograms(histograms, num_histograms);
196 i = 0usize;
197 while i < num_histograms {
198 {
199 let mut pos: usize = length.wrapping_mul(i).wrapping_div(num_histograms);
200 if i != 0usize {
201 pos = pos.wrapping_add((MyRand(&mut seed) as usize).wrapping_rem(block_length));
202 }
203 if pos.wrapping_add(stride) >= length {
204 pos = length.wrapping_sub(stride).wrapping_sub(1);
205 }
206 HistogramAddVector(&mut histograms[i], &data[pos..], stride);
207 }
208 i = i.wrapping_add(1);
209 }
210}
211
212fn RandomSample<
213 HistogramType: SliceWrapper<u32> + SliceWrapperMut<u32> + CostAccessors,
214 IntegerType: Sized + Clone,
215>(
216 seed: &mut u32,
217 data: &[IntegerType],
218 length: usize,
219 mut stride: usize,
220 sample: &mut HistogramType,
221) where
222 u64: core::convert::From<IntegerType>,
223{
224 let pos: usize;
225 if stride >= length {
226 pos = 0usize;
227 stride = length;
228 } else {
229 pos = (MyRand(seed) as usize).wrapping_rem(length.wrapping_sub(stride).wrapping_add(1));
230 }
231 HistogramAddVector(sample, &data[pos..], stride);
232}
233
234fn RefineEntropyCodes<
235 HistogramType: SliceWrapper<u32> + SliceWrapperMut<u32> + CostAccessors + core::default::Default,
236 IntegerType: Sized + Clone,
237>(
238 data: &[IntegerType],
239 length: usize,
240 stride: usize,
241 num_histograms: usize,
242 histograms: &mut [HistogramType],
243) where
244 u64: core::convert::From<IntegerType>,
245{
246 let mut iters: usize = kIterMulForRefining
247 .wrapping_mul(length)
248 .wrapping_div(stride)
249 .wrapping_add(kMinItersForRefining);
250 let mut seed: u32 = 7u32;
251 let mut iter: usize;
252 iters = iters
253 .wrapping_add(num_histograms)
254 .wrapping_sub(1)
255 .wrapping_div(num_histograms)
256 .wrapping_mul(num_histograms);
257 iter = 0usize;
258 while iter < iters {
259 {
260 let mut sample = HistogramType::default();
261 HistogramClear(&mut sample);
262 RandomSample(&mut seed, data, length, stride, &mut sample);
263 HistogramAddHistogram(
264 &mut histograms[iter.wrapping_rem(num_histograms)],
265 &mut sample,
266 );
267 }
268 iter = iter.wrapping_add(1);
269 }
270}
271
272fn BitCost(count: usize) -> super::util::floatX {
273 if count == 0usize {
274 -2.0 as super::util::floatX
275 } else {
276 FastLog2(count as u64)
277 }
278}
279
280fn FindBlocks<
281 HistogramType: SliceWrapper<u32> + SliceWrapperMut<u32> + CostAccessors,
282 IntegerType: Sized + Clone,
283>(
284 data: &[IntegerType],
285 length: usize,
286 block_switch_bitcost: super::util::floatX,
287 num_histograms: usize,
288 histograms: &[HistogramType],
289 insert_cost: &mut [super::util::floatX],
290 cost: &mut [Mem256f],
291 switch_signal: &mut [u8],
292 block_id: &mut [u8],
293) -> usize
294where
295 u64: core::convert::From<IntegerType>,
296{
297 if num_histograms == 0 {
298 return 0;
299 }
300 let data_size: usize = histograms[0].slice().len();
301 let bitmaplen: usize = num_histograms.wrapping_add(7) >> 3;
302 let mut num_blocks: usize = 1;
303 let mut i: usize;
304 let mut j: usize;
305 0i32;
306 if num_histograms <= 1 {
307 i = 0usize;
308 while i < length {
309 {
310 block_id[i] = 0u8;
311 }
312 i = i.wrapping_add(1);
313 }
314 return 1;
315 }
316 for item in insert_cost[..(data_size * num_histograms)].iter_mut() {
317 *item = 0.0 as super::util::floatX;
318 }
319 i = 0usize;
320 while i < num_histograms {
321 {
322 insert_cost[i] = FastLog2((histograms[i]).total_count() as u32 as (u64));
323 }
324 i = i.wrapping_add(1);
325 }
326 i = data_size;
327 while i != 0usize {
328 i = i.wrapping_sub(1);
329 j = 0usize;
330 while j < num_histograms {
331 {
332 insert_cost[i.wrapping_mul(num_histograms).wrapping_add(j)] =
333 insert_cost[j] - BitCost((histograms[j]).slice()[i] as usize);
334 }
335 j = j.wrapping_add(1);
336 }
337 }
338 for item in cost.iter_mut() {
339 *item = Mem256f::default();
340 }
341 for item in switch_signal[..(length * bitmaplen)].iter_mut() {
342 *item = 0;
343 }
344 for (byte_ix, data_byte_ix) in data[..length].iter().enumerate() {
345 {
346 let block_id_ptr = &mut block_id[byte_ix];
347 let ix: usize = byte_ix.wrapping_mul(bitmaplen);
348 let insert_cost_ix: usize =
349 u64::from(data_byte_ix.clone()).wrapping_mul(num_histograms as u64) as usize;
350 let mut min_cost: super::util::floatX = 1e38 as super::util::floatX;
351 let mut block_switch_cost: super::util::floatX = block_switch_bitcost;
352 if false {
353 for (k, insert_cost_iter) in insert_cost
355 [insert_cost_ix..(insert_cost_ix + num_histograms)]
356 .iter()
357 .enumerate()
358 {
359 let cost_iter = &mut cost[(k >> 3)][k & 7];
360 *cost_iter += *insert_cost_iter;
361 if *cost_iter < min_cost {
362 min_cost = *cost_iter;
363 *block_id_ptr = k as u8;
364 }
365 }
366 } else {
367 let insert_cost_slice = insert_cost.split_at(insert_cost_ix).1;
369 for (v_index, cost_iter) in cost
370 .split_at_mut(num_histograms >> 3)
371 .0
372 .iter_mut()
373 .enumerate()
374 {
375 let base_index = v_index << 3;
376 let mut local_insert_cost = [0.0 as super::util::floatX; 8];
377 local_insert_cost
378 .clone_from_slice(insert_cost_slice.split_at(base_index).1.split_at(8).0);
379 for sub_index in 0usize..8usize {
380 cost_iter[sub_index] += local_insert_cost[sub_index];
381 let final_cost = cost_iter[sub_index];
382 if final_cost < min_cost {
383 min_cost = final_cost;
384 *block_id_ptr = (base_index + sub_index) as u8;
385 }
386 }
387 }
388 let vectorized_offset = ((num_histograms >> 3) << 3);
389 let mut k = vectorized_offset;
390 for insert_cost_iter in insert_cost
392 .split_at(insert_cost_ix + vectorized_offset)
393 .1
394 .split_at(num_histograms & 7)
395 .0
396 .iter()
397 {
398 let cost_iter = &mut cost[(k >> 3)];
399 cost_iter[k & 7] += *insert_cost_iter;
400 if cost_iter[k & 7] < min_cost {
401 min_cost = cost_iter[k & 7];
402 *block_id_ptr = k as u8;
403 }
404 k += 1;
405 }
406 }
407 if byte_ix < 2000usize {
408 block_switch_cost *= (0.77 as super::util::floatX
409 + 0.07 as super::util::floatX * byte_ix as (super::util::floatX)
410 / 2000i32 as (super::util::floatX));
411 }
412 update_cost_and_signal(
413 num_histograms as u32,
414 ix,
415 min_cost,
416 block_switch_cost,
417 cost,
418 switch_signal,
419 );
420 }
421 }
422 {
423 let mut byte_ix: usize = length.wrapping_sub(1);
424 let mut ix: usize = byte_ix.wrapping_mul(bitmaplen);
425 let mut cur_id: u8 = block_id[byte_ix];
426 while byte_ix > 0usize {
427 let mask: u8 = (1u32 << (cur_id as i32 & 7i32)) as u8;
428 0i32;
429 byte_ix -= 1;
430 ix = ix.wrapping_sub(bitmaplen);
431 if switch_signal[ix.wrapping_add((cur_id as i32 >> 3) as usize)] as i32 & mask as i32
432 != 0
433 && cur_id as i32 != block_id[byte_ix] as i32
434 {
435 cur_id = block_id[byte_ix];
436 num_blocks = num_blocks.wrapping_add(1);
437 }
438 block_id[byte_ix] = cur_id;
439 }
440 }
441 num_blocks
442}
443
444fn RemapBlockIds(
445 block_ids: &mut [u8],
446 length: usize,
447 new_id: &mut [u16],
448 num_histograms: usize,
449) -> usize {
450 static kInvalidId: u16 = 256u16;
451 let mut next_id: u16 = 0u16;
452 let mut i: usize;
453 i = 0usize;
454 while i < num_histograms {
455 {
456 new_id[i] = kInvalidId;
457 }
458 i = i.wrapping_add(1);
459 }
460 i = 0usize;
461 while i < length {
462 {
463 0i32;
464 if new_id[(block_ids[i] as usize)] as i32 == kInvalidId as i32 {
465 new_id[(block_ids[i] as usize)] = {
466 let _old = next_id;
467 next_id = (next_id as i32 + 1) as u16;
468 _old
469 };
470 }
471 }
472 i = i.wrapping_add(1);
473 }
474 i = 0usize;
475 while i < length {
476 {
477 block_ids[i] = new_id[(block_ids[i] as usize)] as u8;
478 0i32;
479 }
480 i = i.wrapping_add(1);
481 }
482 0i32;
483 next_id as usize
484}
485
486fn BuildBlockHistograms<
487 HistogramType: SliceWrapper<u32> + SliceWrapperMut<u32> + CostAccessors,
488 IntegerType: Sized + Clone,
489>(
490 data: &[IntegerType],
491 length: usize,
492 block_ids: &[u8],
493 num_histograms: usize,
494 histograms: &mut [HistogramType],
495) where
496 u64: core::convert::From<IntegerType>,
497{
498 let mut i: usize;
499 ClearHistograms(histograms, num_histograms);
500 i = 0usize;
501 while i < length {
502 {
503 HistogramAddItem(
504 &mut histograms[(block_ids[i] as usize)],
505 u64::from(data[i].clone()) as usize,
506 );
507 }
508 i = i.wrapping_add(1);
509 }
510}
511
512fn ClusterBlocks<
513 HistogramType: SliceWrapper<u32> + SliceWrapperMut<u32> + CostAccessors + core::default::Default + Clone,
514 Alloc: alloc::Allocator<u8>
515 + alloc::Allocator<u32>
516 + alloc::Allocator<HistogramType>
517 + alloc::Allocator<HistogramPair>,
518 IntegerType: Sized + Clone,
519>(
520 alloc: &mut Alloc,
521 data: &[IntegerType],
522 length: usize,
523 num_blocks: usize,
524 scratch_space: &mut HistogramType::i32vec,
525 block_ids: &mut [u8],
526 split: &mut BlockSplit<Alloc>,
527) where
528 u64: core::convert::From<IntegerType>,
529{
530 let mut histogram_symbols = <Alloc as Allocator<u32>>::alloc_cell(alloc, num_blocks);
531 let mut block_lengths = <Alloc as Allocator<u32>>::alloc_cell(alloc, num_blocks);
532 let expected_num_clusters: usize = (16usize)
533 .wrapping_mul(num_blocks.wrapping_add(64).wrapping_sub(1))
534 .wrapping_div(64);
535 let mut all_histograms_size: usize = 0usize;
536 let mut all_histograms_capacity: usize = expected_num_clusters;
537 let mut all_histograms =
538 <Alloc as Allocator<HistogramType>>::alloc_cell(alloc, all_histograms_capacity);
539 let mut cluster_size_size: usize = 0usize;
540 let mut cluster_size_capacity: usize = expected_num_clusters;
541 let mut cluster_size = <Alloc as Allocator<u32>>::alloc_cell(alloc, cluster_size_capacity);
542 let mut num_clusters: usize = 0usize;
543 let mut histograms = <Alloc as Allocator<HistogramType>>::alloc_cell(
544 alloc,
545 brotli_min_size_t(num_blocks, 64usize),
546 );
547 let mut max_num_pairs: usize = (64i32 * 64i32 / 2i32) as usize;
548 let pairs_capacity: usize = max_num_pairs.wrapping_add(1);
549 let mut pairs = <Alloc as Allocator<HistogramPair>>::alloc_cell(alloc, pairs_capacity);
550 let mut pos: usize = 0usize;
551 let mut clusters: <Alloc as Allocator<u32>>::AllocatedMemory;
552
553 static kInvalidIndex: u32 = !(0u32);
554 let mut i: usize;
555 let mut sizes: [u32; 64] = [0; 64];
556 let mut new_clusters: [u32; 64] = [0; 64];
557 let mut symbols: [u32; 64] = [0; 64];
558 let mut remap: [u32; 64] = [0; 64];
559 {
560 let mut block_idx: usize = 0usize;
561 i = 0usize;
562 while i < length {
563 {
564 0i32;
565 {
566 let _rhs = 1;
567 let _lhs = &mut block_lengths.slice_mut()[block_idx];
568 *_lhs = (*_lhs).wrapping_add(_rhs as u32);
569 }
570 if i.wrapping_add(1) == length
571 || block_ids[i] as i32 != block_ids[i.wrapping_add(1)] as i32
572 {
573 block_idx = block_idx.wrapping_add(1);
574 }
575 }
576 i = i.wrapping_add(1);
577 }
578 0i32;
579 }
580 i = 0usize;
581 while i < num_blocks {
582 {
583 let num_to_combine: usize = brotli_min_size_t(num_blocks.wrapping_sub(i), 64usize);
584
585 let mut j: usize;
586 j = 0usize;
587 while j < num_to_combine {
588 {
589 let mut k: usize;
590 HistogramClear(&mut histograms.slice_mut()[j]);
591 k = 0usize;
592 while k < block_lengths.slice()[i.wrapping_add(j)] as usize {
593 {
594 HistogramAddItem(
595 &mut histograms.slice_mut()[j],
596 u64::from(data[pos].clone()) as usize,
597 );
598 pos = pos.wrapping_add(1);
599 }
600 k = k.wrapping_add(1);
601 }
602 let new_cost = BrotliPopulationCost(&histograms.slice()[j], scratch_space);
603 (histograms.slice_mut()[j]).set_bit_cost(new_cost);
604
605 new_clusters[j] = j as u32;
606 symbols[j] = j as u32;
607 sizes[j] = 1u32;
608 }
609 j = j.wrapping_add(1);
610 }
611 let num_new_clusters: usize = BrotliHistogramCombine(
612 histograms.slice_mut(),
613 &mut sizes[..],
614 &mut symbols[..],
615 &mut new_clusters[..],
616 pairs.slice_mut(),
617 num_to_combine,
618 num_to_combine,
619 64usize,
620 max_num_pairs,
621 scratch_space,
622 );
623 {
624 if all_histograms_capacity < all_histograms_size.wrapping_add(num_new_clusters) {
625 let mut _new_size: usize = if all_histograms_capacity == 0usize {
626 all_histograms_size.wrapping_add(num_new_clusters)
627 } else {
628 all_histograms_capacity
629 };
630 while _new_size < all_histograms_size.wrapping_add(num_new_clusters) {
631 _new_size = _new_size.wrapping_mul(2);
632 }
633 let mut new_array =
634 <Alloc as Allocator<HistogramType>>::alloc_cell(alloc, _new_size);
635 new_array.slice_mut()[..all_histograms_capacity]
636 .clone_from_slice(&all_histograms.slice()[..all_histograms_capacity]);
637 <Alloc as Allocator<HistogramType>>::free_cell(
638 alloc,
639 core::mem::replace(&mut all_histograms, new_array),
640 );
641 all_histograms_capacity = _new_size;
642 }
643 }
644 {
645 if cluster_size_capacity < cluster_size_size.wrapping_add(num_new_clusters) {
646 let mut _new_size: usize = if cluster_size_capacity == 0usize {
647 cluster_size_size.wrapping_add(num_new_clusters)
648 } else {
649 cluster_size_capacity
650 };
651 while _new_size < cluster_size_size.wrapping_add(num_new_clusters) {
652 _new_size = _new_size.wrapping_mul(2);
653 }
654 let mut new_array = <Alloc as Allocator<u32>>::alloc_cell(alloc, _new_size);
655 new_array.slice_mut()[..cluster_size_capacity]
656 .clone_from_slice(&cluster_size.slice()[..cluster_size_capacity]);
657 <Alloc as Allocator<u32>>::free_cell(
658 alloc,
659 core::mem::replace(&mut cluster_size, new_array),
660 );
661 cluster_size_capacity = _new_size;
662 }
663 }
664 j = 0usize;
665 while j < num_new_clusters {
666 {
667 all_histograms.slice_mut()[all_histograms_size] =
668 histograms.slice()[new_clusters[j] as usize].clone();
669 all_histograms_size = all_histograms_size.wrapping_add(1);
670 cluster_size.slice_mut()[cluster_size_size] = sizes[new_clusters[j] as usize];
671 cluster_size_size = cluster_size_size.wrapping_add(1);
672 remap[new_clusters[j] as usize] = j as u32;
673 }
674 j = j.wrapping_add(1);
675 }
676 j = 0usize;
677 while j < num_to_combine {
678 {
679 histogram_symbols.slice_mut()[i.wrapping_add(j)] =
680 (num_clusters as u32).wrapping_add(remap[symbols[j] as usize]);
681 }
682 j = j.wrapping_add(1);
683 }
684 num_clusters = num_clusters.wrapping_add(num_new_clusters);
685 0i32;
686 0i32;
687 }
688 i = i.wrapping_add(64);
689 }
690 <Alloc as Allocator<HistogramType>>::free_cell(alloc, core::mem::take(&mut histograms));
691 max_num_pairs = brotli_min_size_t(
692 (64usize).wrapping_mul(num_clusters),
693 num_clusters.wrapping_div(2).wrapping_mul(num_clusters),
694 );
695 if pairs_capacity < max_num_pairs.wrapping_add(1) {
696 let new_cell =
697 <Alloc as Allocator<HistogramPair>>::alloc_cell(alloc, max_num_pairs.wrapping_add(1));
698 <Alloc as Allocator<HistogramPair>>::free_cell(
699 alloc,
700 core::mem::replace(&mut pairs, new_cell),
701 );
702 }
703 clusters = <Alloc as Allocator<u32>>::alloc_cell(alloc, num_clusters);
704 i = 0usize;
705 for item in clusters.slice_mut()[..num_clusters].iter_mut() {
706 *item = i as u32;
707 i = i.wrapping_add(1);
708 }
709 let num_final_clusters: usize = BrotliHistogramCombine(
710 all_histograms.slice_mut(),
711 cluster_size.slice_mut(),
712 histogram_symbols.slice_mut(),
713 clusters.slice_mut(),
714 pairs.slice_mut(),
715 num_clusters,
716 num_blocks,
717 256usize,
718 max_num_pairs,
719 scratch_space,
720 );
721 <Alloc as Allocator<HistogramPair>>::free_cell(alloc, core::mem::take(&mut pairs));
722 <Alloc as Allocator<u32>>::free_cell(alloc, core::mem::take(&mut cluster_size));
723
724 let mut new_index = <Alloc as Allocator<u32>>::alloc_cell(alloc, num_clusters);
725 for item in new_index.slice_mut().iter_mut() {
726 *item = kInvalidIndex;
727 }
728 pos = 0usize;
729 {
730 let mut next_index: u32 = 0u32;
731 i = 0usize;
732 while i < num_blocks {
733 {
734 let mut histo: HistogramType = HistogramType::default();
735 let mut j: usize;
736 let mut best_out: u32;
737 let mut best_bits: super::util::floatX;
738 HistogramClear(&mut histo);
739 j = 0usize;
740 while j < block_lengths.slice()[i] as usize {
741 {
742 HistogramAddItem(&mut histo, u64::from(data[pos].clone()) as usize);
743 pos = pos.wrapping_add(1);
744 }
745 j = j.wrapping_add(1);
746 }
747 best_out = if i == 0usize {
748 histogram_symbols.slice()[0]
749 } else {
750 histogram_symbols.slice()[i.wrapping_sub(1)]
751 };
752 best_bits = BrotliHistogramBitCostDistance(
753 &mut histo,
754 &mut all_histograms.slice_mut()[(best_out as usize)],
755 scratch_space,
756 );
757 j = 0usize;
758 while j < num_final_clusters {
759 {
760 let cur_bits: super::util::floatX = BrotliHistogramBitCostDistance(
761 &mut histo,
762 &mut all_histograms.slice_mut()[(clusters.slice()[j] as usize)],
763 scratch_space,
764 );
765 if cur_bits < best_bits {
766 best_bits = cur_bits;
767 best_out = clusters.slice()[j];
768 }
769 }
770 j = j.wrapping_add(1);
771 }
772 histogram_symbols.slice_mut()[i] = best_out;
773 if new_index.slice()[best_out as usize] == kInvalidIndex {
774 new_index.slice_mut()[best_out as usize] = next_index;
775 next_index = next_index.wrapping_add(1);
776 }
777 }
778 i = i.wrapping_add(1);
779 }
780 }
781 <Alloc as Allocator<u32>>::free_cell(alloc, core::mem::take(&mut clusters));
782 <Alloc as Allocator<HistogramType>>::free_cell(alloc, core::mem::take(&mut all_histograms));
783 {
784 if split.types_alloc_size() < num_blocks {
785 let mut _new_size: usize = if split.types_alloc_size() == 0usize {
786 num_blocks
787 } else {
788 split.types_alloc_size()
789 };
790 while _new_size < num_blocks {
791 _new_size = _new_size.wrapping_mul(2);
792 }
793 let mut new_array = <Alloc as Allocator<u8>>::alloc_cell(alloc, _new_size);
794 new_array.slice_mut()[..split.types_alloc_size()]
795 .clone_from_slice(&split.types.slice()[..split.types_alloc_size()]);
796 <Alloc as Allocator<u8>>::free_cell(
797 alloc,
798 core::mem::replace(&mut split.types, new_array),
799 );
800 }
801 }
802 {
803 if split.lengths_alloc_size() < num_blocks {
804 let mut _new_size: usize = if split.lengths_alloc_size() == 0usize {
805 num_blocks
806 } else {
807 split.lengths_alloc_size()
808 };
809 while _new_size < num_blocks {
810 _new_size = _new_size.wrapping_mul(2);
811 }
812 let mut new_array = <Alloc as Allocator<u32>>::alloc_cell(alloc, _new_size);
813 new_array.slice_mut()[..split.lengths_alloc_size()]
814 .clone_from_slice(split.lengths.slice());
815 <Alloc as Allocator<u32>>::free_cell(
816 alloc,
817 core::mem::replace(&mut split.lengths, new_array),
818 );
819 }
820 }
821 {
822 let mut cur_length: u32 = 0u32;
823 let mut block_idx: usize = 0usize;
824 let mut max_type: u8 = 0u8;
825 i = 0usize;
826 while i < num_blocks {
827 {
828 cur_length = cur_length.wrapping_add(block_lengths.slice()[i]);
829 if i.wrapping_add(1) == num_blocks
830 || histogram_symbols.slice()[i] != histogram_symbols.slice()[i.wrapping_add(1)]
831 {
832 let id: u8 = new_index.slice()[(histogram_symbols.slice()[i] as usize)] as u8;
833 split.types.slice_mut()[block_idx] = id;
834 split.lengths.slice_mut()[block_idx] = cur_length;
835 max_type = brotli_max_uint8_t(max_type, id);
836 cur_length = 0u32;
837 block_idx = block_idx.wrapping_add(1);
838 }
839 }
840 i = i.wrapping_add(1);
841 }
842 split.num_blocks = block_idx;
843 split.num_types = (max_type as usize).wrapping_add(1);
844 }
845 <Alloc as Allocator<u32>>::free_cell(alloc, new_index);
846 <Alloc as Allocator<u32>>::free_cell(alloc, block_lengths);
847 <Alloc as Allocator<u32>>::free_cell(alloc, histogram_symbols);
848}
849
850fn SplitByteVector<
851 HistogramType: SliceWrapper<u32> + SliceWrapperMut<u32> + CostAccessors + core::default::Default + Clone,
852 Alloc: alloc::Allocator<u8>
853 + alloc::Allocator<u16>
854 + alloc::Allocator<u32>
855 + alloc::Allocator<super::util::floatX>
856 + alloc::Allocator<Mem256f>
857 + alloc::Allocator<HistogramType>
858 + alloc::Allocator<HistogramPair>,
859 IntegerType: Sized + Clone,
860>(
861 alloc: &mut Alloc,
862 data: &[IntegerType],
863 length: usize,
864 literals_per_histogram: usize,
865 max_histograms: usize,
866 sampling_stride_length: usize,
867 block_switch_cost: super::util::floatX,
868 params: &BrotliEncoderParams,
869 scratch_space: &mut HistogramType::i32vec,
870 split: &mut BlockSplit<Alloc>,
871) where
872 u64: core::convert::From<IntegerType>,
873{
874 let data_size: usize = HistogramType::default().slice().len();
875 let mut num_histograms: usize = length.wrapping_div(literals_per_histogram).wrapping_add(1);
876 if num_histograms > max_histograms {
877 num_histograms = max_histograms;
878 }
879 if length == 0usize {
880 split.num_types = 1;
881 return;
882 } else if length < kMinLengthForBlockSplitting {
883 {
884 if split.types_alloc_size() < split.num_blocks.wrapping_add(1) {
885 let mut _new_size: usize = if split.types_alloc_size() == 0usize {
886 split.num_blocks.wrapping_add(1)
887 } else {
888 split.types_alloc_size()
889 };
890
891 while _new_size < split.num_blocks.wrapping_add(1) {
892 _new_size = _new_size.wrapping_mul(2);
893 }
894 let mut new_array = <Alloc as Allocator<u8>>::alloc_cell(alloc, _new_size);
895 new_array.slice_mut()[..split.types_alloc_size()]
896 .clone_from_slice(&split.types.slice()[..split.types_alloc_size()]);
897 <Alloc as Allocator<u8>>::free_cell(
898 alloc,
899 core::mem::replace(&mut split.types, new_array),
900 );
901 }
902 }
903 {
904 if split.lengths_alloc_size() < split.num_blocks.wrapping_add(1) {
905 let mut _new_size: usize = if split.lengths_alloc_size() == 0usize {
906 split.num_blocks.wrapping_add(1)
907 } else {
908 split.lengths_alloc_size()
909 };
910 while _new_size < split.num_blocks.wrapping_add(1) {
911 _new_size = _new_size.wrapping_mul(2);
912 }
913 let mut new_array = <Alloc as Allocator<u32>>::alloc_cell(alloc, _new_size);
914 new_array.slice_mut()[..split.lengths_alloc_size()]
915 .clone_from_slice(&split.lengths.slice()[..split.lengths_alloc_size()]);
916 <Alloc as Allocator<u32>>::free_cell(
917 alloc,
918 core::mem::replace(&mut split.lengths, new_array),
919 );
920 }
921 }
922 split.num_types = 1;
923 split.types.slice_mut()[split.num_blocks] = 0u8;
924 split.lengths.slice_mut()[split.num_blocks] = length as u32;
925 split.num_blocks = split.num_blocks.wrapping_add(1);
926 return;
927 }
928 let mut histograms = <Alloc as Allocator<HistogramType>>::alloc_cell(alloc, num_histograms);
929
930 InitialEntropyCodes(
931 data,
932 length,
933 sampling_stride_length,
934 num_histograms,
935 histograms.slice_mut(),
936 );
937 RefineEntropyCodes(
938 data,
939 length,
940 sampling_stride_length,
941 num_histograms,
942 histograms.slice_mut(),
943 );
944 {
945 let mut block_ids = <Alloc as Allocator<u8>>::alloc_cell(alloc, length);
946 let mut num_blocks: usize = 0usize;
947 let bitmaplen: usize = num_histograms.wrapping_add(7) >> 3;
948 let mut insert_cost = <Alloc as Allocator<super::util::floatX>>::alloc_cell(
949 alloc,
950 data_size.wrapping_mul(num_histograms),
951 );
952 let mut cost =
953 <Alloc as Allocator<Mem256f>>::alloc_cell(alloc, ((num_histograms + 7) >> 3));
954 let mut switch_signal =
955 <Alloc as Allocator<u8>>::alloc_cell(alloc, length.wrapping_mul(bitmaplen));
956 let mut new_id = <Alloc as Allocator<u16>>::alloc_cell(alloc, num_histograms);
957 let iters: usize = (if params.quality <= 11 { 3i32 } else { 10i32 }) as usize;
958 let mut i: usize;
959 i = 0usize;
960 while i < iters {
961 {
962 num_blocks = FindBlocks(
963 data,
964 length,
965 block_switch_cost,
966 num_histograms,
967 histograms.slice_mut(),
968 insert_cost.slice_mut(),
969 cost.slice_mut(),
970 switch_signal.slice_mut(),
971 block_ids.slice_mut(),
972 );
973 num_histograms = RemapBlockIds(
974 block_ids.slice_mut(),
975 length,
976 new_id.slice_mut(),
977 num_histograms,
978 );
979 BuildBlockHistograms(
980 data,
981 length,
982 block_ids.slice(),
983 num_histograms,
984 histograms.slice_mut(),
985 );
986 }
987 i = i.wrapping_add(1);
988 }
989 <Alloc as Allocator<super::util::floatX>>::free_cell(alloc, insert_cost);
990 <Alloc as Allocator<Mem256f>>::free_cell(alloc, cost);
991 <Alloc as Allocator<u8>>::free_cell(alloc, switch_signal);
992 <Alloc as Allocator<u16>>::free_cell(alloc, new_id);
993 <Alloc as Allocator<HistogramType>>::free_cell(alloc, histograms);
994 ClusterBlocks::<HistogramType, Alloc, IntegerType>(
995 alloc,
996 data,
997 length,
998 num_blocks,
999 scratch_space,
1000 block_ids.slice_mut(),
1001 split,
1002 );
1003 <Alloc as Allocator<u8>>::free_cell(alloc, block_ids);
1004 }
1005}
1006
1007pub fn BrotliSplitBlock<
1008 Alloc: alloc::Allocator<u8>
1009 + alloc::Allocator<u16>
1010 + alloc::Allocator<u32>
1011 + alloc::Allocator<super::util::floatX>
1012 + alloc::Allocator<Mem256f>
1013 + alloc::Allocator<HistogramLiteral>
1014 + alloc::Allocator<HistogramCommand>
1015 + alloc::Allocator<HistogramDistance>
1016 + alloc::Allocator<HistogramPair>,
1017>(
1018 alloc: &mut Alloc,
1019 cmds: &[Command],
1020 num_commands: usize,
1021 data: &[u8],
1022 pos: usize,
1023 mask: usize,
1024 params: &BrotliEncoderParams,
1025 lit_scratch_space: &mut <HistogramLiteral as CostAccessors>::i32vec,
1026 cmd_scratch_space: &mut <HistogramCommand as CostAccessors>::i32vec,
1027 dst_scratch_space: &mut <HistogramDistance as CostAccessors>::i32vec,
1028 literal_split: &mut BlockSplit<Alloc>,
1029 insert_and_copy_split: &mut BlockSplit<Alloc>,
1030 dist_split: &mut BlockSplit<Alloc>,
1031) {
1032 {
1033 let literals_count: usize = CountLiterals(cmds, num_commands);
1038 let mut literals = <Alloc as Allocator<u8>>::alloc_cell(alloc, literals_count);
1039 CopyLiteralsToByteArray(cmds, num_commands, data, pos, mask, literals.slice_mut());
1040 SplitByteVector::<HistogramLiteral, Alloc, u8>(
1041 alloc,
1042 literals.slice(),
1043 literals_count,
1044 kSymbolsPerLiteralHistogram,
1045 kMaxLiteralHistograms,
1046 kLiteralStrideLength,
1047 kLiteralBlockSwitchCost,
1048 params,
1049 lit_scratch_space,
1050 literal_split,
1051 );
1052 <Alloc as Allocator<u8>>::free_cell(alloc, literals);
1053 }
1054 {
1055 let mut insert_and_copy_codes = <Alloc as Allocator<u16>>::alloc_cell(alloc, num_commands);
1056 for i in 0..core::cmp::min(num_commands, cmds.len()) {
1057 insert_and_copy_codes.slice_mut()[i] = (cmds[i]).cmd_prefix_;
1058 }
1059 SplitByteVector::<HistogramCommand, Alloc, u16>(
1060 alloc,
1061 insert_and_copy_codes.slice(),
1062 num_commands,
1063 kSymbolsPerCommandHistogram,
1064 kMaxCommandHistograms,
1065 kCommandStrideLength,
1066 kCommandBlockSwitchCost,
1067 params,
1068 cmd_scratch_space,
1069 insert_and_copy_split,
1070 );
1071 <Alloc as Allocator<u16>>::free_cell(alloc, insert_and_copy_codes);
1072 }
1073 {
1074 let mut distance_prefixes = <Alloc as Allocator<u16>>::alloc_cell(alloc, num_commands);
1075 let mut j: usize = 0usize;
1076 let mut i: usize;
1077 i = 0usize;
1078 while i < num_commands {
1079 {
1080 let cmd = &cmds[i];
1081 if CommandCopyLen(cmd) != 0 && (cmd.cmd_prefix_ as i32 >= 128i32) {
1082 distance_prefixes.slice_mut()[j] = cmd.dist_prefix_ & 0x3ff;
1083 j = j.wrapping_add(1);
1084 }
1085 }
1086 i = i.wrapping_add(1);
1087 }
1088 SplitByteVector::<HistogramDistance, Alloc, u16>(
1089 alloc,
1090 distance_prefixes.slice(),
1091 j,
1092 kSymbolsPerDistanceHistogram,
1093 kMaxCommandHistograms,
1094 kCommandStrideLength,
1095 kDistanceBlockSwitchCost,
1096 params,
1097 dst_scratch_space,
1098 dist_split,
1099 );
1100 <Alloc as Allocator<u16>>::free_cell(alloc, distance_prefixes);
1101 }
1102}