lib/uzlib/tinflate: Implement more compact lookup tables.

Saves 68 bytes on PYBV11.

This work was funded through GitHub Sponsors.

Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This commit is contained in:
Jim Mussared 2023-06-27 02:47:05 +10:00 committed by Damien George
parent d75a3cd861
commit ef5061fefd
2 changed files with 42 additions and 73 deletions

View File

@ -7,6 +7,9 @@
*
* Copyright (c) 2014-2018 by Paul Sokolovsky
*
* Optimised for MicroPython:
* Copyright (c) 2023 by Jim Mussared
*
* This software is provided 'as-is', without any express
* or implied warranty. In no event will the authors be
* held liable for any damages arising from the use of
@ -51,45 +54,45 @@ uint32_t tinf_get_be_uint32(uzlib_uncomp_t *d);
* -- uninitialized global data (static structures) -- *
* --------------------------------------------------- */
#ifdef RUNTIME_BITS_TABLES
typedef struct {
unsigned char length_bits : 3;
unsigned short length_base : 9;
unsigned char dist_bits : 4;
unsigned short dist_base : 15;
} lookup_table_entry_t;
/* extra bits and base tables for length codes */
unsigned char length_bits[30];
unsigned short length_base[30];
/* extra bits and base tables for distance codes */
unsigned char dist_bits[30];
unsigned short dist_base[30];
#else
const unsigned char length_bits[30] = {
0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 2, 2, 2, 2,
3, 3, 3, 3, 4, 4, 4, 4,
5, 5, 5, 5
const lookup_table_entry_t lookup_table[30] = {
{0, 3, 0, 1},
{0, 4, 0, 2},
{0, 5, 0, 3},
{0, 6, 0, 4},
{0, 7, 1, 5},
{0, 8, 1, 7},
{0, 9, 2, 9},
{0, 10, 2, 13},
{1, 11, 3, 17},
{1, 13, 3, 25},
{1, 15, 4, 33},
{1, 17, 4, 49},
{2, 19, 5, 65},
{2, 23, 5, 97},
{2, 27, 6, 129},
{2, 31, 6, 193},
{3, 35, 7, 257},
{3, 43, 7, 385},
{3, 51, 8, 513},
{3, 59, 8, 769},
{4, 67, 9, 1025},
{4, 83, 9, 1537},
{4, 99, 10, 2049},
{4, 115, 10, 3073},
{5, 131, 11, 4097},
{5, 163, 11, 6145},
{5, 195, 12, 8193},
{5, 227, 12, 12289},
{0, 258, 13, 16385},
{0, 0, 13, 24577},
};
const unsigned short length_base[30] = {
3, 4, 5, 6, 7, 8, 9, 10,
11, 13, 15, 17, 19, 23, 27, 31,
35, 43, 51, 59, 67, 83, 99, 115,
131, 163, 195, 227, 258
};
const unsigned char dist_bits[30] = {
0, 0, 0, 0, 1, 1, 2, 2,
3, 3, 4, 4, 5, 5, 6, 6,
7, 7, 8, 8, 9, 9, 10, 10,
11, 11, 12, 12, 13, 13
};
const unsigned short dist_base[30] = {
1, 2, 3, 4, 5, 7, 9, 13,
17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073,
4097, 6145, 8193, 12289, 16385, 24577
};
#endif
/* special ordering of code length codes */
const unsigned char clcidx[] = {
@ -102,25 +105,6 @@ const unsigned char clcidx[] = {
* -- utility functions -- *
* ----------------------- */
#ifdef RUNTIME_BITS_TABLES
/* build extra bits and base tables */
static void tinf_build_bits_base(unsigned char *bits, unsigned short *base, int delta, int first)
{
int i, sum;
/* build bits table */
for (i = 0; i < delta; ++i) bits[i] = 0;
for (i = 0; i < 30 - delta; ++i) bits[i + delta] = i / delta;
/* build base table */
for (sum = first, i = 0; i < 30; ++i)
{
base[i] = sum;
sum += 1 << bits[i];
}
}
#endif
/* build the fixed huffman trees */
static void tinf_build_fixed_trees(TINF_TREE *lt, TINF_TREE *dt)
{
@ -433,7 +417,7 @@ static int tinf_inflate_block_data(uzlib_uncomp_t *d, TINF_TREE *lt, TINF_TREE *
}
/* possibly get more bits from length code */
d->curlen = tinf_read_bits(d, length_bits[sym], length_base[sym]);
d->curlen = tinf_read_bits(d, lookup_table[sym].length_bits, lookup_table[sym].length_base);
dist = tinf_decode_symbol(d, dt);
if (dist >= 30) {
@ -441,7 +425,7 @@ static int tinf_inflate_block_data(uzlib_uncomp_t *d, TINF_TREE *lt, TINF_TREE *
}
/* possibly get more bits from distance code */
offs = tinf_read_bits(d, dist_bits[dist], dist_base[dist]);
offs = tinf_read_bits(d, lookup_table[dist].dist_bits, lookup_table[dist].dist_base);
/* calculate and validate actual LZ offset to use */
if (d->dict_ring) {
@ -521,20 +505,6 @@ static int tinf_inflate_uncompressed_block(uzlib_uncomp_t *d)
* -- public functions -- *
* ---------------------- */
/* initialize global (static) data */
void uzlib_init(void)
{
#ifdef RUNTIME_BITS_TABLES
/* build extra bits and base tables */
tinf_build_bits_base(length_bits, length_base, 4, 3);
tinf_build_bits_base(dist_bits, dist_base, 2, 1);
/* fix a special case */
length_bits[28] = 0;
length_base[28] = 258;
#endif
}
/* initialize decompression structure */
void uzlib_uncompress_init(uzlib_uncomp_t *d, void *dict, unsigned int dictLen)
{

View File

@ -125,7 +125,6 @@ unsigned char uzlib_get_byte(uzlib_uncomp_t *d);
/* Decompression API */
void uzlib_init(void);
void uzlib_uncompress_init(uzlib_uncomp_t *d, void *dict, unsigned int dictLen);
int uzlib_uncompress(uzlib_uncomp_t *d);
int uzlib_uncompress_chksum(uzlib_uncomp_t *d);