From 8da3cbb64e30b63599109b2c40872440e4916941 Mon Sep 17 00:00:00 2001 From: Christian Sandberg Date: Sat, 20 Jun 2020 17:31:32 +0200 Subject: [PATCH 1/9] Reduce memory usage for inflate Use Huffman tables with correct sizes instead of always 288 --- miniz_tinfl.c | 34 +++++++++++++++++----------------- miniz_tinfl.h | 17 +++++++++++++++-- 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/miniz_tinfl.c b/miniz_tinfl.c index 992de7a..05ce478 100644 --- a/miniz_tinfl.c +++ b/miniz_tinfl.c @@ -121,7 +121,7 @@ extern "C" { code_len = TINFL_FAST_LOOKUP_BITS; \ do \ { \ - temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \ + temp = (pHuff)->m_pTree[~temp + ((bit_buf >> code_len++) & 1)];\ } while ((temp < 0) && (num_bits >= (code_len + 1))); \ if (temp >= 0) \ break; \ @@ -162,7 +162,7 @@ extern "C" { code_len = TINFL_FAST_LOOKUP_BITS; \ do \ { \ - temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \ + temp = (pHuff)->m_pTree[~temp + ((bit_buf >> code_len++) & 1)]; \ } while (temp < 0); \ } \ sym = temp; \ @@ -271,11 +271,11 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex { if (r->m_type == 1) { - mz_uint8 *p = r->m_tables[0].m_code_size; + mz_uint8 *p = r->m_code_size_0; mz_uint i; r->m_table_sizes[0] = 288; r->m_table_sizes[1] = 32; - TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32); + TINFL_MEMSET(r->m_code_size_1, 5, 32); for (i = 0; i <= 143; ++i) *p++ = 8; for (; i <= 255; ++i) @@ -292,12 +292,12 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); r->m_table_sizes[counter] += s_min_table_sizes[counter]; } - MZ_CLEAR_OBJ(r->m_tables[2].m_code_size); + MZ_CLEAR_OBJ(r->m_code_size_2); for (counter = 0; counter < r->m_table_sizes[2]; counter++) { mz_uint s; TINFL_GET_BITS(14, s, 3); - r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; + r->m_code_size_2[s_length_dezigzag[counter]] = (mz_uint8)s; } r->m_table_sizes[2] = 19; } @@ -309,9 +309,9 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex pTable = &r->m_tables[r->m_type]; MZ_CLEAR_OBJ(total_syms); MZ_CLEAR_OBJ(pTable->m_look_up); - MZ_CLEAR_OBJ(pTable->m_tree); + TINFL_MEMSET(pTable->m_pTree, 0, r->m_table_sizes[r->m_type] * sizeof(pTable->m_pTree[0]) * 2); for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) - total_syms[pTable->m_code_size[i]]++; + total_syms[pTable->m_pCode_size[i]]++; used_syms = 0, total = 0; next_code[0] = next_code[1] = 0; for (i = 1; i <= 15; ++i) @@ -325,7 +325,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex } for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index) { - mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index]; + mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_pCode_size[sym_index]; if (!code_size) continue; cur_code = next_code[code_size]++; @@ -351,17 +351,17 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--) { tree_cur -= ((rev_code >>= 1) & 1); - if (!pTable->m_tree[-tree_cur - 1]) + if (!pTable->m_pTree[-tree_cur - 1]) { - pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next; + pTable->m_pTree[-tree_cur - 1] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } else - tree_cur = pTable->m_tree[-tree_cur - 1]; + tree_cur = pTable->m_pTree[-tree_cur - 1]; } tree_cur -= ((rev_code >>= 1) & 1); - pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index; + pTable->m_pTree[-tree_cur - 1] = (mz_int16)sym_index; } if (r->m_type == 2) { @@ -388,8 +388,8 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex { TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED); } - TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]); - TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]); + TINFL_MEMCPY(r->m_tables[0].m_pCode_size, r->m_len_codes, r->m_table_sizes[0]); + TINFL_MEMCPY(r->m_tables[1].m_pCode_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]); } } for (;;) @@ -434,7 +434,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex code_len = TINFL_FAST_LOOKUP_BITS; do { - sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; + sym2 = r->m_tree_0[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0); } counter = sym2; @@ -458,7 +458,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex code_len = TINFL_FAST_LOOKUP_BITS; do { - sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; + sym2 = r->m_tree_0[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0); } bit_buf >>= code_len; diff --git a/miniz_tinfl.h b/miniz_tinfl.h index 1b4a820..9ec14d6 100644 --- a/miniz_tinfl.h +++ b/miniz_tinfl.h @@ -91,6 +91,12 @@ typedef enum { do \ { \ (r)->m_state = 0; \ + (r)->m_tables[0].m_pCode_size = (r)->m_code_size_0; \ + (r)->m_tables[0].m_pTree = (r)->m_tree_0; \ + (r)->m_tables[1].m_pCode_size = (r)->m_code_size_1; \ + (r)->m_tables[1].m_pTree = (r)->m_tree_1; \ + (r)->m_tables[2].m_pCode_size = (r)->m_code_size_2; \ + (r)->m_tables[2].m_pTree = (r)->m_tree_2; \ } \ MZ_MACRO_END #define tinfl_get_adler32(r) (r)->m_check_adler32 @@ -112,8 +118,9 @@ enum typedef struct { - mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0]; - mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2]; + mz_uint8 *m_pCode_size; + mz_int16 *m_pTree; + mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE]; } tinfl_huff_table; #if MINIZ_HAS_64BIT_REGISTERS @@ -136,6 +143,12 @@ struct tinfl_decompressor_tag tinfl_bit_buf_t m_bit_buf; size_t m_dist_from_out_buf_start; tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES]; + mz_int16 m_tree_0[TINFL_MAX_HUFF_SYMBOLS_0 * 2]; + mz_int16 m_tree_1[TINFL_MAX_HUFF_SYMBOLS_1 * 2]; + mz_int16 m_tree_2[TINFL_MAX_HUFF_SYMBOLS_2 * 2]; + mz_uint8 m_code_size_0[TINFL_MAX_HUFF_SYMBOLS_0]; + mz_uint8 m_code_size_1[TINFL_MAX_HUFF_SYMBOLS_1]; + mz_uint8 m_code_size_2[TINFL_MAX_HUFF_SYMBOLS_2]; mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137]; }; From 40b0612004f49107f92b14cc531d27a6bf75d75e Mon Sep 17 00:00:00 2001 From: Christian Sandberg Date: Mon, 22 Jun 2020 19:39:52 +0200 Subject: [PATCH 2/9] Skip unnecessary pointer usage --- miniz_tinfl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/miniz_tinfl.c b/miniz_tinfl.c index 05ce478..c740854 100644 --- a/miniz_tinfl.c +++ b/miniz_tinfl.c @@ -388,8 +388,8 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex { TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED); } - TINFL_MEMCPY(r->m_tables[0].m_pCode_size, r->m_len_codes, r->m_table_sizes[0]); - TINFL_MEMCPY(r->m_tables[1].m_pCode_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]); + TINFL_MEMCPY(r->m_code_size_0, r->m_len_codes, r->m_table_sizes[0]); + TINFL_MEMCPY(r->m_code_size_1, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]); } } for (;;) From 3d000933a76f6c7330c0910169026220532b1b04 Mon Sep 17 00:00:00 2001 From: Christian Sandberg Date: Tue, 23 Jun 2020 11:42:03 +0200 Subject: [PATCH 3/9] Reduce size of const data --- miniz_tinfl.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/miniz_tinfl.c b/miniz_tinfl.c index c740854..d6b91a9 100644 --- a/miniz_tinfl.c +++ b/miniz_tinfl.c @@ -173,12 +173,12 @@ extern "C" { tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags) { - static const int s_length_base[31] = { 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, 0, 0 }; - static const int s_length_extra[31] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0 }; - static const int s_dist_base[32] = { 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, 0, 0 }; - static const int s_dist_extra[32] = { 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 }; + static const mz_uint16 s_length_base[31] = { 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, 0, 0 }; + static const mz_uint8 s_length_extra[31] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0 }; + static const mz_uint16 s_dist_base[32] = { 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, 0, 0 }; + static const mz_uint8 s_dist_extra[32] = { 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 }; static const mz_uint8 s_length_dezigzag[19] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; - static const int s_min_table_sizes[3] = { 257, 1, 4 }; + static const mz_uint16 s_min_table_sizes[3] = { 257, 1, 4 }; tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; From 524906517dd2f62fb49b6e19e2b8ff776dd9ab58 Mon Sep 17 00:00:00 2001 From: Christian Sandberg Date: Tue, 23 Jun 2020 11:51:26 +0200 Subject: [PATCH 4/9] Cache pointers to tables for speed --- miniz_tinfl.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/miniz_tinfl.c b/miniz_tinfl.c index d6b91a9..d5d512f 100644 --- a/miniz_tinfl.c +++ b/miniz_tinfl.c @@ -109,6 +109,7 @@ extern "C" { #define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \ do \ { \ + mz_int16 *pTree; \ temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \ if (temp >= 0) \ { \ @@ -118,10 +119,11 @@ extern "C" { } \ else if (num_bits > TINFL_FAST_LOOKUP_BITS) \ { \ + pTree = (pHuff)->m_pTree; \ code_len = TINFL_FAST_LOOKUP_BITS; \ do \ { \ - temp = (pHuff)->m_pTree[~temp + ((bit_buf >> code_len++) & 1)];\ + temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \ } while ((temp < 0) && (num_bits >= (code_len + 1))); \ if (temp >= 0) \ break; \ @@ -142,6 +144,7 @@ extern "C" { { \ int temp; \ mz_uint code_len, c; \ + mz_int16 *pTree; \ if (num_bits < 15) \ { \ if ((pIn_buf_end - pIn_buf_cur) < 2) \ @@ -159,10 +162,11 @@ extern "C" { code_len = temp >> 9, temp &= 511; \ else \ { \ + pTree = (pHuff)->m_pTree; \ code_len = TINFL_FAST_LOOKUP_BITS; \ do \ { \ - temp = (pHuff)->m_pTree[~temp + ((bit_buf >> code_len++) & 1)]; \ + temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \ } while (temp < 0); \ } \ sym = temp; \ @@ -305,13 +309,17 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex { int tree_next, tree_cur; tinfl_huff_table *pTable; + mz_int16 *pTree; + mz_uint8 *pCode_size; mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; pTable = &r->m_tables[r->m_type]; + pTree = pTable->m_pTree; + pCode_size = pTable->m_pCode_size; MZ_CLEAR_OBJ(total_syms); MZ_CLEAR_OBJ(pTable->m_look_up); - TINFL_MEMSET(pTable->m_pTree, 0, r->m_table_sizes[r->m_type] * sizeof(pTable->m_pTree[0]) * 2); + TINFL_MEMSET(pTree, 0, r->m_table_sizes[r->m_type] * sizeof(pTree[0]) * 2); for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) - total_syms[pTable->m_pCode_size[i]]++; + total_syms[pCode_size[i]]++; used_syms = 0, total = 0; next_code[0] = next_code[1] = 0; for (i = 1; i <= 15; ++i) @@ -325,7 +333,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex } for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index) { - mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_pCode_size[sym_index]; + mz_uint rev_code = 0, l, cur_code, code_size = pCode_size[sym_index]; if (!code_size) continue; cur_code = next_code[code_size]++; @@ -351,17 +359,17 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--) { tree_cur -= ((rev_code >>= 1) & 1); - if (!pTable->m_pTree[-tree_cur - 1]) + if (!pTree[-tree_cur - 1]) { - pTable->m_pTree[-tree_cur - 1] = (mz_int16)tree_next; + pTree[-tree_cur - 1] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } else - tree_cur = pTable->m_pTree[-tree_cur - 1]; + tree_cur = pTree[-tree_cur - 1]; } tree_cur -= ((rev_code >>= 1) & 1); - pTable->m_pTree[-tree_cur - 1] = (mz_int16)sym_index; + pTree[-tree_cur - 1] = (mz_int16)sym_index; } if (r->m_type == 2) { From 49860a15fa2e975de4204989638d70c2ab949d60 Mon Sep 17 00:00:00 2001 From: Christian Sandberg Date: Fri, 3 Jul 2020 13:22:18 +0200 Subject: [PATCH 5/9] Eliminate 64-bit operations on 32-bit machines --- miniz_tinfl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/miniz_tinfl.c b/miniz_tinfl.c index d5d512f..557a7f2 100644 --- a/miniz_tinfl.c +++ b/miniz_tinfl.c @@ -580,7 +580,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex --pIn_buf_cur; num_bits -= 8; } - bit_buf &= (tinfl_bit_buf_t)((((mz_uint64)1) << num_bits) - (mz_uint64)1); + bit_buf &= ~(~(tinfl_bit_buf_t)0 << num_bits); MZ_ASSERT(!num_bits); /* if this assert fires then we've read beyond the end of non-deflate/zlib streams with following data (such as gzip streams). */ if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) @@ -612,7 +612,7 @@ common_exit: } } r->m_num_bits = num_bits; - r->m_bit_buf = bit_buf & (tinfl_bit_buf_t)((((mz_uint64)1) << num_bits) - (mz_uint64)1); + r->m_bit_buf = bit_buf & ~(~(tinfl_bit_buf_t)0 << num_bits); r->m_dist = dist; r->m_counter = counter; r->m_num_extra = num_extra; From ff862d459631b5c2c39a7c5a048dea8c637c9d95 Mon Sep 17 00:00:00 2001 From: Christian Sandberg Date: Sun, 23 Jan 2022 14:12:48 +0100 Subject: [PATCH 6/9] Fix -Wshadow --- miniz_tinfl.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/miniz_tinfl.c b/miniz_tinfl.c index 9337da8..174d655 100644 --- a/miniz_tinfl.c +++ b/miniz_tinfl.c @@ -111,7 +111,7 @@ extern "C" { #define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \ do \ { \ - mz_int16 *pTree; \ + mz_int16 *pTreeFill; \ temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \ if (temp >= 0) \ { \ @@ -121,11 +121,11 @@ extern "C" { } \ else if (num_bits > TINFL_FAST_LOOKUP_BITS) \ { \ - pTree = (pHuff)->m_pTree; \ + pTreeFill = (pHuff)->m_pTree; \ code_len = TINFL_FAST_LOOKUP_BITS; \ do \ { \ - temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \ + temp = pTreeFill[~temp + ((bit_buf >> code_len++) & 1)]; \ } while ((temp < 0) && (num_bits >= (code_len + 1))); \ if (temp >= 0) \ break; \ @@ -146,7 +146,7 @@ extern "C" { { \ int temp; \ mz_uint code_len, c; \ - mz_int16 *pTree; \ + mz_int16 *pTreeDec; \ if (num_bits < 15) \ { \ if ((pIn_buf_end - pIn_buf_cur) < 2) \ @@ -164,11 +164,11 @@ extern "C" { code_len = temp >> 9, temp &= 511; \ else \ { \ - pTree = (pHuff)->m_pTree; \ + pTreeDec = (pHuff)->m_pTree; \ code_len = TINFL_FAST_LOOKUP_BITS; \ do \ { \ - temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \ + temp = pTreeDec[~temp + ((bit_buf >> code_len++) & 1)]; \ } while (temp < 0); \ } \ sym = temp; \ From 698faddd956c214b384d5c24f5dda43a9393f118 Mon Sep 17 00:00:00 2001 From: Christian Sandberg Date: Sun, 23 Jan 2022 14:14:27 +0100 Subject: [PATCH 7/9] Minor formatting fix --- miniz_tinfl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/miniz_tinfl.c b/miniz_tinfl.c index 174d655..4b68104 100644 --- a/miniz_tinfl.c +++ b/miniz_tinfl.c @@ -146,7 +146,7 @@ extern "C" { { \ int temp; \ mz_uint code_len, c; \ - mz_int16 *pTreeDec; \ + mz_int16 *pTreeDec; \ if (num_bits < 15) \ { \ if ((pIn_buf_end - pIn_buf_cur) < 2) \ @@ -164,11 +164,11 @@ extern "C" { code_len = temp >> 9, temp &= 511; \ else \ { \ - pTreeDec = (pHuff)->m_pTree; \ + pTreeDec = (pHuff)->m_pTree; \ code_len = TINFL_FAST_LOOKUP_BITS; \ do \ { \ - temp = pTreeDec[~temp + ((bit_buf >> code_len++) & 1)]; \ + temp = pTreeDec[~temp + ((bit_buf >> code_len++) & 1)]; \ } while (temp < 0); \ } \ sym = temp; \ From 8997650f5caaf362360340623647a0bb58df54d8 Mon Sep 17 00:00:00 2001 From: Christian Sandberg Date: Sun, 23 Jan 2022 20:24:58 +0100 Subject: [PATCH 8/9] Remove m_tables --- miniz_tinfl.c | 47 +++++++++++++++++++++++------------------------ miniz_tinfl.h | 15 +-------------- 2 files changed, 24 insertions(+), 38 deletions(-) diff --git a/miniz_tinfl.c b/miniz_tinfl.c index 4b68104..34408b5 100644 --- a/miniz_tinfl.c +++ b/miniz_tinfl.c @@ -108,11 +108,10 @@ extern "C" { /* It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a */ /* Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the */ /* bit buffer contains >=15 bits (deflate's max. Huffman code size). */ -#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \ +#define TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree) \ do \ { \ - mz_int16 *pTreeFill; \ - temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \ + temp = pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \ if (temp >= 0) \ { \ code_len = temp >> 9; \ @@ -121,11 +120,10 @@ extern "C" { } \ else if (num_bits > TINFL_FAST_LOOKUP_BITS) \ { \ - pTreeFill = (pHuff)->m_pTree; \ code_len = TINFL_FAST_LOOKUP_BITS; \ do \ { \ - temp = pTreeFill[~temp + ((bit_buf >> code_len++) & 1)]; \ + temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \ } while ((temp < 0) && (num_bits >= (code_len + 1))); \ if (temp >= 0) \ break; \ @@ -141,17 +139,16 @@ extern "C" { /* The slow path is only executed at the very end of the input buffer. */ /* v1.16: The original macro handled the case at the very end of the passed-in input buffer, but we also need to handle the case where the user passes in 1+zillion bytes */ /* following the deflate data and our non-conservative read-ahead path won't kick in here on this code. This is much trickier. */ -#define TINFL_HUFF_DECODE(state_index, sym, pHuff) \ +#define TINFL_HUFF_DECODE(state_index, sym, pLookUp, pTree) \ do \ { \ int temp; \ mz_uint code_len, c; \ - mz_int16 *pTreeDec; \ if (num_bits < 15) \ { \ if ((pIn_buf_end - pIn_buf_cur) < 2) \ { \ - TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \ + TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree); \ } \ else \ { \ @@ -160,15 +157,14 @@ extern "C" { num_bits += 16; \ } \ } \ - if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \ + if ((temp = pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \ code_len = temp >> 9, temp &= 511; \ else \ { \ - pTreeDec = (pHuff)->m_pTree; \ code_len = TINFL_FAST_LOOKUP_BITS; \ do \ { \ - temp = pTreeDec[~temp + ((bit_buf >> code_len++) & 1)]; \ + temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \ } while (temp < 0); \ } \ sym = temp; \ @@ -186,6 +182,9 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex static const mz_uint8 s_length_dezigzag[19] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; static const mz_uint16 s_min_table_sizes[3] = { 257, 1, 4 }; + mz_int16 *pTrees[3] = { r->m_tree_0, r->m_tree_1, r->m_tree_2 }; + mz_uint8 *pCode_sizes[3] = { r->m_code_size_0, r->m_code_size_1, r->m_code_size_2 }; + tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; tinfl_bit_buf_t bit_buf; @@ -310,15 +309,15 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex for (; (int)r->m_type >= 0; r->m_type--) { int tree_next, tree_cur; - tinfl_huff_table *pTable; + mz_int16 *pLookUp; mz_int16 *pTree; mz_uint8 *pCode_size; mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; - pTable = &r->m_tables[r->m_type]; - pTree = pTable->m_pTree; - pCode_size = pTable->m_pCode_size; + pLookUp = r->m_look_up[r->m_type]; + pTree = pTrees[r->m_type]; + pCode_size = pCode_sizes[r->m_type]; MZ_CLEAR_ARR(total_syms); - MZ_CLEAR_ARR(pTable->m_look_up); + TINFL_MEMSET(pLookUp, 0, sizeof(r->m_look_up[0])); TINFL_MEMSET(pTree, 0, r->m_table_sizes[r->m_type] * sizeof(pTree[0]) * 2); for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) total_syms[pCode_size[i]]++; @@ -346,14 +345,14 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex mz_int16 k = (mz_int16)((code_size << 9) | sym_index); while (rev_code < TINFL_FAST_LOOKUP_SIZE) { - pTable->m_look_up[rev_code] = k; + pLookUp[rev_code] = k; rev_code += (1 << code_size); } continue; } - if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) + if (0 == (tree_cur = pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) { - pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; + pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } @@ -378,7 +377,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]);) { mz_uint s; - TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); + TINFL_HUFF_DECODE(16, dist, r->m_look_up[2], r->m_tree_2); if (dist < 16) { r->m_len_codes[counter++] = (mz_uint8)dist; @@ -409,7 +408,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex { if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2)) { - TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]); + TINFL_HUFF_DECODE(23, counter, r->m_look_up[0], r->m_tree_0); if (counter >= 256) break; while (pOut_buf_cur >= pOut_buf_end) @@ -437,7 +436,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex num_bits += 16; } #endif - if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) + if ((sym2 = r->m_look_up[0][bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) code_len = sym2 >> 9; else { @@ -461,7 +460,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex num_bits += 16; } #endif - if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) + if ((sym2 = r->m_look_up[0][bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) code_len = sym2 >> 9; else { @@ -497,7 +496,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex counter += extra_bits; } - TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]); + TINFL_HUFF_DECODE(26, dist, r->m_look_up[1], r->m_tree_1); num_extra = s_dist_extra[dist]; dist = s_dist_base[dist]; if (num_extra) diff --git a/miniz_tinfl.h b/miniz_tinfl.h index 64d9eed..1021557 100644 --- a/miniz_tinfl.h +++ b/miniz_tinfl.h @@ -93,12 +93,6 @@ typedef enum { do \ { \ (r)->m_state = 0; \ - (r)->m_tables[0].m_pCode_size = (r)->m_code_size_0; \ - (r)->m_tables[0].m_pTree = (r)->m_tree_0; \ - (r)->m_tables[1].m_pCode_size = (r)->m_code_size_1; \ - (r)->m_tables[1].m_pTree = (r)->m_tree_1; \ - (r)->m_tables[2].m_pCode_size = (r)->m_code_size_2; \ - (r)->m_tables[2].m_pTree = (r)->m_tree_2; \ } \ MZ_MACRO_END #define tinfl_get_adler32(r) (r)->m_check_adler32 @@ -118,13 +112,6 @@ enum TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS }; -typedef struct -{ - mz_uint8 *m_pCode_size; - mz_int16 *m_pTree; - mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE]; -} tinfl_huff_table; - #if MINIZ_HAS_64BIT_REGISTERS #define TINFL_USE_64BIT_BITBUF 1 #else @@ -144,7 +131,7 @@ struct tinfl_decompressor_tag mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES]; tinfl_bit_buf_t m_bit_buf; size_t m_dist_from_out_buf_start; - tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES]; + mz_int16 m_look_up[TINFL_MAX_HUFF_TABLES][TINFL_FAST_LOOKUP_SIZE]; mz_int16 m_tree_0[TINFL_MAX_HUFF_SYMBOLS_0 * 2]; mz_int16 m_tree_1[TINFL_MAX_HUFF_SYMBOLS_1 * 2]; mz_int16 m_tree_2[TINFL_MAX_HUFF_SYMBOLS_2 * 2]; From 60942b0f040f0d5271488f39cc81a9c4afee3689 Mon Sep 17 00:00:00 2001 From: Christian Sandberg Date: Mon, 24 Jan 2022 09:55:56 +0100 Subject: [PATCH 9/9] Initialize tree and code size tables separately --- miniz_tinfl.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/miniz_tinfl.c b/miniz_tinfl.c index 34408b5..027b0d6 100644 --- a/miniz_tinfl.c +++ b/miniz_tinfl.c @@ -182,8 +182,8 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex static const mz_uint8 s_length_dezigzag[19] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; static const mz_uint16 s_min_table_sizes[3] = { 257, 1, 4 }; - mz_int16 *pTrees[3] = { r->m_tree_0, r->m_tree_1, r->m_tree_2 }; - mz_uint8 *pCode_sizes[3] = { r->m_code_size_0, r->m_code_size_1, r->m_code_size_2 }; + mz_int16 *pTrees[3]; + mz_uint8 *pCode_sizes[3]; tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; @@ -199,6 +199,13 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex return TINFL_STATUS_BAD_PARAM; } + pTrees[0] = r->m_tree_0; + pTrees[1] = r->m_tree_1; + pTrees[2] = r->m_tree_2; + pCode_sizes[0] = r->m_code_size_0; + pCode_sizes[1] = r->m_code_size_1; + pCode_sizes[2] = r->m_code_size_2; + num_bits = r->m_num_bits; bit_buf = r->m_bit_buf; dist = r->m_dist;