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/// Level 0 writes a stored block once this much input is waiting (or half
24/// the buffer, for small windows).
25const 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
46/// `LENGTH_CODE[len - 3]`: the length symbol index (0 to 28).
47static 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    // 258 has its own symbol; 257 - 3 = 254 stays in code 27.
59    t[255] = 28;
60    t
61};
62
63/// Distance symbol for `dist - 1` below 256, and for `256 + ((dist - 1) >> 7)`
64/// above (zlib's two-part table).
65static 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
96/// Fixed literal/length code lengths.
97const 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/// Match-finder settings per level (zlib's configuration table).
117#[derive(Clone, Copy)]
118struct Params {
119    /// Shorten the chain search once a match this long is found.
120    good: usize,
121    /// Greedy levels: insert hashes inside matches up to this length. Lazy
122    /// levels: do not look for a better match once one this long is found.
123    lazy: usize,
124    /// Stop searching at a match this long.
125    nice: usize,
126    /// Chain positions searched per match.
127    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/// How far a call should go before returning.
154#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
155#[non_exhaustive]
156pub enum Flush {
157    /// Compress as input allows; output may lag behind input.
158    None,
159    /// Write out everything so far, end on a byte boundary with an empty
160    /// stored block (`00 00 FF FF`). History is kept. WebSocket
161    /// permessage-deflate ends every message this way.
162    Sync,
163    /// As `Sync`, and forget history: later data never refers back across
164    /// this point, so a decoder can start here.
165    Full,
166    /// Write out everything and end the stream with a final block.
167    Finish,
168}
169
170/// Scratch for building one block's codes (about 3 KiB, boxed once).
171struct 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    /// Run-length coded code lengths: (symbol, extra value).
179    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
186/// A streaming raw DEFLATE encoder (RFC 1951).
187///
188/// Push input, pull output, with a [`Flush`] choosing how far each call
189/// goes. Memory is fixed when the deflater is built (section 5.6 of the
190/// plan): at window bits 15 and level 6, a 64 KiB window, 128 KiB of hash
191/// chains, 64 KiB of symbols, and up to one block of pending output.
192///
193/// # Examples
194///
195/// ```
196/// use compress_lib::{Level, deflate::{self, Deflater, Flush}};
197///
198/// let mut deflater = Deflater::new(Level::DEFAULT);
199/// let mut packed = Vec::new();
200/// deflater.compress_vec(b"hello, hello, hello", &mut packed, Flush::Finish)?;
201/// assert_eq!(deflate::decompress(&packed)?, b"hello, hello, hello");
202/// # Ok::<(), compress_lib::Error>(())
203/// ```
204pub struct Deflater {
205    level: u8,
206    params: Params,
207    window_bits: u8,
208    /// Window buffer of `wsize * span` bytes; positions are indices into it.
209    win: Vec<u8>,
210    wsize: usize,
211    /// History always kept before `strstart`, and so the longest distance
212    /// used: the whole window, or 262 bytes less when the buffer is only two
213    /// windows (zlib's MAX_DIST), so positions fit in 16 bits.
214    keep: usize,
215    strstart: usize,
216    lookahead: usize,
217    /// Start of the current block's input in `win` (negative once slid out).
218    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    /// Symbols of the current block: `dist << 16 | litlen`, where a literal
228    /// has `dist == 0` and a match stores `length - 3`.
229    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    /// The flush asked for has been written into `pending`.
239    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    /// A deflater at `level` with window bits 15.
263    ///
264    /// # Examples
265    ///
266    /// ```
267    /// use compress_lib::{Level, deflate::Deflater};
268    ///
269    /// let deflater = Deflater::new(Level::FAST);
270    /// assert_eq!(deflater.level(), Level::FAST);
271    /// ```
272    #[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        // At least 8 KiB of buffer, so small windows still read input in
280        // useful pieces; always a whole number of windows (the hash chains
281        // are indexed modulo the window).
282        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            // One block is at most about four bytes per symbol (fixed codes,
323            // longest extra bits), or the stored form of its input.
324            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    /// Sets the window to `2^bits` bytes, 8 to 15: no match distance is ever
336    /// longer (RFC 7692 negotiates these sizes; 8 is a real 256-byte
337    /// window). Smaller windows also use smaller hash and symbol tables.
338    ///
339    /// # Errors
340    ///
341    /// [`ErrorKind::InvalidWindowBits`] outside 8 to 15.
342    ///
343    /// # Examples
344    ///
345    /// ```
346    /// use compress_lib::{Level, deflate::Deflater};
347    ///
348    /// let small = Deflater::new(Level::FAST).with_window_bits(9)?;
349    /// assert!(small.memory_in_use() < Deflater::new(Level::FAST).memory_in_use());
350    /// assert!(Deflater::new(Level::FAST).with_window_bits(7).is_err());
351    /// # Ok::<(), compress_lib::Error>(())
352    /// ```
353    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    /// The level in force.
361    ///
362    /// # Examples
363    ///
364    /// ```
365    /// use compress_lib::{Level, deflate::Deflater};
366    ///
367    /// assert_eq!(Deflater::default().level(), Level::DEFAULT);
368    /// ```
369    #[must_use]
370    pub fn level(&self) -> Level {
371        Level::new(self.level).unwrap_or(Level::DEFAULT)
372    }
373
374    /// The window size in bits.
375    ///
376    /// # Examples
377    ///
378    /// ```
379    /// assert_eq!(compress_lib::deflate::Deflater::default().window_bits(), 15);
380    /// ```
381    #[must_use]
382    pub fn window_bits(&self) -> u8 {
383        self.window_bits
384    }
385
386    /// Changes the level for data not yet compressed. The current block is
387    /// ended first when the change switches to or from level 0.
388    ///
389    /// # Examples
390    ///
391    /// ```
392    /// use compress_lib::{Level, deflate::{self, Deflater, Flush}};
393    ///
394    /// let mut deflater = Deflater::new(Level::BEST);
395    /// let mut out = Vec::new();
396    /// deflater.compress_vec(b"header ", &mut out, Flush::None)?;
397    /// deflater.set_level(Level::NONE);
398    /// deflater.compress_vec(b"body", &mut out, Flush::Finish)?;
399    /// assert_eq!(deflate::decompress(&out)?, b"header body");
400    /// # Ok::<(), compress_lib::Error>(())
401    /// ```
402    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            // Finish the input waiting under the old level first.
407            self.process(true);
408            self.end_block(false);
409        } else if self.params.lazy_matching && !next.lazy_matching && self.match_available {
410            // Lazy matching holds the byte before `strstart` back; greedy
411            // matching does not know about it.
412            self.literal(self.win[self.strstart - 1]);
413            self.match_available = false;
414            self.block_full();
415        }
416        // No pending match crosses the change.
417        self.match_length = MIN_MATCH - 1;
418        self.prev_length = MIN_MATCH - 1;
419        self.level = level;
420        self.params = next;
421    }
422
423    /// Uncompressed bytes taken since the deflater was built or reset.
424    ///
425    /// # Examples
426    ///
427    /// ```
428    /// use compress_lib::deflate::{Deflater, Flush};
429    ///
430    /// let mut d = Deflater::default();
431    /// d.compress_vec(b"abc", &mut Vec::new(), Flush::Finish)?;
432    /// assert_eq!(d.total_in(), 3);
433    /// # Ok::<(), compress_lib::Error>(())
434    /// ```
435    #[must_use]
436    pub fn total_in(&self) -> u64 {
437        self.total_in
438    }
439
440    /// Compressed bytes handed out since the deflater was built or reset.
441    ///
442    /// # Examples
443    ///
444    /// ```
445    /// use compress_lib::deflate::{Deflater, Flush};
446    ///
447    /// let mut d = Deflater::default();
448    /// let mut out = Vec::new();
449    /// d.compress_vec(b"", &mut out, Flush::Finish)?;
450    /// assert_eq!(d.total_out(), out.len() as u64);
451    /// # Ok::<(), compress_lib::Error>(())
452    /// ```
453    #[must_use]
454    pub fn total_out(&self) -> u64 {
455        self.total_out
456    }
457
458    /// Heap bytes held: window, hash chains, symbols, pending output, and
459    /// block scratch.
460    ///
461    /// # Examples
462    ///
463    /// ```
464    /// let d = compress_lib::deflate::Deflater::default();
465    /// assert!(d.memory_in_use() > 64 * 1024);
466    /// ```
467    #[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    /// Starts a new, unrelated stream, keeping the allocations.
477    ///
478    /// # Examples
479    ///
480    /// ```
481    /// use compress_lib::deflate::{self, Deflater, Flush};
482    ///
483    /// let mut d = Deflater::default();
484    /// let mut a = Vec::new();
485    /// d.compress_vec(b"first", &mut a, Flush::Finish)?;
486    /// d.reset();
487    /// let mut b = Vec::new();
488    /// d.compress_vec(b"second", &mut b, Flush::Finish)?;
489    /// assert_eq!(deflate::decompress(&b)?, b"second");
490    /// # Ok::<(), compress_lib::Error>(())
491    /// ```
492    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    /// Presets the history with `dictionary` (its last `2^window_bits`
512    /// bytes): matches may refer into it. The decoder must be given the same
513    /// dictionary. Only before any input.
514    ///
515    /// # Errors
516    ///
517    /// [`ErrorKind::InvalidState`] after input has been given.
518    ///
519    /// # Examples
520    ///
521    /// ```
522    /// use compress_lib::deflate::{Deflater, Flush, Inflater};
523    ///
524    /// let dict = b"{\"type\":\"update\",\"value\":";
525    /// let mut d = Deflater::default();
526    /// d.set_dictionary(dict)?;
527    /// let mut packed = Vec::new();
528    /// d.compress_vec(b"{\"type\":\"update\",\"value\":42}", &mut packed, Flush::Finish)?;
529    /// let mut i = Inflater::new();
530    /// i.set_dictionary(dict)?;
531    /// let mut out = Vec::new();
532    /// i.finish_vec(&packed, &mut out)?;
533    /// assert_eq!(out, b"{\"type\":\"update\",\"value\":42}");
534    /// # Ok::<(), compress_lib::Error>(())
535    /// ```
536    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        // Position 0 is the hash chains' "none", so the dictionary starts at 1.
543        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    /// Compresses as much of `input` as the window takes and writes
561    /// compressed bytes to `output`.
562    ///
563    /// With `Flush::None` the result is `NeedsInput` once all input is taken
564    /// (output may lag behind), or `NeedsOutput` when `output` is full.
565    /// With a flush, `Done` means all input is taken and the flush point is
566    /// completely in `output`; on `NeedsOutput`, call again with the same
567    /// flush and the input not yet consumed.
568    ///
569    /// # Errors
570    ///
571    /// [`ErrorKind::InvalidState`] when input is given after `Finish`
572    /// completed (call [`reset`](Deflater::reset) for a new stream).
573    ///
574    /// # Examples
575    ///
576    /// ```
577    /// use compress_lib::deflate::{self, Deflater, Flush, Status};
578    ///
579    /// let mut d = Deflater::default();
580    /// let mut out = [0u8; 256];
581    /// let p = d.compress(b"some data", &mut out, Flush::Finish)?;
582    /// assert_eq!(p.status, Status::Done);
583    /// assert_eq!(deflate::decompress(&out[..p.produced])?, b"some data");
584    /// # Ok::<(), compress_lib::Error>(())
585    /// ```
586    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                // Every round takes input or turns lookahead into output; a
629                // round that does neither would repeat forever. Fail closed.
630                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    /// Compresses `input` and appends to `out` until the flush point is
644    /// written (with `Flush::None`, until all input is taken). Returns
645    /// `Done`, or `NeedsInput` for `Flush::None`.
646    ///
647    /// # Errors
648    ///
649    /// As [`compress`](Deflater::compress), plus
650    /// [`ErrorKind::AllocationFailed`] when `out` cannot grow.
651    ///
652    /// # Examples
653    ///
654    /// ```
655    /// use compress_lib::deflate::{self, Deflater, Flush};
656    ///
657    /// let mut d = Deflater::default();
658    /// let mut out = Vec::new();
659    /// d.compress_vec(b"part one, ", &mut out, Flush::None)?;
660    /// d.compress_vec(b"part two", &mut out, Flush::Finish)?;
661    /// assert_eq!(deflate::decompress(&out)?, b"part one, part two");
662    /// # Ok::<(), compress_lib::Error>(())
663    /// ```
664    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    /// Moves pending output into `output[*produced..]`.
702    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    /// Copies input into the window, sliding it first when the lookahead
716    /// would not fit. Returns the bytes taken.
717    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    /// Slides the window down by a whole number of windows, keeping at
734    /// least one window of history before `strstart`.
735    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            // Stored blocks are cut from the window; level 0 writes them
742            // before the data leaves.
743            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        // Positions are below 2^16 and so is the shift; entries that slide
752        // out become 0, "none".
753        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    /// Inserts `pos` into the hash chains; returns the previous head (0 for
768    /// none).
769    #[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    /// The longest match at `strstart` along the chain from `cur`, better
779    /// than `prev_length`; sets `match_start`.
780    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    /// Records a literal. The caller ends the block when the symbol buffer
824    /// is full, once `strstart` covers the symbol's input.
825    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    /// Records a match (see [`literal`](Self::literal)).
831    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    /// Ends the block when the symbol buffer is full.
839    #[inline]
840    fn block_full(&mut self) {
841        if self.syms.len() >= self.sym_cap {
842            self.end_block(false);
843        }
844    }
845
846    /// Turns the lookahead into symbols. Without `flushing`, stops while
847    /// fewer than `MIN_LOOKAHEAD` bytes wait (more input could extend a
848    /// match); with it, uses everything.
849    fn process(&mut self, flushing: bool) {
850        if self.level == 0 {
851            let chunk = STORED_CHUNK.min(self.win.len() / 2);
852            // A window too full to take more input and not yet able to slide
853            // must be written out too, or the stream would stall.
854            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                // The literal is the byte before `strstart`: end the block
942                // before moving on, so the block's input covers it exactly.
943                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    // ---- bit output ----------------------------------------------------
961
962    #[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    /// Writes out whole bytes and pads the last one with zero bits.
975    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                // An empty stored block: header, pad, 00 00 FF FF.
994                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    /// Writes the current block (if it has data, or if it is the last) as
1007    /// the cheapest of stored, fixed, and dynamic.
1008    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        // Every block gets at least two literal/length codes and two
1049        // distance codes, as zlib does, so no decoder meets the one-code
1050        // special case.
1051        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        // Payload bits under each code; extra bits are the same for both.
1067        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        // The forced dummy symbols are counted above but never written: the
1088        // estimate is a few bits high for both codes alike.
1089        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/// Bytes in common at `a` and `b` (`a < b`), at most `max`.
1203#[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
1223/// Run-length codes the literal/length lengths `[..hlit]` followed by the
1224/// distance lengths `[..hdist]` with symbols 16 (repeat previous 3 to 6), 17
1225/// (zeros 3 to 10), and 18 (zeros 11 to 138), and counts precode
1226/// frequencies.
1227fn 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}