1use alloc::{vec, vec::Vec};
11
12use super::huffman;
13use crate::{Error, ErrorKind, Level, Progress, Status};
14
15const MIN_MATCH: usize = 3;
16const MAX_MATCH: usize = 258;
17const MIN_LOOKAHEAD: usize = MAX_MATCH + MIN_MATCH + 1;
20const TOO_FAR: usize = 4096;
23const WIN_PAD: usize = 8;
26const STORED_CHUNK: usize = 16 * 1024;
29
30const LENGTH_BASE: [u16; 29] = [
31 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131,
32 163, 195, 227, 258,
33];
34const LENGTH_EXTRA: [u8; 29] = [
35 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0,
36];
37const DIST_BASE: [u16; 30] = [
38 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537,
39 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577,
40];
41const DIST_EXTRA: [u8; 30] = [
42 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13,
43 13,
44];
45const PRECODE_ORDER: [usize; 19] = [
46 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15,
47];
48
49static LENGTH_CODE: [u8; 256] = {
51 let mut t = [0u8; 256];
52 let mut code = 0;
53 while code < 28 {
54 let mut i = 0;
55 while i < (1 << LENGTH_EXTRA[code]) {
56 t[LENGTH_BASE[code] as usize - 3 + i] = code as u8;
57 i += 1;
58 }
59 code += 1;
60 }
61 t[255] = 28;
63 t
64};
65
66static DIST_CODE: [u8; 512] = {
69 let mut t = [0u8; 512];
70 let mut code = 0;
71 while code < 30 {
72 let base = DIST_BASE[code] as usize - 1;
73 let count = 1usize << DIST_EXTRA[code];
74 let mut i = 0;
75 while i < count {
76 let d = base + i;
77 if d < 256 {
78 t[d] = code as u8;
79 } else {
80 t[256 + (d >> 7)] = code as u8;
81 }
82 i += 1;
83 }
84 code += 1;
85 }
86 t
87};
88
89#[inline]
90fn dist_code(dist: usize) -> usize {
91 let d = dist - 1;
92 if d < 256 {
93 DIST_CODE[d] as usize
94 } else {
95 DIST_CODE[256 + (d >> 7)] as usize
96 }
97}
98
99const fn fixed_lit_lens() -> [u8; 288] {
101 let mut l = [0u8; 288];
102 let mut i = 0;
103 while i < 288 {
104 l[i] = if i < 144 {
105 8
106 } else if i < 256 {
107 9
108 } else if i < 280 {
109 7
110 } else {
111 8
112 };
113 i += 1;
114 }
115 l
116}
117static FIXED_LIT_LENS: [u8; 288] = fixed_lit_lens();
118
119#[derive(Clone, Copy)]
121struct Params {
122 good: usize,
124 lazy: usize,
127 nice: usize,
129 chain: usize,
131 lazy_matching: bool,
132}
133
134const fn params(level: u8) -> Params {
135 let (good, lazy, nice, chain, lazy_matching) = match level {
136 1 => (4, 4, 8, 1, false),
137 2 => (4, 5, 16, 8, false),
138 3 => (4, 6, 32, 32, false),
139 4 => (4, 4, 16, 16, true),
140 5 => (8, 16, 32, 32, true),
141 6 => (8, 16, 128, 128, true),
142 7 => (8, 32, 128, 256, true),
143 8 => (32, 128, 258, 1024, true),
144 9 => (32, 258, 258, 4096, true),
145 _ => (0, 0, 0, 0, false),
146 };
147 Params {
148 good,
149 lazy,
150 nice,
151 chain,
152 lazy_matching,
153 }
154}
155
156#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
158#[non_exhaustive]
159pub enum Flush {
160 None,
162 Sync,
166 Full,
169 Finish,
171}
172
173#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
190#[non_exhaustive]
191pub struct MemoryConfig {
192 hash_bits: u8,
194 block_symbols: usize,
196}
197
198impl MemoryConfig {
199 #[must_use]
207 pub const fn new() -> Self {
208 Self {
209 hash_bits: 0,
210 block_symbols: 0,
211 }
212 }
213
214 #[must_use]
223 pub const fn with_hash_bits(mut self, bits: u8) -> Self {
224 self.hash_bits = if bits == 0 {
225 0
226 } else if bits < 8 {
227 8
228 } else if bits > 16 {
229 16
230 } else {
231 bits
232 };
233 self
234 }
235
236 #[must_use]
245 pub const fn with_block_symbols(mut self, symbols: usize) -> Self {
246 self.block_symbols = if symbols == 0 {
247 0
248 } else if symbols < 256 {
249 256
250 } else if symbols > 65_536 {
251 65_536
252 } else {
253 symbols
254 };
255 self
256 }
257
258 #[must_use]
266 pub const fn hash_bits(&self) -> u8 {
267 self.hash_bits
268 }
269
270 #[must_use]
278 pub const fn block_symbols(&self) -> usize {
279 self.block_symbols
280 }
281}
282
283struct BlockScratch {
285 lit_freq: [u32; 286],
286 dist_freq: [u32; 30],
287 lit_lens: [u8; 286],
288 dist_lens: [u8; 30],
289 lit_codes: [u16; 288],
290 dist_codes: [u16; 30],
291 rle: [(u8, u8); 316],
293 rle_len: usize,
294 pre_freq: [u32; 19],
295 pre_lens: [u8; 19],
296 pre_codes: [u16; 19],
297}
298
299pub struct Deflater {
318 memory: MemoryConfig,
319 level: u8,
320 params: Params,
321 window_bits: u8,
322 win: Vec<u8>,
324 size: usize,
327 wsize: usize,
328 keep: usize,
332 strstart: usize,
333 lookahead: usize,
334 block_start: isize,
336 hash_bits: u32,
337 head: Vec<u16>,
338 prev: Vec<u16>,
339 match_available: bool,
340 match_length: usize,
341 match_start: usize,
342 prev_length: usize,
343 prev_match: usize,
344 syms: Vec<u32>,
347 sym_cap: usize,
348 scratch: alloc::boxed::Box<BlockScratch>,
349 pending: Vec<u8>,
350 pending_pos: usize,
351 bitbuf: u64,
352 bitcnt: u32,
353 total_in: u64,
354 total_out: u64,
355 flush_written: bool,
357 finished: bool,
358}
359
360impl core::fmt::Debug for Deflater {
361 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
362 f.debug_struct("Deflater")
363 .field("level", &self.level)
364 .field("window_bits", &self.window_bits)
365 .field("total_in", &self.total_in)
366 .field("total_out", &self.total_out)
367 .field("finished", &self.finished)
368 .finish_non_exhaustive()
369 }
370}
371
372impl Default for Deflater {
373 fn default() -> Self {
374 Self::new(Level::DEFAULT)
375 }
376}
377
378impl Deflater {
379 #[must_use]
390 pub fn new(level: Level) -> Self {
391 Self::build(level.get(), 15, MemoryConfig::new())
392 }
393
394 fn build(level: u8, window_bits: u8, memory: MemoryConfig) -> Self {
395 let wsize = 1usize << window_bits;
396 let span = (8192 / wsize).max(2);
400 let max_hash = if level == 1 { 12 } else { 15 };
403 let hash_bits = match memory.hash_bits {
404 0 => u32::from(window_bits + 1).clamp(9, max_hash),
405 bits => u32::from(bits),
406 };
407 let sym_cap = match memory.block_symbols {
408 0 => (1usize << (window_bits + 1)).clamp(1024, 16_384),
409 n => n,
410 };
411 Self {
412 memory,
413 level,
414 params: params(level),
415 window_bits,
416 win: vec![0; wsize * span + WIN_PAD],
417 size: wsize * span,
418 wsize,
419 keep: if span >= 3 {
420 wsize
421 } else {
422 wsize - MIN_LOOKAHEAD
423 },
424 strstart: 1,
426 lookahead: 0,
427 block_start: 1,
428 hash_bits,
429 head: vec![0; 1 << hash_bits],
430 prev: vec![0; wsize],
431 match_available: false,
432 match_length: MIN_MATCH - 1,
433 match_start: 0,
434 prev_length: MIN_MATCH - 1,
435 prev_match: 0,
436 syms: Vec::with_capacity(sym_cap),
437 sym_cap,
438 scratch: alloc::boxed::Box::new(BlockScratch {
439 lit_freq: [0; 286],
440 dist_freq: [0; 30],
441 lit_lens: [0; 286],
442 dist_lens: [0; 30],
443 lit_codes: [0; 288],
444 dist_codes: [0; 30],
445 rle: [(0, 0); 316],
446 rle_len: 0,
447 pre_freq: [0; 19],
448 pre_lens: [0; 19],
449 pre_codes: [0; 19],
450 }),
451 pending: Vec::with_capacity(sym_cap * 4 + wsize * span + 64),
454 pending_pos: 0,
455 bitbuf: 0,
456 bitcnt: 0,
457 total_in: 0,
458 total_out: 0,
459 flush_written: false,
460 finished: false,
461 }
462 }
463
464 pub fn with_window_bits(self, bits: u8) -> Result<Self, Error> {
483 if !(8..=15).contains(&bits) {
484 return Err(Error::config(ErrorKind::InvalidWindowBits));
485 }
486 Ok(Self::build(self.level, bits, self.memory))
487 }
488
489 #[must_use]
507 pub fn with_memory(self, memory: MemoryConfig) -> Self {
508 Self::build(self.level, self.window_bits, memory)
509 }
510
511 #[must_use]
521 pub fn level(&self) -> Level {
522 Level::new(self.level).unwrap_or(Level::DEFAULT)
523 }
524
525 #[must_use]
533 pub fn window_bits(&self) -> u8 {
534 self.window_bits
535 }
536
537 pub fn set_level(&mut self, level: Level) {
554 let level = level.get();
555 let next = params(level);
556 if (level == 0) != (self.level == 0) {
557 self.process(true);
559 self.end_block(false);
560 } else if self.params.lazy_matching && !next.lazy_matching && self.match_available {
561 self.literal(self.win[self.strstart - 1]);
564 self.match_available = false;
565 self.block_full();
566 }
567 self.match_length = MIN_MATCH - 1;
569 self.prev_length = MIN_MATCH - 1;
570 self.level = level;
571 self.params = next;
572 }
573
574 #[must_use]
587 pub fn total_in(&self) -> u64 {
588 self.total_in
589 }
590
591 #[must_use]
605 pub fn total_out(&self) -> u64 {
606 self.total_out
607 }
608
609 #[must_use]
619 pub fn memory_in_use(&self) -> usize {
620 self.win.capacity()
621 + 2 * (self.head.capacity() + self.prev.capacity())
622 + 4 * self.syms.capacity()
623 + self.pending.capacity()
624 + core::mem::size_of::<BlockScratch>()
625 }
626
627 pub fn reset(&mut self) {
644 let end = self.strstart + self.lookahead;
648 if self.total_in as usize + 1 < self.size && end < self.head.len() / 4 {
649 let shift = 32 - self.hash_bits;
650 for pos in 1..end.saturating_sub(MIN_MATCH - 1) {
651 self.head[hash3(load32(&self.win, pos), shift)] = 0;
652 }
653 } else {
654 self.head.fill(0);
655 }
656 self.strstart = 1;
657 self.lookahead = 0;
658 self.block_start = 1;
659 self.match_available = false;
660 self.match_length = MIN_MATCH - 1;
661 self.prev_length = MIN_MATCH - 1;
662 self.syms.clear();
663 self.pending.clear();
664 self.pending_pos = 0;
665 self.bitbuf = 0;
666 self.bitcnt = 0;
667 self.total_in = 0;
668 self.total_out = 0;
669 self.flush_written = false;
670 self.finished = false;
671 }
672
673 pub fn set_dictionary(&mut self, dictionary: &[u8]) -> Result<(), Error> {
699 if self.total_in != 0 || self.lookahead != 0 || self.strstart != 1 {
700 return Err(Error::config(ErrorKind::InvalidState));
701 }
702 let take = dictionary.len().min(self.wsize);
703 let dict = &dictionary[dictionary.len() - take..];
704 self.win[1..1 + take].copy_from_slice(dict);
706 self.strstart = 1;
707 self.lookahead = take;
708 if self.level != 0 {
709 let end = 1 + take;
710 let mut pos = 1;
711 while pos + MIN_MATCH <= end {
712 self.insert(pos);
713 pos += 1;
714 }
715 }
716 self.strstart = 1 + take;
717 self.lookahead = 0;
718 self.block_start = self.strstart as isize;
719 Ok(())
720 }
721
722 pub fn compress(
749 &mut self,
750 input: &[u8],
751 output: &mut [u8],
752 flush: Flush,
753 ) -> Result<Progress, Error> {
754 let mut consumed = 0;
755 let mut produced = 0;
756 if self.finished {
757 if !input.is_empty() {
758 return Err(Error::config(ErrorKind::InvalidState));
759 }
760 self.drain(output, &mut produced);
761 let status = if self.pending_left() == 0 {
762 Status::Done
763 } else {
764 Status::NeedsOutput
765 };
766 return Ok(Progress::new(0, produced, status));
767 }
768 loop {
769 self.drain(output, &mut produced);
770 if self.pending_left() > 0 {
771 return Ok(Progress::new(consumed, produced, Status::NeedsOutput));
772 }
773 if self.flush_written && consumed == input.len() {
774 self.flush_written = false;
775 if flush == Flush::Finish {
776 self.finished = true;
777 }
778 return Ok(Progress::new(consumed, produced, Status::Done));
779 }
780 self.flush_written = false;
781 let before = (consumed, self.strstart, self.lookahead);
782 consumed += self.fill_window(&input[consumed..]);
783 let all_in = consumed == input.len();
784 let flushing = flush != Flush::None && all_in;
785 self.process(flushing);
786 if self.pending_left() > 0 {
787 continue;
788 }
789 if !all_in {
790 if before == (consumed, self.strstart, self.lookahead) {
793 return Err(Error::config(ErrorKind::InvalidState));
794 }
795 continue;
796 }
797 if flush == Flush::None {
798 return Ok(Progress::new(consumed, produced, Status::NeedsInput));
799 }
800 self.write_flush(flush);
801 self.flush_written = true;
802 }
803 }
804
805 pub fn compress_vec(
827 &mut self,
828 input: &[u8],
829 out: &mut Vec<u8>,
830 flush: Flush,
831 ) -> Result<Progress, Error> {
832 let start = out.len();
833 let mut consumed = 0;
834 loop {
835 let have = out.len();
836 let room = (input.len() - consumed) / 2 + 1024;
837 if out.capacity() - have < room && out.try_reserve(room).is_err() {
838 return Err(Error::config(ErrorKind::AllocationFailed));
839 }
840 let spare = out.capacity() - have;
841 out.resize(have + spare, 0);
842 let p = self.compress(&input[consumed..], &mut out[have..], flush);
843 match p {
844 Ok(p) => {
845 out.truncate(have + p.produced);
846 consumed += p.consumed;
847 if p.status != Status::NeedsOutput {
848 return Ok(Progress::new(consumed, out.len() - start, p.status));
849 }
850 }
851 Err(e) => {
852 out.truncate(have);
853 return Err(e);
854 }
855 }
856 }
857 }
858
859 fn pending_left(&self) -> usize {
860 self.pending.len() - self.pending_pos
861 }
862
863 fn drain(&mut self, output: &mut [u8], produced: &mut usize) {
865 let n = self.pending_left().min(output.len() - *produced);
866 output[*produced..*produced + n]
867 .copy_from_slice(&self.pending[self.pending_pos..self.pending_pos + n]);
868 self.pending_pos += n;
869 *produced += n;
870 self.total_out += n as u64;
871 if self.pending_pos == self.pending.len() {
872 self.pending.clear();
873 self.pending_pos = 0;
874 }
875 }
876
877 fn fill_window(&mut self, input: &[u8]) -> usize {
880 let size = self.size;
881 if size - self.strstart - self.lookahead < MIN_LOOKAHEAD
882 && self.strstart >= self.keep + self.wsize
883 {
884 self.slide();
885 }
886 let room = size - self.strstart - self.lookahead;
887 let n = room.min(input.len());
888 let at = self.strstart + self.lookahead;
889 self.win[at..at + n].copy_from_slice(&input[..n]);
890 self.lookahead += n;
891 self.total_in += n as u64;
892 n
893 }
894
895 fn slide(&mut self) {
898 let shift = (self.strstart - self.keep) / self.wsize * self.wsize;
899 if shift == 0 {
900 return;
901 }
902 if self.level == 0 && self.block_start < shift as isize {
903 self.end_block(false);
906 }
907 let end = self.strstart + self.lookahead;
908 self.win.copy_within(shift..end, 0);
909 self.strstart -= shift;
910 self.match_start = self.match_start.saturating_sub(shift);
911 self.prev_match = self.prev_match.saturating_sub(shift);
912 self.block_start -= shift as isize;
913 let s = shift as u32;
916 for h in self.head.iter_mut().chain(self.prev.iter_mut()) {
917 *h = u32::from(*h).saturating_sub(s) as u16;
918 }
919 }
920
921 #[inline]
924 fn insert(&mut self, pos: usize) -> usize {
925 insert_at(
926 &mut self.head,
927 &mut self.prev,
928 &self.win,
929 pos,
930 32 - self.hash_bits,
931 self.wsize - 1,
932 )
933 }
934
935 fn literal(&mut self, b: u8) {
937 self.syms.push(u32::from(b));
938 self.scratch.lit_freq[b as usize] += 1;
939 }
940
941 #[inline]
944 fn block_full(&mut self) {
945 if self.syms.len() >= self.sym_cap {
946 let held = usize::from(self.match_available);
947 self.strstart -= held;
948 self.end_block(false);
949 self.strstart += held;
950 }
951 }
952
953 fn process(&mut self, flushing: bool) {
957 if self.level == 0 {
958 let chunk = STORED_CHUNK.min(self.size / 2);
959 let full = self.strstart + self.lookahead + MIN_LOOKAHEAD > self.size;
962 while self.lookahead >= chunk || ((flushing || full) && self.lookahead > 0) {
963 let n = self.lookahead.min(65_535);
964 self.strstart += n;
965 self.lookahead -= n;
966 self.end_block(false);
967 }
968 return;
969 }
970 loop {
971 let used_up = if self.params.lazy_matching {
972 self.lazy_run(flushing)
973 } else {
974 self.greedy_run(flushing)
975 };
976 self.block_full();
977 if used_up {
978 break;
979 }
980 }
981 if flushing && self.match_available {
982 self.literal(self.win[self.strstart - 1]);
983 self.match_available = false;
984 self.block_full();
985 }
986 }
987
988 fn greedy_run(&mut self, flushing: bool) -> bool {
992 let p = self.params;
993 let wmask = self.wsize - 1;
994 let keep = self.keep;
995 let shift = 32 - self.hash_bits;
996 let cap = self.sym_cap;
997 let mut s = self.strstart;
998 let mut look = self.lookahead;
999 let mut misses = 0usize;
1000 let skip = self.level == 1;
1001 let win = &self.win[..];
1002 let head = &mut self.head[..];
1003 let prev = &mut self.prev[..];
1004 let syms = &mut self.syms;
1005 let freq = &mut *self.scratch;
1006 let used_up = loop {
1007 if look < MIN_LOOKAHEAD && (!flushing || look == 0) {
1008 break true;
1009 }
1010 if syms.len() >= cap {
1011 break false;
1012 }
1013 let mut len = 0;
1014 let mut start = 0;
1015 if look >= MIN_MATCH {
1016 let s4 = load32(win, s);
1017 let h = hash3(s4, shift);
1018 let mut cur = usize::from(head[h]);
1019 prev[s & wmask] = head[h];
1020 head[h] = s as u16;
1021 let max = MAX_MATCH.min(look);
1022 let mut chain = p.chain;
1023 while cur != 0 && cur < s && s - cur <= keep {
1024 if (load32(win, cur) ^ s4) & 0x00FF_FFFF == 0 {
1025 let l = MIN_MATCH
1026 + common_prefix(win, cur + MIN_MATCH, s + MIN_MATCH, max - MIN_MATCH);
1027 if l > len {
1028 len = l;
1029 start = cur;
1030 if l >= p.nice.min(max) {
1031 break;
1032 }
1033 }
1034 }
1035 chain -= 1;
1036 if chain == 0 {
1037 break;
1038 }
1039 let next = usize::from(prev[cur & wmask]);
1040 if next >= cur {
1041 break;
1042 }
1043 cur = next;
1044 }
1045 }
1046 if len >= MIN_MATCH {
1047 let dist = s - start;
1048 syms.push(((dist as u32) << 16) | (len - MIN_MATCH) as u32);
1049 freq.lit_freq[257 + LENGTH_CODE[len - MIN_MATCH] as usize] += 1;
1050 freq.dist_freq[dist_code(dist)] += 1;
1051 look -= len;
1052 misses = 0;
1053 if len <= p.lazy && look >= MIN_MATCH {
1054 for _ in 1..len {
1055 s += 1;
1056 insert_at(head, prev, win, s, shift, wmask);
1057 }
1058 s += 1;
1059 } else {
1060 s += len;
1061 }
1062 } else {
1063 let b = win[s];
1064 syms.push(u32::from(b));
1065 freq.lit_freq[b as usize] += 1;
1066 look -= 1;
1067 s += 1;
1068 misses += 1;
1069 if skip && misses > 64 {
1073 let extra = ((misses - 64) >> 4).min(15).min(look).min(cap - syms.len());
1074 for &b in &win[s..s + extra] {
1075 syms.push(u32::from(b));
1076 freq.lit_freq[b as usize] += 1;
1077 }
1078 s += extra;
1079 look -= extra;
1080 }
1081 }
1082 };
1083 self.strstart = s;
1084 self.lookahead = look;
1085 self.match_length = MIN_MATCH - 1;
1086 used_up
1087 }
1088
1089 fn lazy_run(&mut self, flushing: bool) -> bool {
1092 let p = self.params;
1093 let wmask = self.wsize - 1;
1094 let keep = self.keep;
1095 let shift = 32 - self.hash_bits;
1096 let cap = self.sym_cap;
1097 let mut s = self.strstart;
1098 let mut look = self.lookahead;
1099 let mut available = self.match_available;
1100 let mut match_length = self.match_length;
1101 let mut match_start = self.match_start;
1102 let mut prev_length;
1103 let mut prev_match;
1104 let win = &self.win[..];
1105 let head = &mut self.head[..];
1106 let prev = &mut self.prev[..];
1107 let syms = &mut self.syms;
1108 let freq = &mut *self.scratch;
1109 let used_up = loop {
1110 if look < MIN_LOOKAHEAD && (!flushing || look == 0) {
1111 break true;
1112 }
1113 if syms.len() >= cap {
1114 break false;
1115 }
1116 let mut cur = 0;
1117 let mut s4 = 0;
1118 if look >= MIN_MATCH {
1119 s4 = load32(win, s);
1120 let h = hash3(s4, shift);
1121 cur = usize::from(head[h]);
1122 prev[s & wmask] = head[h];
1123 head[h] = s as u16;
1124 }
1125 prev_length = match_length;
1126 prev_match = match_start;
1127 match_length = MIN_MATCH - 1;
1128 if cur != 0 && prev_length < p.lazy && cur < s && s - cur <= keep {
1129 let max = MAX_MATCH.min(look);
1131 let nice = p.nice.min(max);
1132 let mut chain = if prev_length >= p.good {
1133 p.chain >> 2
1134 } else {
1135 p.chain
1136 };
1137 let mut best = prev_length;
1138 while cur != 0 && cur < s && s - cur <= keep && best < max {
1139 if load16(win, cur + best - 1) == load16(win, s + best - 1)
1142 && (load32(win, cur) ^ s4) & 0x00FF_FFFF == 0
1143 {
1144 let l = MIN_MATCH
1145 + common_prefix(win, cur + MIN_MATCH, s + MIN_MATCH, max - MIN_MATCH);
1146 if l > best {
1147 best = l;
1148 match_start = cur;
1149 if l >= nice {
1150 break;
1151 }
1152 }
1153 }
1154 chain -= 1;
1155 if chain == 0 {
1156 break;
1157 }
1158 let next = usize::from(prev[cur & wmask]);
1159 if next >= cur {
1160 break;
1161 }
1162 cur = next;
1163 }
1164 match_length = best.min(look);
1165 if match_length == MIN_MATCH && s - match_start > TOO_FAR {
1166 match_length = MIN_MATCH - 1;
1167 }
1168 }
1169 if prev_length >= MIN_MATCH && match_length <= prev_length {
1170 let max_insert = s + look - MIN_MATCH;
1171 let dist = s - 1 - prev_match;
1172 syms.push(((dist as u32) << 16) | (prev_length - MIN_MATCH) as u32);
1173 freq.lit_freq[257 + LENGTH_CODE[prev_length - MIN_MATCH] as usize] += 1;
1174 freq.dist_freq[dist_code(dist)] += 1;
1175 look -= prev_length - 1;
1176 for _ in 0..prev_length - 2 {
1177 s += 1;
1178 if s <= max_insert {
1179 insert_at(head, prev, win, s, shift, wmask);
1180 }
1181 }
1182 available = false;
1183 match_length = MIN_MATCH - 1;
1184 s += 1;
1185 } else if available {
1186 let b = win[s - 1];
1187 syms.push(u32::from(b));
1188 freq.lit_freq[b as usize] += 1;
1189 s += 1;
1190 look -= 1;
1191 } else {
1192 available = true;
1193 s += 1;
1194 look -= 1;
1195 }
1196 };
1197 self.strstart = s;
1198 self.lookahead = look;
1199 self.match_available = available;
1200 self.match_length = match_length;
1201 self.match_start = match_start;
1202 self.prev_length = match_length;
1203 used_up
1204 }
1205
1206 #[inline]
1209 fn put(&mut self, value: u32, bits: u32) {
1210 self.bitbuf |= u64::from(value) << self.bitcnt;
1211 self.bitcnt += bits;
1212 if self.bitcnt >= 32 {
1213 self.pending
1214 .extend_from_slice(&(self.bitbuf as u32).to_le_bytes());
1215 self.bitbuf >>= 32;
1216 self.bitcnt -= 32;
1217 }
1218 }
1219
1220 fn align(&mut self) {
1222 while self.bitcnt > 0 {
1223 self.pending.push(self.bitbuf as u8);
1224 self.bitbuf >>= 8;
1225 self.bitcnt = self.bitcnt.saturating_sub(8);
1226 }
1227 self.bitbuf = 0;
1228 }
1229
1230 fn write_flush(&mut self, flush: Flush) {
1231 match flush {
1232 Flush::None => {}
1233 Flush::Finish => {
1234 self.end_block(true);
1235 self.align();
1236 }
1237 Flush::Sync | Flush::Full => {
1238 self.end_block(false);
1239 self.put(0, 3);
1241 self.align();
1242 self.pending.extend_from_slice(&[0, 0, 0xFF, 0xFF]);
1243 if flush == Flush::Full {
1244 self.head.fill(0);
1245 self.match_length = MIN_MATCH - 1;
1246 self.prev_length = MIN_MATCH - 1;
1247 }
1248 }
1249 }
1250 }
1251
1252 fn end_block(&mut self, last: bool) {
1255 let stored_len = (self.strstart as isize - self.block_start).max(0) as usize;
1256 if self.syms.is_empty() && stored_len == 0 && !last {
1257 return;
1258 }
1259 let stored_ok = self.block_start >= 0;
1260 if self.level == 0 && stored_ok {
1261 self.write_stored(self.block_start as usize, stored_len, last);
1262 } else {
1263 self.write_huffman_or_stored(stored_ok, stored_len, last);
1264 }
1265 self.syms.clear();
1266 self.scratch.lit_freq.fill(0);
1267 self.scratch.dist_freq.fill(0);
1268 self.block_start = self.strstart as isize;
1269 }
1270
1271 fn write_stored(&mut self, start: usize, len: usize, last: bool) {
1272 let mut at = start;
1273 let mut left = len;
1274 loop {
1275 let n = left.min(65_535);
1276 let final_piece = n == left;
1277 self.put(u32::from(last && final_piece), 1);
1278 self.put(0, 2);
1279 self.align();
1280 self.pending.extend_from_slice(&(n as u16).to_le_bytes());
1281 self.pending.extend_from_slice(&(!(n as u16)).to_le_bytes());
1282 self.pending.extend_from_slice(&self.win[at..at + n]);
1283 at += n;
1284 left -= n;
1285 if final_piece {
1286 break;
1287 }
1288 }
1289 }
1290
1291 fn write_huffman_or_stored(&mut self, stored_ok: bool, stored_len: usize, last: bool) {
1292 let s = &mut *self.scratch;
1293 s.lit_freq[256] = 1;
1294 let lit_used = s.lit_freq.iter().filter(|&&f| f != 0).count();
1298 if lit_used < 2 {
1299 s.lit_freq[if s.lit_freq[0] == 0 { 0 } else { 1 }] += 1;
1300 }
1301 let dist_used = s.dist_freq.iter().filter(|&&f| f != 0).count();
1302 if dist_used == 0 {
1303 s.dist_freq[0] = 1;
1304 s.dist_freq[1] = 1;
1305 } else if dist_used == 1 {
1306 let d = if s.dist_freq[0] == 0 { 0 } else { 1 };
1307 s.dist_freq[d] = 1;
1308 }
1309 huffman::lengths(&s.lit_freq, 15, &mut s.lit_lens);
1310 huffman::lengths(&s.dist_freq, 15, &mut s.dist_lens);
1311
1312 let mut extra: u64 = 0;
1314 let mut dyn_bits: u64 = 0;
1315 let mut fix_bits: u64 = 0;
1316 for sym in 0..286 {
1317 let f = u64::from(s.lit_freq[sym]);
1318 if f == 0 {
1319 continue;
1320 }
1321 dyn_bits += f * u64::from(s.lit_lens[sym]);
1322 fix_bits += f * u64::from(FIXED_LIT_LENS[sym]);
1323 if sym >= 257 {
1324 extra += f * u64::from(LENGTH_EXTRA[sym - 257]);
1325 }
1326 }
1327 for ((&f, &len), &x) in s.dist_freq.iter().zip(&s.dist_lens).zip(&DIST_EXTRA) {
1328 let f = u64::from(f);
1329 dyn_bits += f * u64::from(len);
1330 fix_bits += f * 5;
1331 extra += f * u64::from(x);
1332 }
1333 let hlit = 257
1336 + s.lit_lens[257..286]
1337 .iter()
1338 .rposition(|&l| l != 0)
1339 .map_or(0, |i| i + 1);
1340 let hdist = 1 + s.dist_lens.iter().rposition(|&l| l != 0).unwrap_or(0);
1341 rle_lengths(s, hlit, hdist);
1342 huffman::lengths(&s.pre_freq, 7, &mut s.pre_lens);
1343 let hclen = 4 + PRECODE_ORDER
1344 .iter()
1345 .rposition(|&i| s.pre_lens[i] != 0)
1346 .map_or(0, |i| (i + 1).saturating_sub(4));
1347 let mut header_bits = 14 + 3 * hclen as u64;
1348 for &(sym, _) in &s.rle[..s.rle_len] {
1349 header_bits += u64::from(s.pre_lens[sym as usize]);
1350 header_bits += match sym {
1351 16 => 2,
1352 17 => 3,
1353 18 => 7,
1354 _ => 0,
1355 };
1356 }
1357 let dynamic = 3 + header_bits + dyn_bits + extra;
1358 let fixed = 3 + fix_bits + extra;
1359 let pad = u64::from((8 - (self.bitcnt + 3) % 8) % 8);
1360 let pieces = (stored_len as u64).div_ceil(65_535).max(1);
1361 let stored = pieces * (3 + 32) + pad + 8 * stored_len as u64 + (pieces - 1) * 5;
1362
1363 if stored_ok && stored <= fixed.min(dynamic) {
1364 self.write_stored(self.block_start as usize, stored_len, last);
1365 return;
1366 }
1367 if fixed <= dynamic {
1368 self.put(u32::from(last), 1);
1369 self.put(1, 2);
1370 let mut lit_codes = [0u16; 288];
1371 huffman::codes(&FIXED_LIT_LENS, &mut lit_codes);
1372 let mut dist_codes = [0u16; 30];
1373 huffman::codes(&[5u8; 30], &mut dist_codes);
1374 self.write_symbols(&lit_codes, &FIXED_LIT_LENS, &dist_codes, &[5u8; 30]);
1375 } else {
1376 self.put(u32::from(last), 1);
1377 self.put(2, 2);
1378 self.put((hlit - 257) as u32, 5);
1379 self.put((hdist - 1) as u32, 5);
1380 self.put((hclen - 4) as u32, 4);
1381 let s = &mut *self.scratch;
1382 huffman::codes(&s.pre_lens, &mut s.pre_codes);
1383 huffman::codes(&s.lit_lens, &mut s.lit_codes[..286]);
1384 huffman::codes(&s.dist_lens, &mut s.dist_codes);
1385 for &i in &PRECODE_ORDER[..hclen] {
1386 let l = self.scratch.pre_lens[i];
1387 self.put(u32::from(l), 3);
1388 }
1389 for k in 0..self.scratch.rle_len {
1390 let (sym, value) = self.scratch.rle[k];
1391 let code = self.scratch.pre_codes[sym as usize];
1392 let len = self.scratch.pre_lens[sym as usize];
1393 self.put(u32::from(code), u32::from(len));
1394 match sym {
1395 16 => self.put(u32::from(value), 2),
1396 17 => self.put(u32::from(value), 3),
1397 18 => self.put(u32::from(value), 7),
1398 _ => {}
1399 }
1400 }
1401 let lit_codes = self.scratch.lit_codes;
1402 let lit_lens = self.scratch.lit_lens;
1403 let dist_codes = self.scratch.dist_codes;
1404 let dist_lens = self.scratch.dist_lens;
1405 self.write_symbols(&lit_codes, &lit_lens, &dist_codes, &dist_lens);
1406 }
1407 }
1408
1409 fn write_symbols(
1410 &mut self,
1411 lit_codes: &[u16],
1412 lit_lens: &[u8],
1413 dist_codes: &[u16],
1414 dist_lens: &[u8],
1415 ) {
1416 let mut bits = self.bitbuf;
1420 let mut count = self.bitcnt;
1421 let out = &mut self.pending;
1422 let mut put = |value: u64, n: u32| {
1423 bits |= value << count;
1424 count += n;
1425 if count >= 32 {
1426 out.extend_from_slice(&(bits as u32).to_le_bytes());
1427 bits >>= 32;
1428 count -= 32;
1429 }
1430 };
1431 for &sym in &self.syms {
1432 let dist = (sym >> 16) as usize;
1433 let litlen = (sym & 0xFFFF) as usize;
1434 if dist == 0 {
1435 put(u64::from(lit_codes[litlen]), u32::from(lit_lens[litlen]));
1436 } else {
1437 let code = LENGTH_CODE[litlen] as usize;
1438 let len_bits = u32::from(lit_lens[257 + code]);
1439 let extra = (litlen + MIN_MATCH - LENGTH_BASE[code] as usize) as u64;
1440 put(
1441 u64::from(lit_codes[257 + code]) | (extra << len_bits),
1442 len_bits + u32::from(LENGTH_EXTRA[code]),
1443 );
1444 let d = dist_code(dist);
1445 let dist_bits = u32::from(dist_lens[d]);
1446 let extra = (dist - DIST_BASE[d] as usize) as u64;
1447 put(
1448 u64::from(dist_codes[d]) | (extra << dist_bits),
1449 dist_bits + u32::from(DIST_EXTRA[d]),
1450 );
1451 }
1452 }
1453 put(u64::from(lit_codes[256]), u32::from(lit_lens[256]));
1454 self.bitbuf = bits;
1455 self.bitcnt = count;
1456 }
1457}
1458
1459#[inline(always)]
1461fn load32(win: &[u8], pos: usize) -> u32 {
1462 let mut b = [0u8; 4];
1463 b.copy_from_slice(&win[pos..pos + 4]);
1464 u32::from_le_bytes(b)
1465}
1466
1467#[inline(always)]
1469fn load16(win: &[u8], pos: usize) -> u16 {
1470 u16::from_le_bytes([win[pos], win[pos + 1]])
1471}
1472
1473#[inline(always)]
1475fn hash3(v: u32, shift: u32) -> usize {
1476 ((v & 0x00FF_FFFF).wrapping_mul(0x9E37_79B1) >> shift) as usize
1477}
1478
1479#[inline(always)]
1481fn insert_at(
1482 head: &mut [u16],
1483 prev: &mut [u16],
1484 win: &[u8],
1485 pos: usize,
1486 shift: u32,
1487 wmask: usize,
1488) -> usize {
1489 let h = hash3(load32(win, pos), shift);
1490 let old = head[h];
1491 prev[pos & wmask] = old;
1492 head[h] = pos as u16;
1493 usize::from(old)
1494}
1495
1496#[inline]
1498fn common_prefix(win: &[u8], a: usize, b: usize, max: usize) -> usize {
1499 let mut n = 0;
1500 while n + 8 <= max {
1501 let mut x = [0u8; 8];
1502 let mut y = [0u8; 8];
1503 x.copy_from_slice(&win[a + n..a + n + 8]);
1504 y.copy_from_slice(&win[b + n..b + n + 8]);
1505 let diff = u64::from_le_bytes(x) ^ u64::from_le_bytes(y);
1506 if diff != 0 {
1507 return n + (diff.trailing_zeros() / 8) as usize;
1508 }
1509 n += 8;
1510 }
1511 while n < max && win[a + n] == win[b + n] {
1512 n += 1;
1513 }
1514 n
1515}
1516
1517fn rle_lengths(s: &mut BlockScratch, hlit: usize, hdist: usize) {
1522 let mut all = [0u8; 316];
1523 all[..hlit].copy_from_slice(&s.lit_lens[..hlit]);
1524 all[hlit..hlit + hdist].copy_from_slice(&s.dist_lens[..hdist]);
1525 let all = &all[..hlit + hdist];
1526 s.pre_freq = [0; 19];
1527 s.rle_len = 0;
1528 let push = |s: &mut BlockScratch, sym: u8, value: u8| {
1529 s.rle[s.rle_len] = (sym, value);
1530 s.rle_len += 1;
1531 s.pre_freq[sym as usize] += 1;
1532 };
1533 let mut i = 0;
1534 while i < all.len() {
1535 let v = all[i];
1536 let mut run = 1;
1537 while i + run < all.len() && all[i + run] == v {
1538 run += 1;
1539 }
1540 i += run;
1541 if v == 0 {
1542 while run >= 11 {
1543 let n = run.min(138);
1544 push(s, 18, (n - 11) as u8);
1545 run -= n;
1546 }
1547 if run >= 3 {
1548 push(s, 17, (run - 3) as u8);
1549 run = 0;
1550 }
1551 for _ in 0..run {
1552 push(s, 0, 0);
1553 }
1554 } else {
1555 push(s, v, 0);
1556 run -= 1;
1557 while run >= 3 {
1558 let n = run.min(6);
1559 push(s, 16, (n - 3) as u8);
1560 run -= n;
1561 }
1562 for _ in 0..run {
1563 push(s, v, 0);
1564 }
1565 }
1566 }
1567}