diff options
Diffstat (limited to 'source/kit/miniz/miniz_tinfl.c')
-rw-r--r-- | source/kit/miniz/miniz_tinfl.c | 818 |
1 files changed, 0 insertions, 818 deletions
diff --git a/source/kit/miniz/miniz_tinfl.c b/source/kit/miniz/miniz_tinfl.c deleted file mode 100644 index c8843ad..0000000 --- a/source/kit/miniz/miniz_tinfl.c +++ /dev/null @@ -1,818 +0,0 @@ -/************************************************************************** - * - * Copyright 2013-2014 RAD Game Tools and Valve Software - * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person - *obtaining a copy of this software and associated documentation files - *(the "Software"), to deal in the Software without restriction, - *including without limitation the rights to use, copy, modify, merge, - *publish, distribute, sublicense, and/or sell copies of the Software, - *and to permit persons to whom the Software is furnished to do so, - *subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - *NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - *BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - *ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - *CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - *SOFTWARE. - * - **************************************************************************/ - -#include "miniz.h" - -#ifndef MINIZ_NO_INFLATE_APIS - -# ifdef __cplusplus -extern "C" { -# endif - -/* ------------------- Low-level Decompression (completely independent - * from all compression API's) */ - -# define TINFL_MEMCPY(d, s, l) memcpy(d, s, l) -# define TINFL_MEMSET(p, c, l) memset(p, c, l) - -# define TINFL_CR_BEGIN \ - switch (r->m_state) { \ - case 0: -# define TINFL_CR_RETURN(state_index, result) \ - do { \ - status = result; \ - r->m_state = state_index; \ - goto common_exit; \ - case state_index:; \ - } \ - MZ_MACRO_END -# define TINFL_CR_RETURN_FOREVER(state_index, result) \ - do { \ - for (;;) { TINFL_CR_RETURN(state_index, result); } \ - } \ - MZ_MACRO_END -# define TINFL_CR_FINISH } - -# define TINFL_GET_BYTE(state_index, c) \ - do { \ - while (pIn_buf_cur >= pIn_buf_end) { \ - TINFL_CR_RETURN( \ - state_index, \ - (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) \ - ? TINFL_STATUS_NEEDS_MORE_INPUT \ - : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS); \ - } \ - c = *pIn_buf_cur++; \ - } \ - MZ_MACRO_END - -# define TINFL_NEED_BITS(state_index, n) \ - do { \ - mz_uint c; \ - TINFL_GET_BYTE(state_index, c); \ - bit_buf |= (((tinfl_bit_buf_t) c) << num_bits); \ - num_bits += 8; \ - } while (num_bits < (mz_uint) (n)) -# define TINFL_SKIP_BITS(state_index, n) \ - do { \ - if (num_bits < (mz_uint) (n)) { \ - TINFL_NEED_BITS(state_index, n); \ - } \ - bit_buf >>= (n); \ - num_bits -= (n); \ - } \ - MZ_MACRO_END -# define TINFL_GET_BITS(state_index, b, n) \ - do { \ - if (num_bits < (mz_uint) (n)) { \ - TINFL_NEED_BITS(state_index, n); \ - } \ - b = bit_buf & ((1 << (n)) - 1); \ - bit_buf >>= (n); \ - num_bits -= (n); \ - } \ - MZ_MACRO_END - -/* TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of - * bytes remaining in the input buffer falls below 2. */ -/* 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, pLookUp, pTree) \ - do { \ - temp = pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \ - if (temp >= 0) { \ - code_len = temp >> 9; \ - if ((code_len) && (num_bits >= code_len)) \ - break; \ - } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \ - code_len = TINFL_FAST_LOOKUP_BITS; \ - do { \ - temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \ - } while ((temp < 0) && (num_bits >= (code_len + 1))); \ - if (temp >= 0) \ - break; \ - } \ - TINFL_GET_BYTE(state_index, c); \ - bit_buf |= (((tinfl_bit_buf_t) c) << num_bits); \ - num_bits += 8; \ - } while (num_bits < 15); - -/* TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's - * more complex than you would initially expect because the zlib API - * expects the decompressor to never read */ -/* beyond the final byte of the deflate stream. (In other words, when - * this macro wants to read another byte from the input, it REALLY - * needs another byte in order to fully */ -/* decode the next Huffman code.) Handling this properly is - * particularly important on raw deflate (non-zlib) streams, which - * aren't followed by a byte aligned adler-32. */ -/* 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, pLookUp, pTree) \ - do { \ - int temp; \ - mz_uint code_len, c; \ - if (num_bits < 15) { \ - if ((pIn_buf_end - pIn_buf_cur) < 2) { \ - TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree); \ - } else { \ - bit_buf |= (((tinfl_bit_buf_t) pIn_buf_cur[0]) \ - << num_bits) | \ - (((tinfl_bit_buf_t) pIn_buf_cur[1]) \ - << (num_bits + 8)); \ - pIn_buf_cur += 2; \ - num_bits += 16; \ - } \ - } \ - if ((temp = \ - pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= \ - 0) \ - code_len = temp >> 9, temp &= 511; \ - else { \ - code_len = TINFL_FAST_LOOKUP_BITS; \ - do { \ - temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \ - } while (temp < 0); \ - } \ - sym = temp; \ - bit_buf >>= code_len; \ - num_bits -= code_len; \ - } \ - MZ_MACRO_END - -static void tinfl_clear_tree(tinfl_decompressor *r) { - if (r->m_type == 0) - MZ_CLEAR_ARR(r->m_tree_0); - else if (r->m_type == 1) - MZ_CLEAR_ARR(r->m_tree_1); - else - MZ_CLEAR_ARR(r->m_tree_2); -} - -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 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 mz_uint16 s_min_table_sizes[3] = { 257, 1, 4 }; - - mz_int16 *pTrees[3]; - mz_uint8 *pCode_sizes[3]; - - tinfl_status status = TINFL_STATUS_FAILED; - mz_uint32 num_bits, dist, counter, num_extra; - tinfl_bit_buf_t bit_buf; - const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = - pIn_buf_next + - *pIn_buf_size; - mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = - pOut_buf_next - ? pOut_buf_next + - *pOut_buf_size - : NULL; - size_t out_buf_size_mask = - (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) - ? (size_t) -1 - : ((pOut_buf_next - pOut_buf_start) + - *pOut_buf_size) - - 1, - dist_from_out_buf_start; - - /* Ensure the output buffer's size is a power of 2, unless the - * output buffer is large enough to hold the entire output file (in - * which case it doesn't matter). */ - if (((out_buf_size_mask + 1) & out_buf_size_mask) || - (pOut_buf_next < pOut_buf_start)) { - *pIn_buf_size = *pOut_buf_size = 0; - 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; - counter = r->m_counter; - num_extra = r->m_num_extra; - dist_from_out_buf_start = r->m_dist_from_out_buf_start; - TINFL_CR_BEGIN - - bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = - r->m_zhdr1 = 0; - r->m_z_adler32 = r->m_check_adler32 = 1; - if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) { - TINFL_GET_BYTE(1, r->m_zhdr0); - TINFL_GET_BYTE(2, r->m_zhdr1); - counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || - (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8)); - if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) - counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || - ((out_buf_size_mask + 1) < - (size_t) ((size_t) 1 - << (8U + (r->m_zhdr0 >> 4))))); - if (counter) { - TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); - } - } - - do { - TINFL_GET_BITS(3, r->m_final, 3); - r->m_type = r->m_final >> 1; - if (r->m_type == 0) { - TINFL_SKIP_BITS(5, num_bits & 7); - for (counter = 0; counter < 4; ++counter) { - if (num_bits) - TINFL_GET_BITS(6, r->m_raw_header[counter], 8); - else - TINFL_GET_BYTE(7, r->m_raw_header[counter]); - } - if ((counter = (r->m_raw_header[0] | - (r->m_raw_header[1] << 8))) != - (mz_uint) (0xFFFF ^ (r->m_raw_header[2] | - (r->m_raw_header[3] << 8)))) { - TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED); - } - while ((counter) && (num_bits)) { - TINFL_GET_BITS(51, dist, 8); - while (pOut_buf_cur >= pOut_buf_end) { - TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT); - } - *pOut_buf_cur++ = (mz_uint8) dist; - counter--; - } - while (counter) { - size_t n; - while (pOut_buf_cur >= pOut_buf_end) { - TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); - } - while (pIn_buf_cur >= pIn_buf_end) { - TINFL_CR_RETURN( - 38, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) - ? TINFL_STATUS_NEEDS_MORE_INPUT - : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS); - } - n = MZ_MIN(MZ_MIN((size_t) (pOut_buf_end - pOut_buf_cur), - (size_t) (pIn_buf_end - pIn_buf_cur)), - counter); - TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); - pIn_buf_cur += n; - pOut_buf_cur += n; - counter -= (mz_uint) n; - } - } else if (r->m_type == 3) { - TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED); - } else { - if (r->m_type == 1) { - 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_code_size_1, 5, 32); - for (i = 0; i <= 143; ++i) *p++ = 8; - for (; i <= 255; ++i) *p++ = 9; - for (; i <= 279; ++i) *p++ = 7; - for (; i <= 287; ++i) *p++ = 8; - } else { - for (counter = 0; counter < 3; counter++) { - 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_ARR(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_code_size_2[s_length_dezigzag[counter]] = (mz_uint8) s; - } - r->m_table_sizes[2] = 19; - } - for (; (int) r->m_type >= 0; r->m_type--) { - int tree_next, tree_cur; - 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]; - 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); - TINFL_MEMSET(pLookUp, 0, sizeof(r->m_look_up[0])); - tinfl_clear_tree(r); - for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) - total_syms[pCode_size[i]]++; - used_syms = 0, total = 0; - next_code[0] = next_code[1] = 0; - for (i = 1; i <= 15; ++i) { - used_syms += total_syms[i]; - next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); - } - if ((65536 != total) && (used_syms > 1)) { - TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED); - } - 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 = pCode_size[sym_index]; - if (!code_size) - continue; - cur_code = next_code[code_size]++; - for (l = code_size; l > 0; l--, cur_code >>= 1) - rev_code = (rev_code << 1) | (cur_code & 1); - if (code_size <= TINFL_FAST_LOOKUP_BITS) { - mz_int16 k = (mz_int16) ((code_size << 9) | sym_index); - while (rev_code < TINFL_FAST_LOOKUP_SIZE) { - pLookUp[rev_code] = k; - rev_code += (1 << code_size); - } - continue; - } - if (0 == - (tree_cur = pLookUp[rev_code & - (TINFL_FAST_LOOKUP_SIZE - 1)])) { - pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = - (mz_int16) tree_next; - tree_cur = tree_next; - tree_next -= 2; - } - rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1); - for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--) { - tree_cur -= ((rev_code >>= 1) & 1); - if (!pTree[-tree_cur - 1]) { - pTree[-tree_cur - 1] = (mz_int16) tree_next; - tree_cur = tree_next; - tree_next -= 2; - } else - tree_cur = pTree[-tree_cur - 1]; - } - tree_cur -= ((rev_code >>= 1) & 1); - pTree[-tree_cur - 1] = (mz_int16) sym_index; - } - if (r->m_type == 2) { - for (counter = 0; counter < (r->m_table_sizes[0] + - r->m_table_sizes[1]);) { - mz_uint s; - 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; - continue; - } - if ((dist == 16) && (!counter)) { - TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED); - } - num_extra = "\02\03\07"[dist - 16]; - TINFL_GET_BITS(18, s, num_extra); - s += "\03\03\013"[dist - 16]; - TINFL_MEMSET( - r->m_len_codes + counter, - (dist == 16) ? r->m_len_codes[counter - 1] : 0, s); - counter += s; - } - if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != - counter) { - TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED); - } - 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 (;;) { - mz_uint8 *pSrc; - for (;;) { - if (((pIn_buf_end - pIn_buf_cur) < 4) || - ((pOut_buf_end - pOut_buf_cur) < 2)) { - 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) { - TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT); - } - *pOut_buf_cur++ = (mz_uint8) counter; - } else { - int sym2; - mz_uint code_len; -# if TINFL_USE_64BIT_BITBUF - if (num_bits < 30) { - bit_buf |= - (((tinfl_bit_buf_t) MZ_READ_LE32(pIn_buf_cur)) - << num_bits); - pIn_buf_cur += 4; - num_bits += 32; - } -# else - if (num_bits < 15) { - bit_buf |= - (((tinfl_bit_buf_t) MZ_READ_LE16(pIn_buf_cur)) - << num_bits); - pIn_buf_cur += 2; - num_bits += 16; - } -# endif - if ((sym2 = - r->m_look_up[0][bit_buf & - (TINFL_FAST_LOOKUP_SIZE - 1)]) >= - 0) - code_len = sym2 >> 9; - else { - code_len = TINFL_FAST_LOOKUP_BITS; - do { - sym2 = r->m_tree_0[~sym2 + - ((bit_buf >> code_len++) & 1)]; - } while (sym2 < 0); - } - counter = sym2; - bit_buf >>= code_len; - num_bits -= code_len; - if (counter & 256) - break; - -# if !TINFL_USE_64BIT_BITBUF - if (num_bits < 15) { - bit_buf |= - (((tinfl_bit_buf_t) MZ_READ_LE16(pIn_buf_cur)) - << num_bits); - pIn_buf_cur += 2; - num_bits += 16; - } -# endif - if ((sym2 = - r->m_look_up[0][bit_buf & - (TINFL_FAST_LOOKUP_SIZE - 1)]) >= - 0) - code_len = sym2 >> 9; - else { - code_len = TINFL_FAST_LOOKUP_BITS; - do { - sym2 = r->m_tree_0[~sym2 + - ((bit_buf >> code_len++) & 1)]; - } while (sym2 < 0); - } - bit_buf >>= code_len; - num_bits -= code_len; - - pOut_buf_cur[0] = (mz_uint8) counter; - if (sym2 & 256) { - pOut_buf_cur++; - counter = sym2; - break; - } - pOut_buf_cur[1] = (mz_uint8) sym2; - pOut_buf_cur += 2; - } - } - if ((counter &= 511) == 256) - break; - - num_extra = s_length_extra[counter - 257]; - counter = s_length_base[counter - 257]; - if (num_extra) { - mz_uint extra_bits; - TINFL_GET_BITS(25, extra_bits, num_extra); - counter += extra_bits; - } - - 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) { - mz_uint extra_bits; - TINFL_GET_BITS(27, extra_bits, num_extra); - dist += extra_bits; - } - - dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start; - if ((dist == 0 || dist > dist_from_out_buf_start || - dist_from_out_buf_start == 0) && - (decomp_flags & - TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) { - TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED); - } - - pSrc = pOut_buf_start + - ((dist_from_out_buf_start - dist) & out_buf_size_mask); - - if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end) { - while (counter--) { - while (pOut_buf_cur >= pOut_buf_end) { - TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT); - } - *pOut_buf_cur++ = - pOut_buf_start[(dist_from_out_buf_start++ - dist) & - out_buf_size_mask]; - } - continue; - } -# if MINIZ_USE_UNALIGNED_LOADS_AND_STORES - else if ((counter >= 9) && (counter <= dist)) { - const mz_uint8 *pSrc_end = pSrc + (counter & ~7); - do { -# ifdef MINIZ_UNALIGNED_USE_MEMCPY - memcpy(pOut_buf_cur, pSrc, sizeof(mz_uint32) * 2); -# else - ((mz_uint32 *) pOut_buf_cur)[0] = (( - const mz_uint32 *) pSrc)[0]; - ((mz_uint32 *) pOut_buf_cur)[1] = (( - const mz_uint32 *) pSrc)[1]; -# endif - pOut_buf_cur += 8; - } while ((pSrc += 8) < pSrc_end); - if ((counter &= 7) < 3) { - if (counter) { - pOut_buf_cur[0] = pSrc[0]; - if (counter > 1) - pOut_buf_cur[1] = pSrc[1]; - pOut_buf_cur += counter; - } - continue; - } - } -# endif - while (counter > 2) { - pOut_buf_cur[0] = pSrc[0]; - pOut_buf_cur[1] = pSrc[1]; - pOut_buf_cur[2] = pSrc[2]; - pOut_buf_cur += 3; - pSrc += 3; - counter -= 3; - } - if (counter > 0) { - pOut_buf_cur[0] = pSrc[0]; - if (counter > 1) - pOut_buf_cur[1] = pSrc[1]; - pOut_buf_cur += counter; - } - } - } - } while (!(r->m_final & 1)); - - /* Ensure byte alignment and put back any bytes from the bitbuf if - * we've looked ahead too far on gzip, or other Deflate streams - * followed by arbitrary data. */ - /* I'm being super conservative here. A number of simplifications - * can be made to the byte alignment part, and the Adler32 check - * shouldn't ever need to worry about reading from the bitbuf now. - */ - TINFL_SKIP_BITS(32, num_bits & 7); - while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8)) { - --pIn_buf_cur; - num_bits -= 8; - } - 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) { - for (counter = 0; counter < 4; ++counter) { - mz_uint s; - if (num_bits) - TINFL_GET_BITS(41, s, 8); - else - TINFL_GET_BYTE(42, s); - r->m_z_adler32 = (r->m_z_adler32 << 8) | s; - } - } - TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE); - - TINFL_CR_FINISH - -common_exit: - /* As long as we aren't telling the caller that we NEED more input - * to make forward progress: */ - /* Put back any bytes from the bitbuf in case we've looked ahead too - * far on gzip, or other Deflate streams followed by arbitrary data. - */ - /* We need to be very careful here to NOT push back any bytes we - * definitely know we need to make forward progress, though, or - * we'll lock the caller up into an inf loop. */ - if ((status != TINFL_STATUS_NEEDS_MORE_INPUT) && - (status != TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS)) { - while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8)) { - --pIn_buf_cur; - num_bits -= 8; - } - } - r->m_num_bits = num_bits; - 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; - r->m_dist_from_out_buf_start = dist_from_out_buf_start; - *pIn_buf_size = pIn_buf_cur - pIn_buf_next; - *pOut_buf_size = pOut_buf_cur - pOut_buf_next; - if ((decomp_flags & - (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && - (status >= 0)) { - const mz_uint8 *ptr = pOut_buf_next; - size_t buf_len = *pOut_buf_size; - mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, - s2 = r->m_check_adler32 >> 16; - size_t block_len = buf_len % 5552; - while (buf_len) { - for (i = 0; i + 7 < block_len; i += 8, ptr += 8) { - s1 += ptr[0], s2 += s1; - s1 += ptr[1], s2 += s1; - s1 += ptr[2], s2 += s1; - s1 += ptr[3], s2 += s1; - s1 += ptr[4], s2 += s1; - s1 += ptr[5], s2 += s1; - s1 += ptr[6], s2 += s1; - s1 += ptr[7], s2 += s1; - } - for (; i < block_len; ++i) s1 += *ptr++, s2 += s1; - s1 %= 65521U, s2 %= 65521U; - buf_len -= block_len; - block_len = 5552; - } - r->m_check_adler32 = (s2 << 16) + s1; - if ((status == TINFL_STATUS_DONE) && - (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && - (r->m_check_adler32 != r->m_z_adler32)) - status = TINFL_STATUS_ADLER32_MISMATCH; - } - return status; -} - -/* Higher level helper functions. */ -void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, - size_t src_buf_len, - size_t *pOut_len, int flags) { - tinfl_decompressor decomp; - void *pBuf = NULL, *pNew_buf; - size_t src_buf_ofs = 0, out_buf_capacity = 0; - *pOut_len = 0; - tinfl_init(&decomp); - for (;;) { - size_t src_buf_size = src_buf_len - src_buf_ofs, - dst_buf_size = out_buf_capacity - *pOut_len, - new_out_buf_capacity; - tinfl_status status = tinfl_decompress( - &decomp, (const mz_uint8 *) pSrc_buf + src_buf_ofs, - &src_buf_size, (mz_uint8 *) pBuf, - pBuf ? (mz_uint8 *) pBuf + *pOut_len : NULL, &dst_buf_size, - (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | - TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); - if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT)) { - MZ_FREE(pBuf); - *pOut_len = 0; - return NULL; - } - src_buf_ofs += src_buf_size; - *pOut_len += dst_buf_size; - if (status == TINFL_STATUS_DONE) - break; - new_out_buf_capacity = out_buf_capacity * 2; - if (new_out_buf_capacity < 128) - new_out_buf_capacity = 128; - pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity); - if (!pNew_buf) { - MZ_FREE(pBuf); - *pOut_len = 0; - return NULL; - } - pBuf = pNew_buf; - out_buf_capacity = new_out_buf_capacity; - } - return pBuf; -} - -size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, - const void *pSrc_buf, - size_t src_buf_len, int flags) { - tinfl_decompressor decomp; - tinfl_status status; - tinfl_init(&decomp); - status = tinfl_decompress( - &decomp, (const mz_uint8 *) pSrc_buf, &src_buf_len, - (mz_uint8 *) pOut_buf, (mz_uint8 *) pOut_buf, &out_buf_len, - (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | - TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); - return (status != TINFL_STATUS_DONE) - ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED - : out_buf_len; -} - -int tinfl_decompress_mem_to_callback( - const void *pIn_buf, size_t *pIn_buf_size, - tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, - int flags) { - int result = 0; - tinfl_decompressor decomp; - mz_uint8 *pDict = (mz_uint8 *) MZ_MALLOC(TINFL_LZ_DICT_SIZE); - size_t in_buf_ofs = 0, dict_ofs = 0; - if (!pDict) - return TINFL_STATUS_FAILED; - memset(pDict, 0, TINFL_LZ_DICT_SIZE); - tinfl_init(&decomp); - for (;;) { - size_t in_buf_size = *pIn_buf_size - in_buf_ofs, - dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs; - tinfl_status status = tinfl_decompress( - &decomp, (const mz_uint8 *) pIn_buf + in_buf_ofs, - &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size, - (flags & ~(TINFL_FLAG_HAS_MORE_INPUT | - TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))); - in_buf_ofs += in_buf_size; - if ((dst_buf_size) && - (!(*pPut_buf_func)(pDict + dict_ofs, (int) dst_buf_size, - pPut_buf_user))) - break; - if (status != TINFL_STATUS_HAS_MORE_OUTPUT) { - result = (status == TINFL_STATUS_DONE); - break; - } - dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1); - } - MZ_FREE(pDict); - *pIn_buf_size = in_buf_ofs; - return result; -} - -# ifndef MINIZ_NO_MALLOC -tinfl_decompressor *tinfl_decompressor_alloc(void) { - tinfl_decompressor *pDecomp = (tinfl_decompressor *) MZ_MALLOC( - sizeof(tinfl_decompressor)); - if (pDecomp) - tinfl_init(pDecomp); - return pDecomp; -} - -void tinfl_decompressor_free(tinfl_decompressor *pDecomp) { - MZ_FREE(pDecomp); -} -# endif - -# ifdef __cplusplus -} -# endif - -#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/ |