Skip to main content

compress_lib/deflate/
encoder.rs

1//! The raw DEFLATE (RFC 1951) encoder.
2//!
3//! Input is copied into a sliding window; a hash of three bytes indexes
4//! chains of earlier positions; greedy (levels 1 to 3) or lazy (4 to 9)
5//! matching turns the window into literal and match symbols; every 16,384
6//! symbols (fewer for small windows) a block is written as stored, fixed, or
7//! dynamic Huffman, whichever is smallest. Output waits in a pending buffer
8//! of at most one block until the caller drains it.
9
10use 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;
17/// Lookahead kept before matching at a position, so a full match and the
18/// hash of the next position always fit.
19const MIN_LOOKAHEAD: usize = MAX_MATCH + MIN_MATCH + 1;
20/// A match of length 3 further back than this costs more than three
21/// literals (zlib's TOO_FAR).
22const TOO_FAR: usize = 4096;
23/// Bytes past the window's logical end, so four-byte loads at any position
24/// of the window are in bounds.
25const WIN_PAD: usize = 8;
26/// Level 0 writes a stored block once this much input is waiting (or half
27/// the buffer, for small windows).
28const 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
49/// `LENGTH_CODE[len - 3]`: the length symbol index (0 to 28).
50static 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    // 258 has its own symbol; 257 - 3 = 254 stays in code 27.
62    t[255] = 28;
63    t
64};
65
66/// Distance symbol for `dist - 1` below 256, and for `256 + ((dist - 1) >> 7)`
67/// above (zlib's two-part table).
68static 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
99/// Fixed literal/length code lengths.
100const 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/// Match-finder settings per level (zlib's configuration table).
120#[derive(Clone, Copy)]
121struct Params {
122    /// Shorten the chain search once a match this long is found.
123    good: usize,
124    /// Greedy levels: insert hashes inside matches up to this length. Lazy
125    /// levels: do not look for a better match once one this long is found.
126    lazy: usize,
127    /// Stop searching at a match this long.
128    nice: usize,
129    /// Chain positions searched per match.
130    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/// How far a call should go before returning.
157#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
158#[non_exhaustive]
159pub enum Flush {
160    /// Compress as input allows; output may lag behind input.
161    None,
162    /// Write out everything so far, end on a byte boundary with an empty
163    /// stored block (`00 00 FF FF`). History is kept. WebSocket
164    /// permessage-deflate ends every message this way.
165    Sync,
166    /// As `Sync`, and forget history: later data never refers back across
167    /// this point, so a decoder can start here.
168    Full,
169    /// Write out everything and end the stream with a final block.
170    Finish,
171}
172
173/// Memory settings for a [`Deflater`]: the hash table and the symbol
174/// buffer, the two largest parts after the window.
175///
176/// | Setting | Default | Memory | Effect |
177/// |---|---|---|---|
178/// | hash bits | window bits + 1, 9 to 15 (12 at most at level 1) | 2 bytes per entry | fewer bits: less memory, more collisions, slightly larger output |
179/// | block symbols | 2^(window bits + 1), 1,024 to 16,384 | 4 bytes per symbol, plus up to 4 bytes of pending output | fewer: less memory, more block headers |
180///
181/// # Examples
182///
183/// ```
184/// use compress_lib::deflate::MemoryConfig;
185///
186/// let config = MemoryConfig::new().with_hash_bits(11).with_block_symbols(4096);
187/// assert_eq!((config.hash_bits(), config.block_symbols()), (11, 4096));
188/// ```
189#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
190#[non_exhaustive]
191pub struct MemoryConfig {
192    /// 0: chosen from the window bits.
193    hash_bits: u8,
194    /// 0: chosen from the window bits.
195    block_symbols: usize,
196}
197
198impl MemoryConfig {
199    /// Both sizes chosen from the window bits.
200    ///
201    /// # Examples
202    ///
203    /// ```
204    /// assert_eq!(compress_lib::deflate::MemoryConfig::new().hash_bits(), 0);
205    /// ```
206    #[must_use]
207    pub const fn new() -> Self {
208        Self {
209            hash_bits: 0,
210            block_symbols: 0,
211        }
212    }
213
214    /// Sets the hash table to `2^bits` entries; clamped to 8 to 16 (0 keeps
215    /// the default).
216    ///
217    /// # Examples
218    ///
219    /// ```
220    /// assert_eq!(compress_lib::deflate::MemoryConfig::new().with_hash_bits(20).hash_bits(), 16);
221    /// ```
222    #[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    /// Sets the symbols per block; clamped to 256 to 65,536 (0 keeps the
237    /// default).
238    ///
239    /// # Examples
240    ///
241    /// ```
242    /// assert_eq!(compress_lib::deflate::MemoryConfig::new().with_block_symbols(100).block_symbols(), 256);
243    /// ```
244    #[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    /// The hash bits set (0: chosen from the window bits).
259    ///
260    /// # Examples
261    ///
262    /// ```
263    /// assert_eq!(compress_lib::deflate::MemoryConfig::new().with_hash_bits(10).hash_bits(), 10);
264    /// ```
265    #[must_use]
266    pub const fn hash_bits(&self) -> u8 {
267        self.hash_bits
268    }
269
270    /// The symbols per block set (0: chosen from the window bits).
271    ///
272    /// # Examples
273    ///
274    /// ```
275    /// assert_eq!(compress_lib::deflate::MemoryConfig::new().block_symbols(), 0);
276    /// ```
277    #[must_use]
278    pub const fn block_symbols(&self) -> usize {
279        self.block_symbols
280    }
281}
282
283/// Scratch for building one block's codes (about 3 KiB, boxed once).
284struct 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    /// Run-length coded code lengths: (symbol, extra value).
292    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
299/// A streaming raw DEFLATE encoder (RFC 1951).
300///
301/// Push input, pull output, with a [`Flush`] choosing how far each call
302/// goes. Memory is fixed when the deflater is built (section 5.6 of the
303/// plan): at window bits 15 and level 6, a 64 KiB window, 128 KiB of hash
304/// chains, 64 KiB of symbols, and up to one block of pending output.
305///
306/// # Examples
307///
308/// ```
309/// use compress_lib::{Level, deflate::{self, Deflater, Flush}};
310///
311/// let mut deflater = Deflater::new(Level::DEFAULT);
312/// let mut packed = Vec::new();
313/// deflater.compress_vec(b"hello, hello, hello", &mut packed, Flush::Finish)?;
314/// assert_eq!(deflate::decompress(&packed)?, b"hello, hello, hello");
315/// # Ok::<(), compress_lib::Error>(())
316/// ```
317pub struct Deflater {
318    memory: MemoryConfig,
319    level: u8,
320    params: Params,
321    window_bits: u8,
322    /// Window buffer of `wsize * span` bytes; positions are indices into it.
323    win: Vec<u8>,
324    /// Logical size of `win`; the vector has `WIN_PAD` more zero bytes so
325    /// four-byte loads near the end stay in bounds.
326    size: usize,
327    wsize: usize,
328    /// History always kept before `strstart`, and so the longest distance
329    /// used: the whole window, or 262 bytes less when the buffer is only two
330    /// windows (zlib's MAX_DIST), so positions fit in 16 bits.
331    keep: usize,
332    strstart: usize,
333    lookahead: usize,
334    /// Start of the current block's input in `win` (negative once slid out).
335    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    /// Symbols of the current block: `dist << 16 | litlen`, where a literal
345    /// has `dist == 0` and a match stores `length - 3`.
346    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    /// The flush asked for has been written into `pending`.
356    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    /// A deflater at `level` with window bits 15.
380    ///
381    /// # Examples
382    ///
383    /// ```
384    /// use compress_lib::{Level, deflate::Deflater};
385    ///
386    /// let deflater = Deflater::new(Level::FAST);
387    /// assert_eq!(deflater.level(), Level::FAST);
388    /// ```
389    #[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        // At least 8 KiB of buffer, so small windows still read input in
397        // useful pieces; always a whole number of windows (the hash chains
398        // are indexed modulo the window).
399        let span = (8192 / wsize).max(2);
400        // Level 1 probes once, so a table that stays in the first-level cache
401        // is faster and loses little (D-040).
402        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            // Position 0 means "none" in the hash chains, so data starts at 1.
425            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            // One block is at most about four bytes per symbol (fixed codes,
452            // longest extra bits), or the stored form of its input.
453            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    /// Sets the window to `2^bits` bytes, 8 to 15: no match distance is ever
465    /// longer (RFC 7692 negotiates these sizes; 8 is a real 256-byte
466    /// window). Smaller windows also use smaller hash and symbol tables.
467    ///
468    /// # Errors
469    ///
470    /// [`ErrorKind::InvalidWindowBits`] outside 8 to 15.
471    ///
472    /// # Examples
473    ///
474    /// ```
475    /// use compress_lib::{Level, deflate::Deflater};
476    ///
477    /// let small = Deflater::new(Level::FAST).with_window_bits(9)?;
478    /// assert!(small.memory_in_use() < Deflater::new(Level::FAST).memory_in_use());
479    /// assert!(Deflater::new(Level::FAST).with_window_bits(7).is_err());
480    /// # Ok::<(), compress_lib::Error>(())
481    /// ```
482    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    /// Sizes the hash table and the symbol buffer explicitly (see
490    /// [`MemoryConfig`]), for many connections on little memory or for a
491    /// little more ratio.
492    ///
493    /// # Examples
494    ///
495    /// ```
496    /// use compress_lib::{Level, deflate::{self, Deflater, Flush, MemoryConfig}};
497    ///
498    /// let lean = MemoryConfig::new().with_hash_bits(9).with_block_symbols(512);
499    /// let mut d = Deflater::new(Level::FAST).with_window_bits(9)?.with_memory(lean);
500    /// assert!(d.memory_in_use() < Deflater::new(Level::FAST).with_window_bits(9)?.memory_in_use());
501    /// let mut out = Vec::new();
502    /// d.compress_vec(b"small and lean", &mut out, Flush::Finish)?;
503    /// assert_eq!(deflate::decompress(&out)?, b"small and lean");
504    /// # Ok::<(), compress_lib::Error>(())
505    /// ```
506    #[must_use]
507    pub fn with_memory(self, memory: MemoryConfig) -> Self {
508        Self::build(self.level, self.window_bits, memory)
509    }
510
511    /// The level in force.
512    ///
513    /// # Examples
514    ///
515    /// ```
516    /// use compress_lib::{Level, deflate::Deflater};
517    ///
518    /// assert_eq!(Deflater::default().level(), Level::DEFAULT);
519    /// ```
520    #[must_use]
521    pub fn level(&self) -> Level {
522        Level::new(self.level).unwrap_or(Level::DEFAULT)
523    }
524
525    /// The window size in bits.
526    ///
527    /// # Examples
528    ///
529    /// ```
530    /// assert_eq!(compress_lib::deflate::Deflater::default().window_bits(), 15);
531    /// ```
532    #[must_use]
533    pub fn window_bits(&self) -> u8 {
534        self.window_bits
535    }
536
537    /// Changes the level for data not yet compressed. The current block is
538    /// ended first when the change switches to or from level 0.
539    ///
540    /// # Examples
541    ///
542    /// ```
543    /// use compress_lib::{Level, deflate::{self, Deflater, Flush}};
544    ///
545    /// let mut deflater = Deflater::new(Level::BEST);
546    /// let mut out = Vec::new();
547    /// deflater.compress_vec(b"header ", &mut out, Flush::None)?;
548    /// deflater.set_level(Level::NONE);
549    /// deflater.compress_vec(b"body", &mut out, Flush::Finish)?;
550    /// assert_eq!(deflate::decompress(&out)?, b"header body");
551    /// # Ok::<(), compress_lib::Error>(())
552    /// ```
553    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            // Finish the input waiting under the old level first.
558            self.process(true);
559            self.end_block(false);
560        } else if self.params.lazy_matching && !next.lazy_matching && self.match_available {
561            // Lazy matching holds the byte before `strstart` back; greedy
562            // matching does not know about it.
563            self.literal(self.win[self.strstart - 1]);
564            self.match_available = false;
565            self.block_full();
566        }
567        // No pending match crosses the change.
568        self.match_length = MIN_MATCH - 1;
569        self.prev_length = MIN_MATCH - 1;
570        self.level = level;
571        self.params = next;
572    }
573
574    /// Uncompressed bytes taken since the deflater was built or reset.
575    ///
576    /// # Examples
577    ///
578    /// ```
579    /// use compress_lib::deflate::{Deflater, Flush};
580    ///
581    /// let mut d = Deflater::default();
582    /// d.compress_vec(b"abc", &mut Vec::new(), Flush::Finish)?;
583    /// assert_eq!(d.total_in(), 3);
584    /// # Ok::<(), compress_lib::Error>(())
585    /// ```
586    #[must_use]
587    pub fn total_in(&self) -> u64 {
588        self.total_in
589    }
590
591    /// Compressed bytes handed out since the deflater was built or reset.
592    ///
593    /// # Examples
594    ///
595    /// ```
596    /// use compress_lib::deflate::{Deflater, Flush};
597    ///
598    /// let mut d = Deflater::default();
599    /// let mut out = Vec::new();
600    /// d.compress_vec(b"", &mut out, Flush::Finish)?;
601    /// assert_eq!(d.total_out(), out.len() as u64);
602    /// # Ok::<(), compress_lib::Error>(())
603    /// ```
604    #[must_use]
605    pub fn total_out(&self) -> u64 {
606        self.total_out
607    }
608
609    /// Heap bytes held: window, hash chains, symbols, pending output, and
610    /// block scratch.
611    ///
612    /// # Examples
613    ///
614    /// ```
615    /// let d = compress_lib::deflate::Deflater::default();
616    /// assert!(d.memory_in_use() > 64 * 1024);
617    /// ```
618    #[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    /// Starts a new, unrelated stream, keeping the allocations.
628    ///
629    /// # Examples
630    ///
631    /// ```
632    /// use compress_lib::deflate::{self, Deflater, Flush};
633    ///
634    /// let mut d = Deflater::default();
635    /// let mut a = Vec::new();
636    /// d.compress_vec(b"first", &mut a, Flush::Finish)?;
637    /// d.reset();
638    /// let mut b = Vec::new();
639    /// d.compress_vec(b"second", &mut b, Flush::Finish)?;
640    /// assert_eq!(deflate::decompress(&b)?, b"second");
641    /// # Ok::<(), compress_lib::Error>(())
642    /// ```
643    pub fn reset(&mut self) {
644        // Clear only the hash heads this stream used when it was short and
645        // never slid (a small WebSocket message touches a few dozen of 32,768
646        // entries); otherwise clear them all.
647        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    /// Presets the history with `dictionary` (its last `2^window_bits`
674    /// bytes): matches may refer into it. The decoder must be given the same
675    /// dictionary. Only before any input.
676    ///
677    /// # Errors
678    ///
679    /// [`ErrorKind::InvalidState`] after input has been given.
680    ///
681    /// # Examples
682    ///
683    /// ```
684    /// use compress_lib::deflate::{Deflater, Flush, Inflater};
685    ///
686    /// let dict = b"{\"type\":\"update\",\"value\":";
687    /// let mut d = Deflater::default();
688    /// d.set_dictionary(dict)?;
689    /// let mut packed = Vec::new();
690    /// d.compress_vec(b"{\"type\":\"update\",\"value\":42}", &mut packed, Flush::Finish)?;
691    /// let mut i = Inflater::new();
692    /// i.set_dictionary(dict)?;
693    /// let mut out = Vec::new();
694    /// i.finish_vec(&packed, &mut out)?;
695    /// assert_eq!(out, b"{\"type\":\"update\",\"value\":42}");
696    /// # Ok::<(), compress_lib::Error>(())
697    /// ```
698    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        // Position 0 is the hash chains' "none", so the dictionary starts at 1.
705        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    /// Compresses as much of `input` as the window takes and writes
723    /// compressed bytes to `output`.
724    ///
725    /// With `Flush::None` the result is `NeedsInput` once all input is taken
726    /// (output may lag behind), or `NeedsOutput` when `output` is full.
727    /// With a flush, `Done` means all input is taken and the flush point is
728    /// completely in `output`; on `NeedsOutput`, call again with the same
729    /// flush and the input not yet consumed.
730    ///
731    /// # Errors
732    ///
733    /// [`ErrorKind::InvalidState`] when input is given after `Finish`
734    /// completed (call [`reset`](Deflater::reset) for a new stream).
735    ///
736    /// # Examples
737    ///
738    /// ```
739    /// use compress_lib::deflate::{self, Deflater, Flush, Status};
740    ///
741    /// let mut d = Deflater::default();
742    /// let mut out = [0u8; 256];
743    /// let p = d.compress(b"some data", &mut out, Flush::Finish)?;
744    /// assert_eq!(p.status, Status::Done);
745    /// assert_eq!(deflate::decompress(&out[..p.produced])?, b"some data");
746    /// # Ok::<(), compress_lib::Error>(())
747    /// ```
748    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                // Every round takes input or turns lookahead into output; a
791                // round that does neither would repeat forever. Fail closed.
792                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    /// Compresses `input` and appends to `out` until the flush point is
806    /// written (with `Flush::None`, until all input is taken). Returns
807    /// `Done`, or `NeedsInput` for `Flush::None`.
808    ///
809    /// # Errors
810    ///
811    /// As [`compress`](Deflater::compress), plus
812    /// [`ErrorKind::AllocationFailed`] when `out` cannot grow.
813    ///
814    /// # Examples
815    ///
816    /// ```
817    /// use compress_lib::deflate::{self, Deflater, Flush};
818    ///
819    /// let mut d = Deflater::default();
820    /// let mut out = Vec::new();
821    /// d.compress_vec(b"part one, ", &mut out, Flush::None)?;
822    /// d.compress_vec(b"part two", &mut out, Flush::Finish)?;
823    /// assert_eq!(deflate::decompress(&out)?, b"part one, part two");
824    /// # Ok::<(), compress_lib::Error>(())
825    /// ```
826    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    /// Moves pending output into `output[*produced..]`.
864    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    /// Copies input into the window, sliding it first when the lookahead
878    /// would not fit. Returns the bytes taken.
879    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    /// Slides the window down by a whole number of windows, keeping at
896    /// least one window of history before `strstart`.
897    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            // Stored blocks are cut from the window; level 0 writes them
904            // before the data leaves.
905            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        // Positions are below 2^16 and so is the shift; entries that slide
914        // out become 0, "none".
915        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    /// Inserts `pos` into the hash chains; returns the previous head (0 for
922    /// none).
923    #[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    /// Records a literal (set_level, flushes).
936    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    /// Ends the block when the symbol buffer is full. With a held-back
942    /// literal (lazy matching), the block stops before that byte.
943    #[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    /// Turns the lookahead into symbols. Without `flushing`, stops while
954    /// fewer than `MIN_LOOKAHEAD` bytes wait (more input could extend a
955    /// match); with it, uses everything.
956    fn process(&mut self, flushing: bool) {
957        if self.level == 0 {
958            let chunk = STORED_CHUNK.min(self.size / 2);
959            // A window too full to take more input and not yet able to slide
960            // must be written out too, or the stream would stall.
961            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    /// Greedy matching (levels 1 to 3) with the hot state in locals. Runs
989    /// until the lookahead is used up (`true`) or the symbol buffer is full
990    /// (`false`).
991    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                // Level 1 on data that keeps missing (compressed or random
1070                // input): search only every few positions, more sparsely
1071                // the longer the run of misses (D-040).
1072                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    /// Lazy matching (levels 4 to 9, zlib's deflate_slow) with the hot state
1090    /// in locals; returns as [`greedy_run`](Self::greedy_run).
1091    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                // Search for a match longer than the one held back.
1130                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                    // The two bytes ending a longer match first (zlib's scan
1140                    // end), then the first three.
1141                    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    // ---- bit output ----------------------------------------------------
1207
1208    #[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    /// Writes out whole bytes and pads the last one with zero bits.
1221    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                // An empty stored block: header, pad, 00 00 FF FF.
1240                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    /// Writes the current block (if it has data, or if it is the last) as
1253    /// the cheapest of stored, fixed, and dynamic.
1254    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        // Every block gets at least two literal/length codes and two
1295        // distance codes, as zlib does, so no decoder meets the one-code
1296        // special case.
1297        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        // Payload bits under each code; extra bits are the same for both.
1313        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        // The forced dummy symbols are counted above but never written: the
1334        // estimate is a few bits high for both codes alike.
1335        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        // The bit buffer lives in locals for the whole block; each symbol's
1417        // code and extra bits go out in one write (at most 20 bits for a
1418        // length, 28 for a distance).
1419        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/// Four bytes of `win` at `pos`, little-endian (the window is padded).
1460#[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/// Two bytes of `win` at `pos`.
1468#[inline(always)]
1469fn load16(win: &[u8], pos: usize) -> u16 {
1470    u16::from_le_bytes([win[pos], win[pos + 1]])
1471}
1472
1473/// Hash of the low three bytes of `v` into `32 - shift` bits.
1474#[inline(always)]
1475fn hash3(v: u32, shift: u32) -> usize {
1476    ((v & 0x00FF_FFFF).wrapping_mul(0x9E37_79B1) >> shift) as usize
1477}
1478
1479/// Inserts `pos` into the chains; returns the previous head.
1480#[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/// Bytes in common at `a` and `b` (`a < b`), at most `max`.
1497#[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
1517/// Run-length codes the literal/length lengths `[..hlit]` followed by the
1518/// distance lengths `[..hdist]` with symbols 16 (repeat previous 3 to 6), 17
1519/// (zeros 3 to 10), and 18 (zeros 11 to 138), and counts precode
1520/// frequencies.
1521fn 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}