Skip to main content

miniz_oxide/inflate/
core.rs

1//! Core decompression functionality.
2//!
3//! # Using decompress with a wrapping buffer
4//!
5//! [`decompress`] and [`decompress_with_limit`] can be used with a wrapping buffer.
6//!
7//! To decompress with a wrapping buffer you must:
8//! - not pass `TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF` flag
9//! - pass an output buffer with a size of a power of 2
10//! - pass an output buffer  with a size greater or equal to the decompression window
11//!   (which cannot be more than 32KiB, so 32KiB is a safe size)
12//! - pass the same buffer on each call without modification
13//!
14//! You must process return values so that:
15//! - next call pass the input buffer without the first input bytes read skipped
16//! - next call pass the same output buffer
17//! - next call pass an out_pos incremented by the number of bytes output (wrapping to 0 if needed)
18//! - do a next call only if return status is `NeedsMoreInput` or `NeedsMoreInput`
19//!
20//! [`decompress`] will write to any byte after `out_pos` in the output buffer, but will not
21//! wrap around. This means that all bytes after `out_pos` must be saved while the ones before
22//! do not have to.
23//!
24//! [`decompress_with_limit`] will write to any byte after `out_pos` but not more than `out_max`
25//! and will not wrap around. This means that you can use the buffer as a ring buffer for your
26//! application usage, as long as you keep track of the number of disposable bytes.
27
28use super::*;
29use crate::shared::{update_adler32, HUFFMAN_LENGTH_ORDER};
30use ::core::cell::Cell;
31
32use ::core::cmp;
33use ::core::convert::TryInto;
34
35use self::output_buffer::{InputWrapper, OutputBuffer};
36
37#[cfg(feature = "serde")]
38use crate::serde::big_array::BigArray;
39#[cfg(feature = "serde")]
40use serde::{Deserialize, Serialize};
41
42pub const TINFL_LZ_DICT_SIZE: usize = 32_768;
43
44/// A struct containing huffman code lengths and the huffman code tree used by the decompressor.
45#[cfg_attr(not(feature = "rustc-dep-of-std"), derive(Clone))]
46#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
47struct HuffmanTable {
48    /// Fast lookup table for shorter huffman codes.
49    ///
50    /// See `HuffmanTable::fast_lookup`.
51    #[cfg_attr(feature = "serde", serde(with = "BigArray"))]
52    pub look_up: [i16; FAST_LOOKUP_SIZE as usize],
53    /// Full huffman tree.
54    ///
55    /// Positive values are edge nodes/symbols, negative values are
56    /// parent nodes/references to other nodes.
57    #[cfg_attr(feature = "serde", serde(with = "BigArray"))]
58    pub tree: [i16; MAX_HUFF_TREE_SIZE],
59}
60
61impl HuffmanTable {
62    const fn new() -> HuffmanTable {
63        HuffmanTable {
64            look_up: [0; FAST_LOOKUP_SIZE as usize],
65            tree: [0; MAX_HUFF_TREE_SIZE],
66        }
67    }
68
69    /// Look for a symbol in the fast lookup table.
70    /// The symbol is stored in the lower 9 bits, the length in the next 6.
71    /// If the returned value is negative, the code wasn't found in the
72    /// fast lookup table and the full tree has to be traversed to find the code.
73    #[inline]
74    const fn fast_lookup(&self, bit_buf: BitBuffer) -> i16 {
75        self.look_up[(bit_buf & (FAST_LOOKUP_SIZE - 1) as BitBuffer) as usize]
76    }
77
78    /// Get the symbol and the code length from the huffman tree.
79    #[inline]
80    fn tree_lookup(&self, fast_symbol: i32, bit_buf: BitBuffer, mut code_len: u8) -> (i32, u32) {
81        let mut symbol = fast_symbol;
82        // We step through the tree until we encounter a positive value, which indicates a
83        // symbol.
84        loop {
85            // symbol here indicates the position of the left (0) node, if the next bit is 1
86            // we add 1 to the lookup position to get the right node.
87            let tree_index = (!symbol + ((bit_buf >> code_len) & 1) as i32) as usize;
88
89            // Use get here to avoid generatic panic code.
90            // The init_tree code should prevent this from actually going out of bounds
91            // but if there were somehow a bug with that
92            // we would at worst end up with corrupted output in release mode.
93            debug_assert!(tree_index < self.tree.len());
94            symbol = i32::from(self.tree.get(tree_index).copied().unwrap_or(i16::MAX));
95            code_len += 1;
96            if symbol >= 0 {
97                break;
98            }
99        }
100        // Note: Using a u8 for code_len inside this function seems to improve performance, but changing it
101        // in localvars seems to worsen things so we convert it to a u32 here.
102        (symbol, u32::from(code_len))
103    }
104
105    #[inline]
106    /// Look up a symbol and code length from the bits in the provided bit buffer.
107    ///
108    /// Returns Some(symbol, length) on success,
109    /// None if the length is 0.
110    ///
111    /// It's possible we could avoid checking for 0 if we can guarantee a sane table.
112    /// TODO: Check if a smaller type for code_len helps performance.
113    fn lookup(&self, bit_buf: BitBuffer) -> (i32, u32) {
114        let symbol = self.fast_lookup(bit_buf).into();
115        if symbol >= 0 {
116            let length = (symbol >> 9) as u32;
117            (symbol, length)
118        } else {
119            // We didn't get a symbol from the fast lookup table, so check the tree instead.
120            self.tree_lookup(symbol, bit_buf, FAST_LOOKUP_BITS)
121        }
122    }
123}
124
125/// The number of huffman tables used.
126const MAX_HUFF_TABLES: usize = 3;
127/// The length of the first (literal/length) huffman table.
128const MAX_HUFF_SYMBOLS_0: usize = 288;
129/// The length of the second (distance) huffman table.
130const MAX_HUFF_SYMBOLS_1: usize = 32;
131/// The length of the last (huffman code length) huffman table.
132const MAX_HUFF_SYMBOLS_2: usize = 19;
133/// The maximum length of a code that can be looked up in the fast lookup table.
134const FAST_LOOKUP_BITS: u8 = 10;
135/// The size of the fast lookup table.
136const FAST_LOOKUP_SIZE: u16 = 1 << FAST_LOOKUP_BITS;
137const MAX_HUFF_TREE_SIZE: usize = MAX_HUFF_SYMBOLS_0 * 2;
138const LITLEN_TABLE: usize = 0;
139const DIST_TABLE: usize = 1;
140const HUFFLEN_TABLE: usize = 2;
141const LEN_CODES_SIZE: usize = 512;
142const LEN_CODES_MASK: usize = LEN_CODES_SIZE - 1;
143
144/// Flags to [`decompress()`] to control how inflation works.
145///
146/// These define bits for a bitmask argument.
147pub mod inflate_flags {
148    /// Should we try to parse a zlib header?
149    ///
150    /// If unset, the function will expect an RFC1951 deflate stream.  If set, it will expect a
151    /// RFC1950 zlib wrapper around the deflate stream.
152    pub const TINFL_FLAG_PARSE_ZLIB_HEADER: u32 = 1;
153
154    /// There will be more input that hasn't been given to the decompressor yet.
155    ///
156    /// This is useful when you want to decompress what you have so far,
157    /// even if you know there is probably more input that hasn't gotten here yet (_e.g._, over a
158    /// network connection).  When [`decompress()`][super::decompress] reaches the end of the input
159    /// without finding the end of the compressed stream, it will return
160    /// [`TINFLStatus::NeedsMoreInput`][super::TINFLStatus::NeedsMoreInput] if this is set,
161    /// indicating that you should get more data before calling again.  If not set, it will return
162    /// [`TINFLStatus::FailedCannotMakeProgress`][super::TINFLStatus::FailedCannotMakeProgress]
163    /// suggesting the stream is corrupt, since you claimed it was all there.
164    pub const TINFL_FLAG_HAS_MORE_INPUT: u32 = 2;
165
166    /// The output buffer should not wrap around.
167    pub const TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: u32 = 4;
168
169    /// Calculate the adler32 checksum of the output data even if we're not inflating a zlib stream.
170    ///
171    /// If [`TINFL_FLAG_IGNORE_ADLER32`] is specified, it will override this.
172    ///
173    /// NOTE: Enabling/disabling this between calls to decompress will result in an incorrect
174    /// checksum.
175    pub const TINFL_FLAG_COMPUTE_ADLER32: u32 = 8;
176
177    /// Ignore adler32 checksum even if we are inflating a zlib stream.
178    ///
179    /// Overrides [`TINFL_FLAG_COMPUTE_ADLER32`] if both are enabled.
180    ///
181    /// NOTE: This flag does not exist in miniz as it does not support this and is a
182    /// custom addition for miniz_oxide.
183    ///
184    /// NOTE: Should not be changed from enabled to disabled after decompression has started,
185    /// this will result in checksum failure (outside the unlikely event where the checksum happens
186    /// to match anyway).
187    pub const TINFL_FLAG_IGNORE_ADLER32: u32 = 64;
188
189    /// Return [`TINFLStatus::BlockBoundary`][super::TINFLStatus::BlockBoundary]
190    /// on reaching the boundary between deflate blocks. Calling [`decompress()`][super::decompress]
191    /// again will resume decompression of the next block.
192    #[cfg(feature = "block-boundary")]
193    pub const TINFL_FLAG_STOP_ON_BLOCK_BOUNDARY: u32 = 128;
194}
195
196use self::inflate_flags::*;
197
198const MIN_TABLE_SIZES: [u16; 3] = [257, 1, 4];
199
200#[cfg(target_pointer_width = "64")]
201type BitBuffer = u64;
202
203#[cfg(not(target_pointer_width = "64"))]
204type BitBuffer = u32;
205
206/*
207enum HuffmanTableType {
208    LiteralLength = 0,
209    Dist = 1,
210    Huffman = 2,
211}*/
212
213/// Minimal data representing the [`DecompressorOxide`] state when it is between deflate blocks
214/// (i.e. [`decompress()`] has returned [`TINFLStatus::BlockBoundary`]).
215/// This can be serialized along with the last 32KiB of the output buffer, then passed to
216/// [`DecompressorOxide::from_block_boundary_state()`] to resume decompression from the same point.
217///
218/// The Zlib/Adler32 fields can be ignored if you aren't using those features
219/// ([`TINFL_FLAG_PARSE_ZLIB_HEADER`], [`TINFL_FLAG_COMPUTE_ADLER32`]).
220/// When deserializing, you can reconstruct `bit_buf` from the previous byte in the input file
221/// (if you still have access to it), so `num_bits` is the only field that is always required.
222#[derive(Clone)]
223#[cfg(feature = "block-boundary")]
224#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
225pub struct BlockBoundaryState {
226    /// The number of bits from the last byte of input consumed,
227    /// that are needed for decoding the next deflate block.
228    /// Value is in range `0..=7`
229    pub num_bits: u8,
230
231    /// The `num_bits` MSBs from the last byte of input consumed,
232    /// that are needed for decoding the next deflate block.
233    /// Stored in the LSBs of this field.
234    pub bit_buf: u8,
235
236    /// Zlib CMF
237    pub z_header0: u32,
238    /// Zlib FLG
239    pub z_header1: u32,
240    /// Adler32 checksum of the data decompressed so far
241    pub check_adler32: u32,
242}
243
244#[cfg(feature = "block-boundary")]
245impl Default for BlockBoundaryState {
246    fn default() -> Self {
247        BlockBoundaryState {
248            num_bits: 0,
249            bit_buf: 0,
250            z_header0: 0,
251            z_header1: 0,
252            check_adler32: 1,
253        }
254    }
255}
256
257/// Main decompression struct.
258///
259#[cfg_attr(not(feature = "rustc-dep-of-std"), derive(Clone))]
260#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
261pub struct DecompressorOxide {
262    /// Current state of the decompressor.
263    state: core::State,
264    /// Number of bits in the bit buffer.
265    num_bits: u32,
266    /// Zlib CMF
267    z_header0: u32,
268    /// Zlib FLG
269    z_header1: u32,
270    /// Adler32 checksum from the zlib header.
271    z_adler32: u32,
272    /// 1 if the current block is the last block, 0 otherwise.
273    finish: u8,
274    /// The type of the current block.
275    /// or if in a dynamic block, which huffman table we are currently
276    // initializing.
277    block_type: u8,
278    /// 1 if the adler32 value should be checked.
279    check_adler32: u32,
280    /// Last match distance.
281    dist: u32,
282    /// Variable used for match length, symbols, and a number of other things.
283    counter: u32,
284    /// Number of extra bits for the last length or distance code.
285    num_extra: u8,
286    /// Number of entries in each huffman table.
287    table_sizes: [u16; MAX_HUFF_TABLES],
288    /// Buffer of input data.
289    bit_buf: BitBuffer,
290    /// Huffman tables.
291    tables: [HuffmanTable; MAX_HUFF_TABLES],
292
293    #[cfg_attr(feature = "serde", serde(with = "BigArray"))]
294    code_size_literal: [u8; MAX_HUFF_SYMBOLS_0],
295    code_size_dist: [u8; MAX_HUFF_SYMBOLS_1],
296    code_size_huffman: [u8; MAX_HUFF_SYMBOLS_2],
297    /// Raw block header.
298    raw_header: [u8; 4],
299    /// Huffman length codes.
300    #[cfg_attr(feature = "serde", serde(with = "BigArray"))]
301    // MAX_HUFF_SYMBOLS_0 + MAX_HUFF_SYMBOLS_1 + 137
302    // Extended to 512 to allow masking to help evade bounds checks.
303    len_codes: [u8; LEN_CODES_SIZE],
304}
305
306impl DecompressorOxide {
307    /// Create a new tinfl_decompressor with all fields set to 0.
308    pub fn new() -> DecompressorOxide {
309        DecompressorOxide::default()
310    }
311
312    /// Set the current state to `Start`.
313    #[inline]
314    pub fn init(&mut self) {
315        // The rest of the data is reset or overwritten when used.
316        self.state = core::State::Start;
317    }
318
319    /// Returns the adler32 checksum of the currently decompressed data.
320    /// Note: Will return Some(1) if decompressing zlib but ignoring adler32.
321    #[inline]
322    #[cfg(not(feature = "rustc-dep-of-std"))]
323    pub fn adler32(&self) -> Option<u32> {
324        if self.state != State::Start && !self.state.is_failure() && self.z_header0 != 0 {
325            Some(self.check_adler32)
326        } else {
327            None
328        }
329    }
330
331    /// Returns the adler32 that was read from the zlib header if it exists.
332    #[inline]
333    #[cfg(not(feature = "rustc-dep-of-std"))]
334    pub fn adler32_header(&self) -> Option<u32> {
335        if self.state != State::Start && self.state != State::BadZlibHeader && self.z_header0 != 0 {
336            Some(self.z_adler32)
337        } else {
338            None
339        }
340    }
341
342    // Get zlib header for tests
343    // Only for tests for now, may provide a proper function for this for later.
344    #[cfg(all(test, feature = "with-alloc"))]
345    pub(crate) const fn zlib_header(&self) -> (u32, u32) {
346        (self.z_header0, self.z_header1)
347    }
348
349    /*fn code_size_table(&mut self, table_num: u8) -> &mut [u8] {
350        match table_num {
351            0 => &mut self.code_size_literal,
352            1 => &mut self.code_size_dist,
353            _ => &mut self.code_size_huffman,
354        }
355    }*/
356
357    /// Returns the current [`BlockBoundaryState`]. Should only be called when
358    /// [`decompress()`] has returned [`TINFLStatus::BlockBoundary`];
359    /// otherwise this will return `None`.
360    #[cfg(feature = "block-boundary")]
361    pub fn block_boundary_state(&self) -> Option<BlockBoundaryState> {
362        if self.state == core::State::ReadBlockHeader {
363            // If we're in this state, undo_bytes should have emptied
364            // bit_buf of any whole bytes
365            assert!(self.num_bits < 8);
366
367            Some(BlockBoundaryState {
368                num_bits: self.num_bits as u8,
369                bit_buf: self.bit_buf as u8,
370                z_header0: self.z_header0,
371                z_header1: self.z_header1,
372                check_adler32: self.check_adler32,
373            })
374        } else {
375            None
376        }
377    }
378
379    /// Creates a new `DecompressorOxide` from the state returned by
380    /// `block_boundary_state()`.
381    ///
382    /// When calling [`decompress()`], the 32KiB of `out` preceding `out_pos` must be
383    /// initialized with the same data that it contained when `block_boundary_state()`
384    /// was called.
385    #[cfg(feature = "block-boundary")]
386    pub fn from_block_boundary_state(st: &BlockBoundaryState) -> Self {
387        DecompressorOxide {
388            state: core::State::ReadBlockHeader,
389            num_bits: st.num_bits as u32,
390            bit_buf: st.bit_buf as BitBuffer,
391            z_header0: st.z_header0,
392            z_header1: st.z_header1,
393            z_adler32: 1,
394            check_adler32: st.check_adler32,
395            ..DecompressorOxide::default()
396        }
397    }
398}
399
400impl Default for DecompressorOxide {
401    /// Create a new tinfl_decompressor with all fields set to 0.
402    #[inline(always)]
403    fn default() -> Self {
404        DecompressorOxide {
405            state: core::State::Start,
406            num_bits: 0,
407            z_header0: 0,
408            z_header1: 0,
409            z_adler32: 0,
410            finish: 0,
411            block_type: 0,
412            check_adler32: 0,
413            dist: 0,
414            counter: 0,
415            num_extra: 0,
416            table_sizes: [0; MAX_HUFF_TABLES],
417            bit_buf: 0,
418            // TODO:(oyvindln) Check that copies here are optimized out in release mode.
419            tables: [
420                HuffmanTable::new(),
421                HuffmanTable::new(),
422                HuffmanTable::new(),
423            ],
424            code_size_literal: [0; MAX_HUFF_SYMBOLS_0],
425            code_size_dist: [0; MAX_HUFF_SYMBOLS_1],
426            code_size_huffman: [0; MAX_HUFF_SYMBOLS_2],
427            raw_header: [0; 4],
428            len_codes: [0; LEN_CODES_SIZE],
429        }
430    }
431}
432
433#[derive(Copy, Clone, PartialEq, Eq, Debug)]
434#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
435#[non_exhaustive]
436enum State {
437    Start = 0,
438    ReadZlibCmf,
439    ReadZlibFlg,
440    ReadBlockHeader,
441    BlockTypeNoCompression,
442    RawHeader,
443    RawMemcpy1,
444    RawMemcpy2,
445    ReadTableSizes,
446    ReadHufflenTableCodeSize,
447    ReadLitlenDistTablesCodeSize,
448    ReadExtraBitsCodeSize,
449    DecodeLitlen,
450    WriteSymbol,
451    ReadExtraBitsLitlen,
452    DecodeDistance,
453    ReadExtraBitsDistance,
454    RawReadFirstByte,
455    RawStoreFirstByte,
456    WriteLenBytesToEnd,
457    BlockDone,
458    HuffDecodeOuterLoop1,
459    HuffDecodeOuterLoop2,
460    ReadAdler32,
461
462    DoneForever,
463
464    // Failure states.
465    BlockTypeUnexpected,
466    BadCodeSizeSum,
467    BadDistOrLiteralTableLength,
468    BadTotalSymbols,
469    BadZlibHeader,
470    DistanceOutOfBounds,
471    BadRawLength,
472    BadCodeSizeDistPrevLookup,
473    InvalidLitlen,
474    InvalidDist,
475}
476
477impl State {
478    #[cfg(not(feature = "rustc-dep-of-std"))]
479    const fn is_failure(self) -> bool {
480        matches!(
481            self,
482            BlockTypeUnexpected
483                | BadCodeSizeSum
484                | BadDistOrLiteralTableLength
485                | BadTotalSymbols
486                | BadZlibHeader
487                | DistanceOutOfBounds
488                | BadRawLength
489                | BadCodeSizeDistPrevLookup
490                | InvalidLitlen
491                | InvalidDist
492        )
493    }
494
495    #[inline]
496    fn begin(&mut self, new_state: State) {
497        *self = new_state;
498    }
499}
500
501use self::State::*;
502
503// # Optimization
504// We add a extra value at the end and make the tables 32 elements long
505// so we can use a mask to avoid bounds checks.
506// The invalid values are set to something high enough to avoid underflowing
507// the match length.
508/// Base length for each length code.
509///
510/// The base is used together with the value of the extra bits to decode the actual
511/// length/distance values in a match.
512#[rustfmt::skip]
513const LENGTH_BASE: [u16; 32] = [
514    3,  4,  5,  6,  7,  8,  9,  10,  11,  13,  15,  17,  19,  23,  27,  31,
515    35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 512, 512, 512
516];
517
518/// Number of extra bits for each length code.
519#[rustfmt::skip]
520const LENGTH_EXTRA: [u8; 32] = [
521    0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
522    3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0, 0
523];
524
525/// Base length for each distance code.
526#[rustfmt::skip]
527const DIST_BASE: [u16; 30] = [
528    1,    2,    3,    4,    5,    7,      9,      13,     17,     25,    33,
529    49,   65,   97,   129,  193,  257,    385,    513,    769,    1025,  1537,
530    2049, 3073, 4097, 6145, 8193, 12_289, 16_385, 24_577
531];
532
533/// Get the number of extra bits used for a distance code.
534/// (Code numbers above `NUM_DISTANCE_CODES` will give some garbage
535/// value.)
536#[inline(always)]
537const fn num_extra_bits_for_distance_code(code: u8) -> u8 {
538    // TODO: Need to verify that this is faster on all platforms.
539    // This can be easily calculated without a lookup.
540    let c = code >> 1;
541    c.saturating_sub(1)
542}
543
544/// The mask used when indexing the base/extra arrays.
545const BASE_EXTRA_MASK: usize = 32 - 1;
546
547/// Read an le u16 value from the slice iterator.
548///
549/// # Panics
550/// Panics if there are less than two bytes left.
551#[inline]
552fn read_u16_le(iter: &mut InputWrapper) -> u16 {
553    let ret = {
554        let two_bytes = iter.as_slice()[..2].try_into().unwrap_or_default();
555        u16::from_le_bytes(two_bytes)
556    };
557    iter.advance(2);
558    ret
559}
560
561/// Ensure that there is data in the bit buffer.
562///
563/// On 64-bit platform, we use a 64-bit value so this will
564/// result in there being at least 32 bits in the bit buffer.
565/// This function assumes that there is at least 4 bytes left in the input buffer.
566#[inline(always)]
567#[cfg(target_pointer_width = "64")]
568fn fill_bit_buffer(l: &mut LocalVars, in_iter: &mut InputWrapper) {
569    // Read four bytes into the buffer at once.
570    if l.num_bits < 30 {
571        l.bit_buf |= BitBuffer::from(in_iter.read_u32_le()) << l.num_bits;
572        l.num_bits += 32;
573    }
574}
575
576/// Same as previous, but for non-64-bit platforms.
577/// Ensures at least 16 bits are present, requires at least 2 bytes in the in buffer.
578#[inline(always)]
579#[cfg(not(target_pointer_width = "64"))]
580fn fill_bit_buffer(l: &mut LocalVars, in_iter: &mut InputWrapper) {
581    // If the buffer is 32-bit wide, read 2 bytes instead.
582    if l.num_bits < 15 {
583        l.bit_buf |= BitBuffer::from(read_u16_le(in_iter)) << l.num_bits;
584        l.num_bits += 16;
585    }
586}
587
588/// Check that the zlib header is correct and that there is enough space in the buffer
589/// for the window size specified in the header.
590///
591/// See https://tools.ietf.org/html/rfc1950
592#[inline]
593const fn validate_zlib_header(cmf: u32, flg: u32, flags: u32, mask: usize) -> Action {
594    let mut failed =
595    // cmf + flg should be divisible by 31.
596        (((cmf * 256) + flg) % 31 != 0) ||
597    // If this flag is set, a dictionary was used for this zlib compressed data.
598    // This is currently not supported by miniz or miniz-oxide
599        ((flg & 0b0010_0000) != 0) ||
600    // Compression method. Only 8(DEFLATE) is defined by the standard.
601        ((cmf & 15) != 8);
602
603    let window_size = 1 << ((cmf >> 4) + 8);
604    if (flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) == 0 {
605        // Bail if the buffer is wrapping and the window size is larger than the buffer.
606        failed |= (mask + 1) < window_size;
607    }
608
609    // Zlib doesn't allow window sizes above 32 * 1024.
610    failed |= window_size > 32_768;
611
612    if failed {
613        Action::Jump(BadZlibHeader)
614    } else {
615        Action::Jump(ReadBlockHeader)
616    }
617}
618
619enum Action {
620    None,
621    Jump(State),
622    End(TINFLStatus),
623}
624
625/// Try to decode the next huffman code, and puts it in the counter field of the decompressor
626/// if successful.
627///
628/// # Returns
629/// The specified action returned from `f` on success,
630/// `Action::End` if there are not enough data left to decode a symbol.
631fn decode_huffman_code<F>(
632    r: &mut DecompressorOxide,
633    l: &mut LocalVars,
634    table: usize,
635    flags: u32,
636    in_iter: &mut InputWrapper,
637    f: F,
638) -> Action
639where
640    F: FnOnce(&mut DecompressorOxide, &mut LocalVars, i32) -> Action,
641{
642    // As the huffman codes can be up to 15 bits long we need at least 15 bits
643    // ready in the bit buffer to start decoding the next huffman code.
644    if l.num_bits < 15 {
645        // First, make sure there is enough data in the bit buffer to decode a huffman code.
646        if in_iter.bytes_left() < 2 {
647            // If there is less than 2 bytes left in the input buffer, we try to look up
648            // the huffman code with what's available, and return if that doesn't succeed.
649            // Original explanation in miniz:
650            // /* TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes
651            //  * remaining in the input buffer falls below 2. */
652            // /* It reads just enough bytes from the input stream that are needed to decode
653            //  * the next Huffman code (and absolutely no more). It works by trying to fully
654            //  * decode a */
655            // /* Huffman code by using whatever bits are currently present in the bit buffer.
656            //  * If this fails, it reads another byte, and tries again until it succeeds or
657            //  * until the */
658            // /* bit buffer contains >=15 bits (deflate's max. Huffman code size). */
659            loop {
660                let mut temp = i32::from(r.tables[table].fast_lookup(l.bit_buf));
661                if temp >= 0 {
662                    let code_len = (temp >> 9) as u32;
663                    // TODO: Is there any point to check for code_len != 0 here still?
664                    if (code_len != 0) && (l.num_bits >= code_len) {
665                        break;
666                    }
667                } else if l.num_bits > FAST_LOOKUP_BITS.into() {
668                    let mut code_len = u32::from(FAST_LOOKUP_BITS);
669                    loop {
670                        temp = i32::from(
671                            r.tables[table].tree
672                                [(!temp + ((l.bit_buf >> code_len) & 1) as i32) as usize],
673                        );
674                        code_len += 1;
675                        if temp >= 0 || l.num_bits < code_len + 1 {
676                            break;
677                        }
678                    }
679                    if temp >= 0 {
680                        break;
681                    }
682                }
683
684                // TODO: miniz jumps straight to here after getting here again after failing to read
685                // a byte.
686                // Doing that lets miniz avoid re-doing the lookup that that was done in the
687                // previous call.
688                let mut byte = 0;
689                if let a @ Action::End(_) = read_byte(in_iter, flags, |b| {
690                    byte = b;
691                    Action::None
692                }) {
693                    return a;
694                };
695
696                // Do this outside closure for now to avoid borrowing r.
697                l.bit_buf |= BitBuffer::from(byte) << l.num_bits;
698                l.num_bits += 8;
699
700                if l.num_bits >= 15 {
701                    break;
702                }
703            }
704        } else {
705            // There is enough data in the input buffer, so read the next two bytes
706            // and add them to the bit buffer.
707            // Unwrapping here is fine since we just checked that there are at least two
708            // bytes left.
709            l.bit_buf |= BitBuffer::from(read_u16_le(in_iter)) << l.num_bits;
710            l.num_bits += 16;
711        }
712    }
713
714    // We now have at least 15 bits in the input buffer.
715    let mut symbol = i32::from(r.tables[table].fast_lookup(l.bit_buf));
716    let code_len;
717    // If the symbol was found in the fast lookup table.
718    if symbol >= 0 {
719        // Get the length value from the top bits.
720        // As we shift down the sign bit, converting to an unsigned value
721        // shouldn't overflow.
722        code_len = (symbol >> 9) as u32;
723        // Mask out the length value.
724        symbol &= 511;
725    } else {
726        let res = r.tables[table].tree_lookup(symbol, l.bit_buf, FAST_LOOKUP_BITS);
727        symbol = res.0;
728        code_len = res.1;
729    };
730
731    l.bit_buf >>= code_len;
732    l.num_bits -= code_len;
733    f(r, l, symbol)
734}
735
736/// Try to read one byte from `in_iter` and call `f` with the read byte as an argument,
737/// returning the result.
738/// If reading fails, `Action::End is returned`
739#[inline]
740fn read_byte<F>(in_iter: &mut InputWrapper, flags: u32, f: F) -> Action
741where
742    F: FnOnce(u8) -> Action,
743{
744    match in_iter.read_byte() {
745        None => end_of_input(flags),
746        Some(byte) => f(byte),
747    }
748}
749
750// TODO: `l: &mut LocalVars` may be slow similar to decompress_fast (even with inline(always))
751/// Try to read `amount` number of bits from `in_iter` and call the function `f` with the bits as an
752/// an argument after reading, returning the result of that function, or `Action::End` if there are
753/// not enough bytes left.
754#[inline]
755#[allow(clippy::while_immutable_condition)]
756fn read_bits<F>(
757    l: &mut LocalVars,
758    amount: u32,
759    in_iter: &mut InputWrapper,
760    flags: u32,
761    f: F,
762) -> Action
763where
764    F: FnOnce(&mut LocalVars, BitBuffer) -> Action,
765{
766    // Clippy gives a false positive warning here due to the closure.
767    // Read enough bytes from the input iterator to cover the number of bits we want.
768    while l.num_bits < amount {
769        let action = read_byte(in_iter, flags, |byte| {
770            l.bit_buf |= BitBuffer::from(byte) << l.num_bits;
771            l.num_bits += 8;
772            Action::None
773        });
774
775        // If there are not enough bytes in the input iterator, return and signal that we need more.
776        if !matches!(action, Action::None) {
777            return action;
778        }
779    }
780
781    let bits = l.bit_buf & ((1 << amount) - 1);
782    l.bit_buf >>= amount;
783    l.num_bits -= amount;
784    f(l, bits)
785}
786
787#[inline]
788fn pad_to_bytes<F>(l: &mut LocalVars, in_iter: &mut InputWrapper, flags: u32, f: F) -> Action
789where
790    F: FnOnce(&mut LocalVars) -> Action,
791{
792    let num_bits = l.num_bits & 7;
793    read_bits(l, num_bits, in_iter, flags, |l, _| f(l))
794}
795
796#[inline]
797const fn end_of_input(flags: u32) -> Action {
798    Action::End(if flags & TINFL_FLAG_HAS_MORE_INPUT != 0 {
799        TINFLStatus::NeedsMoreInput
800    } else {
801        TINFLStatus::FailedCannotMakeProgress
802    })
803}
804
805#[inline]
806fn undo_bytes(l: &mut LocalVars, max: u32) -> u32 {
807    let res = cmp::min(l.num_bits >> 3, max);
808    l.num_bits -= res << 3;
809    res
810}
811
812fn start_static_table(r: &mut DecompressorOxide) {
813    r.table_sizes[LITLEN_TABLE] = 288;
814    r.table_sizes[DIST_TABLE] = 32;
815    r.code_size_literal[0..144].fill(8);
816    r.code_size_literal[144..256].fill(9);
817    r.code_size_literal[256..280].fill(7);
818    r.code_size_literal[280..288].fill(8);
819    r.code_size_dist[0..32].fill(5);
820}
821
822#[cfg(any(
823    feature = "rustc-dep-of-std",
824    not(feature = "with-alloc"),
825    target_arch = "aarch64",
826    target_arch = "arm64ec",
827    target_arch = "loongarch64"
828))]
829#[inline]
830const fn reverse_bits(n: u16) -> u16 {
831    // Lookup is not used when building as part of std to avoid wasting space
832    // for lookup table in every rust binary
833    // as it's only used for backtraces in the cold path
834    // - see #152
835
836    // armv7 and newer, and loongarch have a cpu instruction for bit reversal so
837    // it's preferable to just use that on those architectures.
838
839    // Also disable lookup table when not using the alloc feature as
840    // we probably don't want to waste space for a lookup table in an environment
841    // without an allocator.
842    n.reverse_bits()
843}
844
845#[cfg(all(
846    not(any(
847        feature = "rustc-dep-of-std",
848        target_arch = "aarch64",
849        target_arch = "arm64ec",
850        target_arch = "loongarch64"
851    )),
852    feature = "with-alloc"
853))]
854fn reverse_bits(n: u16) -> u16 {
855    static REVERSED_BITS_LOOKUP: [u16; 512] = {
856        let mut table = [0; 512];
857
858        let mut i = 0;
859        while i < 512 {
860            table[i] = (i as u16).reverse_bits();
861            i += 1;
862        }
863
864        table
865    };
866
867    REVERSED_BITS_LOOKUP[n as usize]
868}
869
870fn init_tree(r: &mut DecompressorOxide, l: &mut LocalVars) -> Option<Action> {
871    loop {
872        let bt = r.block_type as usize;
873
874        let code_sizes = match bt {
875            LITLEN_TABLE => &mut r.code_size_literal[..],
876            DIST_TABLE => &mut r.code_size_dist,
877            HUFFLEN_TABLE => &mut r.code_size_huffman,
878            _ => return None,
879        };
880        let table = &mut r.tables[bt];
881
882        let mut total_symbols = [0u16; 16];
883        // Next code - we use the odd length here to simplify a loop later.
884        let mut next_code = [0u32; 17];
885        const INVALID_CODE: i16 = (1 << 9) | 286;
886        // Set the values in the fast table to return a
887        // non-zero length and an invalid symbol instead of zero
888        // so that we do not have to have a check for a zero
889        // code length in the hot code path later
890        // and can instead error out on the invalid symbol check
891        // on bogus input.
892        table.look_up.fill(INVALID_CODE);
893        // If we are initializing the huffman code length we can skip
894        // this since these codes can't be longer than 3 bits
895        // and thus only use the fast table and this table won't be accessed so
896        // there is no point clearing it.
897        // TODO: Avoid creating this table at all.
898        if bt != HUFFLEN_TABLE {
899            table.tree.fill(0);
900        }
901
902        let table_size = r.table_sizes[bt] as usize;
903        if table_size > code_sizes.len() {
904            return None;
905        }
906
907        for &code_size in &code_sizes[..table_size] {
908            let cs = code_size as usize;
909            // Code sizes are limited to max 15 according to the
910            // deflate spec.
911            // If it is larger than this, something has gone wrong...
912            if cs >= total_symbols.len() {
913                return None;
914            }
915            total_symbols[cs] += 1;
916        }
917
918        let mut total = 0u32;
919        let mut max_code_len = 0u32;
920        // Count up the total number of used lengths and check that the table
921        // is not over-subscribed at any step (matching zlib's inftrees.c).
922        {
923            let mut left = 1i32;
924            for (i, (&ts, next)) in total_symbols
925                .iter()
926                .zip(next_code[1..].iter_mut())
927                .enumerate()
928                .skip(1)
929            {
930                if ts > 0 {
931                    max_code_len = i as u32;
932                }
933                total += u32::from(ts);
934                total <<= 1;
935                *next = total;
936
937                left <<= 1;
938                left -= i32::from(ts);
939                if left < 0 {
940                    // Over-subscribed: too many codes for the available bit space.
941                    return Some(Action::Jump(BadTotalSymbols));
942                }
943            }
944        }
945
946        // A complete Huffman code has total == 65536 (2^16 after left-shifting
947        // through all 15 possible code lengths). If total != 65536 the code is
948        // incomplete (unused bit patterns remain).
949        //
950        // Per RFC 1951 and zlib's inftrees.c:
951        // - Code length (hufflen) tables must always be complete.
952        // - Literal/length and distance tables may be incomplete when
953        //   max_code_len <= 1: either all symbols are unused (max_code_len == 0,
954        //   e.g. a distance table with no backreferences) or a single symbol is
955        //   encoded with a 1-bit code (e.g. an EOB-only litlen table).
956        //   Tables with max_code_len > 1 that are incomplete are rejected, as
957        //   they have multi-bit codes that don't form a valid prefix code.
958        if total != 65_536 && (bt == HUFFLEN_TABLE || max_code_len > 1) {
959            return Some(Action::Jump(BadTotalSymbols));
960        }
961
962        let mut tree_next = -1;
963        for symbol_index in 0..table_size {
964            // Code sizes are limited to 15 according to the spec
965            // It's already checked earlier but the compiler might not be smart enough to know that.
966            let code_size = code_sizes[symbol_index] & 15;
967            if code_size == 0 {
968                continue;
969            }
970
971            let cur_code = next_code[code_size as usize];
972            next_code[code_size as usize] += 1;
973
974            let n = (cur_code & (u32::MAX >> (32 - code_size))) as u16;
975
976            let mut rev_code = if n < 512 {
977                // Using a lookup table
978                // for a small speedup here,
979                // Seems to only really make a difference on very short
980                // inputs however.
981                // 512 seems to be around a sweet spot.
982                reverse_bits(n)
983            } else {
984                n.reverse_bits()
985            } >> (16 - code_size);
986
987            if code_size <= FAST_LOOKUP_BITS {
988                let k = (i16::from(code_size) << 9) | symbol_index as i16;
989                while rev_code < FAST_LOOKUP_SIZE {
990                    table.look_up[rev_code as usize] = k;
991                    rev_code += 1 << code_size;
992                }
993                continue;
994            }
995
996            let mut tree_cur = table.look_up[(rev_code & (FAST_LOOKUP_SIZE - 1)) as usize];
997            if tree_cur == INVALID_CODE {
998                table.look_up[(rev_code & (FAST_LOOKUP_SIZE - 1)) as usize] = tree_next;
999                tree_cur = tree_next;
1000                tree_next -= 2;
1001            }
1002
1003            rev_code >>= FAST_LOOKUP_BITS - 1;
1004            for _ in FAST_LOOKUP_BITS + 1..code_size {
1005                rev_code >>= 1;
1006                tree_cur -= (rev_code & 1) as i16;
1007                let tree_index = (-tree_cur - 1) as usize;
1008                if tree_index >= table.tree.len() {
1009                    return None;
1010                }
1011                if table.tree[tree_index] == 0 {
1012                    table.tree[tree_index] = tree_next;
1013                    tree_cur = tree_next;
1014                    tree_next -= 2;
1015                } else {
1016                    tree_cur = table.tree[tree_index];
1017                }
1018            }
1019
1020            rev_code >>= 1;
1021            tree_cur -= (rev_code & 1) as i16;
1022            let tree_index = (-tree_cur - 1) as usize;
1023            if tree_index >= table.tree.len() {
1024                return None;
1025            }
1026            table.tree[tree_index] = symbol_index as i16;
1027        }
1028
1029        if r.block_type == HUFFLEN_TABLE as u8 {
1030            l.counter = 0;
1031            return Some(Action::Jump(ReadLitlenDistTablesCodeSize));
1032        }
1033
1034        if r.block_type == LITLEN_TABLE as u8 {
1035            break;
1036        }
1037        r.block_type -= 1;
1038    }
1039
1040    l.counter = 0;
1041
1042    Some(Action::Jump(DecodeLitlen))
1043}
1044
1045// A helper macro for generating the state machine.
1046//
1047// As Rust doesn't have fallthrough on matches, we have to return to the match statement
1048// and jump for each state change. (Which would ideally be optimized away, but often isn't.)
1049macro_rules! generate_state {
1050    ($state: ident, $state_machine: tt, $f: expr) => {
1051        loop {
1052            match $f {
1053                Action::None => continue,
1054                Action::Jump(new_state) => {
1055                    $state = new_state;
1056                    continue $state_machine;
1057                },
1058                Action::End(result) => break $state_machine result,
1059            }
1060        }
1061    };
1062}
1063
1064#[derive(Copy, Clone)]
1065struct LocalVars {
1066    pub bit_buf: BitBuffer,
1067    pub num_bits: u32,
1068    pub dist: u32,
1069    pub counter: u32,
1070    pub num_extra: u8,
1071}
1072
1073#[inline]
1074fn transfer(
1075    out_slice: &mut [u8],
1076    mut source_pos: usize,
1077    mut out_pos: usize,
1078    match_len: usize,
1079    out_buf_size_mask: usize,
1080) {
1081    // special case that comes up surprisingly often. in the case that `source_pos`
1082    // is 1 less than `out_pos`, we can say that the entire range will be the same
1083    // value and optimize this to be a simple `memset`
1084    let source_diff = if source_pos > out_pos {
1085        source_pos - out_pos
1086    } else {
1087        out_pos - source_pos
1088    };
1089
1090    // The last 3 bytes can wrap as those are dealt with separately at the end.
1091    // Use wrapping_sub rather than saturating for performance reasons here as
1092    // if source_pos + match_len  is < 3 we just want to jump to the end
1093    // condition anyhow.
1094    let not_wrapping = (out_buf_size_mask == usize::MAX)
1095        || ((source_pos + match_len).wrapping_sub(3) < out_slice.len());
1096
1097    let end_pos = ((match_len >> 2) * 4) + out_pos;
1098    if not_wrapping && source_diff == 1 && out_pos > source_pos {
1099        let end = (match_len >> 2) * 4 + out_pos;
1100        let init = out_slice[out_pos - 1];
1101        out_slice[out_pos..end].fill(init);
1102        out_pos = end;
1103        source_pos = end - 1;
1104    // if the difference between `source_pos` and `out_pos` is greater than 3,
1105    // and we are not wrapping, we
1106    // can do slightly better than the naive case by copying everything at once
1107    } else if not_wrapping && out_pos > source_pos && (out_pos - source_pos >= 4) {
1108        let end_pos = cmp::min(end_pos, out_slice.len().saturating_sub(3));
1109        while out_pos < end_pos {
1110            out_slice.copy_within(source_pos..=source_pos + 3, out_pos);
1111            source_pos += 4;
1112            out_pos += 4;
1113        }
1114    } else {
1115        let end_pos = cmp::min(end_pos, out_slice.len().saturating_sub(3));
1116        while out_pos < end_pos {
1117            // Placing these assertions moves some bounds check before the accesses which
1118            // makes the compiler able to optimize better.
1119            // Ideally we would find a safe way to remove them entirely.
1120            assert!(out_pos + 3 < out_slice.len());
1121            assert!((source_pos + 3) & out_buf_size_mask < out_slice.len());
1122
1123            out_slice[out_pos] = out_slice[source_pos & out_buf_size_mask];
1124            out_slice[out_pos + 1] = out_slice[(source_pos + 1) & out_buf_size_mask];
1125            out_slice[out_pos + 2] = out_slice[(source_pos + 2) & out_buf_size_mask];
1126            out_slice[out_pos + 3] = out_slice[(source_pos + 3) & out_buf_size_mask];
1127            source_pos += 4;
1128            out_pos += 4;
1129        }
1130    }
1131
1132    match match_len & 3 {
1133        0 => (),
1134        1 => out_slice[out_pos] = out_slice[source_pos & out_buf_size_mask],
1135        2 => {
1136            assert!(out_pos + 1 < out_slice.len());
1137            assert!((source_pos + 1) & out_buf_size_mask < out_slice.len());
1138            out_slice[out_pos] = out_slice[source_pos & out_buf_size_mask];
1139            out_slice[out_pos + 1] = out_slice[(source_pos + 1) & out_buf_size_mask];
1140        }
1141        3 => {
1142            assert!(out_pos + 2 < out_slice.len());
1143            assert!((source_pos + 2) & out_buf_size_mask < out_slice.len());
1144            out_slice[out_pos] = out_slice[source_pos & out_buf_size_mask];
1145            out_slice[out_pos + 1] = out_slice[(source_pos + 1) & out_buf_size_mask];
1146            out_slice[out_pos + 2] = out_slice[(source_pos + 2) & out_buf_size_mask];
1147        }
1148        _ => unreachable!(),
1149    }
1150}
1151
1152/// Presumes that there is at least match_len bytes in output left.
1153#[inline]
1154fn apply_match(
1155    out_slice: &mut [u8],
1156    out_pos: usize,
1157    dist: usize,
1158    match_len: usize,
1159    out_buf_size_mask: usize,
1160) {
1161    debug_assert!(out_pos.checked_add(match_len).unwrap() <= out_slice.len());
1162
1163    let source_pos = out_pos.wrapping_sub(dist) & out_buf_size_mask;
1164
1165    if match_len == 3 {
1166        let out_slice = Cell::from_mut(out_slice).as_slice_of_cells();
1167        if let Some(dst) = out_slice.get(out_pos..out_pos + 3) {
1168            // Moving bounds checks before any memory mutation allows the optimizer
1169            // combine them together.
1170            let src = out_slice
1171                .get(source_pos)
1172                .zip(out_slice.get((source_pos + 1) & out_buf_size_mask))
1173                .zip(out_slice.get((source_pos + 2) & out_buf_size_mask));
1174            if let Some(((a, b), c)) = src {
1175                // For correctness, the memory reads and writes have to be interleaved.
1176                // Cells make it possible for read and write references to overlap.
1177                dst[0].set(a.get());
1178                dst[1].set(b.get());
1179                dst[2].set(c.get());
1180            }
1181        }
1182        return;
1183    }
1184
1185    if cfg!(not(any(target_arch = "x86", target_arch = "x86_64"))) {
1186        // The copy from slice code seems to not give any added performance at least on
1187        // armv7 so transfer manually
1188        // Need to test on other platforms.
1189        transfer(out_slice, source_pos, out_pos, match_len, out_buf_size_mask);
1190        return;
1191    }
1192
1193    if source_pos >= out_pos && (source_pos - out_pos) < match_len {
1194        transfer(out_slice, source_pos, out_pos, match_len, out_buf_size_mask);
1195    } else if match_len <= dist && source_pos + match_len < out_slice.len() {
1196        // Destination and source segments does not intersect and source does not wrap.
1197        // TODO: An invalid before start of data wrapping match reached here before
1198        // it was fixed (it wrapped around and ended overlapping again)- need
1199        // to check that we are not wrapping here.
1200        if source_pos < out_pos {
1201            let (from_slice, to_slice) = out_slice.split_at_mut(out_pos);
1202            to_slice[..match_len].copy_from_slice(&from_slice[source_pos..source_pos + match_len]);
1203        } else {
1204            let (to_slice, from_slice) = out_slice.split_at_mut(source_pos);
1205            to_slice[out_pos..out_pos + match_len].copy_from_slice(&from_slice[..match_len]);
1206        }
1207    } else {
1208        transfer(out_slice, source_pos, out_pos, match_len, out_buf_size_mask);
1209    }
1210}
1211
1212/// Fast inner decompression loop which is run  while there is at least
1213/// 259 bytes left in the output buffer, and at least 6 bytes left in the input buffer
1214/// (The maximum one match would need + 1).
1215///
1216/// This was inspired by a similar optimization in zlib, which uses this info to do
1217/// faster unchecked copies of multiple bytes at a time.
1218/// Currently we don't do this here, but this function does avoid having to jump through the
1219/// big match loop on each state change(as rust does not have fallthrough or gotos at the moment),
1220/// and already improves decompression speed a fair bit.
1221fn decompress_fast(
1222    r: &mut DecompressorOxide,
1223    in_iter: &mut InputWrapper,
1224    out_buf: &mut OutputBuffer,
1225    flags: u32,
1226    local_vars: &mut LocalVars,
1227    out_buf_size_mask: usize,
1228) -> (TINFLStatus, State) {
1229    // Make a local copy of the most used variables, to avoid having to update and read from values
1230    // in a random memory location and to encourage more register use.
1231    let mut l = *local_vars;
1232    let mut state;
1233
1234    let status: TINFLStatus = 'o: loop {
1235        state = State::DecodeLitlen;
1236        loop {
1237            // This function assumes that there is at least 259 bytes left in the output buffer,
1238            // and that there is at least 14 bytes left in the input buffer. 14 input bytes:
1239            // 15 (prev lit) + 15 (length) + 5 (length extra) + 15 (dist)
1240            // + 29 + 32 (left in bit buf, including last 13 dist extra) = 111 bits < 14 bytes
1241            // We need the one extra byte as we may write one length and one full match
1242            // before checking again.
1243            if out_buf.bytes_left() < 259 || in_iter.bytes_left() < 14 {
1244                state = State::DecodeLitlen;
1245                break 'o TINFLStatus::Done;
1246            }
1247
1248            fill_bit_buffer(&mut l, in_iter);
1249
1250            let (symbol, code_len) = r.tables[LITLEN_TABLE].lookup(l.bit_buf);
1251            l.counter = symbol as u32;
1252            l.bit_buf >>= code_len;
1253            l.num_bits -= code_len;
1254
1255            if (l.counter & 256) != 0 {
1256                // The symbol is not a literal.
1257                break;
1258            } else {
1259                // If we have a 32-bit buffer we need to read another two bytes now
1260                // to have enough bits to keep going.
1261                if cfg!(not(target_pointer_width = "64")) {
1262                    fill_bit_buffer(&mut l, in_iter);
1263                }
1264
1265                let (symbol, code_len) = r.tables[LITLEN_TABLE].lookup(l.bit_buf);
1266                l.bit_buf >>= code_len;
1267                l.num_bits -= code_len;
1268                // The previous symbol was a literal, so write it directly and check
1269                // the next one.
1270                out_buf.write_byte(l.counter as u8);
1271                if (symbol & 256) != 0 {
1272                    l.counter = symbol as u32;
1273                    // The symbol is a length value.
1274                    break;
1275                } else {
1276                    // The symbol is a literal, so write it directly and continue.
1277                    out_buf.write_byte(symbol as u8);
1278                }
1279            }
1280        }
1281
1282        // Mask the top bits since they may contain length info.
1283        l.counter &= 511;
1284        if l.counter == 256 {
1285            // We hit the end of block symbol.
1286            state.begin(BlockDone);
1287            break 'o TINFLStatus::Done;
1288        } else if l.counter > 285 {
1289            // Invalid code.
1290            // We already verified earlier that the code is > 256.
1291            state.begin(InvalidLitlen);
1292            break 'o TINFLStatus::Failed;
1293        } else {
1294            // The symbol was a length code.
1295            // # Optimization
1296            // Mask the value to avoid bounds checks
1297            // While the maximum is checked, the compiler isn't able to know that the
1298            // value won't wrap around here.
1299            l.num_extra = LENGTH_EXTRA[(l.counter - 257) as usize & BASE_EXTRA_MASK];
1300            l.counter = u32::from(LENGTH_BASE[(l.counter - 257) as usize & BASE_EXTRA_MASK]);
1301            // Length and distance codes have a number of extra bits depending on
1302            // the base, which together with the base gives us the exact value.
1303
1304            // We need to make sure we have at least 33 (so min 5 bytes) bits in the buffer at this spot.
1305            fill_bit_buffer(&mut l, in_iter);
1306            if l.num_extra != 0 {
1307                let extra_bits = l.bit_buf & ((1 << l.num_extra) - 1);
1308                l.bit_buf >>= l.num_extra;
1309                l.num_bits -= u32::from(l.num_extra);
1310                l.counter += extra_bits as u32;
1311            }
1312
1313            // We found a length code, so a distance code should follow.
1314
1315            if cfg!(not(target_pointer_width = "64")) {
1316                fill_bit_buffer(&mut l, in_iter);
1317            }
1318
1319            let (mut symbol, code_len) = r.tables[DIST_TABLE].lookup(l.bit_buf);
1320            symbol &= 511;
1321            l.bit_buf >>= code_len;
1322            l.num_bits -= code_len;
1323            if symbol > 29 {
1324                state.begin(InvalidDist);
1325                break 'o TINFLStatus::Failed;
1326            }
1327
1328            l.num_extra = num_extra_bits_for_distance_code(symbol as u8);
1329            l.dist = u32::from(DIST_BASE[symbol as usize]);
1330
1331            if l.num_extra != 0 {
1332                fill_bit_buffer(&mut l, in_iter);
1333                let extra_bits = l.bit_buf & ((1 << l.num_extra) - 1);
1334                l.bit_buf >>= l.num_extra;
1335                l.num_bits -= u32::from(l.num_extra);
1336                l.dist += extra_bits as u32;
1337            }
1338
1339            let position = out_buf.position();
1340            if (l.dist as usize > out_buf.position()
1341                && (flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF != 0))
1342                || (l.dist as usize > out_buf.get_ref().len())
1343            {
1344                // We encountered a distance that refers a position before
1345                // the start of the decoded data, so we can't continue.
1346                state.begin(DistanceOutOfBounds);
1347                break TINFLStatus::Failed;
1348            }
1349
1350            apply_match(
1351                out_buf.get_mut(),
1352                position,
1353                l.dist as usize,
1354                l.counter as usize,
1355                out_buf_size_mask,
1356            );
1357
1358            out_buf.set_position(position + l.counter as usize);
1359        }
1360    };
1361
1362    *local_vars = l;
1363    (status, state)
1364}
1365
1366/// Main decompression function. Keeps decompressing data from `in_buf` until the `in_buf` is
1367/// empty, `out` is full, the end of the deflate stream is hit, or there is an error in the
1368/// deflate stream.
1369///
1370/// # Arguments
1371///
1372/// `r` is a [`DecompressorOxide`] struct with the state of this stream.
1373///
1374/// `in_buf` is a reference to the compressed data that is to be decompressed. The decompressor will
1375/// start at the first byte of this buffer.
1376///
1377/// `out` is a reference to the buffer that will store the decompressed data, and that
1378/// stores previously decompressed data if any.
1379///
1380/// * The offset given by `out_pos` indicates where in the output buffer slice writing should start.
1381/// * If [`TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF`] is not set, the output buffer is used in a
1382///   wrapping manner, and it's size is required to be a power of 2.
1383/// * The decompression function normally needs access to 32KiB of the previously decompressed data
1384///   (or to the beginning of the decompressed data if less than 32KiB has been decompressed.)
1385///     - If this data is not available, decompression may fail.
1386///     - Some deflate compressors allow specifying a window size which limits match distances to
1387///       less than this, or alternatively an RLE mode where matches will only refer to the previous byte
1388///       and thus allows a smaller output buffer. The window size can be specified in the zlib
1389///       header structure, however, the header data should not be relied on to be correct.
1390///
1391/// `flags` indicates settings and status to the decompression function.
1392/// * The [`TINFL_FLAG_HAS_MORE_INPUT`] has to be specified if more compressed data is to be provided
1393///   in a subsequent call to this function.
1394/// * See the the [`inflate_flags`] module for details on other flags.
1395///
1396/// # Returns
1397///
1398/// Returns a tuple containing the status of the compressor, the number of input bytes read, and the
1399/// number of bytes output to `out`.
1400pub fn decompress(
1401    r: &mut DecompressorOxide,
1402    in_buf: &[u8],
1403    out: &mut [u8],
1404    out_pos: usize,
1405    flags: u32,
1406) -> (TINFLStatus, usize, usize) {
1407    decompress_with_limit(r, in_buf, out, out_pos, usize::MAX, flags)
1408}
1409
1410/// Same as [`decompress()`] with a maximum decompressed byte count.
1411///
1412/// By default [`decompress()`] decompress untill end of `out` buffer if possible.
1413/// `decompress_with_limit` will stop when `out_max` bytes have been decompressed,
1414/// or when `out` buffer is full, whichever comes first.
1415///
1416/// This is especially useful when using a wrapping output buffer. This helps keeping
1417/// some data that has not yet been consumed in the buffer while decompressing new bytes.
1418///
1419/// `out_max` is the maximum number of *bytes* that decompress will write
1420pub fn decompress_with_limit(
1421    r: &mut DecompressorOxide,
1422    in_buf: &[u8],
1423    out: &mut [u8],
1424    out_pos: usize,
1425    out_max: usize,
1426    flags: u32,
1427) -> (TINFLStatus, usize, usize) {
1428    let out_buf_size_mask = if flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF != 0 {
1429        usize::MAX
1430    } else {
1431        // In the case of zero len, any attempt to write would produce HasMoreOutput,
1432        // so to gracefully process the case of there really being no output,
1433        // set the mask to all zeros.
1434        out.len().saturating_sub(1)
1435    };
1436
1437    // Ensure the output buffer's size is a power of 2, unless the output buffer
1438    // is large enough to hold the entire output file (in which case it doesn't
1439    // matter).
1440    // Also make sure that the output buffer position is not past the end of the output buffer.
1441    if (out_buf_size_mask.wrapping_add(1) & out_buf_size_mask) != 0 || out_pos > out.len() {
1442        return (TINFLStatus::BadParam, 0, 0);
1443    }
1444
1445    let mut in_iter = InputWrapper::from_slice(in_buf);
1446
1447    let mut state = r.state;
1448
1449    let mut out_buf = OutputBuffer::from_slice_pos_and_max(out, out_pos, out_max);
1450
1451    // Make a local copy of the important variables here so we can work with them on the stack.
1452    let mut l = LocalVars {
1453        bit_buf: r.bit_buf,
1454        num_bits: r.num_bits,
1455        dist: r.dist,
1456        counter: r.counter,
1457        num_extra: r.num_extra,
1458    };
1459
1460    let mut status = 'state_machine: loop {
1461        match state {
1462            Start => generate_state!(state, 'state_machine, {
1463                l.bit_buf = 0;
1464                l.num_bits = 0;
1465                l.dist = 0;
1466                l.counter = 0;
1467                l.num_extra = 0;
1468                r.z_header0 = 0;
1469                r.z_header1 = 0;
1470                r.z_adler32 = 1;
1471                r.check_adler32 = 1;
1472                if flags & TINFL_FLAG_PARSE_ZLIB_HEADER != 0 {
1473                    Action::Jump(State::ReadZlibCmf)
1474                } else {
1475                    Action::Jump(State::ReadBlockHeader)
1476                }
1477            }),
1478
1479            ReadZlibCmf => generate_state!(state, 'state_machine, {
1480                read_byte(&mut in_iter, flags, |cmf| {
1481                    r.z_header0 = u32::from(cmf);
1482                    Action::Jump(State::ReadZlibFlg)
1483                })
1484            }),
1485
1486            ReadZlibFlg => generate_state!(state, 'state_machine, {
1487                read_byte(&mut in_iter, flags, |flg| {
1488                    r.z_header1 = u32::from(flg);
1489                    validate_zlib_header(r.z_header0, r.z_header1, flags, out_buf_size_mask)
1490                })
1491            }),
1492
1493            // Read the block header and jump to the relevant section depending on the block type.
1494            ReadBlockHeader => generate_state!(state, 'state_machine, {
1495                read_bits(&mut l, 3, &mut in_iter, flags, |l, bits| {
1496                    r.finish = (bits & 1) as u8;
1497                    r.block_type = ((bits >> 1) & 3) as u8;
1498                    match r.block_type {
1499                        0 => Action::Jump(BlockTypeNoCompression),
1500                        1 => {
1501                            start_static_table(r);
1502                            init_tree(r, l).unwrap_or(Action::End(TINFLStatus::Failed))
1503                        },
1504                        2 => {
1505                            l.counter = 0;
1506                            Action::Jump(ReadTableSizes)
1507                        },
1508                        3 => Action::Jump(BlockTypeUnexpected),
1509                        _ => unreachable!()
1510                    }
1511                })
1512            }),
1513
1514            // Raw/Stored/uncompressed block.
1515            BlockTypeNoCompression => generate_state!(state, 'state_machine, {
1516                pad_to_bytes(&mut l, &mut in_iter, flags, |l| {
1517                    l.counter = 0;
1518                    Action::Jump(RawHeader)
1519                })
1520            }),
1521
1522            // Check that the raw block header is correct.
1523            RawHeader => generate_state!(state, 'state_machine, {
1524                if l.counter < 4 {
1525                    // Read block length and block length check.
1526                    if l.num_bits != 0 {
1527                        read_bits(&mut l, 8, &mut in_iter, flags, |l, bits| {
1528                            r.raw_header[l.counter as usize] = bits as u8;
1529                            l.counter += 1;
1530                            Action::None
1531                        })
1532                    } else {
1533                        read_byte(&mut in_iter, flags, |byte| {
1534                            r.raw_header[l.counter as usize] = byte;
1535                            l.counter += 1;
1536                            Action::None
1537                        })
1538                    }
1539                } else {
1540                    // Check if the length value of a raw block is correct.
1541                    // The 2 first (2-byte) words in a raw header are the length and the
1542                    // ones complement of the length.
1543                    let length = u16::from(r.raw_header[0]) | (u16::from(r.raw_header[1]) << 8);
1544                    let check = u16::from(r.raw_header[2]) | (u16::from(r.raw_header[3]) << 8);
1545                    let valid = length == !check;
1546                    l.counter = length.into();
1547
1548                    if !valid {
1549                        Action::Jump(BadRawLength)
1550                    } else if l.counter == 0 {
1551                        // Empty raw block. Sometimes used for synchronization.
1552                        Action::Jump(BlockDone)
1553                    } else if l.num_bits != 0 {
1554                        // There is some data in the bit buffer, so we need to write that first.
1555                        Action::Jump(RawReadFirstByte)
1556                    } else {
1557                        // The bit buffer is empty, so memcpy the rest of the uncompressed data from
1558                        // the block.
1559                        Action::Jump(RawMemcpy1)
1560                    }
1561                }
1562            }),
1563
1564            // Read the byte from the bit buffer.
1565            RawReadFirstByte => generate_state!(state, 'state_machine, {
1566                read_bits(&mut l, 8, &mut in_iter, flags, |l, bits| {
1567                    l.dist = bits as u32;
1568                    Action::Jump(RawStoreFirstByte)
1569                })
1570            }),
1571
1572            // Write the byte we just read to the output buffer.
1573            RawStoreFirstByte => generate_state!(state, 'state_machine, {
1574                if out_buf.bytes_left() == 0 {
1575                    Action::End(TINFLStatus::HasMoreOutput)
1576                } else {
1577                    out_buf.write_byte(l.dist as u8);
1578                    l.counter -= 1;
1579                    if l.counter == 0 || l.num_bits == 0 {
1580                        Action::Jump(RawMemcpy1)
1581                    } else {
1582                        // There is still some data left in the bit buffer that needs to be output.
1583                        // TODO: Changed this to jump to `RawReadfirstbyte` rather than
1584                        // `RawStoreFirstByte` as that seemed to be the correct path, but this
1585                        // needs testing.
1586                        Action::Jump(RawReadFirstByte)
1587                    }
1588                }
1589            }),
1590
1591            RawMemcpy1 => generate_state!(state, 'state_machine, {
1592                if l.counter == 0 {
1593                    Action::Jump(BlockDone)
1594                } else if out_buf.bytes_left() == 0 {
1595                    Action::End(TINFLStatus::HasMoreOutput)
1596                } else {
1597                    Action::Jump(RawMemcpy2)
1598                }
1599            }),
1600
1601            RawMemcpy2 => generate_state!(state, 'state_machine, {
1602                if in_iter.bytes_left() > 0 {
1603                    // Copy as many raw bytes as possible from the input to the output using memcpy.
1604                    // Raw block lengths are limited to 64 * 1024, so casting through usize and u32
1605                    // is not an issue.
1606                    let space_left = out_buf.bytes_left();
1607                    let bytes_to_copy = cmp::min(cmp::min(
1608                        space_left,
1609                        in_iter.bytes_left()),
1610                        l.counter as usize
1611                    );
1612
1613                    out_buf.write_slice(&in_iter.as_slice()[..bytes_to_copy]);
1614
1615                    in_iter.advance(bytes_to_copy);
1616                    l.counter -= bytes_to_copy as u32;
1617                    Action::Jump(RawMemcpy1)
1618                } else {
1619                    end_of_input(flags)
1620                }
1621            }),
1622
1623            // Read how many huffman codes/symbols are used for each table.
1624            ReadTableSizes => generate_state!(state, 'state_machine, {
1625                if l.counter < 3 {
1626                    let num_bits = [5, 5, 4][l.counter as usize];
1627                    read_bits(&mut l, num_bits, &mut in_iter, flags, |l, bits| {
1628                        r.table_sizes[l.counter as usize] =
1629                            bits as u16 + MIN_TABLE_SIZES[l.counter as usize];
1630                        l.counter += 1;
1631                        Action::None
1632                    })
1633                } else {
1634                    r.code_size_huffman.fill(0);
1635                    l.counter = 0;
1636                    // Check that the litlen and distance are within spec.
1637                    // litlen table should be <=286 acc to the RFC and
1638                    // additionally zlib rejects dist table sizes larger than 30.
1639                    // NOTE this the final sizes after adding back predefined values, not
1640                    // raw value in the data.
1641                    // See miniz_oxide issue #130 and https://github.com/madler/zlib/issues/82.
1642                    if r.table_sizes[LITLEN_TABLE] <= 286 && r.table_sizes[DIST_TABLE] <= 30 {
1643                        Action::Jump(ReadHufflenTableCodeSize)
1644                    }
1645                    else {
1646                        Action::Jump(BadDistOrLiteralTableLength)
1647                    }
1648                }
1649            }),
1650
1651            // Read the 3-bit lengths of the huffman codes describing the huffman code lengths used
1652            // to decode the lengths of the main tables.
1653            ReadHufflenTableCodeSize => generate_state!(state, 'state_machine, {
1654                if l.counter < r.table_sizes[HUFFLEN_TABLE].into() {
1655                    read_bits(&mut l, 3, &mut in_iter, flags, |l, bits| {
1656                        // These lengths are not stored in a normal ascending order, but rather one
1657                        // specified by the deflate specification intended to put the most used
1658                        // values at the front as trailing zero lengths do not have to be stored.
1659                        r.code_size_huffman[HUFFMAN_LENGTH_ORDER[l.counter as usize] as usize] =
1660                                bits as u8;
1661                        l.counter += 1;
1662                        Action::None
1663                    })
1664                } else {
1665                    r.table_sizes[HUFFLEN_TABLE] = MAX_HUFF_SYMBOLS_2 as u16;
1666                    init_tree(r, &mut l).unwrap_or(Action::End(TINFLStatus::Failed))
1667                }
1668            }),
1669
1670            ReadLitlenDistTablesCodeSize => generate_state!(state, 'state_machine, {
1671                if l.counter < u32::from(r.table_sizes[LITLEN_TABLE]) + u32::from(r.table_sizes[DIST_TABLE]) {
1672                    decode_huffman_code(
1673                        r, &mut l, HUFFLEN_TABLE,
1674                        flags, &mut in_iter, |r, l, symbol| {
1675                            l.dist = symbol as u32;
1676                            if l.dist < 16 {
1677                                r.len_codes[l.counter as usize & LEN_CODES_MASK] = l.dist as u8;
1678                                l.counter += 1;
1679                                Action::None
1680                            } else if l.dist == 16 && l.counter == 0 {
1681                                Action::Jump(BadCodeSizeDistPrevLookup)
1682                            } else {
1683                                // Last value is a dummy to allow mask.
1684                                l.num_extra = [2, 3, 7, 0][(l.dist as usize - 16) & 3];
1685                                Action::Jump(ReadExtraBitsCodeSize)
1686                            }
1687                        }
1688                    )
1689                } else if l.counter != u32::from(r.table_sizes[LITLEN_TABLE]) + u32::from(r.table_sizes[DIST_TABLE]) {
1690                    Action::Jump(BadCodeSizeSum)
1691                } else {
1692
1693                    r.code_size_literal[..r.table_sizes[LITLEN_TABLE] as usize]
1694                        .copy_from_slice(&r.len_codes[..r.table_sizes[LITLEN_TABLE] as usize & LEN_CODES_MASK]);
1695
1696                    let dist_table_start = r.table_sizes[LITLEN_TABLE] as usize;
1697                    debug_assert!(dist_table_start < r.len_codes.len());
1698                    let dist_table_end = (r.table_sizes[LITLEN_TABLE] +
1699                                          r.table_sizes[DIST_TABLE]) as usize;
1700                    let code_size_dist_end = r.table_sizes[DIST_TABLE] as usize;
1701                    debug_assert!(dist_table_end < r.len_codes.len());
1702                    debug_assert!(code_size_dist_end < r.code_size_dist.len());
1703                    let dist_table_start = dist_table_start & LEN_CODES_MASK;
1704                    let dist_table_end = dist_table_end & LEN_CODES_MASK;
1705                    r.code_size_dist[..code_size_dist_end & (MAX_HUFF_SYMBOLS_1 - 1)]
1706                        .copy_from_slice(&r.len_codes[dist_table_start..dist_table_end]);
1707
1708                    r.block_type -= 1;
1709                    init_tree(r, &mut l).unwrap_or(Action::End(TINFLStatus::Failed))
1710                }
1711            }),
1712
1713            ReadExtraBitsCodeSize => generate_state!(state, 'state_machine, {
1714                let num_extra = l.num_extra.into();
1715                read_bits(&mut l, num_extra, &mut in_iter, flags, |l, mut extra_bits| {
1716                    // Mask to avoid a bounds check.
1717                    // We can use 2 since the 2 first values are the same.
1718                    extra_bits += [3, 3, 11][(l.dist as usize - 16) & 2];
1719                    let val = if l.dist == 16 {
1720                        debug_assert!(l.counter as usize - 1 < r.len_codes.len());
1721                        r.len_codes[(l.counter as usize - 1) & LEN_CODES_MASK]
1722                    } else {
1723                        0
1724                    };
1725
1726                    let fill_start = l.counter as usize;
1727                    let fill_end = l.counter as usize + extra_bits as usize;
1728                    debug_assert!(fill_start < r.len_codes.len());
1729                    debug_assert!(fill_end < r.len_codes.len());
1730
1731                    r.len_codes[
1732                            fill_start & LEN_CODES_MASK..fill_end & LEN_CODES_MASK
1733                        ].fill(val);
1734                    l.counter += extra_bits as u32;
1735                    Action::Jump(ReadLitlenDistTablesCodeSize)
1736                })
1737            }),
1738
1739            DecodeLitlen => generate_state!(state, 'state_machine, {
1740                if in_iter.bytes_left() < 4 || out_buf.bytes_left() < 2 {
1741                    // See if we can decode a literal with the data we have left.
1742                    // Jumps to next state (WriteSymbol) if successful.
1743                    decode_huffman_code(
1744                        r,
1745                        &mut l,
1746                        LITLEN_TABLE,
1747                        flags,
1748                        &mut in_iter,
1749                        |_r, l, symbol| {
1750                            l.counter = symbol as u32;
1751                            Action::Jump(WriteSymbol)
1752                        },
1753                    )
1754                } else if
1755                // If there is enough space, use the fast inner decompression
1756                // function.
1757                    out_buf.bytes_left() >= 259 &&
1758                    in_iter.bytes_left() >= 14
1759                {
1760                    let (status, new_state) = decompress_fast(
1761                        r,
1762                        &mut in_iter,
1763                        &mut out_buf,
1764                        flags,
1765                        &mut l,
1766                        out_buf_size_mask,
1767                    );
1768
1769                    state = new_state;
1770                    if status == TINFLStatus::Done {
1771                        Action::Jump(new_state)
1772                    } else {
1773                        Action::End(status)
1774                    }
1775                } else {
1776                    fill_bit_buffer(&mut l, &mut in_iter);
1777
1778                    let (symbol, code_len) = r.tables[LITLEN_TABLE].lookup(l.bit_buf);
1779
1780                    l.counter = symbol as u32;
1781                    l.bit_buf >>= code_len;
1782                    l.num_bits -= code_len;
1783
1784                    if (l.counter & 256) != 0 {
1785                        // The symbol is not a literal.
1786                        Action::Jump(HuffDecodeOuterLoop1)
1787                    } else {
1788                        // If we have a 32-bit buffer we need to read another two bytes now
1789                        // to have enough bits to keep going.
1790                        if cfg!(not(target_pointer_width = "64")) {
1791                            fill_bit_buffer(&mut l, &mut in_iter);
1792                        }
1793
1794                        let (symbol, code_len) = r.tables[LITLEN_TABLE].lookup(l.bit_buf);
1795
1796                            l.bit_buf >>= code_len;
1797                            l.num_bits -= code_len;
1798                            // The previous symbol was a literal, so write it directly and check
1799                            // the next one.
1800                            out_buf.write_byte(l.counter as u8);
1801                            if (symbol & 256) != 0 {
1802                                l.counter = symbol as u32;
1803                                // The symbol is a length value.
1804                                Action::Jump(HuffDecodeOuterLoop1)
1805                            } else {
1806                                // The symbol is a literal, so write it directly and continue.
1807                                out_buf.write_byte(symbol as u8);
1808                                Action::None
1809                            }
1810
1811                    }
1812
1813                }
1814            }),
1815
1816            WriteSymbol => generate_state!(state, 'state_machine, {
1817                if l.counter >= 256 {
1818                    Action::Jump(HuffDecodeOuterLoop1)
1819                } else if out_buf.bytes_left() > 0 {
1820                    out_buf.write_byte(l.counter as u8);
1821                    Action::Jump(DecodeLitlen)
1822                } else {
1823                    Action::End(TINFLStatus::HasMoreOutput)
1824                }
1825            }),
1826
1827            HuffDecodeOuterLoop1 => generate_state!(state, 'state_machine, {
1828                // Mask the top bits since they may contain length info.
1829                l.counter &= 511;
1830
1831                if l.counter
1832                    == 256 {
1833                    // We hit the end of block symbol.
1834                    Action::Jump(BlockDone)
1835                } else if l.counter > 285 {
1836                    // Invalid code.
1837                    // We already verified earlier that the code is > 256.
1838                    Action::Jump(InvalidLitlen)
1839                } else {
1840                    // # Optimization
1841                    // Mask the value to avoid bounds checks
1842                    // We could use get_unchecked later if can statically verify that
1843                    // this will never go out of bounds.
1844                    l.num_extra =
1845                        LENGTH_EXTRA[(l.counter - 257) as usize & BASE_EXTRA_MASK];
1846                    l.counter = u32::from(LENGTH_BASE[(l.counter - 257) as usize & BASE_EXTRA_MASK]);
1847                    // Length and distance codes have a number of extra bits depending on
1848                    // the base, which together with the base gives us the exact value.
1849                    if l.num_extra != 0 {
1850                        Action::Jump(ReadExtraBitsLitlen)
1851                    } else {
1852                        Action::Jump(DecodeDistance)
1853                    }
1854                }
1855            }),
1856
1857            ReadExtraBitsLitlen => generate_state!(state, 'state_machine, {
1858                let num_extra = l.num_extra.into();
1859                read_bits(&mut l, num_extra, &mut in_iter, flags, |l, extra_bits| {
1860                    l.counter += extra_bits as u32;
1861                    Action::Jump(DecodeDistance)
1862                })
1863            }),
1864
1865            DecodeDistance => generate_state!(state, 'state_machine, {
1866                // Try to read a huffman code from the input buffer and look up what
1867                // length code the decoded symbol refers to.
1868                decode_huffman_code(r, &mut l, DIST_TABLE, flags, &mut in_iter, |_r, l, symbol| {
1869                    // # Optimizaton - transform the value into usize here before the check so
1870                    // the compiler can optimize the bounds check later - ideally it should
1871                    // know that the value can't be negative from earlier in the
1872                    // decode_huffman_code function but it seems it may not be able
1873                    // to make the assumption that it can't be negative and thus
1874                    // overflow if it's converted after the check.
1875                    let symbol = symbol as usize;
1876                    if symbol > 29 {
1877                        // Invalid distance code.
1878                        return Action::Jump(InvalidDist)
1879                    }
1880                    l.num_extra = num_extra_bits_for_distance_code(symbol as u8);
1881                    l.dist = u32::from(DIST_BASE[symbol]);
1882                    if l.num_extra != 0 {
1883                        // ReadEXTRA_BITS_DISTACNE
1884                        Action::Jump(ReadExtraBitsDistance)
1885                    } else {
1886                        Action::Jump(HuffDecodeOuterLoop2)
1887                    }
1888                })
1889            }),
1890
1891            ReadExtraBitsDistance => generate_state!(state, 'state_machine, {
1892                let num_extra = l.num_extra.into();
1893                read_bits(&mut l, num_extra, &mut in_iter, flags, |l, extra_bits| {
1894                    l.dist += extra_bits as u32;
1895                    Action::Jump(HuffDecodeOuterLoop2)
1896                })
1897            }),
1898
1899            HuffDecodeOuterLoop2 => generate_state!(state, 'state_machine, {
1900                if (l.dist as usize > out_buf.position() &&
1901                    (flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF != 0)) || (l.dist as usize > out_buf.get_ref().len())
1902                {
1903                    // We encountered a distance that refers a position before
1904                    // the start of the decoded data, so we can't continue.
1905                    Action::Jump(DistanceOutOfBounds)
1906                } else {
1907                    let out_pos = out_buf.position();
1908                    let source_pos = out_buf.position()
1909                        .wrapping_sub(l.dist as usize) & out_buf_size_mask;
1910
1911                    let out_len = out_buf.bytes_left();
1912                    let match_end_pos = out_buf.position() + l.counter as usize;
1913
1914                    if match_end_pos > out_len ||
1915                        // miniz doesn't do this check here. Not sure how it makes sure
1916                        // that this case doesn't happen.
1917                        (source_pos >= out_pos && (source_pos - out_pos) < l.counter as usize)
1918                    {
1919                        // Not enough space for all of the data in the output buffer,
1920                        // so copy what we have space for.
1921                        if l.counter == 0 {
1922                            Action::Jump(DecodeLitlen)
1923                        } else {
1924                            Action::Jump(WriteLenBytesToEnd)
1925                        }
1926                    } else {
1927                        apply_match(
1928                            out_buf.get_mut(),
1929                            out_pos,
1930                            l.dist as usize,
1931                            l.counter as usize,
1932                            out_buf_size_mask
1933                        );
1934                        out_buf.set_position(out_pos + l.counter as usize);
1935                        Action::Jump(DecodeLitlen)
1936                    }
1937                }
1938            }),
1939
1940            WriteLenBytesToEnd => generate_state!(state, 'state_machine, {
1941                if out_buf.bytes_left() > 0 {
1942                    let out_pos = out_buf.position();
1943                    let source_pos = out_buf.position()
1944                        .wrapping_sub(l.dist as usize) & out_buf_size_mask;
1945
1946
1947                    let len = cmp::min(out_buf.bytes_left(), l.counter as usize);
1948
1949                    transfer(out_buf.get_mut(), source_pos, out_pos, len, out_buf_size_mask);
1950
1951                    out_buf.set_position(out_pos + len);
1952                    l.counter -= len as u32;
1953                    if l.counter == 0 {
1954                        Action::Jump(DecodeLitlen)
1955                    } else {
1956                        Action::None
1957                    }
1958                } else {
1959                    Action::End(TINFLStatus::HasMoreOutput)
1960                }
1961            }),
1962
1963            BlockDone => generate_state!(state, 'state_machine, {
1964                // End once we've read the last block.
1965                if r.finish != 0 {
1966                    pad_to_bytes(&mut l, &mut in_iter, flags, |_| Action::None);
1967
1968                    let in_consumed = in_buf.len() - in_iter.bytes_left();
1969                    let undo = undo_bytes(&mut l, in_consumed as u32) as usize;
1970                    in_iter = InputWrapper::from_slice(in_buf[in_consumed - undo..].iter().as_slice());
1971
1972                    l.bit_buf &= ((1 as BitBuffer) << l.num_bits) - 1;
1973                    debug_assert_eq!(l.num_bits, 0);
1974
1975                    if flags & TINFL_FLAG_PARSE_ZLIB_HEADER != 0 {
1976                        l.counter = 0;
1977                        Action::Jump(ReadAdler32)
1978                    } else {
1979                        Action::Jump(DoneForever)
1980                    }
1981                } else {
1982                    #[cfg(feature = "block-boundary")]
1983                    if flags & TINFL_FLAG_STOP_ON_BLOCK_BOUNDARY != 0 {
1984                        Action::End(TINFLStatus::BlockBoundary)
1985                    } else {
1986                        Action::Jump(ReadBlockHeader)
1987                    }
1988                    #[cfg(not(feature = "block-boundary"))]
1989                    {
1990                        Action::Jump(ReadBlockHeader)
1991                    }
1992                }
1993            }),
1994
1995            ReadAdler32 => generate_state!(state, 'state_machine, {
1996                if l.counter < 4 {
1997                    if l.num_bits != 0 {
1998                        read_bits(&mut l, 8, &mut in_iter, flags, |l, bits| {
1999                            r.z_adler32 <<= 8;
2000                            r.z_adler32 |= bits as u32;
2001                            l.counter += 1;
2002                            Action::None
2003                        })
2004                    } else {
2005                        read_byte(&mut in_iter, flags, |byte| {
2006                            r.z_adler32 <<= 8;
2007                            r.z_adler32 |= u32::from(byte);
2008                            l.counter += 1;
2009                            Action::None
2010                        })
2011                    }
2012                } else {
2013                    Action::Jump(DoneForever)
2014                }
2015            }),
2016
2017            // We are done.
2018            DoneForever => break TINFLStatus::Done,
2019
2020            // Anything else indicates failure.
2021            // BadZlibHeader | BadRawLength | BadDistOrLiteralTableLength | BlockTypeUnexpected |
2022            // DistanceOutOfBounds |
2023            // BadTotalSymbols | BadCodeSizeDistPrevLookup | BadCodeSizeSum | InvalidLitlen |
2024            // InvalidDist | InvalidCodeLen
2025            _ => break TINFLStatus::Failed,
2026        };
2027    };
2028
2029    let in_undo = if status != TINFLStatus::NeedsMoreInput
2030        && status != TINFLStatus::FailedCannotMakeProgress
2031    {
2032        undo_bytes(&mut l, (in_buf.len() - in_iter.bytes_left()) as u32) as usize
2033    } else {
2034        0
2035    };
2036
2037    // If we're returning after completing a block, prepare for the next block when called again.
2038    #[cfg(feature = "block-boundary")]
2039    if status == TINFLStatus::BlockBoundary {
2040        state = State::ReadBlockHeader;
2041    }
2042
2043    // Make sure HasMoreOutput overrides NeedsMoreInput if the output buffer is full.
2044    // (Unless the missing input is the adler32 value in which case we don't need to write anything.)
2045    // TODO: May want to see if we can do this in a better way.
2046    if status == TINFLStatus::NeedsMoreInput
2047        && out_buf.bytes_left() == 0
2048        && state != State::ReadAdler32
2049    {
2050        status = TINFLStatus::HasMoreOutput
2051    }
2052
2053    r.state = state;
2054    r.bit_buf = l.bit_buf;
2055    r.num_bits = l.num_bits;
2056    r.dist = l.dist;
2057    r.counter = l.counter;
2058    r.num_extra = l.num_extra;
2059
2060    r.bit_buf &= ((1 as BitBuffer) << r.num_bits) - 1;
2061
2062    // If this is a zlib stream, and update the adler32 checksum with the decompressed bytes if
2063    // requested.
2064    let need_adler = if (flags & TINFL_FLAG_IGNORE_ADLER32) == 0 {
2065        flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32) != 0
2066    } else {
2067        // If TINFL_FLAG_IGNORE_ADLER32 is enabled, ignore the checksum.
2068        false
2069    };
2070    if need_adler && status as i32 >= 0 {
2071        let out_buf_pos = out_buf.position();
2072        r.check_adler32 = update_adler32(r.check_adler32, &out_buf.get_ref()[out_pos..out_buf_pos]);
2073
2074        // disabled so that random input from fuzzer would not be rejected early,
2075        // before it has a chance to reach interesting parts of code
2076        if !cfg!(fuzzing) {
2077            // Once we are done, check if the checksum matches with the one provided in the zlib header.
2078            if status == TINFLStatus::Done
2079                && flags & TINFL_FLAG_PARSE_ZLIB_HEADER != 0
2080                && r.check_adler32 != r.z_adler32
2081            {
2082                status = TINFLStatus::Adler32Mismatch;
2083            }
2084        }
2085    }
2086
2087    (
2088        status,
2089        in_buf.len() - in_iter.bytes_left() - in_undo,
2090        out_buf.position() - out_pos,
2091    )
2092}
2093
2094#[cfg(test)]
2095mod test {
2096    use super::*;
2097
2098    //TODO: Fix these.
2099
2100    fn tinfl_decompress_oxide<'i>(
2101        r: &mut DecompressorOxide,
2102        input_buffer: &'i [u8],
2103        output_buffer: &mut [u8],
2104        flags: u32,
2105    ) -> (TINFLStatus, &'i [u8], usize) {
2106        let (status, in_pos, out_pos) = decompress(r, input_buffer, output_buffer, 0, flags);
2107        (status, &input_buffer[in_pos..], out_pos)
2108    }
2109
2110    #[test]
2111    fn decompress_zlib() {
2112        let encoded = [
2113            120, 156, 243, 72, 205, 201, 201, 215, 81, 168, 202, 201, 76, 82, 4, 0, 27, 101, 4, 19,
2114        ];
2115        let flags = TINFL_FLAG_COMPUTE_ADLER32 | TINFL_FLAG_PARSE_ZLIB_HEADER;
2116
2117        let mut b = DecompressorOxide::new();
2118        const LEN: usize = 32;
2119        let mut b_buf = [0; LEN];
2120
2121        // This should fail with the out buffer being to small.
2122        let b_status = tinfl_decompress_oxide(&mut b, &encoded[..], &mut b_buf, flags);
2123
2124        assert!(b_status.0 == TINFLStatus::Failed);
2125
2126        let flags = flags | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF;
2127
2128        b = DecompressorOxide::new();
2129
2130        // With TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF set this should no longer fail.
2131        let b_status = tinfl_decompress_oxide(&mut b, &encoded[..], &mut b_buf, flags);
2132
2133        assert_eq!(b_buf[..b_status.2], b"Hello, zlib!"[..]);
2134        assert!(b_status.0 == TINFLStatus::Done);
2135    }
2136
2137    #[cfg(feature = "with-alloc")]
2138    #[test]
2139    fn raw_block() {
2140        const LEN: usize = 64;
2141
2142        let text = b"Hello, zlib!";
2143        let encoded = {
2144            let len = text.len();
2145            let notlen = !len;
2146            let mut encoded = vec![
2147                1,
2148                len as u8,
2149                (len >> 8) as u8,
2150                notlen as u8,
2151                (notlen >> 8) as u8,
2152            ];
2153            encoded.extend_from_slice(&text[..]);
2154            encoded
2155        };
2156
2157        //let flags = TINFL_FLAG_COMPUTE_ADLER32 | TINFL_FLAG_PARSE_ZLIB_HEADER |
2158        let flags = TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF;
2159
2160        let mut b = DecompressorOxide::new();
2161
2162        let mut b_buf = [0; LEN];
2163
2164        let b_status = tinfl_decompress_oxide(&mut b, &encoded[..], &mut b_buf, flags);
2165        assert_eq!(b_buf[..b_status.2], text[..]);
2166        assert_eq!(b_status.0, TINFLStatus::Done);
2167    }
2168
2169    fn masked_lookup(table: &HuffmanTable, bit_buf: BitBuffer) -> (i32, u32) {
2170        let ret = table.lookup(bit_buf);
2171        (ret.0 & 511, ret.1)
2172    }
2173
2174    #[test]
2175    fn fixed_table_lookup() {
2176        let mut d = DecompressorOxide::new();
2177        d.block_type = 1;
2178        start_static_table(&mut d);
2179        let mut l = LocalVars {
2180            bit_buf: d.bit_buf,
2181            num_bits: d.num_bits,
2182            dist: d.dist,
2183            counter: d.counter,
2184            num_extra: d.num_extra,
2185        };
2186        init_tree(&mut d, &mut l).unwrap();
2187        let llt = &d.tables[LITLEN_TABLE];
2188        let dt = &d.tables[DIST_TABLE];
2189        assert_eq!(masked_lookup(llt, 0b00001100), (0, 8));
2190        assert_eq!(masked_lookup(llt, 0b00011110), (72, 8));
2191        assert_eq!(masked_lookup(llt, 0b01011110), (74, 8));
2192        assert_eq!(masked_lookup(llt, 0b11111101), (143, 8));
2193        assert_eq!(masked_lookup(llt, 0b000010011), (144, 9));
2194        assert_eq!(masked_lookup(llt, 0b111111111), (255, 9));
2195        assert_eq!(masked_lookup(llt, 0b00000000), (256, 7));
2196        assert_eq!(masked_lookup(llt, 0b1110100), (279, 7));
2197        assert_eq!(masked_lookup(llt, 0b00000011), (280, 8));
2198        assert_eq!(masked_lookup(llt, 0b11100011), (287, 8));
2199
2200        assert_eq!(masked_lookup(dt, 0), (0, 5));
2201        assert_eq!(masked_lookup(dt, 20), (5, 5));
2202    }
2203
2204    // Only run this test with alloc enabled as it uses a larger buffer.
2205    #[cfg(feature = "with-alloc")]
2206    fn check_result(input: &[u8], expected_status: TINFLStatus, expected_state: State, zlib: bool) {
2207        let mut r = DecompressorOxide::default();
2208        let mut output_buf = vec![0; 1024 * 32];
2209        let flags = if zlib {
2210            inflate_flags::TINFL_FLAG_PARSE_ZLIB_HEADER
2211        } else {
2212            0
2213        } | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF
2214            | TINFL_FLAG_HAS_MORE_INPUT;
2215        let (d_status, _in_bytes, _out_bytes) =
2216            decompress(&mut r, input, &mut output_buf, 0, flags);
2217        assert_eq!(expected_status, d_status);
2218        assert_eq!(expected_state, r.state);
2219    }
2220
2221    #[cfg(feature = "with-alloc")]
2222    #[test]
2223    fn bogus_input() {
2224        use self::check_result as cr;
2225        const F: TINFLStatus = TINFLStatus::Failed;
2226        const OK: TINFLStatus = TINFLStatus::Done;
2227        // Bad CM.
2228        cr(&[0x77, 0x85], F, State::BadZlibHeader, true);
2229        // Bad window size (but check is correct).
2230        cr(&[0x88, 0x98], F, State::BadZlibHeader, true);
2231        // Bad check bits.
2232        cr(&[0x78, 0x98], F, State::BadZlibHeader, true);
2233
2234        // Too many code lengths. (From inflate library issues)
2235        cr(
2236            b"M\xff\xffM*\xad\xad\xad\xad\xad\xad\xad\xcd\xcd\xcdM",
2237            F,
2238            State::BadDistOrLiteralTableLength,
2239            false,
2240        );
2241
2242        // Bad CLEN (also from inflate library issues)
2243        cr(
2244            b"\xdd\xff\xff*M\x94ffffffffff",
2245            F,
2246            State::BadDistOrLiteralTableLength,
2247            false,
2248        );
2249
2250        // Port of inflate coverage tests from zlib-ng
2251        // https://github.com/Dead2/zlib-ng/blob/develop/test/infcover.c
2252        let c = |a, b, c| cr(a, b, c, false);
2253
2254        // Invalid uncompressed/raw block length.
2255        c(&[0, 0, 0, 0, 0], F, State::BadRawLength);
2256        // Ok empty uncompressed block.
2257        c(&[3, 0], OK, State::DoneForever);
2258        // Invalid block type.
2259        c(&[6], F, State::BlockTypeUnexpected);
2260        // Ok uncompressed block.
2261        c(&[1, 1, 0, 0xfe, 0xff, 0], OK, State::DoneForever);
2262        // Too many litlens, we handle this later than zlib, so this test won't
2263        // give the same result.
2264        //        c(&[0xfc, 0, 0], F, State::BadTotalSymbols);
2265        // Invalid set of code lengths - TODO Check if this is the correct error for this.
2266        c(&[4, 0, 0xfe, 0xff], F, State::BadTotalSymbols);
2267        // Invalid repeat in list of code lengths.
2268        // (Try to repeat a non-existent code.)
2269        c(&[4, 0, 0x24, 0x49, 0], F, State::BadCodeSizeDistPrevLookup);
2270        // Missing end of block code (should we have a separate error for this?) - fails on further input
2271        //    c(&[4, 0, 0x24, 0xe9, 0xff, 0x6d], F, State::BadTotalSymbols);
2272        // Invalid set of literals/lengths
2273        c(
2274            &[
2275                4, 0x80, 0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0x71, 0xff, 0xff, 0x93, 0x11, 0,
2276            ],
2277            F,
2278            State::BadTotalSymbols,
2279        );
2280        // Invalid set of distances _ needsmoreinput
2281        // c(&[4, 0x80, 0x49, 0x92, 0x24, 0x49, 0x92, 0x24, 0x0f, 0xb4, 0xff, 0xff, 0xc3, 0x84], F, State::BadTotalSymbols);
2282        // Invalid distance code
2283        c(&[2, 0x7e, 0xff, 0xff], F, State::InvalidDist);
2284
2285        // Distance refers to position before the start
2286        c(
2287            &[0x0c, 0xc0, 0x81, 0, 0, 0, 0, 0, 0x90, 0xff, 0x6b, 0x4, 0],
2288            F,
2289            State::DistanceOutOfBounds,
2290        );
2291
2292        // Trailer
2293        // Bad gzip trailer checksum GZip header not handled by miniz_oxide
2294        //cr(&[0x1f, 0x8b, 0x08 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x03, 0, 0, 0, 0, 0x01], F, State::BadCRC, false)
2295        // Bad gzip trailer length
2296        //cr(&[0x1f, 0x8b, 0x08 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x03, 0, 0, 0, 0, 0, 0, 0, 0, 0x01], F, State::BadCRC, false)
2297    }
2298
2299    #[test]
2300    fn empty_output_buffer_non_wrapping() {
2301        let encoded = [
2302            120, 156, 243, 72, 205, 201, 201, 215, 81, 168, 202, 201, 76, 82, 4, 0, 27, 101, 4, 19,
2303        ];
2304        let flags = TINFL_FLAG_COMPUTE_ADLER32
2305            | TINFL_FLAG_PARSE_ZLIB_HEADER
2306            | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF;
2307        let mut r = DecompressorOxide::new();
2308        let mut output_buf: [u8; 0] = [];
2309        // Check that we handle an empty buffer properly and not panicking.
2310        // https://github.com/Frommi/miniz_oxide/issues/23
2311        let res = decompress(&mut r, &encoded, &mut output_buf, 0, flags);
2312        assert!(res == (TINFLStatus::HasMoreOutput, 4, 0));
2313    }
2314
2315    #[test]
2316    fn empty_output_buffer_wrapping() {
2317        let encoded = [
2318            0x73, 0x49, 0x4d, 0xcb, 0x49, 0x2c, 0x49, 0x55, 0x00, 0x11, 0x00,
2319        ];
2320        let flags = TINFL_FLAG_COMPUTE_ADLER32;
2321        let mut r = DecompressorOxide::new();
2322        let mut output_buf: [u8; 0] = [];
2323        // Check that we handle an empty buffer properly and not panicking.
2324        // https://github.com/Frommi/miniz_oxide/issues/23
2325        let res = decompress(&mut r, &encoded, &mut output_buf, 0, flags);
2326        assert!(res == (TINFLStatus::HasMoreOutput, 2, 0));
2327    }
2328
2329    #[test]
2330    fn dist_extra_bits() {
2331        use self::num_extra_bits_for_distance_code;
2332        // Number of extra bits for each distance code.
2333        const DIST_EXTRA: [u8; 29] = [
2334            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,
2335            12, 13,
2336        ];
2337
2338        for (i, &dist) in DIST_EXTRA.iter().enumerate() {
2339            assert_eq!(dist, num_extra_bits_for_distance_code(i as u8));
2340        }
2341    }
2342
2343    #[test]
2344    fn check_tree() {
2345        let mut r = DecompressorOxide::new();
2346        let mut l = LocalVars {
2347            bit_buf: 0,
2348            num_bits: 0,
2349            dist: 0,
2350            counter: 0,
2351            num_extra: 0,
2352        };
2353
2354        r.code_size_huffman[0] = 1;
2355        r.code_size_huffman[1] = 1;
2356        //r.code_size_huffman[2] = 3;
2357        //r.code_size_huffman[3] = 3;
2358        //r.code_size_huffman[1] = 4;
2359        r.block_type = HUFFLEN_TABLE as u8;
2360        r.table_sizes[HUFFLEN_TABLE] = 4;
2361        let res = init_tree(&mut r, &mut l).unwrap();
2362
2363        let status = match res {
2364            Action::Jump(s) => s,
2365            _ => {
2366                //println!("issue");
2367                return;
2368            }
2369        };
2370        //println!("status {:?}", status);
2371        assert!(status != BadTotalSymbols);
2372    }
2373
2374    #[test]
2375    fn reverse_bits_lookup() {
2376        use super::reverse_bits;
2377        for i in 0..512 {
2378            assert_eq!(reverse_bits(i), i.reverse_bits());
2379        }
2380    }
2381}