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 STORED_CHUNK: usize = 16 * 1024;
26
27const LENGTH_BASE: [u16; 29] = [
28 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,
29 163, 195, 227, 258,
30];
31const LENGTH_EXTRA: [u8; 29] = [
32 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,
33];
34const DIST_BASE: [u16; 30] = [
35 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537,
36 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577,
37];
38const DIST_EXTRA: [u8; 30] = [
39 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,
40 13,
41];
42const PRECODE_ORDER: [usize; 19] = [
43 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15,
44];
45
46static LENGTH_CODE: [u8; 256] = {
48 let mut t = [0u8; 256];
49 let mut code = 0;
50 while code < 28 {
51 let mut i = 0;
52 while i < (1 << LENGTH_EXTRA[code]) {
53 t[LENGTH_BASE[code] as usize - 3 + i] = code as u8;
54 i += 1;
55 }
56 code += 1;
57 }
58 t[255] = 28;
60 t
61};
62
63static DIST_CODE: [u8; 512] = {
66 let mut t = [0u8; 512];
67 let mut code = 0;
68 while code < 30 {
69 let base = DIST_BASE[code] as usize - 1;
70 let count = 1usize << DIST_EXTRA[code];
71 let mut i = 0;
72 while i < count {
73 let d = base + i;
74 if d < 256 {
75 t[d] = code as u8;
76 } else {
77 t[256 + (d >> 7)] = code as u8;
78 }
79 i += 1;
80 }
81 code += 1;
82 }
83 t
84};
85
86#[inline]
87fn dist_code(dist: usize) -> usize {
88 let d = dist - 1;
89 if d < 256 {
90 DIST_CODE[d] as usize
91 } else {
92 DIST_CODE[256 + (d >> 7)] as usize
93 }
94}
95
96const fn fixed_lit_lens() -> [u8; 288] {
98 let mut l = [0u8; 288];
99 let mut i = 0;
100 while i < 288 {
101 l[i] = if i < 144 {
102 8
103 } else if i < 256 {
104 9
105 } else if i < 280 {
106 7
107 } else {
108 8
109 };
110 i += 1;
111 }
112 l
113}
114static FIXED_LIT_LENS: [u8; 288] = fixed_lit_lens();
115
116#[derive(Clone, Copy)]
118struct Params {
119 good: usize,
121 lazy: usize,
124 nice: usize,
126 chain: usize,
128 lazy_matching: bool,
129}
130
131const fn params(level: u8) -> Params {
132 let (good, lazy, nice, chain, lazy_matching) = match level {
133 1 => (4, 4, 8, 4, false),
134 2 => (4, 5, 16, 8, false),
135 3 => (4, 6, 32, 32, false),
136 4 => (4, 4, 16, 16, true),
137 5 => (8, 16, 32, 32, true),
138 6 => (8, 16, 128, 128, true),
139 7 => (8, 32, 128, 256, true),
140 8 => (32, 128, 258, 1024, true),
141 9 => (32, 258, 258, 4096, true),
142 _ => (0, 0, 0, 0, false),
143 };
144 Params {
145 good,
146 lazy,
147 nice,
148 chain,
149 lazy_matching,
150 }
151}
152
153#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
155#[non_exhaustive]
156pub enum Flush {
157 None,
159 Sync,
163 Full,
166 Finish,
168}
169
170struct BlockScratch {
172 lit_freq: [u32; 286],
173 dist_freq: [u32; 30],
174 lit_lens: [u8; 286],
175 dist_lens: [u8; 30],
176 lit_codes: [u16; 288],
177 dist_codes: [u16; 30],
178 rle: [(u8, u8); 316],
180 rle_len: usize,
181 pre_freq: [u32; 19],
182 pre_lens: [u8; 19],
183 pre_codes: [u16; 19],
184}
185
186pub struct Deflater {
205 level: u8,
206 params: Params,
207 window_bits: u8,
208 win: Vec<u8>,
210 wsize: usize,
211 keep: usize,
215 strstart: usize,
216 lookahead: usize,
217 block_start: isize,
219 hash_bits: u32,
220 head: Vec<u16>,
221 prev: Vec<u16>,
222 match_available: bool,
223 match_length: usize,
224 match_start: usize,
225 prev_length: usize,
226 prev_match: usize,
227 syms: Vec<u32>,
230 sym_cap: usize,
231 scratch: alloc::boxed::Box<BlockScratch>,
232 pending: Vec<u8>,
233 pending_pos: usize,
234 bitbuf: u64,
235 bitcnt: u32,
236 total_in: u64,
237 total_out: u64,
238 flush_written: bool,
240 finished: bool,
241}
242
243impl core::fmt::Debug for Deflater {
244 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
245 f.debug_struct("Deflater")
246 .field("level", &self.level)
247 .field("window_bits", &self.window_bits)
248 .field("total_in", &self.total_in)
249 .field("total_out", &self.total_out)
250 .field("finished", &self.finished)
251 .finish_non_exhaustive()
252 }
253}
254
255impl Default for Deflater {
256 fn default() -> Self {
257 Self::new(Level::DEFAULT)
258 }
259}
260
261impl Deflater {
262 #[must_use]
273 pub fn new(level: Level) -> Self {
274 Self::build(level.get(), 15)
275 }
276
277 fn build(level: u8, window_bits: u8) -> Self {
278 let wsize = 1usize << window_bits;
279 let span = (8192 / wsize).max(2);
283 let hash_bits = u32::from(window_bits + 1).clamp(9, 15);
284 let sym_cap = (1usize << (window_bits + 1)).clamp(1024, 16_384);
285 Self {
286 level,
287 params: params(level),
288 window_bits,
289 win: vec![0; wsize * span],
290 wsize,
291 keep: if span >= 3 {
292 wsize
293 } else {
294 wsize - MIN_LOOKAHEAD
295 },
296 strstart: 0,
297 lookahead: 0,
298 block_start: 0,
299 hash_bits,
300 head: vec![0; 1 << hash_bits],
301 prev: vec![0; wsize],
302 match_available: false,
303 match_length: MIN_MATCH - 1,
304 match_start: 0,
305 prev_length: MIN_MATCH - 1,
306 prev_match: 0,
307 syms: Vec::with_capacity(sym_cap),
308 sym_cap,
309 scratch: alloc::boxed::Box::new(BlockScratch {
310 lit_freq: [0; 286],
311 dist_freq: [0; 30],
312 lit_lens: [0; 286],
313 dist_lens: [0; 30],
314 lit_codes: [0; 288],
315 dist_codes: [0; 30],
316 rle: [(0, 0); 316],
317 rle_len: 0,
318 pre_freq: [0; 19],
319 pre_lens: [0; 19],
320 pre_codes: [0; 19],
321 }),
322 pending: Vec::with_capacity(sym_cap * 4 + wsize * span + 64),
325 pending_pos: 0,
326 bitbuf: 0,
327 bitcnt: 0,
328 total_in: 0,
329 total_out: 0,
330 flush_written: false,
331 finished: false,
332 }
333 }
334
335 pub fn with_window_bits(self, bits: u8) -> Result<Self, Error> {
354 if !(8..=15).contains(&bits) {
355 return Err(Error::config(ErrorKind::InvalidWindowBits));
356 }
357 Ok(Self::build(self.level, bits))
358 }
359
360 #[must_use]
370 pub fn level(&self) -> Level {
371 Level::new(self.level).unwrap_or(Level::DEFAULT)
372 }
373
374 #[must_use]
382 pub fn window_bits(&self) -> u8 {
383 self.window_bits
384 }
385
386 pub fn set_level(&mut self, level: Level) {
403 let level = level.get();
404 let next = params(level);
405 if (level == 0) != (self.level == 0) {
406 self.process(true);
408 self.end_block(false);
409 } else if self.params.lazy_matching && !next.lazy_matching && self.match_available {
410 self.literal(self.win[self.strstart - 1]);
413 self.match_available = false;
414 self.block_full();
415 }
416 self.match_length = MIN_MATCH - 1;
418 self.prev_length = MIN_MATCH - 1;
419 self.level = level;
420 self.params = next;
421 }
422
423 #[must_use]
436 pub fn total_in(&self) -> u64 {
437 self.total_in
438 }
439
440 #[must_use]
454 pub fn total_out(&self) -> u64 {
455 self.total_out
456 }
457
458 #[must_use]
468 pub fn memory_in_use(&self) -> usize {
469 self.win.capacity()
470 + 2 * (self.head.capacity() + self.prev.capacity())
471 + 4 * self.syms.capacity()
472 + self.pending.capacity()
473 + core::mem::size_of::<BlockScratch>()
474 }
475
476 pub fn reset(&mut self) {
493 self.strstart = 0;
494 self.lookahead = 0;
495 self.block_start = 0;
496 self.head.fill(0);
497 self.match_available = false;
498 self.match_length = MIN_MATCH - 1;
499 self.prev_length = MIN_MATCH - 1;
500 self.syms.clear();
501 self.pending.clear();
502 self.pending_pos = 0;
503 self.bitbuf = 0;
504 self.bitcnt = 0;
505 self.total_in = 0;
506 self.total_out = 0;
507 self.flush_written = false;
508 self.finished = false;
509 }
510
511 pub fn set_dictionary(&mut self, dictionary: &[u8]) -> Result<(), Error> {
537 if self.total_in != 0 || self.lookahead != 0 || self.strstart != 0 {
538 return Err(Error::config(ErrorKind::InvalidState));
539 }
540 let take = dictionary.len().min(self.wsize);
541 let dict = &dictionary[dictionary.len() - take..];
542 self.win[1..1 + take].copy_from_slice(dict);
544 self.strstart = 1;
545 self.lookahead = take;
546 if self.level != 0 {
547 let end = 1 + take;
548 let mut pos = 1;
549 while pos + MIN_MATCH <= end {
550 self.insert(pos);
551 pos += 1;
552 }
553 }
554 self.strstart = 1 + take;
555 self.lookahead = 0;
556 self.block_start = self.strstart as isize;
557 Ok(())
558 }
559
560 pub fn compress(
587 &mut self,
588 input: &[u8],
589 output: &mut [u8],
590 flush: Flush,
591 ) -> Result<Progress, Error> {
592 let mut consumed = 0;
593 let mut produced = 0;
594 if self.finished {
595 if !input.is_empty() {
596 return Err(Error::config(ErrorKind::InvalidState));
597 }
598 self.drain(output, &mut produced);
599 let status = if self.pending_left() == 0 {
600 Status::Done
601 } else {
602 Status::NeedsOutput
603 };
604 return Ok(Progress::new(0, produced, status));
605 }
606 loop {
607 self.drain(output, &mut produced);
608 if self.pending_left() > 0 {
609 return Ok(Progress::new(consumed, produced, Status::NeedsOutput));
610 }
611 if self.flush_written && consumed == input.len() {
612 self.flush_written = false;
613 if flush == Flush::Finish {
614 self.finished = true;
615 }
616 return Ok(Progress::new(consumed, produced, Status::Done));
617 }
618 self.flush_written = false;
619 let before = (consumed, self.strstart, self.lookahead);
620 consumed += self.fill_window(&input[consumed..]);
621 let all_in = consumed == input.len();
622 let flushing = flush != Flush::None && all_in;
623 self.process(flushing);
624 if self.pending_left() > 0 {
625 continue;
626 }
627 if !all_in {
628 if before == (consumed, self.strstart, self.lookahead) {
631 return Err(Error::config(ErrorKind::InvalidState));
632 }
633 continue;
634 }
635 if flush == Flush::None {
636 return Ok(Progress::new(consumed, produced, Status::NeedsInput));
637 }
638 self.write_flush(flush);
639 self.flush_written = true;
640 }
641 }
642
643 pub fn compress_vec(
665 &mut self,
666 input: &[u8],
667 out: &mut Vec<u8>,
668 flush: Flush,
669 ) -> Result<Progress, Error> {
670 let start = out.len();
671 let mut consumed = 0;
672 loop {
673 let have = out.len();
674 let room = (input.len() - consumed) / 2 + 1024;
675 if out.capacity() - have < room && out.try_reserve(room).is_err() {
676 return Err(Error::config(ErrorKind::AllocationFailed));
677 }
678 let spare = out.capacity() - have;
679 out.resize(have + spare, 0);
680 let p = self.compress(&input[consumed..], &mut out[have..], flush);
681 match p {
682 Ok(p) => {
683 out.truncate(have + p.produced);
684 consumed += p.consumed;
685 if p.status != Status::NeedsOutput {
686 return Ok(Progress::new(consumed, out.len() - start, p.status));
687 }
688 }
689 Err(e) => {
690 out.truncate(have);
691 return Err(e);
692 }
693 }
694 }
695 }
696
697 fn pending_left(&self) -> usize {
698 self.pending.len() - self.pending_pos
699 }
700
701 fn drain(&mut self, output: &mut [u8], produced: &mut usize) {
703 let n = self.pending_left().min(output.len() - *produced);
704 output[*produced..*produced + n]
705 .copy_from_slice(&self.pending[self.pending_pos..self.pending_pos + n]);
706 self.pending_pos += n;
707 *produced += n;
708 self.total_out += n as u64;
709 if self.pending_pos == self.pending.len() {
710 self.pending.clear();
711 self.pending_pos = 0;
712 }
713 }
714
715 fn fill_window(&mut self, input: &[u8]) -> usize {
718 let size = self.win.len();
719 if size - self.strstart - self.lookahead < MIN_LOOKAHEAD
720 && self.strstart >= self.keep + self.wsize
721 {
722 self.slide();
723 }
724 let room = size - self.strstart - self.lookahead;
725 let n = room.min(input.len());
726 let at = self.strstart + self.lookahead;
727 self.win[at..at + n].copy_from_slice(&input[..n]);
728 self.lookahead += n;
729 self.total_in += n as u64;
730 n
731 }
732
733 fn slide(&mut self) {
736 let shift = (self.strstart - self.keep) / self.wsize * self.wsize;
737 if shift == 0 {
738 return;
739 }
740 if self.level == 0 && self.block_start < shift as isize {
741 self.end_block(false);
744 }
745 let end = self.strstart + self.lookahead;
746 self.win.copy_within(shift..end, 0);
747 self.strstart -= shift;
748 self.match_start = self.match_start.saturating_sub(shift);
749 self.prev_match = self.prev_match.saturating_sub(shift);
750 self.block_start -= shift as isize;
751 let s = shift as u32;
754 for h in self.head.iter_mut().chain(self.prev.iter_mut()) {
755 *h = u32::from(*h).saturating_sub(s) as u16;
756 }
757 }
758
759 #[inline]
760 fn hash(&self, pos: usize) -> usize {
761 let v = u32::from(self.win[pos])
762 | (u32::from(self.win[pos + 1]) << 8)
763 | (u32::from(self.win[pos + 2]) << 16);
764 (v.wrapping_mul(0x9E37_79B1) >> (32 - self.hash_bits)) as usize
765 }
766
767 #[inline]
770 fn insert(&mut self, pos: usize) -> usize {
771 let h = self.hash(pos);
772 let head = self.head[h];
773 self.prev[pos & (self.wsize - 1)] = head;
774 self.head[h] = pos as u16;
775 head as usize
776 }
777
778 fn longest_match(&mut self, mut cur: usize) -> usize {
781 let p = self.params;
782 let mut chain = p.chain;
783 if self.prev_length >= p.good {
784 chain >>= 2;
785 }
786 let max = MAX_MATCH.min(self.lookahead);
787 let nice = p.nice.min(max);
788 let keep = self.keep;
789 let mut best = self.prev_length;
790 let win = &self.win[..];
791 let s = self.strstart;
792 loop {
793 if cur == 0 || cur >= s || s - cur > keep || best >= max {
794 break;
795 }
796 if best < max
797 && win[cur + best] == win[s + best]
798 && win[cur] == win[s]
799 && win[cur + 1] == win[s + 1]
800 {
801 let len = common_prefix(win, cur, s, max);
802 if len > best {
803 self.match_start = cur;
804 best = len;
805 if len >= nice {
806 break;
807 }
808 }
809 }
810 chain -= 1;
811 if chain == 0 {
812 break;
813 }
814 let next = self.prev[cur & (self.wsize - 1)] as usize;
815 if next >= cur {
816 break;
817 }
818 cur = next;
819 }
820 best.min(self.lookahead)
821 }
822
823 fn literal(&mut self, b: u8) {
826 self.syms.push(u32::from(b));
827 self.scratch.lit_freq[b as usize] += 1;
828 }
829
830 fn matched(&mut self, dist: usize, len: usize) {
832 self.syms
833 .push(((dist as u32) << 16) | (len - MIN_MATCH) as u32);
834 self.scratch.lit_freq[257 + LENGTH_CODE[len - MIN_MATCH] as usize] += 1;
835 self.scratch.dist_freq[dist_code(dist)] += 1;
836 }
837
838 #[inline]
840 fn block_full(&mut self) {
841 if self.syms.len() >= self.sym_cap {
842 self.end_block(false);
843 }
844 }
845
846 fn process(&mut self, flushing: bool) {
850 if self.level == 0 {
851 let chunk = STORED_CHUNK.min(self.win.len() / 2);
852 let full = self.strstart + self.lookahead + MIN_LOOKAHEAD > self.win.len();
855 while self.lookahead >= chunk || ((flushing || full) && self.lookahead > 0) {
856 let n = self.lookahead.min(65_535);
857 self.strstart += n;
858 self.lookahead -= n;
859 self.end_block(false);
860 }
861 return;
862 }
863 if self.params.lazy_matching {
864 self.process_lazy(flushing);
865 } else {
866 self.process_greedy(flushing);
867 }
868 }
869
870 fn process_greedy(&mut self, flushing: bool) {
871 loop {
872 if self.lookahead < MIN_LOOKAHEAD && (!flushing || self.lookahead == 0) {
873 return;
874 }
875 let mut head = 0;
876 if self.lookahead >= MIN_MATCH {
877 head = self.insert(self.strstart);
878 }
879 self.match_length = MIN_MATCH - 1;
880 if head != 0 && self.strstart - head <= self.keep {
881 self.prev_length = MIN_MATCH - 1;
882 self.match_length = self.longest_match(head);
883 }
884 if self.match_length >= MIN_MATCH {
885 let len = self.match_length;
886 self.matched(self.strstart - self.match_start, len);
887 self.lookahead -= len;
888 if len <= self.params.lazy && self.lookahead >= MIN_MATCH {
889 for _ in 1..len {
890 self.strstart += 1;
891 self.insert(self.strstart);
892 }
893 self.strstart += 1;
894 } else {
895 self.strstart += len;
896 }
897 } else {
898 self.literal(self.win[self.strstart]);
899 self.lookahead -= 1;
900 self.strstart += 1;
901 }
902 self.block_full();
903 }
904 }
905
906 fn process_lazy(&mut self, flushing: bool) {
907 loop {
908 if self.lookahead < MIN_LOOKAHEAD && (!flushing || self.lookahead == 0) {
909 break;
910 }
911 let mut head = 0;
912 if self.lookahead >= MIN_MATCH {
913 head = self.insert(self.strstart);
914 }
915 self.prev_length = self.match_length;
916 self.prev_match = self.match_start;
917 self.match_length = MIN_MATCH - 1;
918 if head != 0 && self.prev_length < self.params.lazy && self.strstart - head <= self.keep
919 {
920 self.match_length = self.longest_match(head);
921 if self.match_length == MIN_MATCH && self.strstart - self.match_start > TOO_FAR {
922 self.match_length = MIN_MATCH - 1;
923 }
924 }
925 if self.prev_length >= MIN_MATCH && self.match_length <= self.prev_length {
926 let max_insert = self.strstart + self.lookahead - MIN_MATCH;
927 let len = self.prev_length;
928 self.matched(self.strstart - 1 - self.prev_match, len);
929 self.lookahead -= len - 1;
930 for _ in 0..len - 2 {
931 self.strstart += 1;
932 if self.strstart <= max_insert {
933 self.insert(self.strstart);
934 }
935 }
936 self.match_available = false;
937 self.match_length = MIN_MATCH - 1;
938 self.strstart += 1;
939 self.block_full();
940 } else if self.match_available {
941 self.literal(self.win[self.strstart - 1]);
944 self.block_full();
945 self.strstart += 1;
946 self.lookahead -= 1;
947 } else {
948 self.match_available = true;
949 self.strstart += 1;
950 self.lookahead -= 1;
951 }
952 }
953 if flushing && self.match_available {
954 self.literal(self.win[self.strstart - 1]);
955 self.match_available = false;
956 self.block_full();
957 }
958 }
959
960 #[inline]
963 fn put(&mut self, value: u32, bits: u32) {
964 self.bitbuf |= u64::from(value) << self.bitcnt;
965 self.bitcnt += bits;
966 if self.bitcnt >= 32 {
967 self.pending
968 .extend_from_slice(&(self.bitbuf as u32).to_le_bytes());
969 self.bitbuf >>= 32;
970 self.bitcnt -= 32;
971 }
972 }
973
974 fn align(&mut self) {
976 while self.bitcnt > 0 {
977 self.pending.push(self.bitbuf as u8);
978 self.bitbuf >>= 8;
979 self.bitcnt = self.bitcnt.saturating_sub(8);
980 }
981 self.bitbuf = 0;
982 }
983
984 fn write_flush(&mut self, flush: Flush) {
985 match flush {
986 Flush::None => {}
987 Flush::Finish => {
988 self.end_block(true);
989 self.align();
990 }
991 Flush::Sync | Flush::Full => {
992 self.end_block(false);
993 self.put(0, 3);
995 self.align();
996 self.pending.extend_from_slice(&[0, 0, 0xFF, 0xFF]);
997 if flush == Flush::Full {
998 self.head.fill(0);
999 self.match_length = MIN_MATCH - 1;
1000 self.prev_length = MIN_MATCH - 1;
1001 }
1002 }
1003 }
1004 }
1005
1006 fn end_block(&mut self, last: bool) {
1009 let stored_len = (self.strstart as isize - self.block_start).max(0) as usize;
1010 if self.syms.is_empty() && stored_len == 0 && !last {
1011 return;
1012 }
1013 let stored_ok = self.block_start >= 0;
1014 if self.level == 0 && stored_ok {
1015 self.write_stored(self.block_start as usize, stored_len, last);
1016 } else {
1017 self.write_huffman_or_stored(stored_ok, stored_len, last);
1018 }
1019 self.syms.clear();
1020 self.scratch.lit_freq.fill(0);
1021 self.scratch.dist_freq.fill(0);
1022 self.block_start = self.strstart as isize;
1023 }
1024
1025 fn write_stored(&mut self, start: usize, len: usize, last: bool) {
1026 let mut at = start;
1027 let mut left = len;
1028 loop {
1029 let n = left.min(65_535);
1030 let final_piece = n == left;
1031 self.put(u32::from(last && final_piece), 1);
1032 self.put(0, 2);
1033 self.align();
1034 self.pending.extend_from_slice(&(n as u16).to_le_bytes());
1035 self.pending.extend_from_slice(&(!(n as u16)).to_le_bytes());
1036 self.pending.extend_from_slice(&self.win[at..at + n]);
1037 at += n;
1038 left -= n;
1039 if final_piece {
1040 break;
1041 }
1042 }
1043 }
1044
1045 fn write_huffman_or_stored(&mut self, stored_ok: bool, stored_len: usize, last: bool) {
1046 let s = &mut *self.scratch;
1047 s.lit_freq[256] = 1;
1048 let lit_used = s.lit_freq.iter().filter(|&&f| f != 0).count();
1052 if lit_used < 2 {
1053 s.lit_freq[if s.lit_freq[0] == 0 { 0 } else { 1 }] += 1;
1054 }
1055 let dist_used = s.dist_freq.iter().filter(|&&f| f != 0).count();
1056 if dist_used == 0 {
1057 s.dist_freq[0] = 1;
1058 s.dist_freq[1] = 1;
1059 } else if dist_used == 1 {
1060 let d = if s.dist_freq[0] == 0 { 0 } else { 1 };
1061 s.dist_freq[d] = 1;
1062 }
1063 huffman::lengths(&s.lit_freq, 15, &mut s.lit_lens);
1064 huffman::lengths(&s.dist_freq, 15, &mut s.dist_lens);
1065
1066 let mut extra: u64 = 0;
1068 let mut dyn_bits: u64 = 0;
1069 let mut fix_bits: u64 = 0;
1070 for sym in 0..286 {
1071 let f = u64::from(s.lit_freq[sym]);
1072 if f == 0 {
1073 continue;
1074 }
1075 dyn_bits += f * u64::from(s.lit_lens[sym]);
1076 fix_bits += f * u64::from(FIXED_LIT_LENS[sym]);
1077 if sym >= 257 {
1078 extra += f * u64::from(LENGTH_EXTRA[sym - 257]);
1079 }
1080 }
1081 for ((&f, &len), &x) in s.dist_freq.iter().zip(&s.dist_lens).zip(&DIST_EXTRA) {
1082 let f = u64::from(f);
1083 dyn_bits += f * u64::from(len);
1084 fix_bits += f * 5;
1085 extra += f * u64::from(x);
1086 }
1087 let hlit = 257
1090 + s.lit_lens[257..286]
1091 .iter()
1092 .rposition(|&l| l != 0)
1093 .map_or(0, |i| i + 1);
1094 let hdist = 1 + s.dist_lens.iter().rposition(|&l| l != 0).unwrap_or(0);
1095 rle_lengths(s, hlit, hdist);
1096 huffman::lengths(&s.pre_freq, 7, &mut s.pre_lens);
1097 let hclen = 4 + PRECODE_ORDER
1098 .iter()
1099 .rposition(|&i| s.pre_lens[i] != 0)
1100 .map_or(0, |i| (i + 1).saturating_sub(4));
1101 let mut header_bits = 14 + 3 * hclen as u64;
1102 for &(sym, _) in &s.rle[..s.rle_len] {
1103 header_bits += u64::from(s.pre_lens[sym as usize]);
1104 header_bits += match sym {
1105 16 => 2,
1106 17 => 3,
1107 18 => 7,
1108 _ => 0,
1109 };
1110 }
1111 let dynamic = 3 + header_bits + dyn_bits + extra;
1112 let fixed = 3 + fix_bits + extra;
1113 let pad = u64::from((8 - (self.bitcnt + 3) % 8) % 8);
1114 let pieces = (stored_len as u64).div_ceil(65_535).max(1);
1115 let stored = pieces * (3 + 32) + pad + 8 * stored_len as u64 + (pieces - 1) * 5;
1116
1117 if stored_ok && stored <= fixed.min(dynamic) {
1118 self.write_stored(self.block_start as usize, stored_len, last);
1119 return;
1120 }
1121 if fixed <= dynamic {
1122 self.put(u32::from(last), 1);
1123 self.put(1, 2);
1124 let mut lit_codes = [0u16; 288];
1125 huffman::codes(&FIXED_LIT_LENS, &mut lit_codes);
1126 let mut dist_codes = [0u16; 30];
1127 huffman::codes(&[5u8; 30], &mut dist_codes);
1128 self.write_symbols(&lit_codes, &FIXED_LIT_LENS, &dist_codes, &[5u8; 30]);
1129 } else {
1130 self.put(u32::from(last), 1);
1131 self.put(2, 2);
1132 self.put((hlit - 257) as u32, 5);
1133 self.put((hdist - 1) as u32, 5);
1134 self.put((hclen - 4) as u32, 4);
1135 let s = &mut *self.scratch;
1136 huffman::codes(&s.pre_lens, &mut s.pre_codes);
1137 huffman::codes(&s.lit_lens, &mut s.lit_codes[..286]);
1138 huffman::codes(&s.dist_lens, &mut s.dist_codes);
1139 for &i in &PRECODE_ORDER[..hclen] {
1140 let l = self.scratch.pre_lens[i];
1141 self.put(u32::from(l), 3);
1142 }
1143 for k in 0..self.scratch.rle_len {
1144 let (sym, value) = self.scratch.rle[k];
1145 let code = self.scratch.pre_codes[sym as usize];
1146 let len = self.scratch.pre_lens[sym as usize];
1147 self.put(u32::from(code), u32::from(len));
1148 match sym {
1149 16 => self.put(u32::from(value), 2),
1150 17 => self.put(u32::from(value), 3),
1151 18 => self.put(u32::from(value), 7),
1152 _ => {}
1153 }
1154 }
1155 let lit_codes = self.scratch.lit_codes;
1156 let lit_lens = self.scratch.lit_lens;
1157 let dist_codes = self.scratch.dist_codes;
1158 let dist_lens = self.scratch.dist_lens;
1159 self.write_symbols(&lit_codes, &lit_lens, &dist_codes, &dist_lens);
1160 }
1161 }
1162
1163 fn write_symbols(
1164 &mut self,
1165 lit_codes: &[u16],
1166 lit_lens: &[u8],
1167 dist_codes: &[u16],
1168 dist_lens: &[u8],
1169 ) {
1170 let syms = core::mem::take(&mut self.syms);
1171 for &sym in &syms {
1172 let dist = (sym >> 16) as usize;
1173 let litlen = (sym & 0xFFFF) as usize;
1174 if dist == 0 {
1175 self.put(u32::from(lit_codes[litlen]), u32::from(lit_lens[litlen]));
1176 } else {
1177 let code = LENGTH_CODE[litlen] as usize;
1178 self.put(
1179 u32::from(lit_codes[257 + code]),
1180 u32::from(lit_lens[257 + code]),
1181 );
1182 let extra = u32::from(LENGTH_EXTRA[code]);
1183 if extra != 0 {
1184 self.put(
1185 (litlen + MIN_MATCH - LENGTH_BASE[code] as usize) as u32,
1186 extra,
1187 );
1188 }
1189 let d = dist_code(dist);
1190 self.put(u32::from(dist_codes[d]), u32::from(dist_lens[d]));
1191 let extra = u32::from(DIST_EXTRA[d]);
1192 if extra != 0 {
1193 self.put((dist - DIST_BASE[d] as usize) as u32, extra);
1194 }
1195 }
1196 }
1197 self.syms = syms;
1198 self.put(u32::from(lit_codes[256]), u32::from(lit_lens[256]));
1199 }
1200}
1201
1202#[inline]
1204fn common_prefix(win: &[u8], a: usize, b: usize, max: usize) -> usize {
1205 let mut n = 0;
1206 while n + 8 <= max {
1207 let mut x = [0u8; 8];
1208 let mut y = [0u8; 8];
1209 x.copy_from_slice(&win[a + n..a + n + 8]);
1210 y.copy_from_slice(&win[b + n..b + n + 8]);
1211 let diff = u64::from_le_bytes(x) ^ u64::from_le_bytes(y);
1212 if diff != 0 {
1213 return n + (diff.trailing_zeros() / 8) as usize;
1214 }
1215 n += 8;
1216 }
1217 while n < max && win[a + n] == win[b + n] {
1218 n += 1;
1219 }
1220 n
1221}
1222
1223fn rle_lengths(s: &mut BlockScratch, hlit: usize, hdist: usize) {
1228 let mut all = [0u8; 316];
1229 all[..hlit].copy_from_slice(&s.lit_lens[..hlit]);
1230 all[hlit..hlit + hdist].copy_from_slice(&s.dist_lens[..hdist]);
1231 let all = &all[..hlit + hdist];
1232 s.pre_freq = [0; 19];
1233 s.rle_len = 0;
1234 let push = |s: &mut BlockScratch, sym: u8, value: u8| {
1235 s.rle[s.rle_len] = (sym, value);
1236 s.rle_len += 1;
1237 s.pre_freq[sym as usize] += 1;
1238 };
1239 let mut i = 0;
1240 while i < all.len() {
1241 let v = all[i];
1242 let mut run = 1;
1243 while i + run < all.len() && all[i + run] == v {
1244 run += 1;
1245 }
1246 i += run;
1247 if v == 0 {
1248 while run >= 11 {
1249 let n = run.min(138);
1250 push(s, 18, (n - 11) as u8);
1251 run -= n;
1252 }
1253 if run >= 3 {
1254 push(s, 17, (run - 3) as u8);
1255 run = 0;
1256 }
1257 for _ in 0..run {
1258 push(s, 0, 0);
1259 }
1260 } else {
1261 push(s, v, 0);
1262 run -= 1;
1263 while run >= 3 {
1264 let n = run.min(6);
1265 push(s, 16, (n - 3) as u8);
1266 run -= n;
1267 }
1268 for _ in 0..run {
1269 push(s, v, 0);
1270 }
1271 }
1272 }
1273}