yazi/
decode.rs

1//! RFC 1590 decompression implementation.
2
3#![allow(
4    clippy::needless_range_loop,
5    clippy::new_without_default,
6    clippy::too_many_arguments
7)]
8
9use super::{Error, Format};
10use alloc::boxed::Box;
11use alloc::vec::Vec;
12
13#[cfg(feature = "std")]
14use std::io::{self, Write};
15
16/// Stateful context for decompression.
17///
18/// See the crate level [decompression](index.html#decompression) section
19/// for detailed usage.
20pub struct Decoder(InflateContext);
21
22impl Decoder {
23    /// Creates a new deflate decoder.
24    pub fn new() -> Self {
25        Self(InflateContext::new())
26    }
27
28    /// Creates a new deflate decoder on the heap.
29    pub fn boxed() -> Box<Self> {
30        Box::new(Self(InflateContext::new()))
31    }
32
33    /// Sets the expected format of the input data for the next usage of the
34    /// decoder.
35    pub fn set_format(&mut self, format: Format) {
36        self.0.reset(format == Format::Zlib)
37    }
38
39    /// Creates a decoder stream that will write into the specified writer.
40    #[cfg(feature = "std")]
41    pub fn stream<'a, W: Write>(
42        &'a mut self,
43        writer: &'a mut W,
44    ) -> DecoderStream<'a, impl Sink + 'a> {
45        self.0.reset(self.0.zlib);
46        DecoderStream {
47            ctx: &mut self.0,
48            sink: WriterSink {
49                writer,
50                ring: RingBuffer::new(),
51                written: 0,
52            },
53            finished: false,
54        }
55    }
56
57    /// Creates a decoder stream that will write into the specified vector.
58    /// The resulting stream will not clear the vector but will instead append
59    /// the decompressed data.     
60    pub fn stream_into_vec<'a>(
61        &'a mut self,
62        vec: &'a mut Vec<u8>,
63    ) -> DecoderStream<'a, impl Sink + 'a> {
64        self.0.reset(self.0.zlib);
65        DecoderStream {
66            ctx: &mut self.0,
67            sink: VecSink::new(vec),
68            finished: false,
69        }
70    }
71
72    /// Creates a decoder stream that will write into the specified buffer. The
73    /// stream will generate an overflow error if the buffer is not large enough
74    /// to contain the decompressed data.
75    pub fn stream_into_buf<'a>(
76        &'a mut self,
77        buf: &'a mut [u8],
78    ) -> DecoderStream<'a, impl Sink + 'a> {
79        self.0.reset(self.0.zlib);
80        DecoderStream {
81            ctx: &mut self.0,
82            sink: BufSink {
83                buffer: buf,
84                pos: 0,
85            },
86            finished: false,
87        }
88    }
89}
90
91/// Decompression stream combining a decoder context with an output.
92///
93/// See the crate level [decompression](index.html#decompression) section
94/// for detailed usage.
95pub struct DecoderStream<'a, S: Sink> {
96    ctx: &'a mut InflateContext,
97    sink: S,
98    finished: bool,
99}
100
101impl<S: Sink> DecoderStream<'_, S> {
102    /// Writes the specified buffer to the stream, producing decompressed data
103    /// in the output.
104    pub fn write(&mut self, buf: &[u8]) -> Result<(), Error> {
105        if self.finished {
106            return Err(Error::Finished);
107        }
108        self.ctx.inflate(buf, &mut self.sink, false)
109    }
110
111    /// Returns the number of decompressed bytes that have been written to the
112    /// output.
113    pub fn decompressed_size(&self) -> u64 {
114        self.sink.written()
115    }
116
117    /// Consumes the stream, flushing any input that may be buffered. Returns
118    /// the total number of decompressed bytes written to the output and an
119    /// optional checksum if the stream was zlib encoded.
120    pub fn finish(mut self) -> Result<(u64, Option<u32>), Error> {
121        if self.finished {
122            return Err(Error::Finished);
123        }
124        self.finished = true;
125        self.ctx.inflate(&[], &mut self.sink, true)?;
126        Ok((self.sink.written(), self.ctx.checksum))
127    }
128}
129
130impl<S: Sink> Drop for DecoderStream<'_, S> {
131    fn drop(&mut self) {
132        if !self.finished {
133            let _ = self.ctx.inflate(&[], &mut self.sink, true);
134            self.finished = true;
135        }
136    }
137}
138
139#[cfg(feature = "std")]
140impl<S: Sink> Write for DecoderStream<'_, S> {
141    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
142        match self.ctx.inflate(buf, &mut self.sink, false) {
143            Ok(_) => Ok(buf.len()),
144            Err(err) => match err {
145                Error::Io(err) => Err(err),
146                Error::Underflow | Error::Overflow => {
147                    Err(io::Error::from(io::ErrorKind::InvalidInput))
148                }
149                _ => Err(io::Error::from(io::ErrorKind::InvalidData)),
150            },
151        }
152    }
153
154    fn flush(&mut self) -> io::Result<()> {
155        Ok(())
156    }
157}
158
159/// Decompresses a buffer of the specified format into a vector.
160///
161/// On success, returns a vector containing the decompressed data and
162/// optionally an Adler-32 checksum if the source data was zlib
163/// encoded.
164pub fn decompress(buf: &[u8], format: Format) -> Result<(Vec<u8>, Option<u32>), Error> {
165    let mut decoder = Decoder::new();
166    decoder.set_format(format);
167    let mut vec = Vec::with_capacity(buf.len() * 2);
168    let mut stream = decoder.stream_into_vec(&mut vec);
169    stream.write(buf)?;
170    let (_, checksum) = stream.finish()?;
171    Ok((vec, checksum))
172}
173
174struct InflateContext {
175    zlib: bool,
176    state: State,
177    remainder: Remainder,
178    pos: usize,
179    bit_buffer: u64,
180    bits_in: u32,
181    trees: Trees,
182    checksum: Option<u32>,
183    last_block: bool,
184    done: bool,
185}
186
187impl InflateContext {
188    #[inline(always)]
189    fn new() -> Self {
190        Self {
191            zlib: false,
192            state: State::Block,
193            remainder: Remainder::new(),
194            bit_buffer: 0,
195            bits_in: 0,
196            pos: 0,
197            trees: Trees::new(),
198            checksum: None,
199            last_block: false,
200            done: false,
201        }
202    }
203
204    fn reset(&mut self, zlib: bool) {
205        self.zlib = zlib;
206        self.state = if zlib { State::Header } else { State::Block };
207        self.remainder.pos = 0;
208        self.remainder.avail = 0;
209        self.pos = 0;
210        self.bit_buffer = 0;
211        self.bits_in = 0;
212        self.checksum = None;
213        self.last_block = false;
214        self.done = false;
215    }
216
217    fn inflate<S: Sink>(
218        &mut self,
219        mut buf: &[u8],
220        sink: &mut S,
221        is_last: bool,
222    ) -> Result<(), Error> {
223        while !self.done && (is_last || !buf.is_empty()) {
224            let mut bits = Bits::new(self.bit_buffer, self.bits_in);
225            let (res, used_remainder) = if self.remainder.avail != 0 {
226                let used = self.remainder.push(buf);
227                buf = &buf[used..];
228                let mut source = Source::from_remainder(&self.remainder);
229                let res = inflate(
230                    self.zlib,
231                    &mut self.state,
232                    &mut self.last_block,
233                    &mut self.done,
234                    &mut source,
235                    &mut bits,
236                    &mut self.trees,
237                    sink,
238                    &mut self.checksum,
239                    is_last,
240                );
241                let source_pos = source.pos;
242                self.remainder.pos = source_pos;
243                self.remainder.avail -= source_pos;
244                (res, true)
245            } else {
246                let mut source = Source::new(buf);
247                let res = inflate(
248                    self.zlib,
249                    &mut self.state,
250                    &mut self.last_block,
251                    &mut self.done,
252                    &mut source,
253                    &mut bits,
254                    &mut self.trees,
255                    sink,
256                    &mut self.checksum,
257                    is_last,
258                );
259                buf = &buf[source.pos..];
260                (res, false)
261            };
262            self.bit_buffer = bits.bit_buffer;
263            self.bits_in = bits.bits_in;
264            let more_input = !buf.is_empty();
265            match res {
266                Err(Error::Underflow) => {
267                    if is_last && !more_input {
268                        return res;
269                    } else if !more_input {
270                        return Ok(());
271                    } else if self.remainder.avail != 0 || !used_remainder {
272                        let used = self.remainder.push(buf);
273                        buf = &buf[used..];
274                    }
275                }
276                Err(_) => {
277                    return res;
278                }
279                _ => {
280                    if is_last {
281                        return Ok(());
282                    }
283                }
284            }
285        }
286        Ok(())
287    }
288}
289
290#[derive(Copy, Clone, PartialEq, Debug)]
291enum State {
292    Header,
293    Block,
294    Copy(usize),
295    Inflate,
296    Match(u32),
297}
298
299fn inflate<S: Sink>(
300    zlib: bool,
301    state: &mut State,
302    last_block: &mut bool,
303    done: &mut bool,
304    source: &mut Source,
305    bits: &mut Bits,
306    trees: &mut Trees,
307    sink: &mut S,
308    checksum: &mut Option<u32>,
309    is_last: bool,
310) -> Result<(), Error> {
311    loop {
312        match *state {
313            State::Header => {
314                if bits.bytes_available(source) < 2 {
315                    return Err(Error::Underflow);
316                }
317                verify_zlib_header(source, bits)?;
318                *state = State::Block;
319                continue;
320            }
321            State::Block => {
322                if *last_block {
323                    if zlib && checksum.is_none() {
324                        bits.skip(bits.bits_in & 7);
325                        if bits.bytes_available(source) < 4 {
326                            return Err(Error::Underflow);
327                        }
328                        *checksum = Some(read_zlib_checksum(source, bits)?);
329                    }
330                    *done = true;
331                    return Ok(());
332                }
333                if bits.bytes_available(source) < 286 && !is_last {
334                    return Err(Error::Underflow);
335                }
336                let header = bits.try_pop_source(source, 3)?;
337                *last_block = header & 1 != 0;
338                match header >> 1 {
339                    0 => {
340                        bits.try_skip(bits.bits_in & 7)?;
341                        let mut parts = [0u32; 4];
342                        for part in &mut parts {
343                            if bits.bits_in >= 8 {
344                                *part = bits.pop(8);
345                            } else {
346                                *part = *source
347                                    .buffer
348                                    .get(source.pos)
349                                    .ok_or(Error::InvalidBitstream)?
350                                    as u32;
351                                source.pos += 1;
352                                source.avail -= 1;
353                            }
354                        }
355                        let length = parts[0] | (parts[1] << 8);
356                        let inv_length = parts[2] | (parts[3] << 8);
357                        if length != (!inv_length & 0xFFFF) {
358                            return Err(Error::InvalidBitstream);
359                        }
360                        let mut remaining = length as usize;
361                        while bits.bits_in >= 8 && remaining > 0 {
362                            sink.push(bits.pop(8) as u8)?;
363                            remaining -= 1;
364                        }
365                        if bits.bits_in == 0 {
366                            bits.bit_buffer = 0;
367                        }
368                        *state = State::Copy(remaining);
369                        while remaining > 0 {
370                            let bytes = source.try_get(remaining)?;
371                            sink.write(bytes)?;
372                            remaining -= bytes.len();
373                            *state = State::Copy(remaining);
374                        }
375                        *state = State::Block;
376                        continue;
377                    }
378                    1 => {
379                        const DISTANCE_LENGTHS: [u8; 32] = [5; 32];
380                        let mut lengths: [u8; 288] = [0; 288];
381                        lengths[0..144].iter_mut().for_each(|p| *p = 8);
382                        lengths[144..256].iter_mut().for_each(|p| *p = 9);
383                        lengths[256..280].iter_mut().for_each(|p| *p = 7);
384                        lengths[280..288].iter_mut().for_each(|p| *p = 8);
385                        trees.lt.build(&lengths[..288]);
386                        trees.dt.build(&DISTANCE_LENGTHS);
387                        *state = State::Inflate;
388                        continue;
389                    }
390                    2 => {
391                        decode_trees(source, bits, &mut trees.lt, &mut trees.dt, is_last)?;
392                        *state = State::Inflate;
393                        continue;
394                    }
395                    _ => {
396                        return Err(Error::InvalidBitstream);
397                    }
398                }
399            }
400            State::Copy(mut remaining) => {
401                while remaining > 0 {
402                    let bytes = source.try_get(remaining)?;
403                    sink.write(bytes)?;
404                    remaining -= bytes.len();
405                    *state = State::Copy(remaining);
406                }
407                *state = State::Block;
408                continue;
409            }
410            State::Inflate => {
411                let mut lbits = *bits;
412                let mut entry = 0;
413                if !is_last {
414                    loop {
415                        let mut handle_match = false;
416                        while lbits.bits_in >= 15 {
417                            entry = trees.lt.table[lbits.peek(LITERAL_LENGTH_TABLE_BITS) as usize];
418                            if entry & ENTRY_SUBTABLE != 0 {
419                                lbits.skip(LITERAL_LENGTH_TABLE_BITS);
420                                entry = trees.lt.table[(((entry >> ENTRY_SHIFT) & 0xFFFF)
421                                    + lbits.peek(entry & ENTRY_LENGTH_MASK))
422                                    as usize];
423                            }
424                            lbits.skip(entry & ENTRY_LENGTH_MASK);
425                            if entry & ENTRY_LITERAL == 0 {
426                                handle_match = true;
427                                break;
428                            }
429                            sink.push((entry >> ENTRY_SHIFT) as u8)?;
430                        }
431                        if !handle_match {
432                            if lbits.fill(source) >= 15 {
433                                entry =
434                                    trees.lt.table[lbits.peek(LITERAL_LENGTH_TABLE_BITS) as usize];
435                                if entry & ENTRY_SUBTABLE != 0 {
436                                    lbits.skip(LITERAL_LENGTH_TABLE_BITS);
437                                    entry = trees.lt.table[(((entry >> ENTRY_SHIFT) & 0xFFFF)
438                                        + lbits.peek(entry & ENTRY_LENGTH_MASK))
439                                        as usize];
440                                }
441                                lbits.skip(entry & ENTRY_LENGTH_MASK);
442                                if entry & ENTRY_LITERAL != 0 {
443                                    sink.push((entry >> ENTRY_SHIFT) as u8)?;
444                                    continue;
445                                }
446                            } else {
447                                *bits = lbits;
448                                return Err(Error::Underflow);
449                            }
450                        }
451                        entry >>= ENTRY_SHIFT;
452                        if lbits.fill(source) >= 33 {
453                            let length = ((entry >> LENGTH_BASE_SHIFT)
454                                + lbits.pop(entry & EXTRA_LENGTH_BITS_MASK))
455                                as usize;
456                            if length == 0 {
457                                *bits = lbits;
458                                *state = State::Block;
459                                break;
460                            }
461                            entry = trees.dt.table[lbits.peek(DISTANCE_TABLE_BITS) as usize];
462                            if entry & ENTRY_SUBTABLE != 0 {
463                                lbits.skip(DISTANCE_TABLE_BITS);
464                                entry = trees.dt.table[(((entry >> ENTRY_SHIFT) & 0xFFFF)
465                                    + lbits.peek(entry & ENTRY_LENGTH_MASK))
466                                    as usize];
467                            }
468                            lbits.skip(entry & ENTRY_LENGTH_MASK);
469                            entry >>= ENTRY_SHIFT;
470                            let distance = ((entry & DISTANCE_BASE_MASK)
471                                + lbits.pop(entry >> EXTRA_DISTANCE_BITS_SHIFT))
472                                as usize;
473                            sink.apply_match(distance, length)?;
474                        } else {
475                            *bits = lbits;
476                            *state = State::Match(entry);
477                            return Err(Error::Underflow);
478                        }
479                    }
480                } else {
481                    loop {
482                        if lbits.bits_in < 15 {
483                            lbits.fill(source);
484                        }
485                        let mut entry =
486                            trees.lt.table[lbits.peek(LITERAL_LENGTH_TABLE_BITS) as usize];
487                        if entry & ENTRY_SUBTABLE != 0 {
488                            lbits.try_skip(LITERAL_LENGTH_TABLE_BITS)?;
489                            entry = trees.lt.table[(((entry >> ENTRY_SHIFT) & 0xFFFF)
490                                + lbits.peek(entry & ENTRY_LENGTH_MASK))
491                                as usize];
492                        }
493                        lbits.try_skip(entry & ENTRY_LENGTH_MASK)?;
494                        if entry & ENTRY_LITERAL != 0 {
495                            sink.push((entry >> ENTRY_SHIFT) as u8)?;
496                            continue;
497                        }
498                        entry >>= ENTRY_SHIFT;
499                        lbits.fill(source);
500                        let length = ((entry >> LENGTH_BASE_SHIFT)
501                            + lbits.try_pop(entry & EXTRA_LENGTH_BITS_MASK)?)
502                            as usize;
503                        if length == 0 {
504                            *bits = lbits;
505                            *state = State::Block;
506                            break;
507                        }
508                        entry = trees.dt.table[lbits.peek(DISTANCE_TABLE_BITS) as usize];
509                        if entry & ENTRY_SUBTABLE != 0 {
510                            lbits.try_skip(DISTANCE_TABLE_BITS)?;
511                            entry = trees.dt.table[(((entry >> ENTRY_SHIFT) & 0xFFFF)
512                                + lbits.peek(entry & ENTRY_LENGTH_MASK))
513                                as usize];
514                        }
515                        lbits.try_skip(entry & ENTRY_LENGTH_MASK)?;
516                        entry >>= ENTRY_SHIFT;
517                        let distance = ((entry & DISTANCE_BASE_MASK)
518                            + lbits.try_pop(entry >> EXTRA_DISTANCE_BITS_SHIFT)?)
519                            as usize;
520                        sink.apply_match(distance, length)?;
521                    }
522                }
523            }
524            State::Match(mut entry) => {
525                let mut lbits = *bits;
526                if !is_last {
527                    if lbits.fill(source) < 33 {
528                        *bits = lbits;
529                        return Err(Error::Underflow);
530                    }
531                    let length = ((entry >> LENGTH_BASE_SHIFT)
532                        + lbits.pop(entry & EXTRA_LENGTH_BITS_MASK))
533                        as usize;
534                    if length == 0 {
535                        *bits = lbits;
536                        *state = State::Block;
537                        continue;
538                    }
539                    entry = trees.dt.table[lbits.peek(DISTANCE_TABLE_BITS) as usize];
540                    if entry & ENTRY_SUBTABLE != 0 {
541                        lbits.skip(DISTANCE_TABLE_BITS);
542                        entry = trees.dt.table[(((entry >> ENTRY_SHIFT) & 0xFFFF)
543                            + lbits.peek(entry & ENTRY_LENGTH_MASK))
544                            as usize];
545                    }
546                    lbits.skip(entry & ENTRY_LENGTH_MASK);
547                    entry >>= ENTRY_SHIFT;
548                    let distance = ((entry & DISTANCE_BASE_MASK)
549                        + lbits.pop(entry >> EXTRA_DISTANCE_BITS_SHIFT))
550                        as usize;
551                    *bits = lbits;
552                    *state = State::Inflate;
553                    sink.apply_match(distance, length)?;
554                } else {
555                    let length = ((entry >> LENGTH_BASE_SHIFT)
556                        + lbits.try_pop(entry & EXTRA_LENGTH_BITS_MASK)?)
557                        as usize;
558                    if length == 0 {
559                        *bits = lbits;
560                        *state = State::Block;
561                        continue;
562                    }
563                    entry = trees.dt.table[lbits.peek(DISTANCE_TABLE_BITS) as usize];
564                    if entry & ENTRY_SUBTABLE != 0 {
565                        lbits.try_skip(DISTANCE_TABLE_BITS)?;
566                        entry = trees.dt.table[(((entry >> ENTRY_SHIFT) & 0xFFFF)
567                            + lbits.peek(entry & ENTRY_LENGTH_MASK))
568                            as usize];
569                    }
570                    lbits.try_skip(entry & ENTRY_LENGTH_MASK)?;
571                    entry >>= ENTRY_SHIFT;
572                    let distance = ((entry & DISTANCE_BASE_MASK)
573                        + lbits.try_pop(entry >> EXTRA_DISTANCE_BITS_SHIFT)?)
574                        as usize;
575                    *bits = lbits;
576                    *state = State::Inflate;
577                    sink.apply_match(distance, length)?;
578                }
579            }
580        }
581    }
582}
583
584fn decode_trees(
585    source: &mut Source,
586    bits: &mut Bits,
587    lt: &mut LiteralLengthTree,
588    dt: &mut DistanceTree,
589    is_last: bool,
590) -> Result<(), Error> {
591    let mut lengths: [u8; MAX_LENGTHS] = [0; MAX_LENGTHS];
592    bits.fill(source);
593    let ltlen;
594    let dtlen;
595    if !is_last {
596        ltlen = bits.pop(5) as usize + 257;
597        dtlen = bits.pop(5) as usize + 1;
598        let ptlen = bits.pop(4) as usize + 4;
599        if ltlen > 286 || dtlen > 30 {
600            return Err(Error::InvalidBitstream);
601        }
602        for length in &mut lengths[0..19] {
603            *length = 0;
604        }
605        bits.fill(source);
606        for code in &PRECODE_SWIZZLE[..ptlen] {
607            let clen = bits.try_pop_source(source, 3)?;
608            lengths[*code as usize] = clen as u8;
609        }
610        if !lt.build_precode(&lengths[..19]) {
611            return Err(Error::InvalidBitstream);
612        }
613        let mut i = 0;
614        while i < (ltlen + dtlen) {
615            if bits.bits_in < 7 {
616                bits.fill(source);
617            }
618            let entry = lt.table[bits.peek(7) as usize];
619            bits.skip(entry & ENTRY_LENGTH_MASK);
620            let presym = entry >> ENTRY_SHIFT;
621            if presym < 16 {
622                lengths[i] = presym as u8;
623                i += 1;
624                continue;
625            }
626            if bits.bits_in < 7 {
627                bits.fill(source);
628            }
629            if presym > 18 || (presym == 16 && i == 0) {
630                return Err(Error::InvalidBitstream);
631            }
632            let (extra_bits, extra) =
633                [(2, 3), (3, 3), (7, 11), (0, 0)][(presym as usize - 16) & 0x3];
634            let count = bits.pop(extra_bits) as usize + extra;
635            let l = if presym == 16 { lengths[i - 1] } else { 0 };
636            let p = lengths
637                .get_mut(i..i + count)
638                .ok_or(Error::InvalidBitstream)?;
639            p.iter_mut().for_each(|p| *p = l);
640            i += count;
641        }
642    } else {
643        ltlen = bits.try_pop(5)? as usize + 257;
644        dtlen = bits.try_pop(5)? as usize + 1;
645        let ptlen = bits.try_pop(4)? as usize + 4;
646        if ltlen > 286 || dtlen > 30 {
647            return Err(Error::InvalidBitstream);
648        }
649        for length in &mut lengths[0..19] {
650            *length = 0;
651        }
652        bits.fill(source);
653        for code in &PRECODE_SWIZZLE[..ptlen] {
654            let clen = bits.try_pop_source(source, 3)?;
655            lengths[*code as usize] = clen as u8;
656        }
657        if !lt.build_precode(&lengths[..19]) {
658            return Err(Error::InvalidBitstream);
659        }
660        let mut i = 0;
661        while i < (ltlen + dtlen) {
662            if bits.bits_in < 7 {
663                bits.fill(source);
664            }
665            let entry = lt.table[bits.peek(7) as usize];
666            bits.try_skip(entry & ENTRY_LENGTH_MASK)?;
667            let presym = entry >> ENTRY_SHIFT;
668            if presym < 16 {
669                lengths[i] = presym as u8;
670                i += 1;
671                continue;
672            }
673            if bits.bits_in < 7 {
674                bits.fill(source);
675            }
676            if presym > 18 || (presym == 16 && i == 0) {
677                return Err(Error::InvalidBitstream);
678            }
679            let (extra_bits, extra) =
680                [(2, 3), (3, 3), (7, 11), (0, 0)][(presym as usize - 16) & 0x3];
681            let count = bits.try_pop(extra_bits)? as usize + extra;
682            let l = if presym == 16 { lengths[i - 1] } else { 0 };
683            let p = lengths
684                .get_mut(i..i + count)
685                .ok_or(Error::InvalidBitstream)?;
686            p.iter_mut().for_each(|p| *p = l);
687            i += count;
688        }
689    }
690    if lengths[256] == 0
691        || !lt.build(&lengths[..ltlen])
692        || !dt.build(&lengths[ltlen..ltlen + dtlen])
693    {
694        return Err(Error::InvalidBitstream);
695    }
696    Ok(())
697}
698
699fn build_tree(
700    table: &mut [u32],
701    lengths: &[u8],
702    entries: &[u32],
703    table_bits: usize,
704    max_codeword_len: usize,
705) -> bool {
706    let mut len_counts = [0usize; MAX_CODE_SIZE + 1];
707    let mut offsets = [0usize; MAX_CODE_SIZE + 1];
708    let mut sorted_entries: [u32; 288] = [0; 288];
709    for &len in lengths {
710        len_counts[len as usize] += 1;
711    }
712    offsets[1] = len_counts[0];
713    let mut codespace_used = 0;
714    for len in 1..max_codeword_len {
715        offsets[len + 1] = offsets[len] + len_counts[len];
716        codespace_used = (codespace_used << 1) + len_counts[len];
717    }
718    codespace_used = (codespace_used << 1) + len_counts[max_codeword_len];
719    for sym in 0..lengths.len() {
720        let len = lengths[sym];
721        let idx = &mut offsets[len as usize];
722        sorted_entries[*idx] = entries[sym];
723        *idx += 1;
724    }
725    let sorted_entries = &mut sorted_entries[offsets[0]..];
726    if codespace_used > (1 << max_codeword_len) {
727        return false;
728    }
729    if codespace_used < (1 << max_codeword_len) {
730        let entry = if codespace_used == 0 {
731            entries[0] | 1
732        } else {
733            if codespace_used != (1 << (max_codeword_len - 1)) || len_counts[1] != 1 {
734                return false;
735            }
736            sorted_entries[0] | 1
737        };
738        for i in 0..(1 << table_bits) {
739            table[i] = entry;
740        }
741        return true;
742    }
743    let mut len = 1;
744    let mut count;
745    loop {
746        count = len_counts[len & 15];
747        if count != 0 {
748            break;
749        }
750        len += 1;
751    }
752    let mut codeword = 0;
753    let mut cur_table_end = 1 << len;
754    let mut s = 0;
755    while len <= table_bits {
756        loop {
757            table[codeword] = sorted_entries[s] | len as u32;
758            s += 1;
759            if codeword == cur_table_end - 1 {
760                while len < table_bits {
761                    table.copy_within(0..cur_table_end, cur_table_end);
762                    cur_table_end <<= 1;
763                    len += 1;
764                }
765                return true;
766            }
767            let bit = 1 << (31 - ((codeword ^ (cur_table_end - 1)) as u32).leading_zeros());
768            codeword &= bit - 1;
769            codeword |= bit;
770            count -= 1;
771            if count == 0 {
772                break;
773            }
774        }
775        loop {
776            len += 1;
777            if len <= table_bits {
778                table.copy_within(0..cur_table_end, cur_table_end);
779                cur_table_end <<= 1;
780            }
781            count = len_counts[len & 15];
782            if count != 0 {
783                break;
784            }
785        }
786    }
787    cur_table_end = 1 << table_bits;
788    let mut subtable_prefix = !0;
789    let mut subtable_start = 0;
790    loop {
791        if (codeword & ((1 << table_bits) - 1)) != subtable_prefix {
792            subtable_prefix = codeword & ((1 << table_bits) - 1);
793            subtable_start = cur_table_end;
794            let mut subtable_bits = len - table_bits;
795            codespace_used = count;
796            while codespace_used < (1 << subtable_bits) {
797                subtable_bits += 1;
798                codespace_used = (codespace_used << 1) + len_counts[table_bits + subtable_bits];
799            }
800            cur_table_end = subtable_start + (1 << subtable_bits);
801            table[subtable_prefix] =
802                ENTRY_SUBTABLE | (subtable_start << 8) as u32 | subtable_bits as u32;
803        }
804        let entry = sorted_entries[s] | (len - table_bits) as u32;
805        s += 1;
806        let mut i = subtable_start + (codeword >> table_bits);
807        let stride = 1 << (len - table_bits);
808        loop {
809            table[i] = entry;
810            i += stride;
811            if i >= cur_table_end {
812                break;
813            }
814        }
815        if codeword == (1 << len) - 1 {
816            return true;
817        }
818        let bit = 1 << (31 - ((codeword ^ ((1 << len) - 1)) as u32).leading_zeros());
819        codeword &= bit - 1;
820        codeword |= bit;
821        count -= 1;
822        while count == 0 {
823            len += 1;
824            count = len_counts[len & 15];
825        }
826    }
827}
828
829fn verify_zlib_header(source: &mut Source, bits: &mut Bits) -> Result<(), Error> {
830    let cmf = bits.try_pop_source(source, 8)?;
831    let flg = bits.try_pop_source(source, 8)?;
832    if (256 * cmf + flg) % 31 != 0 || cmf & 0x0F != 8 || (cmf >> 4) > 7 || flg & 0x20 != 0 {
833        return Err(Error::InvalidBitstream);
834    }
835    Ok(())
836}
837
838fn read_zlib_checksum(source: &mut Source, bits: &mut Bits) -> Result<u32, Error> {
839    let mut parts = [0u32; 4];
840    for part in &mut parts {
841        *part = bits.try_pop_source(source, 8)?;
842    }
843    Ok((parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3])
844}
845
846struct Trees {
847    lt: LiteralLengthTree,
848    dt: DistanceTree,
849}
850
851impl Trees {
852    #[inline(always)]
853    fn new() -> Self {
854        Self {
855            lt: LiteralLengthTree::new(),
856            dt: DistanceTree::new(),
857        }
858    }
859}
860
861struct Remainder {
862    buffer: [u8; 286],
863    pos: usize,
864    avail: usize,
865}
866
867impl Remainder {
868    fn new() -> Self {
869        Self {
870            buffer: [0; 286],
871            pos: 0,
872            avail: 0,
873        }
874    }
875
876    fn push(&mut self, buf: &[u8]) -> usize {
877        if self.pos != 0 {
878            self.buffer.copy_within(self.pos..self.pos + self.avail, 0);
879            self.pos = 0;
880        }
881        let extra = self.buffer.len() - self.avail;
882        let copy_len = extra.min(buf.len());
883        self.buffer[self.avail..self.avail + copy_len].copy_from_slice(&buf[0..copy_len]);
884        self.avail += copy_len;
885        copy_len
886    }
887}
888
889struct Source<'a> {
890    buffer: &'a [u8],
891    pos: usize,
892    avail: usize,
893}
894
895impl<'a> Source<'a> {
896    fn new(buffer: &'a [u8]) -> Self {
897        Self {
898            buffer,
899            pos: 0,
900            avail: buffer.len(),
901        }
902    }
903
904    fn from_remainder(remainder: &'a Remainder) -> Self {
905        Self {
906            buffer: &remainder.buffer[remainder.pos..remainder.pos + remainder.avail],
907            pos: 0,
908            avail: remainder.avail,
909        }
910    }
911
912    fn try_get(&mut self, len: usize) -> Result<&[u8], Error> {
913        let bytes = self.get(len);
914        if bytes.is_empty() {
915            return Err(Error::Underflow);
916        }
917        Ok(bytes)
918    }
919
920    #[inline(always)]
921    fn get(&mut self, len: usize) -> &[u8] {
922        let len = len.min(self.avail);
923        let pos = self.pos;
924        let bytes = &self.buffer[pos..pos + len];
925        self.pos += len;
926        self.avail -= len;
927        bytes
928    }
929}
930
931#[derive(Copy, Clone)]
932struct Bits {
933    bit_buffer: u64,
934    bits_in: u32,
935}
936
937impl Bits {
938    fn new(bit_buffer: u64, bits_in: u32) -> Self {
939        Self {
940            bit_buffer,
941            bits_in,
942        }
943    }
944
945    fn bytes_available(&self, source: &Source) -> usize {
946        source.avail + (self.bits_in as usize / 8)
947    }
948
949    #[inline(always)]
950    fn fill(&mut self, source: &mut Source) -> u32 {
951        let count = (64 - self.bits_in as usize) >> 3;
952        let bytes = source.get(count);
953        let len = bytes.len();
954        let mut i = 0;
955        while (i + 4) <= len {
956            use core::convert::TryInto;
957            let v = u32::from_le_bytes((&bytes[i..i + 4]).try_into().unwrap()) as u64;
958            self.bit_buffer |= v << self.bits_in;
959            self.bits_in += 32;
960            i += 4;
961        }
962        while i < len {
963            self.bit_buffer |= (bytes[i] as u64) << self.bits_in;
964            self.bits_in += 8;
965            i += 1;
966        }
967        self.bits_in
968    }
969
970    #[inline(always)]
971    fn try_pop_source(&mut self, source: &mut Source, len: u32) -> Result<u32, Error> {
972        if self.bits_in < len && self.fill(source) < len {
973            return Err(Error::Underflow);
974        }
975        let bits = self.bit_buffer & ((1 << len) - 1);
976        self.bit_buffer >>= len;
977        self.bits_in -= len;
978        Ok(bits as u32)
979    }
980
981    #[inline(always)]
982    fn try_pop(&mut self, len: u32) -> Result<u32, Error> {
983        if self.bits_in < len {
984            return Err(Error::Underflow);
985        }
986        let bits = self.bit_buffer & ((1 << len) - 1);
987        self.bit_buffer >>= len;
988        self.bits_in -= len;
989        Ok(bits as u32)
990    }
991
992    #[inline(always)]
993    fn try_skip(&mut self, len: u32) -> Result<(), Error> {
994        if self.bits_in < len {
995            return Err(Error::Underflow);
996        }
997        self.bit_buffer >>= len;
998        self.bits_in -= len;
999        Ok(())
1000    }
1001
1002    #[inline(always)]
1003    fn peek(&mut self, len: u32) -> u32 {
1004        (self.bit_buffer & ((1 << len) - 1)) as u32
1005    }
1006
1007    #[inline(always)]
1008    fn pop(&mut self, len: u32) -> u32 {
1009        let bits = self.bit_buffer & ((1 << len) - 1);
1010        self.bit_buffer >>= len;
1011        self.bits_in -= len;
1012        bits as u32
1013    }
1014
1015    #[inline(always)]
1016    fn skip(&mut self, len: u32) {
1017        self.bit_buffer >>= len;
1018        self.bits_in -= len;
1019    }
1020}
1021
1022#[inline(always)]
1023fn copy_match(buf: &mut [u8], pos: usize, len: usize, buf_end: usize) {
1024    let dist = buf_end - pos;
1025    if dist > len {
1026        buf.copy_within(pos..pos + len, buf_end);
1027    } else {
1028        for i in 0..len {
1029            buf[buf_end + i] = buf[pos + i];
1030        }
1031    }
1032}
1033
1034#[doc(hidden)]
1035pub trait Sink {
1036    fn written(&self) -> u64;
1037    fn push(&mut self, byte: u8) -> Result<(), Error>;
1038    fn write(&mut self, bytes: &[u8]) -> Result<(), Error>;
1039    fn apply_match(&mut self, dist: usize, len: usize) -> Result<(), Error>;
1040}
1041
1042struct VecSink<'a> {
1043    buffer: &'a mut Vec<u8>,
1044    start_pos: usize,
1045    pos: usize,
1046}
1047
1048impl<'a> VecSink<'a> {
1049    fn new(buffer: &'a mut Vec<u8>) -> Self {
1050        let start_pos = buffer.len();
1051        Self {
1052            buffer,
1053            start_pos,
1054            pos: start_pos,
1055        }
1056    }
1057}
1058
1059impl Drop for VecSink<'_> {
1060    fn drop(&mut self) {
1061        self.buffer.truncate(self.pos);
1062    }
1063}
1064
1065impl Sink for VecSink<'_> {
1066    fn written(&self) -> u64 {
1067        (self.pos - self.start_pos) as u64
1068    }
1069
1070    #[inline(always)]
1071    fn push(&mut self, byte: u8) -> Result<(), Error> {
1072        self.buffer.push(byte);
1073        self.pos += 1;
1074        Ok(())
1075    }
1076
1077    fn write(&mut self, bytes: &[u8]) -> Result<(), Error> {
1078        let len = bytes.len();
1079        self.buffer.extend_from_slice(bytes);
1080        self.pos += len;
1081        Ok(())
1082    }
1083
1084    #[inline(always)]
1085    fn apply_match(&mut self, dist: usize, len: usize) -> Result<(), Error> {
1086        let buf_len = self.pos - self.start_pos;
1087        if dist > buf_len {
1088            return Err(Error::InvalidBitstream);
1089        }
1090        let pos = self.pos - dist;
1091        self.buffer.resize(self.pos + len, 0);
1092        copy_match(self.buffer, pos, len, self.pos);
1093        self.pos += len;
1094        Ok(())
1095    }
1096}
1097
1098struct BufSink<'a> {
1099    buffer: &'a mut [u8],
1100    pos: usize,
1101}
1102
1103impl Sink for BufSink<'_> {
1104    fn written(&self) -> u64 {
1105        self.pos as u64
1106    }
1107
1108    #[inline(always)]
1109    fn push(&mut self, byte: u8) -> Result<(), Error> {
1110        if self.pos < self.buffer.len() {
1111            self.buffer[self.pos] = byte;
1112            self.pos += 1;
1113            Ok(())
1114        } else {
1115            Err(Error::Overflow)
1116        }
1117    }
1118
1119    fn write(&mut self, bytes: &[u8]) -> Result<(), Error> {
1120        let len = bytes.len();
1121        if self.pos + len <= self.buffer.len() {
1122            self.buffer[self.pos..self.pos + len].copy_from_slice(bytes);
1123            self.pos += len;
1124            Ok(())
1125        } else {
1126            Err(Error::Overflow)
1127        }
1128    }
1129
1130    #[inline(always)]
1131    fn apply_match(&mut self, dist: usize, len: usize) -> Result<(), Error> {
1132        if dist > self.pos {
1133            return Err(Error::InvalidBitstream);
1134        }
1135        if self.pos + len > self.buffer.len() {
1136            return Err(Error::Overflow);
1137        }
1138        let pos = self.pos - dist;
1139        copy_match(self.buffer, pos, len, self.pos);
1140        self.pos += len;
1141        Ok(())
1142    }
1143}
1144
1145#[cfg(feature = "std")]
1146struct WriterSink<W> {
1147    writer: W,
1148    ring: RingBuffer,
1149    written: u64,
1150}
1151
1152#[cfg(feature = "std")]
1153impl<W: Write> Sink for WriterSink<W> {
1154    fn written(&self) -> u64 {
1155        self.written
1156    }
1157
1158    #[inline]
1159    fn push(&mut self, byte: u8) -> Result<(), Error> {
1160        self.ring.push(byte);
1161        self.written += 1;
1162        match self.writer.write_all(&[byte]) {
1163            Err(err) => Err(Error::Io(err)),
1164            Ok(_) => Ok(()),
1165        }
1166    }
1167
1168    fn write(&mut self, bytes: &[u8]) -> Result<(), Error> {
1169        for &b in bytes {
1170            self.ring.push(b);
1171        }
1172        self.written += bytes.len() as u64;
1173        match self.writer.write_all(bytes) {
1174            Err(err) => Err(Error::Io(err)),
1175            Ok(_) => Ok(()),
1176        }
1177    }
1178
1179    #[inline]
1180    fn apply_match(&mut self, dist: usize, len: usize) -> Result<(), Error> {
1181        if dist > self.ring.len {
1182            return Err(Error::InvalidBitstream);
1183        }
1184        let pos = self.ring.len - dist;
1185        for i in 0..len {
1186            self.push(self.ring.get(pos + i))?;
1187        }
1188        Ok(())
1189    }
1190}
1191
1192#[cfg(feature = "std")]
1193struct RingBuffer {
1194    buffer: [u8; RING_BUFFER_SIZE],
1195    len: usize,
1196}
1197
1198#[cfg(feature = "std")]
1199impl RingBuffer {
1200    #[inline(always)]
1201    fn new() -> Self {
1202        Self {
1203            buffer: [0; RING_BUFFER_SIZE],
1204            len: 0,
1205        }
1206    }
1207
1208    #[inline(always)]
1209    fn push(&mut self, value: u8) {
1210        self.buffer[self.len & (RING_BUFFER_SIZE - 1)] = value;
1211        self.len += 1;
1212    }
1213
1214    #[inline(always)]
1215    fn get(&self, index: usize) -> u8 {
1216        self.buffer[index & (RING_BUFFER_SIZE - 1)]
1217    }
1218}
1219
1220struct LiteralLengthTree {
1221    table: [u32; LITERAL_LENGTH_TREE_SIZE],
1222}
1223
1224impl LiteralLengthTree {
1225    #[inline(always)]
1226    fn new() -> Self {
1227        Self {
1228            table: [0; LITERAL_LENGTH_TREE_SIZE],
1229        }
1230    }
1231
1232    fn build(&mut self, lengths: &[u8]) -> bool {
1233        build_tree(&mut self.table, lengths, &LITERAL_LENGTH_ENTRIES, 10, 15)
1234    }
1235
1236    fn build_precode(&mut self, lengths: &[u8]) -> bool {
1237        build_tree(&mut self.table, &lengths[..19], &PRECODE_ENTRIES, 7, 7)
1238    }
1239}
1240
1241struct DistanceTree {
1242    table: [u32; DISTANCE_TREE_SIZE],
1243}
1244
1245impl DistanceTree {
1246    #[inline(always)]
1247    fn new() -> Self {
1248        Self {
1249            table: [0; DISTANCE_TREE_SIZE],
1250        }
1251    }
1252
1253    fn build(&mut self, lengths: &[u8]) -> bool {
1254        build_tree(&mut self.table, lengths, &DISTANCE_ENTRIES, 8, 15)
1255    }
1256}
1257
1258#[cfg(feature = "std")]
1259const RING_BUFFER_SIZE: usize = 32768;
1260const LITERAL_LENGTH_TREE_SIZE: usize = 1334;
1261const DISTANCE_TREE_SIZE: usize = 402;
1262const MAX_CODE_SIZE: usize = 15;
1263const MAX_LENGTHS: usize = 288 + 32;
1264const ENTRY_LITERAL: u32 = 0x40000000;
1265const ENTRY_SUBTABLE: u32 = 0x80000000;
1266const ENTRY_LENGTH_MASK: u32 = 0xFF;
1267const ENTRY_SHIFT: u32 = 8;
1268const LITERAL_LENGTH_TABLE_BITS: u32 = 10;
1269const DISTANCE_TABLE_BITS: u32 = 8;
1270const EXTRA_LENGTH_BITS_MASK: u32 = 0xFF;
1271const LENGTH_BASE_SHIFT: u32 = 8;
1272const EXTRA_DISTANCE_BITS_SHIFT: u32 = 16;
1273const DISTANCE_BASE_MASK: u32 = (1 << EXTRA_DISTANCE_BITS_SHIFT) - 1;
1274
1275const PRECODE_SWIZZLE: [u8; 19] = [
1276    16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15,
1277];
1278
1279const PRECODE_ENTRIES: [u32; 19] = [
1280    0x00000000, 0x00000100, 0x00000200, 0x00000300, 0x00000400, 0x00000500, 0x00000600, 0x00000700,
1281    0x00000800, 0x00000900, 0x00000A00, 0x00000B00, 0x00000C00, 0x00000D00, 0x00000E00, 0x00000F00,
1282    0x00001000, 0x00001100, 0x00001200,
1283];
1284
1285const LITERAL_LENGTH_ENTRIES: [u32; 288] = [
1286    0x40000000, 0x40000100, 0x40000200, 0x40000300, 0x40000400, 0x40000500, 0x40000600, 0x40000700,
1287    0x40000800, 0x40000900, 0x40000A00, 0x40000B00, 0x40000C00, 0x40000D00, 0x40000E00, 0x40000F00,
1288    0x40001000, 0x40001100, 0x40001200, 0x40001300, 0x40001400, 0x40001500, 0x40001600, 0x40001700,
1289    0x40001800, 0x40001900, 0x40001A00, 0x40001B00, 0x40001C00, 0x40001D00, 0x40001E00, 0x40001F00,
1290    0x40002000, 0x40002100, 0x40002200, 0x40002300, 0x40002400, 0x40002500, 0x40002600, 0x40002700,
1291    0x40002800, 0x40002900, 0x40002A00, 0x40002B00, 0x40002C00, 0x40002D00, 0x40002E00, 0x40002F00,
1292    0x40003000, 0x40003100, 0x40003200, 0x40003300, 0x40003400, 0x40003500, 0x40003600, 0x40003700,
1293    0x40003800, 0x40003900, 0x40003A00, 0x40003B00, 0x40003C00, 0x40003D00, 0x40003E00, 0x40003F00,
1294    0x40004000, 0x40004100, 0x40004200, 0x40004300, 0x40004400, 0x40004500, 0x40004600, 0x40004700,
1295    0x40004800, 0x40004900, 0x40004A00, 0x40004B00, 0x40004C00, 0x40004D00, 0x40004E00, 0x40004F00,
1296    0x40005000, 0x40005100, 0x40005200, 0x40005300, 0x40005400, 0x40005500, 0x40005600, 0x40005700,
1297    0x40005800, 0x40005900, 0x40005A00, 0x40005B00, 0x40005C00, 0x40005D00, 0x40005E00, 0x40005F00,
1298    0x40006000, 0x40006100, 0x40006200, 0x40006300, 0x40006400, 0x40006500, 0x40006600, 0x40006700,
1299    0x40006800, 0x40006900, 0x40006A00, 0x40006B00, 0x40006C00, 0x40006D00, 0x40006E00, 0x40006F00,
1300    0x40007000, 0x40007100, 0x40007200, 0x40007300, 0x40007400, 0x40007500, 0x40007600, 0x40007700,
1301    0x40007800, 0x40007900, 0x40007A00, 0x40007B00, 0x40007C00, 0x40007D00, 0x40007E00, 0x40007F00,
1302    0x40008000, 0x40008100, 0x40008200, 0x40008300, 0x40008400, 0x40008500, 0x40008600, 0x40008700,
1303    0x40008800, 0x40008900, 0x40008A00, 0x40008B00, 0x40008C00, 0x40008D00, 0x40008E00, 0x40008F00,
1304    0x40009000, 0x40009100, 0x40009200, 0x40009300, 0x40009400, 0x40009500, 0x40009600, 0x40009700,
1305    0x40009800, 0x40009900, 0x40009A00, 0x40009B00, 0x40009C00, 0x40009D00, 0x40009E00, 0x40009F00,
1306    0x4000A000, 0x4000A100, 0x4000A200, 0x4000A300, 0x4000A400, 0x4000A500, 0x4000A600, 0x4000A700,
1307    0x4000A800, 0x4000A900, 0x4000AA00, 0x4000AB00, 0x4000AC00, 0x4000AD00, 0x4000AE00, 0x4000AF00,
1308    0x4000B000, 0x4000B100, 0x4000B200, 0x4000B300, 0x4000B400, 0x4000B500, 0x4000B600, 0x4000B700,
1309    0x4000B800, 0x4000B900, 0x4000BA00, 0x4000BB00, 0x4000BC00, 0x4000BD00, 0x4000BE00, 0x4000BF00,
1310    0x4000C000, 0x4000C100, 0x4000C200, 0x4000C300, 0x4000C400, 0x4000C500, 0x4000C600, 0x4000C700,
1311    0x4000C800, 0x4000C900, 0x4000CA00, 0x4000CB00, 0x4000CC00, 0x4000CD00, 0x4000CE00, 0x4000CF00,
1312    0x4000D000, 0x4000D100, 0x4000D200, 0x4000D300, 0x4000D400, 0x4000D500, 0x4000D600, 0x4000D700,
1313    0x4000D800, 0x4000D900, 0x4000DA00, 0x4000DB00, 0x4000DC00, 0x4000DD00, 0x4000DE00, 0x4000DF00,
1314    0x4000E000, 0x4000E100, 0x4000E200, 0x4000E300, 0x4000E400, 0x4000E500, 0x4000E600, 0x4000E700,
1315    0x4000E800, 0x4000E900, 0x4000EA00, 0x4000EB00, 0x4000EC00, 0x4000ED00, 0x4000EE00, 0x4000EF00,
1316    0x4000F000, 0x4000F100, 0x4000F200, 0x4000F300, 0x4000F400, 0x4000F500, 0x4000F600, 0x4000F700,
1317    0x4000F800, 0x4000F900, 0x4000FA00, 0x4000FB00, 0x4000FC00, 0x4000FD00, 0x4000FE00, 0x4000FF00,
1318    0x00000000, 0x00030000, 0x00040000, 0x00050000, 0x00060000, 0x00070000, 0x00080000, 0x00090000,
1319    0x000A0000, 0x000B0100, 0x000D0100, 0x000F0100, 0x00110100, 0x00130200, 0x00170200, 0x001B0200,
1320    0x001F0200, 0x00230300, 0x002B0300, 0x00330300, 0x003B0300, 0x00430400, 0x00530400, 0x00630400,
1321    0x00730400, 0x00830500, 0x00A30500, 0x00C30500, 0x00E30500, 0x01020000, 0x01020000, 0x01020000,
1322];
1323
1324const DISTANCE_ENTRIES: [u32; 32] = [
1325    0x00000100, 0x00000200, 0x00000300, 0x00000400, 0x01000500, 0x01000700, 0x02000900, 0x02000D00,
1326    0x03001100, 0x03001900, 0x04002100, 0x04003100, 0x05004100, 0x05006100, 0x06008100, 0x0600C100,
1327    0x07010100, 0x07018100, 0x08020100, 0x08030100, 0x09040100, 0x09060100, 0x0A080100, 0x0A0C0100,
1328    0x0B100100, 0x0B180100, 0x0C200100, 0x0C300100, 0x0D400100, 0x0D600100, 0x0E800100, 0x0EC00100,
1329];