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