1use super::super::BitReader;
6use super::range_coder::{RangeCoder, SubRange};
7use super::sub_alloc::SubAllocator;
8
9const INT_BITS: u32 = 7;
11const PERIOD_BITS: u32 = 7;
12const TOT_BITS: u32 = INT_BITS + PERIOD_BITS;
13const INTERVAL: u32 = 1 << INT_BITS;
14const BIN_SCALE: u32 = 1 << TOT_BITS;
15const MAX_FREQ: u32 = 124;
16const MAX_O: usize = 64;
17#[allow(dead_code)]
18const INIT_ESC: u32 = 4;
19
20#[derive(Clone, Copy, Default)]
22struct State {
23 symbol: u8,
24 freq: u8,
25 #[allow(dead_code)]
26 successor: u32, }
28
29#[allow(dead_code)]
31struct Context {
32 num_stats: u16,
33 summ_freq: u16,
34 stats: u32, suffix: u32, one_state: State,
38}
39
40#[derive(Clone, Copy)]
42struct See2Context {
43 summ: u16,
44 shift: u8,
45 count: u8,
46}
47
48impl See2Context {
49 fn new(init_val: u16) -> Self {
50 Self {
51 summ: init_val << (PERIOD_BITS as u8 - 4),
52 shift: PERIOD_BITS as u8 - 4,
53 count: 4,
54 }
55 }
56
57 fn get_mean(&mut self) -> u32 {
58 let ret = (self.summ >> self.shift) as i16;
59 self.summ = self.summ.wrapping_sub(ret as u16);
60 if ret == 0 {
61 1
62 } else {
63 ret as u32
64 }
65 }
66
67 fn update(&mut self) {
68 if self.shift < PERIOD_BITS as u8 {
69 self.count = self.count.wrapping_sub(1);
70 if self.count == 0 {
71 self.summ = self.summ.wrapping_add(self.summ);
72 self.count = 3 << self.shift;
73 self.shift += 1;
74 }
75 }
76 }
77}
78
79pub struct PpmModel {
81 sub_alloc: SubAllocator,
83 min_context: u32,
85 #[allow(dead_code)]
87 med_context: u32,
88 max_context: u32,
90 found_state: u32,
92 num_masked: usize,
94 init_esc: u32,
96 order_fall: i32,
98 max_order: i32,
100 run_length: i32,
102 init_rl: i32,
104 char_mask: [u8; 256],
106 ns2_indx: [u8; 256],
108 ns2_bs_indx: [u8; 256],
110 hb2_flag: [u8; 256],
112 esc_count: u8,
114 prev_success: u8,
116 hi_bits_flag: u8,
118 bin_summ: [[u16; 64]; 128],
120 see2_cont: [[See2Context; 16]; 25],
122 dummy_see2: See2Context,
124 esc_char: i32,
126 #[allow(dead_code)]
128 debug_count: u32,
129}
130
131impl PpmModel {
132 pub fn new() -> Self {
134 Self {
135 sub_alloc: SubAllocator::new(1), min_context: 0,
137 med_context: 0,
138 max_context: 0,
139 found_state: 0,
140 num_masked: 0,
141 init_esc: 0,
142 order_fall: 0,
143 max_order: 0,
144 run_length: 0,
145 init_rl: 0,
146 char_mask: [0; 256],
147 ns2_indx: [0; 256],
148 ns2_bs_indx: [0; 256],
149 hb2_flag: [0; 256],
150 esc_count: 0,
151 prev_success: 0,
152 hi_bits_flag: 0,
153 bin_summ: [[0; 64]; 128],
154 see2_cont: [[See2Context::new(0); 16]; 25],
155 dummy_see2: See2Context {
156 summ: 0,
157 shift: PERIOD_BITS as u8,
158 count: 0,
159 },
160 esc_char: -1,
161
162 debug_count: 0,
163 }
164 }
165
166 pub fn init(&mut self, reader: &mut BitReader) -> Result<(RangeCoder, i32), &'static str> {
168 let max_order_byte = reader.read_byte().ok_or("EOF reading max order")?;
169 let reset = (max_order_byte & 0x20) != 0;
170
171 #[cfg(test)]
172 eprintln!(
173 "[PPM init] max_order_byte=0x{:02x} reset={}",
174 max_order_byte, reset
175 );
176
177 let need_init = reset || self.min_context == 0;
179
180 let max_mb = if reset {
181 reader.read_byte().ok_or("EOF reading max MB")? as usize
182 } else {
183 1 };
185
186 if (max_order_byte & 0x40) != 0 {
187 self.esc_char = reader.read_byte().ok_or("EOF reading esc char")? as i32;
188 }
189
190 let coder = RangeCoder::new(reader);
192
193 if need_init {
194 let mut max_order = (max_order_byte & 0x1f) as i32 + 1;
195 if max_order > 16 {
196 max_order = 16 + (max_order - 16) * 3;
197 }
198
199 #[cfg(test)]
200 eprintln!("[PPM init] max_order={} max_mb={}", max_order, max_mb);
201
202 if max_order == 1 {
203 return Err("Invalid max order");
204 }
205
206 self.sub_alloc.resize(max_mb + 1);
208 self.start_model(max_order);
209 }
210
211 if self.min_context == 0 {
212 return Err("Model initialization failed");
213 }
214
215 Ok((coder, self.esc_char))
216 }
217
218 fn start_model(&mut self, max_order: i32) {
220 self.max_order = max_order;
221 self.esc_count = 1;
222 self.restart_model();
223
224 self.ns2_bs_indx[0] = 0;
226 self.ns2_bs_indx[1] = 2;
227 for i in 2..11 {
228 self.ns2_bs_indx[i] = 4;
229 }
230 for i in 11..256 {
231 self.ns2_bs_indx[i] = 6;
232 }
233
234 for i in 0..3 {
235 self.ns2_indx[i] = i as u8;
236 }
237 let mut m = 3u8;
238 let mut k = 1usize;
239 let mut step = 1usize;
240 for i in 3..256 {
241 self.ns2_indx[i] = m;
242 k = k.saturating_sub(1);
243 if k == 0 {
244 step += 1;
245 k = step;
246 m += 1;
247 }
248 }
249
250 for i in 0..0x40 {
251 self.hb2_flag[i] = 0;
252 }
253 for i in 0x40..0x100 {
254 self.hb2_flag[i] = 0x08;
255 }
256
257 self.dummy_see2.shift = PERIOD_BITS as u8;
258 }
259
260 fn restart_model(&mut self) {
262 self.char_mask = [0; 256];
263 self.sub_alloc.init();
264
265 self.init_rl = -(if self.max_order < 12 {
266 self.max_order
267 } else {
268 12
269 }) - 1;
270
271 let ctx = self.sub_alloc.alloc_context().unwrap_or(0);
273 self.min_context = ctx as u32;
274 self.max_context = ctx as u32;
275
276 if ctx == 0 {
277 return;
278 }
279
280 self.write_context_num_stats(ctx, 256);
282 self.write_context_summ_freq(ctx, 257);
283
284 let stats = self.sub_alloc.alloc_units(128).unwrap_or(0);
285 self.write_context_stats(ctx, stats as u32);
286
287 {
290 let _read_back = self.read_context_stats(ctx);
291 }
292 self.write_context_stats(ctx, stats as u32);
293
294 self.order_fall = self.max_order;
295 self.found_state = stats as u32;
296
297 for i in 0..256 {
299 self.write_state(stats + i * 6, i as u8, 1, 0);
300 }
301
302 #[cfg(test)]
304 {
305 for i in 0..256 {
306 let sym = self.read_state_symbol(stats + i * 6);
307 if sym != i as u8 {
308 eprintln!(
309 "[INIT] ERROR: stats[{}] has sym {} instead of {}",
310 i, sym, i
311 );
312 }
313 }
314 }
315
316 self.run_length = self.init_rl;
317 self.prev_success = 0;
318
319 let init_bin_esc: [u16; 8] = [
321 0x3CDD, 0x1F3F, 0x59BF, 0x48F3, 0x64A1, 0x5ABC, 0x6632, 0x6051,
322 ];
323
324 for i in 0..128 {
325 for k in 0..8 {
326 for m in (0..64).step_by(8) {
327 self.bin_summ[i][k + m] =
328 (BIN_SCALE as u16).wrapping_sub(init_bin_esc[k] / (i as u16 + 2));
329 }
330 }
331 }
332
333 for i in 0..25 {
335 for k in 0..16 {
336 self.see2_cont[i][k] = See2Context::new((5 * i + 10) as u16);
337 }
338 }
339 }
340
341 pub fn decode_char(
343 &mut self,
344 coder: &mut RangeCoder,
345 reader: &mut BitReader,
346 ) -> Result<i32, &'static str> {
347 #[cfg(test)]
348 {
349 self.debug_count += 1;
350 }
351
352 #[cfg(test)]
353 let start_bytes = reader.byte_position();
354
355 #[cfg(test)]
356 if self.debug_count == 0 {
357 let (code, low, range) = coder.debug_state();
358 eprintln!(
359 "[ENTRY pos={}] low={} range={} code={} code-low={} prev_success={}",
360 self.debug_count,
361 low,
362 range,
363 code,
364 code.wrapping_sub(low),
365 self.prev_success
366 );
367 }
368
369 let text_ptr = self.sub_alloc.text_ptr();
371 let heap_end = self.sub_alloc.heap_end();
372
373 if self.min_context as usize <= text_ptr || self.min_context as usize > heap_end {
374 return Err("Invalid context");
375 }
376
377 let num_stats = self.read_context_num_stats(self.min_context as usize);
378
379 #[cfg(test)]
380 if self.debug_count == 0 {
381 let (code, low, range) = coder.debug_state();
382 eprintln!(
383 "[ENTRY pos={}] low={} range={} code={} NumStats={} ctx={}",
384 self.debug_count, low, range, code, num_stats, self.min_context
385 );
386 }
387
388 #[cfg(test)]
389 if self.debug_count == 0 {
390 let summ = self.read_context_summ_freq(self.min_context as usize);
391 eprintln!(
392 "[pos={}] min_context={} NumStats={} SummFreq={} order_fall={}",
393 self.debug_count, self.min_context, num_stats, summ, self.order_fall
394 );
395 }
396
397 if num_stats != 1 {
398 let stats = self.read_context_stats(self.min_context as usize);
400 if stats as usize <= text_ptr || stats as usize > heap_end {
401 #[cfg(test)]
402 eprintln!(
403 "[pos={}] INVALID STATS: ctx={} num_stats={} stats={} text_ptr={} heap_end={}",
404 self.debug_count, self.min_context, num_stats, stats, text_ptr, heap_end
405 );
406 return Err("Invalid stats pointer");
407 }
408 #[cfg(test)]
409 if self.debug_count == 0 {
410 eprintln!(
411 "[pos={}] Multi-symbol context at {}, num_stats={}",
412 self.debug_count, self.min_context, num_stats
413 );
414 }
415 self.decode_symbol1(coder, reader)?;
416 } else {
417 #[cfg(test)]
419 if self.debug_count == 0 {
420 let sym = self.sub_alloc.read_byte(self.min_context as usize + 2);
422 let suffix = self.read_context_suffix(self.min_context as usize);
423 eprintln!("[pos={}] Binary context at {}, sym='{}' ({}), suffix={}, order_fall={}, max_order={}",
424 self.debug_count, self.min_context, sym as char, sym, suffix, self.order_fall, self.max_order);
425 }
426 self.decode_bin_symbol(coder, reader)?;
427 }
428
429 while self.found_state == 0 {
433 coder.normalize(reader);
434 #[cfg(test)]
435 if self.debug_count == 0 {
436 let (code, low, range) = coder.debug_state();
437 eprintln!(
438 "[ESCAPE pos={}] After normalize: low={} range={} code={}",
439 self.debug_count, low, range, code
440 );
441 }
442
443 loop {
445 self.order_fall += 1;
446 let suffix = self.read_context_suffix(self.min_context as usize);
447
448 #[cfg(test)]
449 if self.debug_count == 0 {
450 eprintln!(
451 "[ESCAPE pos={}] order_fall={} min_context={} suffix={}",
452 self.debug_count, self.order_fall, self.min_context, suffix
453 );
454 }
455
456 if suffix as usize <= text_ptr || suffix as usize > heap_end {
457 #[cfg(test)]
458 eprintln!(
459 "[ESCAPE pos={}] Invalid suffix={} (text_ptr={} heap_end={})",
460 self.debug_count, suffix, text_ptr, heap_end
461 );
462 return Err("Invalid suffix");
463 }
464
465 self.min_context = suffix;
466
467 let ns = self.read_context_num_stats(suffix as usize);
468 if ns as usize != self.num_masked {
469 #[cfg(test)]
470 if self.debug_count == 0 {
471 eprintln!(
472 "[ESCAPE pos={}] Found context with ns={} (masked={})",
473 self.debug_count, ns, self.num_masked
474 );
475 }
476 break;
477 }
478 }
479
480 self.decode_symbol2(coder, reader)?;
481 }
483
484 let symbol = self.read_state_symbol(self.found_state as usize);
486
487 let successor = self.read_state_successor(self.found_state as usize);
489 if self.order_fall == 0 && successor as usize > text_ptr {
490 let succ = successor;
491 self.min_context = succ;
492 self.max_context = succ;
493 } else {
494 self.update_model();
495 if self.esc_count == 0 {
496 self.clear_mask();
497 }
498 }
499
500 coder.normalize(reader);
501
502 #[cfg(test)]
503 {
504 let end_bytes = reader.byte_position();
505 let bytes_consumed = end_bytes - start_bytes;
506 if self.debug_count == 0 || (self.debug_count >= 1120 && self.debug_count <= 1135) {
507 eprintln!(
508 "[pos={}] sym='{}' ({}) bytes_consumed={} found_state={}",
509 self.debug_count, symbol as char, symbol, bytes_consumed, self.found_state
510 );
511 }
512 }
513
514 Ok(symbol as i32)
515 }
516
517 #[inline]
519 fn decode_symbol1(
520 &mut self,
521 coder: &mut RangeCoder,
522 _reader: &mut BitReader,
523 ) -> Result<(), &'static str> {
524 let summ_freq = self.read_context_summ_freq(self.min_context as usize);
525 let stats = self.read_context_stats(self.min_context as usize);
526 let num_stats = self.read_context_num_stats(self.min_context as usize);
527
528 #[cfg(test)]
529 if self.debug_count == 0 {
530 eprintln!(
531 "[DS1 pos={}] summ_freq={} num_stats={} prev_success_before={}",
532 self.debug_count, summ_freq, num_stats, self.prev_success
533 );
534 }
535
536 let count = coder.get_current_count(summ_freq as u32);
537
538 #[cfg(test)]
539 if self.debug_count == 0 {
540 eprintln!("[DS1 pos={}] count={}", self.debug_count, count);
541 }
542
543 if count >= summ_freq as u32 {
545 return Err("Count exceeds scale");
546 }
547
548 let mut hi_cnt = 0u32;
549
550 for i in 0..num_stats {
551 let state_ptr = stats as usize + (i as usize) * 6;
552 let freq = self.read_state_freq(state_ptr) as u32;
553 #[cfg(test)]
554 let sym = self.read_state_symbol(state_ptr);
555 hi_cnt += freq;
556
557 #[cfg(test)]
558 if self.debug_count == 0 {
559 eprintln!(
560 "[DS1 pos={}] i={} sym='{}' ({}) freq={} hi_cnt={}",
561 self.debug_count, i, sym as char, sym, freq, hi_cnt
562 );
563 }
564
565 if hi_cnt > count {
566 let lo_cnt = hi_cnt - freq;
567
568 #[cfg(test)]
569 if self.debug_count == 0 {
570 eprintln!(
571 "[DS1 pos={}] Selected i={} sym='{}' ({}) lo={} hi={}",
572 self.debug_count, i, sym as char, sym, lo_cnt, hi_cnt
573 );
574 let (code, low, range) = coder.debug_state();
575 eprintln!(
576 "[DS1 pos={}] BEFORE decode: low={} range={} code={}",
577 self.debug_count, low, range, code
578 );
579 }
580 let sub = SubRange {
581 low_count: lo_cnt,
582 high_count: hi_cnt,
583 scale: summ_freq as u32,
584 };
585 coder.decode(&sub);
586
587 #[cfg(test)]
588 if self.debug_count == 0 {
589 let (code, low, range) = coder.debug_state();
590 eprintln!(
591 "[DS1 pos={}] AFTER decode: low={:#x} range={:#x} code={:#x}",
592 self.debug_count, low, range, code
593 );
594 }
595
596 if i == 0 {
600 self.prev_success = if 2 * freq > summ_freq as u32 { 1 } else { 0 };
601 self.run_length += self.prev_success as i32;
602 } else {
603 self.prev_success = 0;
604 }
605
606 let hi_cnt = freq + 4;
608 self.write_state_freq(state_ptr, hi_cnt as u8);
609
610 let new_summ = summ_freq.saturating_add(4);
612 self.write_context_summ_freq(self.min_context as usize, new_summ);
613
614 if i > 0 {
617 let prev_ptr = stats as usize + ((i - 1) as usize) * 6;
618 let prev_freq = self.read_state_freq(prev_ptr);
619 if hi_cnt as u8 > prev_freq {
620 let cur_sym = self.read_state_symbol(state_ptr);
622 let cur_succ = self.read_state_successor(state_ptr);
623 let prev_sym = self.read_state_symbol(prev_ptr);
624 let prev_succ = self.read_state_successor(prev_ptr);
625
626 self.write_state(prev_ptr, cur_sym, hi_cnt as u8, cur_succ);
627 self.write_state(state_ptr, prev_sym, prev_freq, prev_succ);
628
629 self.found_state = prev_ptr as u32;
630
631 if hi_cnt > MAX_FREQ {
633 self.rescale();
634 }
635 } else {
636 self.found_state = state_ptr as u32;
637 if hi_cnt > MAX_FREQ {
638 self.rescale();
639 }
640 }
641 } else {
642 self.found_state = state_ptr as u32;
643 if hi_cnt > MAX_FREQ {
644 self.rescale();
645 }
646 }
647
648 return Ok(());
649 }
650 }
651
652 #[cfg(test)]
654 if self.debug_count == 0 {
655 eprintln!(
656 "[DS1 pos={} ESCAPE] hi_cnt={} summ_freq={} before decode",
657 self.debug_count, hi_cnt, summ_freq
658 );
659 }
660
661 self.prev_success = 0;
663
664 if self.found_state != 0 {
666 let prev_sym = self.read_state_symbol(self.found_state as usize);
667 self.hi_bits_flag = self.hb2_flag[prev_sym as usize];
668 }
669
670 let sub = SubRange {
671 low_count: hi_cnt,
672 high_count: summ_freq as u32,
673 scale: summ_freq as u32,
674 };
675 coder.decode(&sub);
676
677 #[cfg(test)]
678 if self.debug_count == 0 {
679 let (code, low, range) = coder.debug_state();
680 eprintln!(
681 "[DS1 pos=98 ESCAPE] After decode: low={} range={} code={}",
682 low, range, code
683 );
684 }
685
686 self.num_masked = num_stats as usize;
687 self.found_state = 0;
688
689 for i in 0..num_stats {
692 let state_ptr = stats as usize + (i as usize) * 6;
693 let sym = self.read_state_symbol(state_ptr);
694 self.char_mask[sym as usize] = self.esc_count;
695 }
696
697 Ok(())
698 }
699
700 #[inline]
702 fn decode_bin_symbol(
703 &mut self,
704 coder: &mut RangeCoder,
705 _reader: &mut BitReader,
706 ) -> Result<(), &'static str> {
707 let state = self.read_context_one_state(self.min_context as usize);
708
709 if self.found_state != 0 {
711 let prev_sym = self.read_state_symbol(self.found_state as usize);
712 self.hi_bits_flag = self.hb2_flag[prev_sym as usize];
713 }
714
715 let suffix = self.read_context_suffix(self.min_context as usize);
717 let suffix_num_stats = if suffix != 0 {
718 self.read_context_num_stats(suffix as usize)
719 } else {
720 1 };
722
723 let ns_idx = if suffix_num_stats > 0 {
725 (suffix_num_stats - 1).min(255)
726 } else {
727 0
728 };
729 let ns1 = unsafe { *self.ns2_bs_indx.get_unchecked(ns_idx as usize) } as usize;
731
732 let idx1 = (self.prev_success as usize)
735 + ns1
736 + self.hi_bits_flag as usize
737 + 2 * (unsafe { *self.hb2_flag.get_unchecked(state.symbol as usize) } as usize)
738 + ((self.run_length >> 26) & 0x20) as usize;
739
740 let freq_idx = state.freq.saturating_sub(1) as usize;
742 let freq_idx = freq_idx & 127; let idx1 = idx1 & 63;
745
746 let bs = unsafe { *self.bin_summ.get_unchecked(freq_idx).get_unchecked(idx1) };
747
748 #[cfg(test)]
749 if self.debug_count == 0 {
750 eprintln!("[BIN pos={} idx] prev_success={} ns1={} hi_bits_flag={} hb2_flag[{}]={} run_length={}",
751 self.debug_count, self.prev_success, ns1, self.hi_bits_flag, state.symbol, self.hb2_flag[state.symbol as usize], self.run_length);
752 eprintln!(
753 "[BIN pos={} idx] idx1={} freq_idx={} bs={}",
754 self.debug_count, idx1, freq_idx, bs
755 );
756 }
757
758 let count = coder.get_current_shift_count(TOT_BITS);
759
760 #[cfg(test)]
761 if self.debug_count == 0 {
762 eprintln!(
763 "[BIN pos={}] sym='{}' ({}) freq={} bs={} count={}",
764 self.debug_count, state.symbol as char, state.symbol, state.freq, bs, count
765 );
766 let (code, low, range) = coder.debug_state();
767 eprintln!(
768 "[BIN pos={}] after get_count: low={} range={} code={}",
769 self.debug_count, low, range, code
770 );
771 }
772
773 if count < bs as u32 {
774 let sub = SubRange {
776 low_count: 0,
777 high_count: bs as u32,
778 scale: BIN_SCALE,
779 };
780
781 #[cfg(test)]
782 if self.debug_count == 0 {
783 let (code, low, range) = coder.debug_state();
784 eprintln!("[BIN pos={}] FOUND: lo=0 hi={} scale={} | before decode: low={} range={} code={}",
785 self.debug_count, bs, BIN_SCALE, low, range, code);
786 }
787
788 coder.decode(&sub);
789
790 let new_freq = state.freq + (if state.freq < 128 { 1 } else { 0 });
792 self.write_context_one_state_freq(self.min_context as usize, new_freq);
793
794 let mean = ((bs as u32 + (1 << (PERIOD_BITS - 2))) >> PERIOD_BITS) as u16;
797 let new_bs = bs.saturating_add((INTERVAL as u16).saturating_sub(mean));
798 unsafe {
800 *self
801 .bin_summ
802 .get_unchecked_mut(freq_idx)
803 .get_unchecked_mut(idx1) = new_bs
804 };
805
806 self.found_state = self.min_context + 2; self.prev_success = 1;
808 self.run_length += 1;
809 } else {
810 let sub = SubRange {
812 low_count: bs as u32,
813 high_count: BIN_SCALE,
814 scale: BIN_SCALE,
815 };
816
817 #[cfg(test)]
818 if self.debug_count == 0 {
819 let (code, low, range) = coder.debug_state();
820 eprintln!("[BIN pos={}] ESCAPE: lo={} hi={} scale={} | before decode: low={} range={} code={}",
821 self.debug_count, bs, BIN_SCALE, BIN_SCALE, low, range, code);
822 }
823
824 coder.decode(&sub);
825
826 let mean = ((bs as u32 + (1 << (PERIOD_BITS - 2))) >> PERIOD_BITS) as u16;
828 let new_bs = bs.saturating_sub(mean);
829 unsafe {
831 *self
832 .bin_summ
833 .get_unchecked_mut(freq_idx)
834 .get_unchecked_mut(idx1) = new_bs
835 };
836
837 static EXP_ESCAPE: [u8; 16] = [25, 14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2];
839 let esc_idx = ((new_bs >> 10) as usize).min(15);
841 self.init_esc = unsafe { *EXP_ESCAPE.get_unchecked(esc_idx) } as u32;
842
843 self.num_masked = 1;
844 self.found_state = 0;
845 unsafe { *self.char_mask.get_unchecked_mut(state.symbol as usize) = self.esc_count };
847 self.prev_success = 0;
849 }
850
851 Ok(())
852 }
853
854 #[inline]
856 fn decode_symbol2(
857 &mut self,
858 coder: &mut RangeCoder,
859 _reader: &mut BitReader,
860 ) -> Result<(), &'static str> {
861 #[cfg(test)]
862 if self.debug_count == 0 {
863 let (code, low, range) = coder.debug_state();
864 eprintln!(
865 "[DS2 pos={} entry] coder: low={:010} range={:010} code={:010}",
866 self.debug_count, low, range, code
867 );
868 }
869
870 let num_stats = self.read_context_num_stats(self.min_context as usize);
871 let stats = self.read_context_stats(self.min_context as usize);
872
873 #[cfg(test)]
874 if self.debug_count == 0 || self.debug_count == 58 {
875 eprintln!(
876 "[DS2 pos={}] min_context={} num_stats={} num_masked={}",
877 self.debug_count, self.min_context, num_stats, self.num_masked
878 );
879 }
880
881 let i = num_stats as usize - self.num_masked;
883 if i == 0 {
884 return Err("All symbols masked");
885 }
886
887 let esc_freq: u32;
889 let see2_row: usize;
890 let see2_col: usize;
891 let is_root = num_stats == 256;
892
893 if !is_root {
894 let ns2_idx = self.ns2_indx[(i - 1).min(255)] as usize;
896 let suffix = self.read_context_suffix(self.min_context as usize);
897 let suffix_num_stats = if suffix != 0 {
898 self.read_context_num_stats(suffix as usize)
899 } else {
900 num_stats
901 };
902 let summ_freq = self.read_context_summ_freq(self.min_context as usize);
903
904 let diff_suffix = (i < (suffix_num_stats as usize - num_stats as usize)) as usize;
906 let freq_check = (summ_freq < 11 * num_stats) as usize;
907 let masked_check = (self.num_masked > i) as usize;
908 let see2_idx = ns2_idx
909 + diff_suffix
910 + 2 * freq_check
911 + 4 * masked_check
912 + self.hi_bits_flag as usize;
913 let see2_idx = see2_idx.min(24 * 16 - 1);
914
915 see2_row = ns2_idx.min(24);
916 see2_col = see2_idx % 16;
917
918 esc_freq = self.see2_cont[see2_row][see2_col].get_mean();
920
921 #[cfg(test)]
922 if self.debug_count == 58 || self.debug_count == 0 {
923 let suffix = self.read_context_suffix(self.min_context as usize);
924 let suffix_ns = if suffix != 0 {
925 self.read_context_num_stats(suffix as usize)
926 } else {
927 0
928 };
929 eprintln!("[DS2 pos={}] SEE2 inputs: i={} suffix_ns={} summ_freq={} num_masked={} hi_bits_flag={}",
930 self.debug_count, i, suffix_ns, summ_freq, self.num_masked, self.hi_bits_flag);
931 eprintln!("[DS2 pos={}] SEE2 indices: ns2_idx={} diff_suffix={} freq_check={} masked_check={}",
932 self.debug_count, ns2_idx, diff_suffix, freq_check, masked_check);
933 eprintln!(
934 "[DS2 pos={}] SEE2: see2_idx={} esc_freq={}",
935 self.debug_count, see2_idx, esc_freq
936 );
937 }
938 } else {
939 esc_freq = 1;
941 see2_row = 0;
942 see2_col = 0;
943 }
944
945 let mut hi_cnt = 0u32;
947
948 for j in 0..num_stats {
949 let state_ptr = stats as usize + (j as usize) * 6;
950 let sym = self.read_state_symbol(state_ptr);
951 if self.char_mask[sym as usize] != self.esc_count {
952 let freq = self.read_state_freq(state_ptr) as u32;
953 hi_cnt += freq;
954 }
955 }
956
957 #[cfg(test)]
958 let _freq_histogram = [0u32; 256];
959
960 #[cfg(test)]
961 if self.debug_count == 15 {
962 eprintln!(
963 "[DS2 pos=15] stats pointer={}, root context={}",
964 stats, self.min_context
965 );
966
967 let mut cum = 0u32;
969 for j in 0..num_stats {
970 let state_ptr = stats as usize + (j as usize) * 6;
971 let sym = self.read_state_symbol(state_ptr);
972 if self.char_mask[sym as usize] != self.esc_count {
973 let freq = self.read_state_freq(state_ptr) as u32;
974 let prev_cum = cum;
975 cum += freq;
976 if sym == 108 {
977 eprintln!(
979 "[DS2 pos=15] 'l' at j={} prev_cum={} cum={} freq={}",
980 j, prev_cum, cum, freq
981 );
982 }
983 if sym == 112 {
984 eprintln!(
986 "[DS2 pos=15] 'p' at j={} prev_cum={} cum={} freq={}",
987 j, prev_cum, cum, freq
988 );
989 }
990 if freq > 1 {
992 eprintln!("[DS2 pos=15] sym='{}' ({}) j={} prev_cum={} cum={} freq={} state_ptr={}",
993 sym as char, sym, j, prev_cum, cum, freq, state_ptr);
994 }
995 }
996 }
997 }
998
999 #[cfg(test)]
1000 if self.debug_count == 13 {
1001 let mut cum = 0u32;
1003 for j in 0..num_stats {
1004 let state_ptr = stats as usize + (j as usize) * 6;
1005 let sym = self.read_state_symbol(state_ptr);
1006 if self.char_mask[sym as usize] != self.esc_count {
1007 let freq = self.read_state_freq(state_ptr) as u32;
1008 let prev_cum = cum;
1009 cum += freq;
1010 if sym == 100 {
1011 eprintln!(
1013 "[DS2 pos=13] 'd' at j={} prev_cum={} cum={} freq={}",
1014 j, prev_cum, cum, freq
1015 );
1016 }
1017 if prev_cum <= 238 && cum > 238 {
1019 eprintln!(
1020 "[DS2 pos=13] At cum=238: j={} sym='{}' ({}) prev_cum={} cum={}",
1021 j, sym as char, sym, prev_cum, cum
1022 );
1023 }
1024 }
1025 }
1026 eprintln!("[DS2 pos=13] To select 'd', need count in [prev_cum, cum)");
1027 }
1028
1029 let scale = esc_freq + hi_cnt;
1031
1032 let count = coder.get_current_count(scale);
1033
1034 #[cfg(test)]
1035 if self.debug_count == 0 {
1036 eprintln!(
1037 "[DS2 pos={}] esc_freq={} hi_cnt={} scale={} count={}",
1038 self.debug_count, esc_freq, hi_cnt, scale, count
1039 );
1040 }
1041
1042 if count < hi_cnt {
1044 let mut cum = 0u32;
1046 for j in 0..num_stats {
1047 let state_ptr = stats as usize + (j as usize) * 6;
1048 let sym = self.read_state_symbol(state_ptr);
1049 if self.char_mask[sym as usize] != self.esc_count {
1050 let freq = self.read_state_freq(state_ptr) as u32;
1051 cum += freq;
1052 if cum > count {
1053 let lo_cnt = cum - freq;
1054
1055 #[cfg(test)]
1056 if self.debug_count == 0 || self.debug_count == 58 {
1057 eprintln!(
1058 "[DS2 pos={}] Selected j={} sym='{}' ({}) at cum={} lo={} freq={}",
1059 self.debug_count, j, sym as char, sym, cum, lo_cnt, freq
1060 );
1061 }
1062
1063 #[cfg(test)]
1064 if self.debug_count == 13 || self.debug_count == 58 {
1065 let (code, low, range) = coder.debug_state();
1066 eprintln!(
1067 "[DS2 pos={}] FOUND lo={} hi={} scale={}",
1068 self.debug_count, lo_cnt, cum, scale
1069 );
1070 eprintln!(
1071 "[DS2 pos={}] Before decode: low={} range={} code={}",
1072 self.debug_count, low, range, code
1073 );
1074 }
1075
1076 let sub = SubRange {
1077 low_count: lo_cnt,
1078 high_count: cum,
1079 scale,
1080 };
1081 coder.decode(&sub);
1082
1083 #[cfg(test)]
1084 if self.debug_count == 13 || self.debug_count == 58 {
1085 let (code, low, range) = coder.debug_state();
1086 eprintln!(
1087 "[DS2 pos={}] After decode: low={} range={} code={}",
1088 self.debug_count, low, range, code
1089 );
1090 }
1091
1092 if !is_root {
1094 self.see2_cont[see2_row][see2_col].update();
1095 }
1096
1097 self.found_state = state_ptr as u32;
1098
1099 let new_freq = freq + 4;
1101 self.write_state_freq(state_ptr, new_freq as u8);
1102
1103 let summ = self.read_context_summ_freq(self.min_context as usize);
1104 self.write_context_summ_freq(self.min_context as usize, summ + 4);
1105
1106 if new_freq > MAX_FREQ {
1108 self.rescale();
1109 }
1110
1111 self.esc_count = self.esc_count.wrapping_add(1);
1112 self.run_length = self.init_rl;
1113
1114 return Ok(());
1115 }
1116 }
1117 }
1118 }
1119
1120 if !is_root {
1122 self.see2_cont[see2_row][see2_col].summ = self.see2_cont[see2_row][see2_col]
1123 .summ
1124 .wrapping_add(scale as u16);
1125 }
1126
1127 let sub = SubRange {
1128 low_count: hi_cnt,
1129 high_count: scale,
1130 scale,
1131 };
1132 coder.decode(&sub);
1133
1134 for j in 0..num_stats {
1136 let state_ptr = stats as usize + (j as usize) * 6;
1137 let sym = self.read_state_symbol(state_ptr);
1138 if self.char_mask[sym as usize] != self.esc_count {
1139 self.char_mask[sym as usize] = self.esc_count;
1140 }
1141 }
1142 self.num_masked = num_stats as usize;
1143
1144 Ok(())
1145 }
1146
1147 fn create_child(
1151 &mut self,
1152 parent_ctx: u32,
1153 p_stats: usize,
1154 first_state_symbol: u8,
1155 first_state_freq: u8,
1156 first_state_successor: u32,
1157 ) -> u32 {
1158 let pc = match self.sub_alloc.alloc_context() {
1159 Some(ctx) => ctx as u32,
1160 None => return 0,
1161 };
1162
1163 self.write_context_num_stats(pc as usize, 1);
1165
1166 self.write_state(
1169 pc as usize + 2,
1170 first_state_symbol,
1171 first_state_freq,
1172 first_state_successor,
1173 );
1174
1175 self.write_context_suffix(pc as usize, parent_ctx);
1177
1178 self.write_state_successor(p_stats, pc);
1180
1181 pc
1182 }
1183
1184 fn rescale(&mut self) {
1187 let ctx = self.min_context as usize;
1188 let old_ns = self.read_context_num_stats(ctx);
1189 let stats = self.read_context_stats(ctx);
1190
1191 let mut p = self.found_state as usize;
1193 while p != stats as usize {
1194 let prev_p = p - 6;
1196 let p_sym = self.read_state_symbol(p);
1197 let p_freq = self.read_state_freq(p);
1198 let p_succ = self.read_state_successor(p);
1199 let prev_sym = self.read_state_symbol(prev_p);
1200 let prev_freq = self.read_state_freq(prev_p);
1201 let prev_succ = self.read_state_successor(prev_p);
1202 self.write_state(p, prev_sym, prev_freq, prev_succ);
1203 self.write_state(prev_p, p_sym, p_freq, p_succ);
1204 p = prev_p;
1205 }
1206
1207 let first_freq = self.read_state_freq(stats as usize);
1209 self.write_state_freq(stats as usize, first_freq.saturating_add(4));
1210 let summ = self.read_context_summ_freq(ctx);
1211 self.write_context_summ_freq(ctx, summ.saturating_add(4));
1212
1213 let new_first_freq = self.read_state_freq(stats as usize) as u32;
1215 let mut esc_freq = self.read_context_summ_freq(ctx) as i32 - new_first_freq as i32;
1216 let adder = if self.order_fall != 0 { 1 } else { 0 };
1217
1218 let halved = ((new_first_freq + adder) >> 1) as u8;
1220 self.write_state_freq(stats as usize, halved);
1221 let mut new_summ = halved as u16;
1222
1223 for i in 1..old_ns as usize {
1225 let state_ptr = stats as usize + i * 6;
1226 let freq = self.read_state_freq(state_ptr);
1227 esc_freq -= freq as i32;
1228
1229 let halved = ((freq as u32 + adder) >> 1) as u8;
1230 self.write_state_freq(state_ptr, halved);
1231 new_summ += halved as u16;
1232
1233 if halved > self.read_state_freq(state_ptr - 6) {
1235 let sym = self.read_state_symbol(state_ptr);
1237 let succ = self.read_state_successor(state_ptr);
1238
1239 let mut j = state_ptr - 6;
1241 while j >= stats as usize + 6 && halved > self.read_state_freq(j - 6) {
1242 j -= 6;
1243 }
1244
1245 let mut k = state_ptr;
1247 while k > j {
1248 let prev_sym = self.read_state_symbol(k - 6);
1249 let prev_freq = self.read_state_freq(k - 6);
1250 let prev_succ = self.read_state_successor(k - 6);
1251 self.write_state(k, prev_sym, prev_freq, prev_succ);
1252 k -= 6;
1253 }
1254
1255 self.write_state(j, sym, halved, succ);
1257 }
1258 }
1259
1260 let mut num_zeros = 0;
1262 for i in (0..old_ns as usize).rev() {
1263 let state_ptr = stats as usize + i * 6;
1264 if self.read_state_freq(state_ptr) == 0 {
1265 num_zeros += 1;
1266 } else {
1267 break;
1268 }
1269 }
1270
1271 if num_zeros > 0 {
1272 esc_freq += num_zeros;
1273 let new_ns = old_ns - num_zeros as u16;
1274
1275 if new_ns == 1 {
1276 let sym = self.read_state_symbol(stats as usize);
1278 let mut freq = self.read_state_freq(stats as usize);
1279 let succ = self.read_state_successor(stats as usize);
1280
1281 while esc_freq > 1 {
1283 freq = freq.saturating_sub(freq >> 1);
1284 esc_freq >>= 1;
1285 }
1286
1287 let units = (old_ns as usize + 1) >> 1;
1289 self.sub_alloc.free_units(stats as usize, units);
1290
1291 self.write_context_num_stats(ctx, 1);
1293 self.write_state(ctx + 2, sym, freq, succ);
1294 self.found_state = (ctx + 2) as u32;
1295 return;
1296 }
1297
1298 self.write_context_num_stats(ctx, new_ns);
1299
1300 }
1303
1304 new_summ += (esc_freq - (esc_freq >> 1)) as u16;
1306 self.write_context_summ_freq(ctx, new_summ);
1307
1308 let new_stats = self.read_context_stats(ctx);
1310 self.found_state = new_stats;
1311 }
1312
1313 fn create_successors(&mut self, skip: bool, p1: Option<usize>) -> u32 {
1316 let up_branch = self.read_state_successor(self.found_state as usize);
1317 let fs_symbol = self.read_state_symbol(self.found_state as usize);
1318
1319 #[cfg(test)]
1320 if self.debug_count == 12 {
1321 eprintln!(
1322 "[CS pos=12] Entry: skip={} p1={:?} up_branch={} fs_symbol='{}'",
1323 skip, p1, up_branch, fs_symbol as char
1324 );
1325 }
1326
1327 let mut pc = self.min_context;
1328 let mut ps: [usize; MAX_O] = [0; MAX_O];
1330 let mut pps_idx = 0;
1331
1332 if !skip {
1333 ps[pps_idx] = self.found_state as usize;
1334 pps_idx += 1;
1335 let suffix = self.read_context_suffix(pc as usize);
1336 if suffix == 0 {
1337 if pps_idx == 0 {
1339 return pc;
1340 }
1341 return self.create_successors_finish(pc, &ps, pps_idx, up_branch, fs_symbol);
1342 }
1343 }
1344
1345 let mut p: usize;
1346 let mut start_in_loop = false;
1347 if let Some(p1_val) = p1 {
1348 p = p1_val;
1349 pc = self.read_context_suffix(pc as usize);
1350 start_in_loop = true;
1351 } else {
1352 p = 0; }
1354
1355 loop {
1357 if !start_in_loop {
1358 pc = self.read_context_suffix(pc as usize);
1359 if pc == 0 {
1360 break;
1361 }
1362
1363 let num_stats = self.read_context_num_stats(pc as usize);
1364 if num_stats != 1 {
1365 let stats = self.read_context_stats(pc as usize);
1366 p = stats as usize;
1367 if self.read_state_symbol(p) != fs_symbol {
1368 let limit = stats as usize + num_stats as usize * 6;
1369 loop {
1370 p += 6;
1371 if p >= limit || self.read_state_symbol(p) == fs_symbol {
1372 break;
1373 }
1374 }
1375 }
1376 } else {
1377 p = pc as usize + 2;
1379 }
1380 }
1381 start_in_loop = false; let p_successor = self.read_state_successor(p);
1385 if p_successor != up_branch {
1386 pc = p_successor;
1387 break;
1388 }
1389
1390 if pps_idx >= MAX_O {
1391 return 0;
1392 }
1393 ps[pps_idx] = p;
1394 pps_idx += 1;
1395
1396 let suffix = self.read_context_suffix(pc as usize);
1397 if suffix == 0 {
1398 break;
1399 }
1400 }
1401
1402 self.create_successors_finish(pc, &ps, pps_idx, up_branch, fs_symbol)
1403 }
1404
1405 fn create_successors_finish(
1406 &mut self,
1407 mut pc: u32,
1408 ps: &[usize; MAX_O],
1409 pps_idx: usize,
1410 up_branch: u32,
1411 fs_symbol: u8,
1412 ) -> u32 {
1413 #[cfg(test)]
1414 if self.debug_count == 12 {
1415 eprintln!(
1416 "[CS_FINISH pos=12] pc={} pps_idx={} up_branch={} fs_symbol='{}'",
1417 pc, pps_idx, up_branch, fs_symbol as char
1418 );
1419 for i in 0..pps_idx {
1420 let sym = self.read_state_symbol(ps[i]);
1421 eprintln!(
1422 "[CS_FINISH pos=12] ps[{}]={} sym='{}'",
1423 i, ps[i], sym as char
1424 );
1425 }
1426 }
1427
1428 let _ = fs_symbol;
1430
1431 if pps_idx == 0 {
1432 return pc;
1433 }
1434
1435 let up_state_symbol = self.sub_alloc.read_byte(up_branch as usize);
1437 let up_state_successor = up_branch + 1;
1439
1440 let up_state_freq: u8;
1441 let num_stats = self.read_context_num_stats(pc as usize);
1442 if num_stats != 1 {
1443 let text_ptr = self.sub_alloc.get_text_ptr();
1444 if pc as usize <= text_ptr {
1445 return 0;
1446 }
1447
1448 let stats = self.read_context_stats(pc as usize);
1449 let mut p = stats as usize;
1450 if self.read_state_symbol(p) != up_state_symbol {
1451 let limit = stats as usize + num_stats as usize * 6;
1452 loop {
1453 p += 6;
1454 if p >= limit || self.read_state_symbol(p) == up_state_symbol {
1455 break;
1456 }
1457 }
1458 }
1459
1460 let cf = self.read_state_freq(p) as u32 - 1;
1461 let s0 = self.read_context_summ_freq(pc as usize) as u32 - num_stats as u32 - cf;
1462 up_state_freq = (1 + if 2 * cf <= s0 {
1465 if 5 * cf > s0 {
1466 1
1467 } else {
1468 0
1469 }
1470 } else {
1471 (2 * cf + 3 * s0 - 1) / (2 * s0)
1472 })
1473 .min(255) as u8;
1474 } else {
1475 up_state_freq = self.read_state_freq(pc as usize + 2);
1477 }
1478
1479 let mut i = pps_idx;
1481 while i > 0 {
1482 i -= 1;
1483 pc = self.create_child(
1484 pc,
1485 ps[i],
1486 up_state_symbol,
1487 up_state_freq,
1488 up_state_successor,
1489 );
1490 if pc == 0 {
1491 return 0;
1492 }
1493 }
1494
1495 pc
1496 }
1497
1498 fn update_model(&mut self) {
1499 #[cfg(test)]
1500 if self.debug_count == 11 || self.debug_count == 12 {
1501 eprintln!(
1502 "[UPDATE pos={}] Before: min_context={} max_context={} order_fall={}",
1503 self.debug_count, self.min_context, self.max_context, self.order_fall
1504 );
1505 }
1506
1507 let fs_symbol = self.read_state_symbol(self.found_state as usize);
1509 let fs_freq = self.read_state_freq(self.found_state as usize);
1510 let fs_successor = self.read_state_successor(self.found_state as usize);
1511
1512 #[cfg(test)]
1513 if self.debug_count == 12 {
1514 eprintln!(
1515 "[UPDATE pos=12] found_state={} fs_sym='{}' fs_freq={} fs_successor={}",
1516 self.found_state, fs_symbol as char, fs_freq, fs_successor
1517 );
1518 let text_ptr = self.sub_alloc.get_text_ptr();
1519 eprintln!(
1520 "[UPDATE pos=12] text_ptr={}, fs_successor<=text_ptr: {}",
1521 text_ptr,
1522 (fs_successor as usize) <= text_ptr
1523 );
1524 }
1525
1526 let mut p: Option<usize> = None;
1528 let suffix = self.read_context_suffix(self.min_context as usize);
1529 if suffix != 0 && (fs_freq as u32) < MAX_FREQ / 4 {
1530 let num_stats = self.read_context_num_stats(suffix as usize);
1531 if num_stats != 1 {
1532 let stats = self.read_context_stats(suffix as usize);
1534 let mut state_ptr = stats as usize;
1535 if self.read_state_symbol(state_ptr) != fs_symbol {
1536 let limit = stats as usize + num_stats as usize * 6;
1537 loop {
1538 state_ptr += 6;
1539 if state_ptr >= limit || self.read_state_symbol(state_ptr) == fs_symbol {
1540 break;
1541 }
1542 }
1543 let freq = self.read_state_freq(state_ptr);
1545 let prev_freq = self.read_state_freq(state_ptr - 6);
1546 if freq >= prev_freq {
1547 let prev_ptr = state_ptr - 6;
1549 let curr_sym = self.read_state_symbol(state_ptr);
1550 let curr_freq = self.read_state_freq(state_ptr);
1551 let curr_succ = self.read_state_successor(state_ptr);
1552 let prev_sym = self.read_state_symbol(prev_ptr);
1553 let prev_freq = self.read_state_freq(prev_ptr);
1554 let prev_succ = self.read_state_successor(prev_ptr);
1555 self.write_state(state_ptr, prev_sym, prev_freq, prev_succ);
1556 self.write_state(prev_ptr, curr_sym, curr_freq, curr_succ);
1557 state_ptr = prev_ptr;
1558 }
1559 }
1560 p = Some(state_ptr);
1561 let freq = self.read_state_freq(state_ptr);
1562 if (freq as u32) < MAX_FREQ - 9 {
1563 self.write_state_freq(state_ptr, freq + 2);
1564 let sf = self.read_context_summ_freq(suffix as usize);
1565 self.write_context_summ_freq(suffix as usize, sf + 2);
1566 }
1567 } else {
1568 let one_state_ptr = suffix as usize + 2;
1570 p = Some(one_state_ptr);
1571 let freq = self.read_state_freq(one_state_ptr);
1572 if freq < 32 {
1573 self.write_state_freq(one_state_ptr, freq + 1);
1574 }
1575 }
1576 }
1577
1578 if self.order_fall == 0 {
1580 let new_ctx = self.create_successors(true, p);
1581 if new_ctx == 0 {
1582 self.restart_model();
1583 return;
1584 }
1585 self.write_state_successor(self.found_state as usize, new_ctx);
1586 self.min_context = new_ctx;
1587 self.max_context = new_ctx;
1588 return;
1589 }
1590
1591 let text_ptr = self.sub_alloc.get_text_ptr();
1593 let units_start = self.sub_alloc.get_units_start();
1594 if text_ptr >= units_start {
1595 self.restart_model();
1596 return;
1597 }
1598 self.sub_alloc.write_byte(text_ptr, fs_symbol);
1599 self.sub_alloc.advance_text_ptr();
1600
1601 let mut successor = self.sub_alloc.get_text_ptr() as u32;
1602
1603 let fs_successor_new: u32;
1605
1606 if fs_successor != 0 {
1607 let text_ptr = self.sub_alloc.get_text_ptr();
1608 if (fs_successor as usize) <= text_ptr {
1609 let new_succ = self.create_successors(false, p);
1610 if new_succ == 0 {
1611 self.restart_model();
1612 return;
1613 }
1614 self.write_state_successor(self.found_state as usize, new_succ);
1615 fs_successor_new = new_succ;
1616 } else {
1617 fs_successor_new = fs_successor;
1618 }
1619 self.order_fall -= 1;
1620 if self.order_fall == 0 {
1621 successor = fs_successor_new;
1623 if self.max_context != self.min_context {
1624 self.sub_alloc.retreat_text_ptr();
1626 }
1627 }
1630 } else {
1631 self.write_state_successor(self.found_state as usize, successor);
1633 fs_successor_new = self.min_context;
1635 }
1636
1637 let ns = self.read_context_num_stats(self.min_context as usize) as u32;
1639 let summ_freq = self.read_context_summ_freq(self.min_context as usize) as u32;
1640 let s0 = summ_freq
1641 .saturating_sub(ns)
1642 .saturating_sub(fs_freq as u32)
1643 .saturating_add(1);
1644
1645 let mut pc = self.max_context;
1646 while pc != self.min_context {
1647 let ns1 = self.read_context_num_stats(pc as usize);
1648
1649 if ns1 != 1 {
1650 if (ns1 & 1) == 0 {
1652 let old_stats = self.read_context_stats(pc as usize);
1654 let new_stats = self
1655 .sub_alloc
1656 .expand_units(old_stats as usize, (ns1 >> 1) as usize);
1657 if new_stats.is_none() {
1658 self.restart_model();
1659 return;
1660 }
1661 self.write_context_stats(pc as usize, new_stats.unwrap() as u32);
1662 }
1663
1664 let mut sf_inc = 0u16;
1666 if 2 * ns1 < ns as u16 {
1667 sf_inc += 1;
1668 }
1669 let summ = self.read_context_summ_freq(pc as usize);
1670 if 4 * ns1 as u32 <= ns && summ <= 8 * ns1 {
1671 sf_inc += 2;
1672 }
1673 self.write_context_summ_freq(pc as usize, summ + sf_inc);
1674 } else {
1675 let new_stats = self.sub_alloc.alloc_units(1);
1677 if new_stats.is_none() {
1678 self.restart_model();
1679 return;
1680 }
1681 let new_stats = new_stats.unwrap();
1682
1683 let one_state_sym = self.read_state_symbol(pc as usize + 2);
1685 let one_state_freq = self.read_state_freq(pc as usize + 2);
1686 let one_state_succ = self.read_state_successor(pc as usize + 2);
1687 self.write_state(new_stats, one_state_sym, one_state_freq, one_state_succ);
1688
1689 self.write_context_stats(pc as usize, new_stats as u32);
1690
1691 let freq = self.read_state_freq(new_stats);
1693 let new_freq = if (freq as u32) < MAX_FREQ / 4 - 1 {
1694 freq * 2
1695 } else {
1696 (MAX_FREQ - 4) as u8
1697 };
1698 self.write_state_freq(new_stats, new_freq);
1699
1700 let init_esc_extra = if ns > 3 { 1 } else { 0 };
1702 let new_summ = new_freq as u16 + self.init_esc as u16 + init_esc_extra as u16;
1703 self.write_context_summ_freq(pc as usize, new_summ);
1704 #[cfg(test)]
1705 if pc == 15728580 {
1706 eprintln!("[UPDATE_MODEL pos={}] context {} promoted: new_freq={} init_esc={} init_esc_extra={} → SummFreq={}",
1707 self.debug_count, pc, new_freq, self.init_esc, init_esc_extra, new_summ);
1708 }
1709 }
1710
1711 let summ = self.read_context_summ_freq(pc as usize) as u32;
1713 let cf = 2 * fs_freq as u32 * (summ + 6);
1714 let sf = s0 + summ;
1715
1716 let sym_freq: u8;
1717 if cf < 6 * sf {
1718 sym_freq = 1 + (cf > sf) as u8 + (cf >= 4 * sf) as u8;
1719 let summ = self.read_context_summ_freq(pc as usize);
1720 self.write_context_summ_freq(pc as usize, summ + 3);
1721 #[cfg(test)]
1722 if pc == 15728580 {
1723 eprintln!(
1724 "[UPDATE_MODEL pos={}] context {} SummFreq: {} → {} (branch1, sym_freq={})",
1725 self.debug_count,
1726 pc,
1727 summ,
1728 summ + 3,
1729 sym_freq
1730 );
1731 }
1732 } else {
1733 sym_freq = 4 + (cf >= 9 * sf) as u8 + (cf >= 12 * sf) as u8 + (cf >= 15 * sf) as u8;
1734 let summ = self.read_context_summ_freq(pc as usize);
1735 self.write_context_summ_freq(pc as usize, summ + sym_freq as u16);
1736 #[cfg(test)]
1737 if pc == 15728580 {
1738 eprintln!(
1739 "[UPDATE_MODEL pos={}] context {} SummFreq: {} → {} (branch2, sym_freq={})",
1740 self.debug_count,
1741 pc,
1742 summ,
1743 summ + sym_freq as u16,
1744 sym_freq
1745 );
1746 }
1747 }
1748
1749 let stats = self.read_context_stats(pc as usize);
1751 let new_state_ptr = stats as usize + (ns1 as usize) * 6;
1752
1753 #[cfg(test)]
1754 if ns1 >= 256 {
1755 eprintln!(
1756 "[UPDATE] ERROR: Adding state at ns1={} to context {} - exceeds 256!",
1757 ns1, pc
1758 );
1759 }
1760
1761 self.write_state(new_state_ptr, fs_symbol, sym_freq, successor);
1762
1763 self.write_context_num_stats(pc as usize, ns1 + 1);
1765
1766 pc = self.read_context_suffix(pc as usize);
1768 }
1769
1770 self.max_context = fs_successor_new;
1772 self.min_context = fs_successor_new;
1773
1774 #[cfg(test)]
1775 if self.debug_count == 11 || self.debug_count == 12 {
1776 eprintln!(
1777 "[UPDATE pos={}] After: min_context={} max_context={}",
1778 self.debug_count, self.min_context, self.max_context
1779 );
1780 }
1781 }
1782
1783 fn clear_mask(&mut self) {
1785 self.esc_count = self.esc_count.wrapping_add(1);
1788 if self.esc_count == 0 {
1789 self.esc_count = 1;
1791 self.char_mask = [0; 256];
1792 }
1793 }
1794
1795 #[inline]
1798 fn read_context_num_stats(&self, offset: usize) -> u16 {
1799 self.sub_alloc.read_u16(offset)
1800 }
1801
1802 #[inline]
1803 fn write_context_num_stats(&mut self, offset: usize, val: u16) {
1804 self.sub_alloc.write_u16(offset, val);
1805 }
1806
1807 #[inline]
1808 fn read_context_summ_freq(&self, offset: usize) -> u16 {
1809 self.sub_alloc.read_u16(offset + 2)
1810 }
1811
1812 #[inline]
1813 fn write_context_summ_freq(&mut self, offset: usize, val: u16) {
1814 self.sub_alloc.write_u16(offset + 2, val);
1815 }
1816
1817 #[inline]
1818 fn read_context_stats(&self, offset: usize) -> u32 {
1819 self.sub_alloc.read_u32(offset + 4)
1820 }
1821
1822 #[inline]
1823 fn write_context_stats(&mut self, offset: usize, val: u32) {
1824 self.sub_alloc.write_u32(offset + 4, val);
1825 }
1826
1827 #[inline]
1828 fn read_context_suffix(&self, offset: usize) -> u32 {
1829 self.sub_alloc.read_u32(offset + 8)
1830 }
1831
1832 #[inline]
1833 fn write_context_suffix(&mut self, offset: usize, val: u32) {
1834 self.sub_alloc.write_u32(offset + 8, val);
1835 }
1836
1837 #[inline]
1838 fn read_context_one_state(&self, offset: usize) -> State {
1839 State {
1842 symbol: self.sub_alloc.read_byte(offset + 2),
1843 freq: self.sub_alloc.read_byte(offset + 3),
1844 successor: self.sub_alloc.read_u32(offset + 4),
1845 }
1846 }
1847
1848 #[inline]
1849 fn write_context_one_state_freq(&mut self, offset: usize, freq: u8) {
1850 self.sub_alloc.write_byte(offset + 3, freq);
1852 }
1853
1854 #[inline]
1855 fn read_state_symbol(&self, offset: usize) -> u8 {
1856 self.sub_alloc.read_byte(offset)
1857 }
1858
1859 #[inline]
1860 fn read_state_freq(&self, offset: usize) -> u8 {
1861 self.sub_alloc.read_byte(offset + 1)
1862 }
1863
1864 #[inline]
1865 fn write_state_freq(&mut self, offset: usize, freq: u8) {
1866 self.sub_alloc.write_byte(offset + 1, freq);
1867 }
1868
1869 #[inline]
1870 fn read_state_successor(&self, offset: usize) -> u32 {
1871 self.sub_alloc.read_u32(offset + 2)
1872 }
1873
1874 #[inline]
1875 fn write_state_successor(&mut self, offset: usize, successor: u32) {
1876 self.sub_alloc.write_u32(offset + 2, successor);
1877 }
1878
1879 #[inline]
1880 fn write_state(&mut self, offset: usize, symbol: u8, freq: u8, successor: u32) {
1881 self.sub_alloc.write_byte(offset, symbol);
1882 self.sub_alloc.write_byte(offset + 1, freq);
1883 self.sub_alloc.write_u32(offset + 2, successor);
1884 }
1885}
1886
1887impl Default for PpmModel {
1888 fn default() -> Self {
1889 Self::new()
1890 }
1891}