compress_lib/inflate/mod.rs
1//! The raw DEFLATE (RFC 1951) decoder.
2//!
3//! Output goes straight into the caller's buffer. Back-references reach
4//! into the output written in the same call, and, further back, into a ring
5//! of `2^window_bits` bytes updated once per call with the newest output, so
6//! a call costs `O(consumed + produced)` however small the buffers are.
7
8pub(crate) mod tables;
9
10use alloc::{boxed::Box, vec::Vec};
11
12use tables::{
13 Alphabet, DIST_ROOT, END_OF_BLOCK, FIXED_DIST, FIXED_LIT, INVALID, LIT_ROOT, LITERAL, PRE_ROOT,
14 SUBTABLE, Tables,
15};
16
17use crate::{Error, ErrorKind, Limits, Progress, Status};
18
19/// Output room the fast loop needs per symbol: the longest match plus an
20/// eight-byte over-copy, rounded up.
21const FAST_OUT: usize = 258 + 16;
22/// Input the fast loop needs per symbol: one eight-byte refill.
23const FAST_IN: usize = 8;
24/// Order in which code-length code lengths are stored (RFC 1951 3.2.7).
25const PRECODE_ORDER: [u8; 19] = [
26 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15,
27];
28/// Most output `decompress_vec` reserves in one step.
29const VEC_CHUNK: usize = 64 << 10;
30
31#[derive(Clone, Copy, Debug, PartialEq, Eq)]
32enum State {
33 /// Waiting for a block header (3 bits).
34 Header,
35 /// Stored block: skip to a byte boundary, then LEN and NLEN.
36 StoredLength,
37 /// Stored block: `stored_left` bytes to copy.
38 Stored,
39 /// Dynamic block: HLIT, HDIST, HCLEN.
40 Counts,
41 /// Dynamic block: code-length code lengths, `index` of `hclen` read.
42 PrecodeLengths,
43 /// Dynamic block: literal/length and distance code lengths, `index` of
44 /// `hlit + hdist` read.
45 CodeLengths,
46 /// Decoding symbols.
47 Data,
48 /// A length was decoded (`pending_len`); its distance comes next.
49 Distance,
50 /// A match is being copied: `pending_len` bytes left at `pending_dist`.
51 Copy,
52 /// The final block ended.
53 Done,
54}
55
56/// Why the decoding loop stopped.
57#[derive(Clone, Copy, PartialEq, Eq)]
58enum Stop {
59 Done,
60 NeedInput,
61 NeedOutput,
62}
63
64/// A streaming raw DEFLATE decoder (RFC 1951).
65///
66/// Push compressed input and pull decompressed output through buffers you
67/// own. Memory is fixed when the inflater is built: the decode tables (about
68/// 11 KiB) and a history window of `2^window_bits` bytes. Every limit in
69/// [`Limits`] is checked before output is written.
70///
71/// # Examples
72///
73/// ```
74/// use compress_lib::deflate::{Inflater, Status};
75///
76/// // "hello" compressed with fixed Huffman codes.
77/// let compressed = [0xCB, 0x48, 0xCD, 0xC9, 0xC9, 0x07, 0x00];
78/// let mut inflater = Inflater::new();
79/// let mut out = [0u8; 64];
80/// let p = inflater.finish(&compressed, &mut out)?;
81/// assert_eq!(p.status, Status::Done);
82/// assert_eq!(&out[..p.produced], b"hello");
83/// # Ok::<(), compress_lib::Error>(())
84/// ```
85pub struct Inflater {
86 limits: Limits,
87 window_bits: u8,
88 /// Keep a history ring across calls (off only for one-shot decoding).
89 keep_history: bool,
90 state: State,
91 final_block: bool,
92 /// The current block uses the fixed codes.
93 fixed: bool,
94 bitbuf: u64,
95 bitcnt: u32,
96 total_in: u64,
97 total_out: u64,
98 failed: Option<Error>,
99 hlit: u16,
100 hdist: u16,
101 hclen: u16,
102 index: u16,
103 stored_left: u32,
104 pending_len: u32,
105 pending_dist: u32,
106 tables: Box<Tables>,
107 /// History ring: the newest `whave` bytes end just before `wpos`.
108 ring: Vec<u8>,
109 wpos: usize,
110 whave: usize,
111}
112
113impl core::fmt::Debug for Inflater {
114 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
115 f.debug_struct("Inflater")
116 .field("window_bits", &self.window_bits)
117 .field("limits", &self.limits)
118 .field("state", &self.state)
119 .field("total_in", &self.total_in)
120 .field("total_out", &self.total_out)
121 .field("failed", &self.failed)
122 .finish_non_exhaustive()
123 }
124}
125
126impl Default for Inflater {
127 fn default() -> Self {
128 Self::new()
129 }
130}
131
132/// Copies `n` bytes from `buf[src..]` to `buf[dst..]` front to back, so an
133/// overlapping source repeats its pattern (LZ77 semantics). `src < dst`.
134#[inline(always)]
135fn copy_forward(buf: &mut [u8], src: usize, dst: usize, n: usize) {
136 let dist = dst - src;
137 if dist >= n {
138 buf.copy_within(src..src + n, dst);
139 } else if dist == 1 {
140 let b = buf[src];
141 buf[dst..dst + n].fill(b);
142 } else {
143 // `buf[src..dst]` repeats with period `dist`; every copy doubles it.
144 let mut done = 0;
145 while done < n {
146 let chunk = (dist + done).min(n - done);
147 buf.copy_within(src..src + chunk, dst + done);
148 done += chunk;
149 }
150 }
151}
152
153impl Inflater {
154 /// An inflater with window bits 15 and the default [`Limits`].
155 ///
156 /// # Examples
157 ///
158 /// ```
159 /// let inflater = compress_lib::deflate::Inflater::new();
160 /// assert_eq!(inflater.window_bits(), 15);
161 /// ```
162 #[must_use]
163 pub fn new() -> Self {
164 let mut inflater = Self::without_history(Limits::new());
165 inflater.keep_history = true;
166 inflater.ring = alloc::vec![0; 1 << 15];
167 inflater
168 }
169
170 /// An inflater that keeps no history between calls: for one-shot
171 /// decoding, where all output lands in one buffer.
172 pub(crate) fn without_history(limits: Limits) -> Self {
173 Self {
174 limits,
175 window_bits: 15,
176 keep_history: false,
177 state: State::Header,
178 final_block: false,
179 fixed: false,
180 bitbuf: 0,
181 bitcnt: 0,
182 total_in: 0,
183 total_out: 0,
184 failed: None,
185 hlit: 0,
186 hdist: 0,
187 hclen: 0,
188 index: 0,
189 stored_left: 0,
190 pending_len: 0,
191 pending_dist: 0,
192 tables: Box::new(Tables::new()),
193 ring: Vec::new(),
194 wpos: 0,
195 whave: 0,
196 }
197 }
198
199 /// Sets the window size to `2^bits` bytes, 8 to 15. A back-reference
200 /// further than the window is `DistanceTooFar` (RFC 7692 negotiates
201 /// these sizes). Memory: the window shrinks with it.
202 ///
203 /// # Errors
204 ///
205 /// [`ErrorKind::InvalidWindowBits`] outside 8 to 15.
206 ///
207 /// # Examples
208 ///
209 /// ```
210 /// use compress_lib::deflate::Inflater;
211 ///
212 /// let inflater = Inflater::new().with_window_bits(9)?;
213 /// assert_eq!(inflater.window_bits(), 9);
214 /// assert!(Inflater::new().with_window_bits(16).is_err());
215 /// # Ok::<(), compress_lib::Error>(())
216 /// ```
217 pub fn with_window_bits(mut self, bits: u8) -> Result<Self, Error> {
218 if !(8..=15).contains(&bits) {
219 return Err(Error::config(ErrorKind::InvalidWindowBits));
220 }
221 self.window_bits = bits;
222 if self.keep_history {
223 self.ring = alloc::vec![0; 1 << bits];
224 }
225 self.reset();
226 Ok(self)
227 }
228
229 /// Sets the limits checked while decoding.
230 ///
231 /// # Examples
232 ///
233 /// ```
234 /// use compress_lib::{Limits, deflate::Inflater};
235 ///
236 /// let inflater = Inflater::new().with_limits(Limits::new().with_max_output(1 << 20));
237 /// assert_eq!(inflater.limits().max_output(), 1 << 20);
238 /// ```
239 #[must_use]
240 pub fn with_limits(mut self, limits: Limits) -> Self {
241 self.limits = limits;
242 self
243 }
244
245 /// The window size in bits.
246 ///
247 /// # Examples
248 ///
249 /// ```
250 /// assert_eq!(compress_lib::deflate::Inflater::new().window_bits(), 15);
251 /// ```
252 #[must_use]
253 pub fn window_bits(&self) -> u8 {
254 self.window_bits
255 }
256
257 /// The limits in force.
258 ///
259 /// # Examples
260 ///
261 /// ```
262 /// use compress_lib::{Limits, deflate::Inflater};
263 ///
264 /// assert_eq!(Inflater::new().limits(), Limits::new());
265 /// ```
266 #[must_use]
267 pub fn limits(&self) -> Limits {
268 self.limits
269 }
270
271 /// `true` once the final block has ended.
272 ///
273 /// # Examples
274 ///
275 /// ```
276 /// use compress_lib::deflate::Inflater;
277 ///
278 /// let mut inflater = Inflater::new();
279 /// assert!(!inflater.is_done());
280 /// inflater.finish(&[0x03, 0x00], &mut [])?; // an empty stream
281 /// assert!(inflater.is_done());
282 /// # Ok::<(), compress_lib::Error>(())
283 /// ```
284 #[must_use]
285 pub fn is_done(&self) -> bool {
286 self.state == State::Done
287 }
288
289 /// Compressed bytes consumed since the inflater was built or reset.
290 ///
291 /// # Examples
292 ///
293 /// ```
294 /// use compress_lib::deflate::Inflater;
295 ///
296 /// let mut inflater = Inflater::new();
297 /// inflater.finish(&[0x03, 0x00], &mut [])?;
298 /// assert_eq!(inflater.total_in(), 2);
299 /// # Ok::<(), compress_lib::Error>(())
300 /// ```
301 #[must_use]
302 pub fn total_in(&self) -> u64 {
303 self.total_in
304 }
305
306 /// Decompressed bytes produced since the inflater was built or reset.
307 ///
308 /// # Examples
309 ///
310 /// ```
311 /// use compress_lib::deflate::Inflater;
312 ///
313 /// let mut inflater = Inflater::new();
314 /// let mut out = [0u8; 8];
315 /// inflater.finish(&[0xCB, 0x48, 0xCD, 0xC9, 0xC9, 0x07, 0x00], &mut out)?;
316 /// assert_eq!(inflater.total_out(), 5);
317 /// # Ok::<(), compress_lib::Error>(())
318 /// ```
319 #[must_use]
320 pub fn total_out(&self) -> u64 {
321 self.total_out
322 }
323
324 /// Heap bytes this inflater holds: the tables and the window.
325 ///
326 /// # Examples
327 ///
328 /// ```
329 /// use compress_lib::deflate::Inflater;
330 ///
331 /// let small = Inflater::new().with_window_bits(9)?;
332 /// assert!(small.memory_in_use() < Inflater::new().memory_in_use());
333 /// # Ok::<(), compress_lib::Error>(())
334 /// ```
335 #[must_use]
336 pub fn memory_in_use(&self) -> usize {
337 core::mem::size_of::<Tables>() + self.ring.capacity()
338 }
339
340 /// Forgets the stream and its history, keeping the allocations, so the
341 /// inflater can decode an unrelated stream.
342 ///
343 /// # Examples
344 ///
345 /// ```
346 /// use compress_lib::deflate::Inflater;
347 ///
348 /// let mut inflater = Inflater::new();
349 /// inflater.finish(&[0x03, 0x00], &mut [])?;
350 /// inflater.reset();
351 /// assert!(!inflater.is_done());
352 /// assert_eq!(inflater.total_in(), 0);
353 /// # Ok::<(), compress_lib::Error>(())
354 /// ```
355 pub fn reset(&mut self) {
356 self.state = State::Header;
357 self.final_block = false;
358 self.fixed = false;
359 self.bitbuf = 0;
360 self.bitcnt = 0;
361 self.total_in = 0;
362 self.total_out = 0;
363 self.failed = None;
364 self.wpos = 0;
365 self.whave = 0;
366 }
367
368 /// After `Done`, starts a new DEFLATE stream that keeps the window, so
369 /// the next stream may refer back into this one. This is RFC 7692 context
370 /// takeover after a message that ended with a final block.
371 ///
372 /// # Errors
373 ///
374 /// [`ErrorKind::InvalidState`] before the current stream is done.
375 ///
376 /// # Examples
377 ///
378 /// ```
379 /// use compress_lib::deflate::Inflater;
380 ///
381 /// let mut inflater = Inflater::new();
382 /// let mut out = Vec::new();
383 /// inflater.finish_vec(&[0x03, 0x00], &mut out)?;
384 /// inflater.next_stream()?;
385 /// inflater.finish_vec(&[0x03, 0x00], &mut out)?;
386 /// # Ok::<(), compress_lib::Error>(())
387 /// ```
388 pub fn next_stream(&mut self) -> Result<(), Error> {
389 if self.state != State::Done {
390 return Err(Error::config(ErrorKind::InvalidState));
391 }
392 self.state = State::Header;
393 self.final_block = false;
394 self.bitbuf = 0;
395 self.bitcnt = 0;
396 Ok(())
397 }
398
399 /// Presets the history with `dictionary` (its last `2^window_bits`
400 /// bytes), for streams compressed with the same preset dictionary. Only
401 /// before any input.
402 ///
403 /// # Errors
404 ///
405 /// [`ErrorKind::InvalidState`] after input has been given.
406 ///
407 /// # Examples
408 ///
409 /// ```
410 /// use compress_lib::deflate::Inflater;
411 ///
412 /// let mut inflater = Inflater::new();
413 /// inflater.set_dictionary(b"common prefix")?;
414 /// # Ok::<(), compress_lib::Error>(())
415 /// ```
416 pub fn set_dictionary(&mut self, dictionary: &[u8]) -> Result<(), Error> {
417 if self.total_in != 0 || self.state != State::Header || self.failed.is_some() {
418 return Err(Error::config(ErrorKind::InvalidState));
419 }
420 if self.ring.is_empty() {
421 self.ring = alloc::vec![0; 1 << self.window_bits];
422 self.keep_history = true;
423 }
424 self.save_history(dictionary);
425 Ok(())
426 }
427
428 /// Decompresses as much of `input` into `output` as fits. More input may
429 /// follow in later calls.
430 ///
431 /// Returns how much input was consumed, how much output was produced,
432 /// and the [`Status`]: `NeedsInput` (all input consumed, the stream goes
433 /// on), `NeedsOutput` (output is full; call again with more room and the
434 /// rest of the input), or `Done` (the final block ended; `consumed`
435 /// stops at the stream's last byte, so trailing data stays with the
436 /// caller).
437 ///
438 /// # Errors
439 ///
440 /// Any decoding error of [`ErrorKind`], or `OutputLimit` / `RatioLimit`
441 /// when a limit stops the stream. After an error every call returns the
442 /// same error until [`reset`](Inflater::reset).
443 ///
444 /// # Examples
445 ///
446 /// ```
447 /// use compress_lib::deflate::{Inflater, Status};
448 ///
449 /// let compressed = [0xCB, 0x48, 0xCD, 0xC9, 0xC9, 0x07, 0x00];
450 /// let mut inflater = Inflater::new();
451 /// let mut out = Vec::new();
452 /// let mut buf = [0u8; 2]; // tiny on purpose
453 /// let mut input = &compressed[..];
454 /// loop {
455 /// let p = inflater.decompress(input, &mut buf)?;
456 /// input = &input[p.consumed..];
457 /// out.extend_from_slice(&buf[..p.produced]);
458 /// if p.status == Status::Done {
459 /// break;
460 /// }
461 /// }
462 /// assert_eq!(out, b"hello");
463 /// # Ok::<(), compress_lib::Error>(())
464 /// ```
465 pub fn decompress(&mut self, input: &[u8], output: &mut [u8]) -> Result<Progress, Error> {
466 self.run_slice(input, output, false)
467 }
468
469 /// As [`decompress`](Inflater::decompress), with `input` the last of the
470 /// stream: if the stream is unfinished once input runs out, the result
471 /// is `UnexpectedEnd` (unless output was full first, which is
472 /// `NeedsOutput`).
473 ///
474 /// # Errors
475 ///
476 /// As `decompress`, plus [`ErrorKind::UnexpectedEnd`].
477 ///
478 /// # Examples
479 ///
480 /// ```
481 /// use compress_lib::{ErrorKind, deflate::Inflater};
482 ///
483 /// let truncated = [0xCB, 0x48, 0xCD];
484 /// let mut out = [0u8; 16];
485 /// let err = Inflater::new().finish(&truncated, &mut out).unwrap_err();
486 /// assert_eq!(err.kind(), ErrorKind::UnexpectedEnd);
487 /// ```
488 pub fn finish(&mut self, input: &[u8], output: &mut [u8]) -> Result<Progress, Error> {
489 self.run_slice(input, output, true)
490 }
491
492 /// Decompresses `input`, appending to `out`, growing it as needed but
493 /// never past the output cap. Growth doubles what this call has
494 /// produced (at least 64 KiB at a time), so peak memory is at most 1.5
495 /// times `max_output` while a reallocation holds the old buffer and the
496 /// new one. Returns `NeedsInput` or `Done`.
497 ///
498 /// # Errors
499 ///
500 /// As [`decompress`](Inflater::decompress), plus
501 /// [`ErrorKind::AllocationFailed`] when the vector cannot grow.
502 ///
503 /// # Examples
504 ///
505 /// ```
506 /// use compress_lib::deflate::{Inflater, Status};
507 ///
508 /// let mut out = Vec::new();
509 /// let p = Inflater::new().decompress_vec(&[0xCB, 0x48, 0xCD, 0xC9, 0xC9, 0x07, 0x00], &mut out)?;
510 /// assert_eq!(p.status, Status::Done);
511 /// assert_eq!(out, b"hello");
512 /// # Ok::<(), compress_lib::Error>(())
513 /// ```
514 pub fn decompress_vec(&mut self, input: &[u8], out: &mut Vec<u8>) -> Result<Progress, Error> {
515 self.run_vec(input, out, false)
516 }
517
518 /// As [`decompress_vec`](Inflater::decompress_vec), with `input` the last
519 /// of the stream: an unfinished stream is `UnexpectedEnd`.
520 ///
521 /// # Errors
522 ///
523 /// As `decompress_vec`, plus [`ErrorKind::UnexpectedEnd`].
524 ///
525 /// # Examples
526 ///
527 /// ```
528 /// use compress_lib::deflate::Inflater;
529 ///
530 /// let mut out = Vec::new();
531 /// Inflater::new().finish_vec(&[0x03, 0x00], &mut out)?;
532 /// assert!(out.is_empty());
533 /// # Ok::<(), compress_lib::Error>(())
534 /// ```
535 pub fn finish_vec(&mut self, input: &[u8], out: &mut Vec<u8>) -> Result<Progress, Error> {
536 self.run_vec(input, out, true)
537 }
538
539 fn run_slice(
540 &mut self,
541 input: &[u8],
542 output: &mut [u8],
543 last: bool,
544 ) -> Result<Progress, Error> {
545 let (consumed, produced, status) = self.run(input, output, 0, last)?;
546 if self.keep_history {
547 self.save_history(&output[..produced]);
548 }
549 Ok(Progress::new(consumed, produced, status))
550 }
551
552 fn run_vec(&mut self, input: &[u8], out: &mut Vec<u8>, last: bool) -> Result<Progress, Error> {
553 let start = out.len();
554 let mut consumed = 0;
555 let status = loop {
556 let have = out.len();
557 let made = have - start;
558 let cap_room = usize::try_from(self.limits.max_output().saturating_sub(self.total_out))
559 .unwrap_or(usize::MAX);
560 // Room offered per step: geometric (at least what this call has
561 // produced) but at most 64 KiB ahead of it, and never past the cap.
562 let want = cap_room.min(VEC_CHUNK.max(made));
563 if out.capacity() - have < want && out.try_reserve_exact(want).is_err() {
564 return Err(self.fail(ErrorKind::AllocationFailed, 0));
565 }
566 let room = (out.capacity() - have).min(want);
567 out.resize(have + room, 0);
568 match self.run(&input[consumed..], &mut out[start..], made, last) {
569 Ok((c, p, status)) => {
570 out.truncate(have + p);
571 consumed += c;
572 if status != Status::NeedsOutput {
573 break status;
574 }
575 }
576 Err(e) => {
577 out.truncate(have);
578 return Err(e);
579 }
580 }
581 };
582 if self.keep_history {
583 self.save_history(&out[start..]);
584 }
585 Ok(Progress::new(consumed, out.len() - start, status))
586 }
587
588 /// Records `newest` (this call's output) in the history ring.
589 fn save_history(&mut self, newest: &[u8]) {
590 let size = self.ring.len();
591 if size == 0 || newest.is_empty() {
592 return;
593 }
594 if newest.len() >= size {
595 self.ring.copy_from_slice(&newest[newest.len() - size..]);
596 self.wpos = 0;
597 self.whave = size;
598 return;
599 }
600 let first = (size - self.wpos).min(newest.len());
601 self.ring[self.wpos..self.wpos + first].copy_from_slice(&newest[..first]);
602 let rest = newest.len() - first;
603 self.ring[..rest].copy_from_slice(&newest[first..]);
604 self.wpos = (self.wpos + newest.len()) & (size - 1);
605 self.whave = (self.whave + newest.len()).min(size);
606 }
607
608 /// Marks the inflater failed with `kind` at the current input position.
609 fn fail(&mut self, kind: ErrorKind, ip: usize) -> Error {
610 let offset = (self.total_in + ip as u64).saturating_sub(u64::from(self.bitcnt / 8));
611 let e = Error::new(kind, offset);
612 self.failed = Some(e);
613 e
614 }
615
616 /// Decodes into `buf[op_start..]`, with `buf[..op_start]` already-valid
617 /// output of this stream (history). Returns (consumed, produced, status).
618 fn run(
619 &mut self,
620 input: &[u8],
621 buf: &mut [u8],
622 op_start: usize,
623 last: bool,
624 ) -> Result<(usize, usize, Status), Error> {
625 if let Some(e) = self.failed {
626 return Err(e);
627 }
628 let mut ip = 0;
629 let mut op = op_start;
630 let stop = loop {
631 let cap_room = self
632 .limits
633 .max_output()
634 .saturating_sub(self.total_out + (op - op_start) as u64);
635 let cap_end = op
636 + usize::try_from(cap_room)
637 .unwrap_or(usize::MAX)
638 .min(buf.len() - op);
639 let mut end = cap_end;
640 if self.limits.max_ratio() != 0 {
641 let taken = self.total_in + ip as u64;
642 let allowed = taken
643 .saturating_mul(u64::from(self.limits.max_ratio()))
644 .max(self.limits.ratio_floor());
645 let ratio_room = allowed.saturating_sub(self.total_out + (op - op_start) as u64);
646 end = end.min(op + usize::try_from(ratio_room).unwrap_or(usize::MAX));
647 }
648 let before = (ip, op);
649 let stop = match self.step(input, &mut ip, buf, &mut op, end) {
650 Ok(stop) => stop,
651 Err(kind) => {
652 self.total_out += (op - op_start) as u64;
653 return Err(self.fail(kind, ip));
654 }
655 };
656 if stop != Stop::NeedOutput {
657 break stop;
658 }
659 // More output is pending: past the cap that is the end, whatever
660 // room the caller gave.
661 if op == cap_end && cap_room == (op - before.1) as u64 {
662 self.total_out += (op - op_start) as u64;
663 return Err(self.fail(ErrorKind::OutputLimit, ip));
664 }
665 if op == buf.len() {
666 break stop;
667 }
668 // Stopped at the ratio bound. More input taken since raises it;
669 // if nothing moved, the ratio is exceeded.
670 if (ip, op) == before && op == end {
671 self.total_out += (op - op_start) as u64;
672 return Err(self.fail(ErrorKind::RatioLimit, ip));
673 }
674 };
675
676 let produced = op - op_start;
677 self.total_out += produced as u64;
678 if stop == Stop::NeedInput && last {
679 self.total_in += ip as u64;
680 return Err(self.fail(ErrorKind::UnexpectedEnd, 0));
681 }
682 // Give back whole bytes the bit buffer read ahead, so `consumed`
683 // stops at the last bit used (after `Done`, trailing data stays with
684 // the caller). On `NeedsInput` every buffered bit belongs to the
685 // pending symbol, and all input counts as consumed.
686 if stop != Stop::NeedInput {
687 let give = ((self.bitcnt / 8) as usize).min(ip);
688 ip -= give;
689 self.bitcnt -= 8 * give as u32;
690 }
691 self.bitbuf &= (1u64 << self.bitcnt) - 1;
692 if stop == Stop::Done {
693 self.bitbuf = 0;
694 self.bitcnt = 0;
695 }
696 self.total_in += ip as u64;
697 let status = match stop {
698 Stop::Done => Status::Done,
699 Stop::NeedInput => Status::NeedsInput,
700 Stop::NeedOutput => Status::NeedsOutput,
701 };
702 Ok((ip, produced, status))
703 }
704
705 /// Pulls bytes into the bit buffer until it holds `n` bits. `false` when
706 /// input runs out first.
707 #[inline]
708 fn need(&mut self, n: u32, input: &[u8], ip: &mut usize) -> bool {
709 while self.bitcnt < n {
710 if *ip >= input.len() {
711 return false;
712 }
713 self.bitbuf |= u64::from(input[*ip]) << self.bitcnt;
714 self.bitcnt += 8;
715 *ip += 1;
716 }
717 true
718 }
719
720 #[inline]
721 fn bits(&self, n: u32) -> u32 {
722 (self.bitbuf & ((1u64 << n) - 1)) as u32
723 }
724
725 #[inline]
726 fn consume(&mut self, n: u32) {
727 self.bitbuf >>= n;
728 self.bitcnt -= n;
729 }
730
731 /// Looks up the next symbol in `table`, pulling bytes one at a time
732 /// until the entry's bits are buffered. Returns the entry with the bits
733 /// to consume, or `None` when input runs out first (nothing consumed).
734 fn peek(&mut self, table: Which, input: &[u8], ip: &mut usize) -> Option<(u32, u32)> {
735 loop {
736 let (t, root): (&[u32], u32) = match table {
737 Which::Lit if self.fixed => (&FIXED_LIT, LIT_ROOT),
738 Which::Lit => (&self.tables.lit, LIT_ROOT),
739 Which::Dist if self.fixed => (&FIXED_DIST, DIST_ROOT),
740 Which::Dist => (&self.tables.dist, DIST_ROOT),
741 Which::Pre => (&self.tables.pre, PRE_ROOT),
742 };
743 let mut e = t[(self.bitbuf & ((1u64 << root) - 1)) as usize];
744 let mut skip = 0;
745 if e & SUBTABLE != 0 {
746 let bits = (e >> 8) & 0xF;
747 let index = ((self.bitbuf >> root) & ((1u64 << bits) - 1)) as usize;
748 e = t[(e >> 16) as usize + index];
749 skip = root;
750 }
751 let needed = skip + (e & 0xFF);
752 if self.bitcnt >= needed {
753 return Some((e, skip));
754 }
755 if *ip >= input.len() {
756 return None;
757 }
758 self.bitbuf |= u64::from(input[*ip]) << self.bitcnt;
759 self.bitcnt += 8;
760 *ip += 1;
761 }
762 }
763
764 /// The state that follows the end of a block.
765 fn end_block(&mut self) -> State {
766 if self.final_block {
767 State::Done
768 } else {
769 State::Header
770 }
771 }
772
773 /// Checks a distance against the window and the history available with
774 /// `in_buf` bytes of this stream's output before the write position.
775 #[inline]
776 fn check_distance(&self, dist: usize, in_buf: usize) -> Result<(), ErrorKind> {
777 if dist > (1usize << self.window_bits) || (dist > in_buf && dist - in_buf > self.whave) {
778 Err(ErrorKind::DistanceTooFar)
779 } else {
780 Ok(())
781 }
782 }
783
784 /// Copies `n` bytes of a match at `dist` to `buf[op..]`; the part before
785 /// `buf[0]` comes from the history ring. The distance was checked.
786 fn copy_match(&self, buf: &mut [u8], op: usize, dist: usize, n: usize) {
787 if dist <= op {
788 copy_forward(buf, op - dist, op, n);
789 return;
790 }
791 let back = dist - op;
792 let from_ring = back.min(n);
793 let size = self.ring.len();
794 let mut r = (self.wpos + size - back) & (size - 1);
795 let mut o = op;
796 let mut left = from_ring;
797 while left > 0 {
798 let run = left.min(size - r);
799 buf[o..o + run].copy_from_slice(&self.ring[r..r + run]);
800 o += run;
801 left -= run;
802 r = (r + run) & (size - 1);
803 }
804 if n > from_ring {
805 // The rest of the match starts at buf[0].
806 copy_forward(buf, 0, o, n - from_ring);
807 }
808 }
809
810 /// Runs the state machine until it stops for input, output, or the end.
811 fn step(
812 &mut self,
813 input: &[u8],
814 ip: &mut usize,
815 buf: &mut [u8],
816 op: &mut usize,
817 end: usize,
818 ) -> Result<Stop, ErrorKind> {
819 loop {
820 match self.state {
821 State::Header => {
822 if !self.need(3, input, ip) {
823 return Ok(Stop::NeedInput);
824 }
825 self.final_block = self.bits(1) == 1;
826 let kind = (self.bitbuf >> 1) & 3;
827 self.consume(3);
828 self.state = match kind {
829 0 => State::StoredLength,
830 1 => {
831 self.fixed = true;
832 State::Data
833 }
834 2 => State::Counts,
835 _ => return Err(ErrorKind::InvalidBlockType),
836 };
837 }
838 State::StoredLength => {
839 let pad = self.bitcnt % 8;
840 self.consume(pad);
841 if !self.need(32, input, ip) {
842 return Ok(Stop::NeedInput);
843 }
844 let len = self.bits(16);
845 let nlen = (self.bitbuf >> 16) as u32 & 0xFFFF;
846 if len != !nlen & 0xFFFF {
847 return Err(ErrorKind::InvalidStoredLength);
848 }
849 self.consume(32);
850 self.stored_left = len;
851 self.state = State::Stored;
852 }
853 State::Stored => {
854 while self.stored_left > 0 {
855 if *op >= end {
856 return Ok(Stop::NeedOutput);
857 }
858 if self.bitcnt >= 8 {
859 buf[*op] = self.bits(8) as u8;
860 self.consume(8);
861 *op += 1;
862 self.stored_left -= 1;
863 } else if *ip < input.len() {
864 let n = (self.stored_left as usize)
865 .min(input.len() - *ip)
866 .min(end - *op);
867 buf[*op..*op + n].copy_from_slice(&input[*ip..*ip + n]);
868 *op += n;
869 *ip += n;
870 self.stored_left -= n as u32;
871 } else {
872 return Ok(Stop::NeedInput);
873 }
874 }
875 self.state = self.end_block();
876 }
877 State::Counts => {
878 if !self.need(14, input, ip) {
879 return Ok(Stop::NeedInput);
880 }
881 self.hlit = self.bits(5) as u16 + 257;
882 self.hdist = (self.bitbuf >> 5) as u16 & 0x1F;
883 self.hdist += 1;
884 self.hclen = (self.bitbuf >> 10) as u16 & 0xF;
885 self.hclen += 4;
886 self.consume(14);
887 if self.hlit > 286 || self.hdist > 30 {
888 return Err(ErrorKind::InvalidCodeLengths);
889 }
890 self.tables.lens[..19].fill(0);
891 self.index = 0;
892 self.state = State::PrecodeLengths;
893 }
894 State::PrecodeLengths => {
895 while self.index < self.hclen {
896 if !self.need(3, input, ip) {
897 return Ok(Stop::NeedInput);
898 }
899 let slot = PRECODE_ORDER[self.index as usize] as usize;
900 self.tables.lens[slot] = self.bits(3) as u8;
901 self.consume(3);
902 self.index += 1;
903 }
904 let t = &mut *self.tables;
905 tables::build(
906 &t.lens[..19],
907 &mut t.pre,
908 PRE_ROOT,
909 Alphabet::Precode,
910 false,
911 )?;
912 self.index = 0;
913 self.state = State::CodeLengths;
914 }
915 State::CodeLengths => {
916 let total = self.hlit + self.hdist;
917 while self.index < total {
918 let Some((e, _)) = self.peek(Which::Pre, input, ip) else {
919 return Ok(Stop::NeedInput);
920 };
921 let symbol = e >> 16;
922 let len = e & 0xFF;
923 if symbol < 16 {
924 self.consume(len);
925 self.tables.lens[self.index as usize] = symbol as u8;
926 self.index += 1;
927 continue;
928 }
929 let (extra, base) = match symbol {
930 16 => (2, 3),
931 17 => (3, 3),
932 _ => (7, 11),
933 };
934 if !self.need(len + extra, input, ip) {
935 return Ok(Stop::NeedInput);
936 }
937 let repeat = base + ((self.bitbuf >> len) as u32 & ((1 << extra) - 1));
938 let value = if symbol == 16 {
939 if self.index == 0 {
940 return Err(ErrorKind::InvalidCodeLengths);
941 }
942 self.tables.lens[self.index as usize - 1]
943 } else {
944 0
945 };
946 if u32::from(self.index) + repeat > u32::from(total) {
947 return Err(ErrorKind::InvalidCodeLengths);
948 }
949 self.consume(len + extra);
950 let i = self.index as usize;
951 self.tables.lens[i..i + repeat as usize].fill(value);
952 self.index += repeat as u16;
953 }
954 let (hlit, hdist) = (self.hlit as usize, self.hdist as usize);
955 let t = &mut *self.tables;
956 if t.lens[256] == 0 {
957 return Err(ErrorKind::InvalidCodeLengths);
958 }
959 tables::build(
960 &t.lens[..hlit],
961 &mut t.lit,
962 LIT_ROOT,
963 Alphabet::LitLen,
964 true,
965 )?;
966 tables::build(
967 &t.lens[hlit..hlit + hdist],
968 &mut t.dist,
969 DIST_ROOT,
970 Alphabet::Dist,
971 true,
972 )?;
973 self.fixed = false;
974 self.state = State::Data;
975 }
976 State::Data => {
977 if input.len() - *ip >= FAST_IN && end - *op >= FAST_OUT {
978 self.fast(input, ip, buf, op, end)?;
979 continue;
980 }
981 let Some((e, skip)) = self.peek(Which::Lit, input, ip) else {
982 return Ok(Stop::NeedInput);
983 };
984 if e & LITERAL != 0 {
985 if *op >= end {
986 return Ok(Stop::NeedOutput);
987 }
988 self.consume(skip + (e & 0xFF));
989 buf[*op] = (e >> 16) as u8;
990 *op += 1;
991 } else if e & END_OF_BLOCK != 0 {
992 self.consume(skip + (e & 0xFF));
993 self.state = self.end_block();
994 } else if e & INVALID != 0 {
995 return Err(ErrorKind::InvalidSymbol);
996 } else {
997 let code = skip + ((e >> 8) & 0xF);
998 let extra = (e & 0xFF) - ((e >> 8) & 0xF);
999 let value = (self.bitbuf >> code) as u32 & ((1 << extra) - 1);
1000 self.consume(skip + (e & 0xFF));
1001 self.pending_len = (e >> 16) + value;
1002 self.state = State::Distance;
1003 }
1004 }
1005 State::Distance => {
1006 let Some((e, skip)) = self.peek(Which::Dist, input, ip) else {
1007 return Ok(Stop::NeedInput);
1008 };
1009 if e & INVALID != 0 {
1010 return Err(ErrorKind::InvalidSymbol);
1011 }
1012 let code = skip + ((e >> 8) & 0xF);
1013 let extra = (e & 0xFF) - ((e >> 8) & 0xF);
1014 let value = (self.bitbuf >> code) as u32 & ((1 << extra) - 1);
1015 let dist = (e >> 16) + value;
1016 self.check_distance(dist as usize, *op)?;
1017 self.consume(skip + (e & 0xFF));
1018 self.pending_dist = dist;
1019 self.state = State::Copy;
1020 }
1021 State::Copy => {
1022 let n = (self.pending_len as usize).min(end - *op);
1023 if n > 0 {
1024 self.copy_match(buf, *op, self.pending_dist as usize, n);
1025 *op += n;
1026 self.pending_len -= n as u32;
1027 }
1028 if self.pending_len > 0 {
1029 return Ok(Stop::NeedOutput);
1030 }
1031 self.state = State::Data;
1032 }
1033 State::Done => return Ok(Stop::Done),
1034 }
1035 }
1036 }
1037
1038 /// The fast loop: decodes symbols while at least `FAST_IN` input bytes
1039 /// and `FAST_OUT` output bytes remain, with one eight-byte refill per
1040 /// symbol and no state saved between symbols. Returns at the end of the
1041 /// block or when the margins run out; the slow path does the rest.
1042 fn fast(
1043 &mut self,
1044 input: &[u8],
1045 ip: &mut usize,
1046 buf: &mut [u8],
1047 op: &mut usize,
1048 end: usize,
1049 ) -> Result<(), ErrorKind> {
1050 let (lit, dist): (&[u32], &[u32]) = if self.fixed {
1051 (&FIXED_LIT, &FIXED_DIST)
1052 } else {
1053 (&self.tables.lit, &self.tables.dist)
1054 };
1055 let window = 1usize << self.window_bits;
1056 let mut bitbuf = self.bitbuf;
1057 let mut bitcnt = self.bitcnt;
1058 let mut i = *ip;
1059 let mut o = *op;
1060 let result = loop {
1061 if input.len() - i < FAST_IN || end - o < FAST_OUT {
1062 break Ok(());
1063 }
1064 let mut word = [0u8; 8];
1065 word.copy_from_slice(&input[i..i + 8]);
1066 bitbuf |= u64::from_le_bytes(word) << bitcnt;
1067 i += ((63 - bitcnt) >> 3) as usize;
1068 bitcnt |= 56;
1069
1070 let mut e = lit[(bitbuf & ((1 << LIT_ROOT) - 1)) as usize];
1071 if e & SUBTABLE != 0 {
1072 bitbuf >>= LIT_ROOT;
1073 bitcnt -= LIT_ROOT;
1074 e = lit[(e >> 16) as usize + (bitbuf & ((1u64 << ((e >> 8) & 0xF)) - 1)) as usize];
1075 }
1076 if e & LITERAL != 0 {
1077 buf[o] = (e >> 16) as u8;
1078 o += 1;
1079 bitbuf >>= e & 0xFF;
1080 bitcnt -= e & 0xFF;
1081 // A second literal often fits in the same refill.
1082 let e2 = lit[(bitbuf & ((1 << LIT_ROOT) - 1)) as usize];
1083 if e2 & LITERAL != 0 && bitcnt >= (e2 & 0xFF) {
1084 buf[o] = (e2 >> 16) as u8;
1085 o += 1;
1086 bitbuf >>= e2 & 0xFF;
1087 bitcnt -= e2 & 0xFF;
1088 }
1089 continue;
1090 }
1091 if e & (END_OF_BLOCK | INVALID) != 0 {
1092 if e & END_OF_BLOCK != 0 {
1093 bitbuf >>= e & 0xFF;
1094 bitcnt -= e & 0xFF;
1095 self.state = if self.final_block {
1096 State::Done
1097 } else {
1098 State::Header
1099 };
1100 break Ok(());
1101 }
1102 break Err(ErrorKind::InvalidSymbol);
1103 }
1104 let code = (e >> 8) & 0xF;
1105 let length = (e >> 16) as usize
1106 + ((bitbuf >> code) & ((1u64 << ((e & 0xFF) - code)) - 1)) as usize;
1107 bitbuf >>= e & 0xFF;
1108 bitcnt -= e & 0xFF;
1109
1110 let mut d = dist[(bitbuf & ((1 << DIST_ROOT) - 1)) as usize];
1111 if d & SUBTABLE != 0 {
1112 bitbuf >>= DIST_ROOT;
1113 bitcnt -= DIST_ROOT;
1114 d = dist[(d >> 16) as usize + (bitbuf & ((1u64 << ((d >> 8) & 0xF)) - 1)) as usize];
1115 }
1116 if d & INVALID != 0 {
1117 break Err(ErrorKind::InvalidSymbol);
1118 }
1119 let code = (d >> 8) & 0xF;
1120 let distance = (d >> 16) as usize
1121 + ((bitbuf >> code) & ((1u64 << ((d & 0xFF) - code)) - 1)) as usize;
1122 bitbuf >>= d & 0xFF;
1123 bitcnt -= d & 0xFF;
1124
1125 if distance > window || (distance > o && distance - o > self.whave) {
1126 break Err(ErrorKind::DistanceTooFar);
1127 }
1128 if distance <= o && distance >= 8 {
1129 // Eight bytes at a time; the source is always written before
1130 // it is read because the distance is at least eight, and the
1131 // over-copy stays inside the FAST_OUT margin.
1132 let mut s = o - distance;
1133 let stop = o + length;
1134 while o < stop {
1135 buf.copy_within(s..s + 8, o);
1136 s += 8;
1137 o += 8;
1138 }
1139 o = stop;
1140 } else {
1141 self.copy_match(buf, o, distance, length);
1142 o += length;
1143 }
1144 };
1145 // The refill leaves read-ahead bits above `bitcnt`; the slow path
1146 // needs them clear.
1147 self.bitbuf = bitbuf & ((1u64 << bitcnt) - 1);
1148 self.bitcnt = bitcnt;
1149 *ip = i;
1150 *op = o;
1151 result
1152 }
1153}
1154
1155/// Which table `peek` reads.
1156#[derive(Clone, Copy)]
1157enum Which {
1158 Lit,
1159 Dist,
1160 Pre,
1161}
1162
1163#[cfg(test)]
1164mod tests;