1use crate::block::literals::LiteralsSection;
20use crate::fse::{BitReader, FseDecoder, FseTable};
21use haagenti_core::{Error, Result};
22
23type ParseTableResult = Result<(Option<(FseTable, usize)>, Option<u8>)>;
25
26const MAX_LL_SYMBOL: u8 = 35; const MAX_OF_SYMBOL: u8 = 31; const MAX_ML_SYMBOL: u8 = 52; #[derive(Debug, Clone, Copy)]
35struct RepeatOffsets {
36 offsets: [u32; 3],
37}
38
39impl RepeatOffsets {
40 fn new() -> Self {
42 Self { offsets: [1, 4, 8] }
43 }
44
45 fn resolve(&mut self, offset_value: u32, literal_length: u32) -> u32 {
53 if offset_value == 0 {
54 1
56 } else if offset_value <= 3 {
57 if literal_length == 0 {
59 match offset_value {
61 1 => {
62 let offset = self.offsets[1];
64 self.offsets.swap(0, 1);
66 offset
67 }
68 2 => {
69 let offset = self.offsets[2];
71 let temp = self.offsets[2];
73 self.offsets[2] = self.offsets[1];
74 self.offsets[1] = self.offsets[0];
75 self.offsets[0] = temp;
76 offset
77 }
78 3 => {
79 let offset = self.offsets[0].saturating_sub(1).max(1);
81 self.offsets[2] = self.offsets[1];
83 self.offsets[1] = self.offsets[0];
84 self.offsets[0] = offset;
85 offset
86 }
87 _ => unreachable!(),
88 }
89 } else {
90 let idx = (offset_value - 1) as usize;
92 let offset = self.offsets[idx];
93
94 if idx > 0 {
96 let temp = self.offsets[idx];
97 for i in (1..=idx).rev() {
98 self.offsets[i] = self.offsets[i - 1];
99 }
100 self.offsets[0] = temp;
101 }
102 offset
103 }
104 } else {
105 let offset = offset_value - 3;
107 self.offsets[2] = self.offsets[1];
109 self.offsets[1] = self.offsets[0];
110 self.offsets[0] = offset;
111 offset
112 }
113 }
114}
115
116#[derive(Debug, Clone, Copy, PartialEq, Eq)]
118pub struct Sequence {
119 pub literal_length: u32,
121 pub offset: u32,
123 pub match_length: u32,
125}
126
127impl Sequence {
128 pub fn new(literal_length: u32, offset: u32, match_length: u32) -> Self {
130 Self {
131 literal_length,
132 offset,
133 match_length,
134 }
135 }
136}
137
138#[derive(Debug, Clone, Copy, PartialEq, Eq)]
140pub enum SymbolMode {
141 Predefined,
143 Rle,
145 Fse,
147 Repeat,
149}
150
151impl SymbolMode {
152 pub fn from_field(field: u8) -> Self {
154 match field {
155 0 => SymbolMode::Predefined,
156 1 => SymbolMode::Rle,
157 2 => SymbolMode::Fse,
158 3 => SymbolMode::Repeat,
159 _ => unreachable!(),
160 }
161 }
162}
163
164#[derive(Debug, Clone)]
166pub struct SequencesSection {
167 pub num_sequences: usize,
169 pub sequences: Vec<Sequence>,
171}
172
173impl SequencesSection {
174 pub fn parse(input: &[u8], _literals: &LiteralsSection) -> Result<Self> {
180 if input.is_empty() {
181 return Ok(Self {
183 num_sequences: 0,
184 sequences: Vec::new(),
185 });
186 }
187
188 let (num_sequences, count_header_size) = Self::parse_sequence_count(input)?;
190
191 if num_sequences == 0 {
192 return Ok(Self {
193 num_sequences: 0,
194 sequences: Vec::new(),
195 });
196 }
197
198 if input.len() < count_header_size + 1 {
199 return Err(Error::corrupted("Sequences section truncated"));
200 }
201
202 let mode_byte = input[count_header_size];
209 let ll_mode = SymbolMode::from_field(mode_byte & 0x03);
210 let of_mode = SymbolMode::from_field((mode_byte >> 2) & 0x03);
211 let ml_mode = SymbolMode::from_field((mode_byte >> 4) & 0x03);
212
213 let mut pos = count_header_size + 1;
214
215 if ll_mode == SymbolMode::Rle && of_mode == SymbolMode::Rle && ml_mode == SymbolMode::Rle {
217 if input.len() < pos + 3 {
218 return Err(Error::corrupted("RLE sequence symbols truncated"));
219 }
220 let ll_sym = input[pos];
221 let of_sym = input[pos + 1];
222 let ml_sym = input[pos + 2];
223 pos += 3;
224
225 return Self::decode_rle_sequences(
226 &input[pos..],
227 num_sequences,
228 ll_sym,
229 of_sym,
230 ml_sym,
231 );
232 }
233
234 let (ll_table, ll_rle_sym) = Self::parse_table_for_mode(
236 ll_mode,
237 &input[pos..],
238 MAX_LL_SYMBOL,
239 "Literal Length",
240 &PREDEFINED_LL_DISTRIBUTION,
241 PREDEFINED_LL_ACCURACY_LOG,
242 )?;
243 pos += ll_table.as_ref().map_or(0, |(_, consumed)| *consumed);
244
245 let (of_table, of_rle_sym) = Self::parse_table_for_mode(
246 of_mode,
247 &input[pos..],
248 MAX_OF_SYMBOL,
249 "Offset",
250 &PREDEFINED_OF_DISTRIBUTION,
251 PREDEFINED_OF_ACCURACY_LOG,
252 )?;
253 pos += of_table.as_ref().map_or(0, |(_, consumed)| *consumed);
254
255 let (ml_table, ml_rle_sym) = Self::parse_table_for_mode(
256 ml_mode,
257 &input[pos..],
258 MAX_ML_SYMBOL,
259 "Match Length",
260 &PREDEFINED_ML_DISTRIBUTION,
261 PREDEFINED_ML_ACCURACY_LOG,
262 )?;
263 pos += ml_table.as_ref().map_or(0, |(_, consumed)| *consumed);
264
265 let has_rle = ll_rle_sym.is_some() || of_rle_sym.is_some() || ml_rle_sym.is_some();
267
268 let ll = ll_table
270 .map(|(t, _)| t)
271 .or_else(|| {
272 FseTable::from_predefined(&PREDEFINED_LL_DISTRIBUTION, PREDEFINED_LL_ACCURACY_LOG)
273 .ok()
274 })
275 .ok_or_else(|| Error::corrupted("Failed to build LL table"))?;
276
277 let of = of_table
278 .map(|(t, _)| t)
279 .or_else(|| {
280 FseTable::from_predefined(&PREDEFINED_OF_DISTRIBUTION, PREDEFINED_OF_ACCURACY_LOG)
281 .ok()
282 })
283 .ok_or_else(|| Error::corrupted("Failed to build OF table"))?;
284
285 let ml = ml_table
286 .map(|(t, _)| t)
287 .or_else(|| {
288 FseTable::from_predefined(&PREDEFINED_ML_DISTRIBUTION, PREDEFINED_ML_ACCURACY_LOG)
289 .ok()
290 })
291 .ok_or_else(|| Error::corrupted("Failed to build ML table"))?;
292
293 if has_rle {
295 return Self::decode_mixed_sequences(
296 &input[pos..],
297 num_sequences,
298 &ll,
299 ll_rle_sym,
300 &of,
301 of_rle_sym,
302 &ml,
303 ml_rle_sym,
304 );
305 }
306
307 let (ll_table, of_table, ml_table) = (ll, of, ml);
308
309 let bitstream_data = &input[pos..];
311 Self::decode_fse_sequences(
312 bitstream_data,
313 num_sequences,
314 &ll_table,
315 &of_table,
316 &ml_table,
317 )
318 }
319
320 fn decode_fse_sequences(
322 data: &[u8],
323 num_sequences: usize,
324 ll_table: &FseTable,
325 of_table: &FseTable,
326 ml_table: &FseTable,
327 ) -> Result<Self> {
328 if data.is_empty() {
329 return Err(Error::corrupted("Empty sequence bitstream"));
330 }
331
332 let mut bits = BitReader::new(data);
334 bits.init_from_end()?;
335
336 let mut ll_decoder = FseDecoder::new(ll_table);
338 let mut of_decoder = FseDecoder::new(of_table);
339 let mut ml_decoder = FseDecoder::new(ml_table);
340
341 ll_decoder.init_state(&mut bits)?;
344 of_decoder.init_state(&mut bits)?;
345 ml_decoder.init_state(&mut bits)?;
346
347 bits.switch_to_lsb_mode()?;
350
351 let mut sequences = Vec::with_capacity(num_sequences);
352 let mut repeat_offsets = RepeatOffsets::new();
353
354 for i in 0..num_sequences {
355 let is_last = i == num_sequences - 1;
361
362 let ll_code = ll_decoder.peek_symbol();
364 let of_code = of_decoder.peek_symbol();
365 let _ml_code = ml_decoder.peek_symbol();
366
367 let ll_extra_bits = if ll_code < LITERAL_LENGTH_BASELINE.len() as u8 {
372 let (bits_needed, _) = LITERAL_LENGTH_BASELINE[ll_code as usize];
373 if bits_needed > 0 {
374 bits.read_bits(bits_needed as usize)?
375 } else {
376 0
377 }
378 } else {
379 0
380 };
381
382 let ml_seq_extra_bits = ml_decoder.peek_seq_extra_bits();
385 let ml_seq_base = ml_decoder.peek_seq_base();
386 let ml_extra_bits = if ml_seq_extra_bits > 0 {
387 bits.read_bits(ml_seq_extra_bits as usize)?
388 } else {
389 0
390 };
391
392 let of_num_bits = offset_code_extra_bits(of_code);
394 let of_extra_bits = if of_num_bits > 0 {
395 bits.read_bits(of_num_bits as usize)?
396 } else {
397 0
398 };
399
400 if !is_last {
403 ll_decoder.update_state(&mut bits)?;
404 ml_decoder.update_state(&mut bits)?;
405 of_decoder.update_state(&mut bits)?;
406 }
407
408 let literal_length = decode_literal_length(ll_code, ll_extra_bits);
410 let match_length = ml_seq_base + ml_extra_bits;
412 let offset_value = decode_offset(of_code, of_extra_bits);
413
414 let offset = repeat_offsets.resolve(offset_value, literal_length);
416
417 sequences.push(Sequence::new(literal_length, offset, match_length));
418 }
419
420 Ok(Self {
421 num_sequences,
422 sequences,
423 })
424 }
425
426 fn decode_rle_sequences(
428 data: &[u8],
429 num_sequences: usize,
430 ll_sym: u8,
431 of_sym: u8,
432 ml_sym: u8,
433 ) -> Result<Self> {
434 if data.is_empty() && num_sequences > 0 {
435 return Err(Error::corrupted("Empty RLE sequence data"));
436 }
437
438 let mut bits = BitReader::new(data);
439 if !data.is_empty() {
440 bits.init_fse()?;
442 }
443
444 let mut sequences = Vec::with_capacity(num_sequences);
445 let mut repeat_offsets = RepeatOffsets::new();
446
447 for _ in 0..num_sequences {
448 let ll_extra_bits = if ll_sym < LITERAL_LENGTH_BASELINE.len() as u8 {
452 let (bits_needed, _) = LITERAL_LENGTH_BASELINE[ll_sym as usize];
453 if bits_needed > 0 {
454 bits.read_bits(bits_needed as usize)?
455 } else {
456 0
457 }
458 } else {
459 0
460 };
461
462 let ml_extra_bits = if ml_sym < MATCH_LENGTH_BASELINE.len() as u8 {
464 let (bits_needed, _) = MATCH_LENGTH_BASELINE[ml_sym as usize];
465 if bits_needed > 0 {
466 bits.read_bits(bits_needed as usize)?
467 } else {
468 0
469 }
470 } else {
471 0
472 };
473
474 let of_num_bits = offset_code_extra_bits(of_sym);
476 let of_extra_bits = if of_num_bits > 0 {
477 bits.read_bits(of_num_bits as usize)?
478 } else {
479 0
480 };
481
482 let literal_length = decode_literal_length(ll_sym, ll_extra_bits);
483 let match_length = decode_match_length(ml_sym, ml_extra_bits);
484 let offset_value = decode_offset(of_sym, of_extra_bits);
485
486 let offset = repeat_offsets.resolve(offset_value, literal_length);
488
489 sequences.push(Sequence::new(literal_length, offset, match_length));
490 }
491
492 Ok(Self {
493 num_sequences,
494 sequences,
495 })
496 }
497
498 fn parse_table_for_mode(
503 mode: SymbolMode,
504 data: &[u8],
505 max_symbol: u8,
506 name: &str,
507 predefined_dist: &[i16],
508 predefined_log: u8,
509 ) -> ParseTableResult {
510 match mode {
511 SymbolMode::Predefined => {
512 let table = FseTable::from_predefined(predefined_dist, predefined_log)?;
513 Ok((Some((table, 0)), None))
514 }
515 SymbolMode::Rle => {
516 if data.is_empty() {
517 return Err(Error::corrupted(format!("{} RLE symbol missing", name)));
518 }
519 Ok((
521 Some((
522 FseTable::from_predefined(predefined_dist, predefined_log)?,
523 1,
524 )),
525 Some(data[0]),
526 ))
527 }
528 SymbolMode::Fse => {
529 let (table, consumed) = FseTable::parse(data, max_symbol)?;
530 Ok((Some((table, consumed)), None))
531 }
532 SymbolMode::Repeat => {
533 Err(Error::Unsupported(format!(
535 "{} Repeat mode not yet implemented",
536 name
537 )))
538 }
539 }
540 }
541
542 #[allow(clippy::too_many_arguments)]
546 fn decode_mixed_sequences(
547 data: &[u8],
548 num_sequences: usize,
549 ll_table: &FseTable,
550 ll_rle: Option<u8>,
551 of_table: &FseTable,
552 of_rle: Option<u8>,
553 ml_table: &FseTable,
554 ml_rle: Option<u8>,
555 ) -> Result<Self> {
556 if data.is_empty() && num_sequences > 0 {
557 return Err(Error::corrupted("Empty mixed sequence data"));
558 }
559
560 let mut bits = BitReader::new(data);
561 if !data.is_empty() {
562 bits.init_from_end()?;
563 }
564
565 let mut ll_decoder = if ll_rle.is_none() {
567 let mut d = FseDecoder::new(ll_table);
568 d.init_state(&mut bits)?;
569 Some(d)
570 } else {
571 None
572 };
573
574 let mut of_decoder = if of_rle.is_none() {
575 let mut d = FseDecoder::new(of_table);
576 d.init_state(&mut bits)?;
577 Some(d)
578 } else {
579 None
580 };
581
582 let mut ml_decoder = if ml_rle.is_none() {
583 let mut d = FseDecoder::new(ml_table);
584 d.init_state(&mut bits)?;
585 Some(d)
586 } else {
587 None
588 };
589
590 bits.switch_to_lsb_mode()?;
592
593 let mut sequences = Vec::with_capacity(num_sequences);
594 let mut repeat_offsets = RepeatOffsets::new();
595
596 for _ in 0..num_sequences {
597 let of_code = if let Some(ref mut dec) = of_decoder {
599 dec.peek_symbol()
600 } else {
601 of_rle.unwrap()
602 };
603
604 let ml_code = if let Some(ref mut dec) = ml_decoder {
605 dec.decode_symbol(&mut bits)?
606 } else {
607 ml_rle.unwrap()
608 };
609
610 let ll_code = if let Some(ref mut dec) = ll_decoder {
611 dec.decode_symbol(&mut bits)?
612 } else {
613 ll_rle.unwrap()
614 };
615
616 let ll_extra_bits = if ll_code < LITERAL_LENGTH_BASELINE.len() as u8 {
618 let (bits_needed, _) = LITERAL_LENGTH_BASELINE[ll_code as usize];
619 if bits_needed > 0 {
620 bits.read_bits(bits_needed as usize)?
621 } else {
622 0
623 }
624 } else {
625 0
626 };
627
628 let ml_extra_bits = if ml_code < MATCH_LENGTH_BASELINE.len() as u8 {
629 let (bits_needed, _) = MATCH_LENGTH_BASELINE[ml_code as usize];
630 if bits_needed > 0 {
631 bits.read_bits(bits_needed as usize)?
632 } else {
633 0
634 }
635 } else {
636 0
637 };
638
639 let of_num_bits = offset_code_extra_bits(of_code);
640 let of_extra_bits = if of_num_bits > 0 {
641 bits.read_bits(of_num_bits as usize)?
642 } else {
643 0
644 };
645
646 let literal_length = decode_literal_length(ll_code, ll_extra_bits);
647 let match_length = decode_match_length(ml_code, ml_extra_bits);
648 let offset_value = decode_offset(of_code, of_extra_bits);
649 let offset = repeat_offsets.resolve(offset_value, literal_length);
650
651 sequences.push(Sequence::new(literal_length, offset, match_length));
652 }
653
654 Ok(Self {
655 num_sequences,
656 sequences,
657 })
658 }
659
660 fn parse_sequence_count(input: &[u8]) -> Result<(usize, usize)> {
662 if input.is_empty() {
663 return Err(Error::corrupted("Empty sequences header"));
664 }
665
666 let byte0 = input[0] as usize;
667
668 if byte0 == 0 {
669 Ok((0, 1))
671 } else if byte0 < 128 {
672 Ok((byte0, 1))
674 } else if byte0 < 255 {
675 if input.len() < 2 {
677 return Err(Error::corrupted("Sequences count truncated"));
678 }
679 let count = ((byte0 - 128) << 8) + (input[1] as usize);
680 Ok((count, 2))
681 } else {
682 if input.len() < 3 {
684 return Err(Error::corrupted("Sequences count truncated"));
685 }
686 let count = (input[1] as usize) + ((input[2] as usize) << 8) + 0x7F00;
687 Ok((count, 3))
688 }
689 }
690}
691
692pub const PREDEFINED_LL_DISTRIBUTION: [i16; 36] = [
699 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1, -1, -1, -1, -1, ];
705
706pub const PREDEFINED_OF_DISTRIBUTION: [i16; 29] = [
709 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, ];
714
715pub const PREDEFINED_ML_DISTRIBUTION: [i16; 53] = [
718 1, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, ];
726
727pub const PREDEFINED_LL_ACCURACY_LOG: u8 = 6;
729
730pub const PREDEFINED_OF_ACCURACY_LOG: u8 = 5;
732
733pub const PREDEFINED_ML_ACCURACY_LOG: u8 = 6;
735
736pub const LITERAL_LENGTH_BASELINE: [(u8, u32); 36] = [
742 (0, 0),
743 (0, 1),
744 (0, 2),
745 (0, 3),
746 (0, 4),
747 (0, 5),
748 (0, 6),
749 (0, 7),
750 (0, 8),
751 (0, 9),
752 (0, 10),
753 (0, 11),
754 (0, 12),
755 (0, 13),
756 (0, 14),
757 (0, 15),
758 (1, 16),
759 (1, 18),
760 (1, 20),
761 (1, 22),
762 (2, 24),
763 (2, 28),
764 (3, 32),
765 (3, 40),
766 (4, 48),
767 (6, 64),
768 (7, 128),
769 (8, 256),
770 (9, 512),
771 (10, 1024),
772 (11, 2048),
773 (12, 4096),
774 (13, 8192),
775 (14, 16384),
776 (15, 32768),
777 (16, 65536),
778];
779
780pub const MATCH_LENGTH_BASELINE: [(u8, u32); 53] = [
790 (0, 3),
792 (0, 4),
793 (0, 5),
794 (0, 6),
795 (0, 7),
796 (0, 8),
797 (0, 9),
798 (0, 10),
799 (0, 11),
800 (0, 12),
801 (0, 13),
802 (0, 14),
803 (0, 15),
804 (0, 16),
805 (0, 17),
806 (0, 18),
807 (0, 19),
808 (0, 20),
809 (0, 21),
810 (0, 22),
811 (0, 23),
812 (0, 24),
813 (0, 25),
814 (0, 26),
815 (0, 27),
816 (0, 28),
817 (0, 29),
818 (0, 30),
819 (0, 31),
820 (0, 32),
821 (0, 33),
822 (0, 34),
823 (1, 35),
825 (1, 37),
826 (1, 39),
827 (1, 41),
828 (2, 43),
830 (2, 47),
831 (3, 51),
833 (3, 59),
834 (4, 67),
836 (4, 83),
837 (5, 99),
839 (7, 131),
841 (8, 259),
843 (9, 515),
845 (10, 1027),
847 (11, 2051),
849 (12, 4099),
851 (13, 8195),
853 (14, 16387),
855 (15, 32771),
857 (16, 65539),
859];
860
861pub fn decode_literal_length(code: u8, extra_bits: u32) -> u32 {
863 if code as usize >= LITERAL_LENGTH_BASELINE.len() {
864 return 0;
865 }
866 let (bits, baseline) = LITERAL_LENGTH_BASELINE[code as usize];
867 if bits == 0 {
868 baseline
869 } else {
870 baseline + (extra_bits & ((1 << bits) - 1))
871 }
872}
873
874pub fn decode_match_length(code: u8, extra_bits: u32) -> u32 {
876 if code as usize >= MATCH_LENGTH_BASELINE.len() {
877 return 3; }
879 let (bits, baseline) = MATCH_LENGTH_BASELINE[code as usize];
880 if bits == 0 {
881 baseline
882 } else {
883 baseline + (extra_bits & ((1 << bits) - 1))
884 }
885}
886
887pub fn decode_offset(code: u8, extra_bits: u32) -> u32 {
895 let code = code.min(31); (1u32 << code) + extra_bits
897}
898
899pub fn offset_code_extra_bits(code: u8) -> u8 {
903 code.min(31)
904}
905
906#[cfg(test)]
908fn build_predefined_tables() -> Result<(FseTable, FseTable, FseTable)> {
909 let ll_table = FseTable::build(
910 &PREDEFINED_LL_DISTRIBUTION,
911 PREDEFINED_LL_ACCURACY_LOG,
912 PREDEFINED_LL_DISTRIBUTION.len() as u8,
913 )?;
914
915 let of_table = FseTable::build(
916 &PREDEFINED_OF_DISTRIBUTION,
917 PREDEFINED_OF_ACCURACY_LOG,
918 PREDEFINED_OF_DISTRIBUTION.len() as u8,
919 )?;
920
921 let ml_table = FseTable::build(
922 &PREDEFINED_ML_DISTRIBUTION,
923 PREDEFINED_ML_ACCURACY_LOG,
924 PREDEFINED_ML_DISTRIBUTION.len() as u8,
925 )?;
926
927 Ok((ll_table, of_table, ml_table))
928}
929
930#[cfg(test)]
935mod tests {
936 use super::*;
937
938 #[test]
939 fn test_sequence_creation() {
940 let seq = Sequence::new(10, 5, 20);
941 assert_eq!(seq.literal_length, 10);
942 assert_eq!(seq.offset, 5);
943 assert_eq!(seq.match_length, 20);
944 }
945
946 #[test]
947 fn test_symbol_mode_parsing() {
948 assert_eq!(SymbolMode::from_field(0), SymbolMode::Predefined);
949 assert_eq!(SymbolMode::from_field(1), SymbolMode::Rle);
950 assert_eq!(SymbolMode::from_field(2), SymbolMode::Fse);
951 assert_eq!(SymbolMode::from_field(3), SymbolMode::Repeat);
952 }
953
954 #[test]
955 fn test_sequence_count_zero() {
956 let (count, size) = SequencesSection::parse_sequence_count(&[0]).unwrap();
957 assert_eq!(count, 0);
958 assert_eq!(size, 1);
959 }
960
961 #[test]
962 fn test_sequence_count_small() {
963 let (count, size) = SequencesSection::parse_sequence_count(&[50]).unwrap();
965 assert_eq!(count, 50);
966 assert_eq!(size, 1);
967 }
968
969 #[test]
970 fn test_sequence_count_medium() {
971 let (count, size) = SequencesSection::parse_sequence_count(&[129, 44]).unwrap();
976 assert_eq!(count, 300);
977 assert_eq!(size, 2);
978 }
979
980 #[test]
981 fn test_sequence_count_large() {
982 let (count, size) = SequencesSection::parse_sequence_count(&[255, 0, 0]).unwrap();
986 assert_eq!(count, 0x7F00);
987 assert_eq!(size, 3);
988
989 let (count, size) = SequencesSection::parse_sequence_count(&[255, 0, 1]).unwrap();
992 assert_eq!(count, 0x8000);
993 assert_eq!(size, 3);
994 }
995
996 #[test]
997 fn test_literal_length_decoding() {
998 assert_eq!(decode_literal_length(0, 0), 0);
1000 assert_eq!(decode_literal_length(15, 0), 15);
1001
1002 assert_eq!(decode_literal_length(16, 0), 16);
1004 assert_eq!(decode_literal_length(16, 1), 17);
1005
1006 assert_eq!(decode_literal_length(20, 0), 24);
1008 assert_eq!(decode_literal_length(20, 3), 27);
1009 }
1010
1011 #[test]
1012 fn test_match_length_decoding() {
1013 assert_eq!(decode_match_length(0, 0), 3);
1015
1016 assert_eq!(decode_match_length(31, 0), 34);
1018
1019 assert_eq!(decode_match_length(32, 0), 35);
1021 assert_eq!(decode_match_length(32, 1), 36);
1022 }
1023
1024 #[test]
1025 fn test_offset_decoding() {
1026 assert_eq!(decode_offset(0, 0), 1);
1031 assert_eq!(decode_offset(0, 1), 2); assert_eq!(decode_offset(1, 0), 2);
1035 assert_eq!(decode_offset(1, 1), 3);
1036
1037 assert_eq!(decode_offset(2, 0), 4);
1039 assert_eq!(decode_offset(2, 3), 7);
1040
1041 assert_eq!(decode_offset(3, 0), 8);
1043 assert_eq!(decode_offset(3, 7), 15);
1044
1045 assert_eq!(decode_offset(10, 0), 1024);
1047 assert_eq!(decode_offset(10, 500), 1524);
1048 }
1049
1050 #[test]
1051 fn test_empty_sequences() {
1052 let literals = LiteralsSection::new_raw(vec![]);
1053 let result = SequencesSection::parse(&[], &literals);
1054 assert!(result.is_ok());
1055 let section = result.unwrap();
1056 assert_eq!(section.num_sequences, 0);
1057 assert!(section.sequences.is_empty());
1058 }
1059
1060 #[test]
1061 fn test_zero_sequences() {
1062 let literals = LiteralsSection::new_raw(vec![]);
1063 let result = SequencesSection::parse(&[0], &literals);
1064 assert!(result.is_ok());
1065 let section = result.unwrap();
1066 assert_eq!(section.num_sequences, 0);
1067 }
1068
1069 #[test]
1070 fn test_predefined_tables_build() {
1071 let result = build_predefined_tables();
1073 assert!(result.is_ok(), "Build failed: {:?}", result.err());
1074
1075 let (ll_table, of_table, ml_table) = result.unwrap();
1076
1077 assert_eq!(ll_table.accuracy_log(), PREDEFINED_LL_ACCURACY_LOG);
1079 assert_eq!(of_table.accuracy_log(), PREDEFINED_OF_ACCURACY_LOG);
1080 assert_eq!(ml_table.accuracy_log(), PREDEFINED_ML_ACCURACY_LOG);
1081 }
1082
1083 #[test]
1084 fn test_predefined_ll_distribution_sum() {
1085 let sum: i32 = PREDEFINED_LL_DISTRIBUTION
1087 .iter()
1088 .filter(|&&x| x > 0)
1089 .map(|&x| x as i32)
1090 .sum();
1091 let less_than_one = PREDEFINED_LL_DISTRIBUTION
1093 .iter()
1094 .filter(|&&x| x == -1)
1095 .count();
1096
1097 assert!(sum + less_than_one as i32 <= 64);
1099 }
1100
1101 #[test]
1102 fn test_predefined_of_distribution_sum() {
1103 let sum: i32 = PREDEFINED_OF_DISTRIBUTION
1104 .iter()
1105 .filter(|&&x| x > 0)
1106 .map(|&x| x as i32)
1107 .sum();
1108 let less_than_one = PREDEFINED_OF_DISTRIBUTION
1109 .iter()
1110 .filter(|&&x| x == -1)
1111 .count();
1112
1113 assert!(sum + less_than_one as i32 <= 32);
1115 }
1116
1117 #[test]
1118 fn test_predefined_ml_distribution_sum() {
1119 let sum: i32 = PREDEFINED_ML_DISTRIBUTION
1120 .iter()
1121 .filter(|&&x| x > 0)
1122 .map(|&x| x as i32)
1123 .sum();
1124 let less_than_one = PREDEFINED_ML_DISTRIBUTION
1125 .iter()
1126 .filter(|&&x| x == -1)
1127 .count();
1128
1129 assert!(sum + less_than_one as i32 <= 64);
1131 }
1132
1133 #[test]
1134 fn test_literal_length_baseline_all_codes() {
1135 for code in 0..36u8 {
1137 let (bits, baseline) = LITERAL_LENGTH_BASELINE[code as usize];
1138 let result = decode_literal_length(code, 0);
1139 assert_eq!(result, baseline, "Code {} failed", code);
1140
1141 if bits > 0 {
1143 let max_extra = (1u32 << bits) - 1;
1144 let result_max = decode_literal_length(code, max_extra);
1145 assert_eq!(result_max, baseline + max_extra);
1146 }
1147 }
1148 }
1149
1150 #[test]
1151 fn test_match_length_baseline_all_codes() {
1152 for code in 0..53u8 {
1154 let (bits, baseline) = MATCH_LENGTH_BASELINE[code as usize];
1155 let result = decode_match_length(code, 0);
1156 assert_eq!(result, baseline, "Code {} failed", code);
1157
1158 if bits > 0 {
1159 let max_extra = (1u32 << bits) - 1;
1160 let result_max = decode_match_length(code, max_extra);
1161 assert_eq!(result_max, baseline + max_extra);
1162 }
1163 }
1164 }
1165
1166 #[test]
1167 fn test_offset_decoding_range() {
1168 for code in 0..=30u8 {
1170 let base_offset = decode_offset(code, 0);
1171 assert_eq!(base_offset, 1u32 << code, "Code {} failed", code);
1172 }
1173
1174 assert_eq!(decode_offset(31, 0), 1u32 << 31);
1176 }
1177
1178 #[test]
1179 fn test_sequences_with_predefined_mode() {
1180 let literals = LiteralsSection::new_raw(vec![]);
1183
1184 let mut data = vec![1]; data.push(0x00); data.push(0x80); let result = SequencesSection::parse(&data, &literals);
1193 if result.is_err() {
1195 } else {
1197 let section = result.unwrap();
1198 assert_eq!(section.num_sequences, 1);
1199 }
1200 }
1201
1202 #[test]
1203 fn test_mode_byte_parsing() {
1204 let mode_byte = 0x00u8;
1207 assert_eq!(
1208 SymbolMode::from_field((mode_byte >> 6) & 0x03),
1209 SymbolMode::Predefined
1210 );
1211 assert_eq!(
1212 SymbolMode::from_field((mode_byte >> 4) & 0x03),
1213 SymbolMode::Predefined
1214 );
1215 assert_eq!(
1216 SymbolMode::from_field((mode_byte >> 2) & 0x03),
1217 SymbolMode::Predefined
1218 );
1219
1220 let mode_byte = 0x54u8;
1222 assert_eq!(
1223 SymbolMode::from_field((mode_byte >> 6) & 0x03),
1224 SymbolMode::Rle
1225 );
1226 assert_eq!(
1227 SymbolMode::from_field((mode_byte >> 4) & 0x03),
1228 SymbolMode::Rle
1229 );
1230 assert_eq!(
1231 SymbolMode::from_field((mode_byte >> 2) & 0x03),
1232 SymbolMode::Rle
1233 );
1234
1235 let mode_byte = 0xA8u8;
1237 assert_eq!(
1238 SymbolMode::from_field((mode_byte >> 6) & 0x03),
1239 SymbolMode::Fse
1240 );
1241 assert_eq!(
1242 SymbolMode::from_field((mode_byte >> 4) & 0x03),
1243 SymbolMode::Fse
1244 );
1245 assert_eq!(
1246 SymbolMode::from_field((mode_byte >> 2) & 0x03),
1247 SymbolMode::Fse
1248 );
1249
1250 let mode_byte = 0xFCu8;
1252 assert_eq!(
1253 SymbolMode::from_field((mode_byte >> 6) & 0x03),
1254 SymbolMode::Repeat
1255 );
1256 assert_eq!(
1257 SymbolMode::from_field((mode_byte >> 4) & 0x03),
1258 SymbolMode::Repeat
1259 );
1260 assert_eq!(
1261 SymbolMode::from_field((mode_byte >> 2) & 0x03),
1262 SymbolMode::Repeat
1263 );
1264 }
1265
1266 #[test]
1267 fn test_sequence_count_boundary_127() {
1268 let (count, size) = SequencesSection::parse_sequence_count(&[127]).unwrap();
1270 assert_eq!(count, 127);
1271 assert_eq!(size, 1);
1272 }
1273
1274 #[test]
1275 fn test_sequence_count_boundary_128() {
1276 let (count, size) = SequencesSection::parse_sequence_count(&[128, 128]).unwrap();
1279 assert_eq!(count, 128);
1280 assert_eq!(size, 2);
1281 }
1282
1283 #[test]
1288 fn test_repeat_offsets_initial_values() {
1289 let offsets = RepeatOffsets::new();
1290 assert_eq!(offsets.offsets, [1, 4, 8]);
1291 }
1292
1293 #[test]
1294 fn test_repeat_offsets_new_offset() {
1295 let mut offsets = RepeatOffsets::new();
1296
1297 let result = offsets.resolve(7, 5); assert_eq!(result, 4); assert_eq!(offsets.offsets, [4, 1, 4]); }
1303
1304 #[test]
1305 fn test_repeat_offsets_use_first() {
1306 let mut offsets = RepeatOffsets::new();
1307
1308 let result = offsets.resolve(1, 5);
1310 assert_eq!(result, 1); assert_eq!(offsets.offsets, [1, 4, 8]); }
1313
1314 #[test]
1315 fn test_repeat_offsets_use_second() {
1316 let mut offsets = RepeatOffsets::new();
1317
1318 let result = offsets.resolve(2, 5);
1320 assert_eq!(result, 4); assert_eq!(offsets.offsets, [4, 1, 8]); }
1323
1324 #[test]
1325 fn test_repeat_offsets_use_third() {
1326 let mut offsets = RepeatOffsets::new();
1327
1328 let result = offsets.resolve(3, 5);
1330 assert_eq!(result, 8); assert_eq!(offsets.offsets, [8, 1, 4]); }
1333
1334 #[test]
1335 fn test_repeat_offsets_ll_zero_special_case_1() {
1336 let mut offsets = RepeatOffsets::new();
1337
1338 let result = offsets.resolve(1, 0);
1340 assert_eq!(result, 4); assert_eq!(offsets.offsets, [4, 1, 8]); }
1343
1344 #[test]
1345 fn test_repeat_offsets_ll_zero_special_case_2() {
1346 let mut offsets = RepeatOffsets::new();
1347
1348 let result = offsets.resolve(2, 0);
1350 assert_eq!(result, 8); assert_eq!(offsets.offsets, [8, 1, 4]); }
1353
1354 #[test]
1355 fn test_repeat_offsets_ll_zero_special_case_3() {
1356 let mut offsets = RepeatOffsets::new();
1357
1358 let result = offsets.resolve(3, 0);
1361 assert_eq!(result, 1); assert_eq!(offsets.offsets, [1, 1, 4]); }
1364
1365 #[test]
1366 fn test_repeat_offsets_ll_zero_case_3_larger_offset() {
1367 let mut offsets = RepeatOffsets::new();
1368
1369 offsets.resolve(13, 5); assert_eq!(offsets.offsets[0], 10);
1372
1373 let result = offsets.resolve(3, 0);
1375 assert_eq!(result, 9);
1376 assert_eq!(offsets.offsets[0], 9);
1377 }
1378
1379 #[test]
1380 fn test_repeat_offsets_sequence_of_operations() {
1381 let mut offsets = RepeatOffsets::new();
1382 offsets.resolve(106, 5);
1386 assert_eq!(offsets.offsets, [103, 1, 4]);
1387
1388 let result = offsets.resolve(1, 5);
1390 assert_eq!(result, 103);
1391 assert_eq!(offsets.offsets, [103, 1, 4]); let result = offsets.resolve(2, 5);
1395 assert_eq!(result, 1);
1396 assert_eq!(offsets.offsets, [1, 103, 4]); }
1398}