10 #ifndef TINFL_HEADER_INCLUDED
11 #define TINFL_HEADER_INCLUDED
22 #if defined(_M_IX86) || defined(_M_X64)
24 #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
26 #define MINIZ_LITTLE_ENDIAN 1
29 #if defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__)
31 #define MINIZ_HAS_64BIT_REGISTERS 1
36 #define MZ_MACRO_END while (0, 0)
38 #define MZ_MACRO_END while (0)
66 #define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1))
77 #define TINFL_LZ_DICT_SIZE 32768
116 #define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END
117 #define tinfl_get_adler32(r) (r)->m_check_adler32
136 #if MINIZ_HAS_64BIT_REGISTERS
137 #define TINFL_USE_64BIT_BITBUF 1
140 #if TINFL_USE_64BIT_BITBUF
142 #define TINFL_BITBUF_SIZE (64)
145 #define TINFL_BITBUF_SIZE (32)
150 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];
157 #endif // #ifdef TINFL_HEADER_INCLUDED
161 #ifndef TINFL_HEADER_FILE_ONLY
166 #ifdef MINIZ_NO_MALLOC
167 #define MZ_MALLOC(x) NULL
168 #define MZ_FREE(x) (void)x, ((void)0)
169 #define MZ_REALLOC(p, x) NULL
171 #define MZ_MALLOC(x) malloc(x)
172 #define MZ_FREE(x) free(x)
173 #define MZ_REALLOC(p, x) realloc(p, x)
176 #define MZ_MAX(a,b) (((a)>(b))?(a):(b))
177 #define MZ_MIN(a,b) (((a)<(b))?(a):(b))
178 #define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
180 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
181 #define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
182 #define MZ_READ_LE32(p) *((const mz_uint32 *)(p))
184 #define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U))
185 #define MZ_READ_LE32(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U))
188 #define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
189 #define TINFL_MEMSET(p, c, l) memset(p, c, l)
191 #define TINFL_CR_BEGIN switch(r->m_state) { case 0:
192 #define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END
193 #define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END
194 #define TINFL_CR_FINISH }
196 #define TINFL_GET_BYTE(state_index, c) do { \
197 while (pIn_buf_cur >= pIn_buf_end) { \
198 TINFL_CR_RETURN(state_index, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS); \
199 } c = *pIn_buf_cur++; } MZ_MACRO_END
201 #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))
202 #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
203 #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
209 #define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \
211 temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
213 code_len = temp >> 9; \
214 if ((code_len) && (num_bits >= code_len)) \
216 } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \
217 code_len = TINFL_FAST_LOOKUP_BITS; \
219 temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
220 } while ((temp < 0) && (num_bits >= (code_len + 1))); if (temp >= 0) break; \
221 } TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; \
222 } while (num_bits < 15);
230 #define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \
231 int temp; mz_uint code_len, c; \
232 if (num_bits < 15) { \
233 if ((pIn_buf_end - pIn_buf_cur) < 2) { \
234 TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
236 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; \
239 if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
240 code_len = temp >> 9, temp &= 511; \
242 code_len = TINFL_FAST_LOOKUP_BITS; do { temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; } while (temp < 0); \
243 } sym = temp; bit_buf >>= code_len; num_bits -= code_len; } MZ_MACRO_END
247 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 };
248 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 };
249 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 };
250 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 };
251 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 };
252 static const int s_min_table_sizes[3] = { 257, 1, 4 };
255 const mz_uint8 *pIn_buf_cur = pIn_buf_next, *
const pIn_buf_end = pIn_buf_next + *pIn_buf_size;
256 mz_uint8 *pOut_buf_cur = pOut_buf_next, *
const pOut_buf_end = pOut_buf_next + *pOut_buf_size;
260 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; }
282 while ((counter) && (num_bits))
292 while (pIn_buf_cur >= pIn_buf_end)
296 n =
MZ_MIN(
MZ_MIN((
size_t)(pOut_buf_end - pOut_buf_cur), (
size_t)(pIn_buf_end - pIn_buf_cur)), counter);
297 TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); pIn_buf_cur += n; pOut_buf_cur += n; counter -= (
mz_uint)n;
310 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;
323 used_syms = 0, total = 0; next_code[0] = next_code[1] = 0;
324 for (i = 1; i <= 15; ++i) { used_syms += total_syms[i]; next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); }
325 if ((65536 != total) && (used_syms > 1))
331 mz_uint rev_code = 0, l, cur_code, code_size = pTable->
m_code_size[sym_index];
if (!code_size)
continue;
332 cur_code = next_code[code_size]++;
for (l = code_size; l > 0; l--, cur_code >>= 1) rev_code = (rev_code << 1) | (cur_code & 1);
338 tree_cur -= ((rev_code >>= 1) & 1);
339 if (!pTable->
m_tree[-tree_cur - 1]) { pTable->
m_tree[-tree_cur - 1] = (
mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; }
340 else tree_cur = pTable->
m_tree[-tree_cur - 1];
342 tree_cur -= ((rev_code >>= 1) & 1); pTable->
m_tree[-tree_cur - 1] = (
mz_int16)sym_index;
349 if ((dist == 16) && (!counter))
353 num_extra =
"\02\03\07"[dist - 16];
TINFL_GET_BITS(18, s, num_extra); s +=
"\03\03\013"[dist - 16];
368 if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2))
374 *pOut_buf_cur++ = (
mz_uint8)counter;
379 #if TINFL_USE_64BIT_BITBUF
385 code_len = sym2 >> 9;
390 counter = sym2; bit_buf >>= code_len; num_bits -= code_len;
394 #if !TINFL_USE_64BIT_BITBUF
398 code_len = sym2 >> 9;
403 bit_buf >>= code_len; num_bits -= code_len;
405 pOut_buf_cur[0] = (
mz_uint8)counter;
416 if ((counter &= 511) == 256)
break;
418 num_extra = s_length_extra[counter - 257]; counter = s_length_base[counter - 257];
419 if (num_extra) {
mz_uint extra_bits;
TINFL_GET_BITS(25, extra_bits, num_extra); counter += extra_bits; }
422 num_extra = s_dist_extra[dist]; dist = s_dist_base[dist];
423 if (num_extra) {
mz_uint extra_bits;
TINFL_GET_BITS(27, extra_bits, num_extra); dist += extra_bits; }
425 dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
431 pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask);
433 if ((
MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end)
438 *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask];
442 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
443 else if ((counter >= 9) && (counter <= dist))
445 const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
451 }
while ((pSrc += 8) < pSrc_end);
452 if ((counter &= 7) < 3)
456 pOut_buf_cur[0] = pSrc[0];
458 pOut_buf_cur[1] = pSrc[1];
459 pOut_buf_cur += counter;
467 pOut_buf_cur[0] = pSrc[0];
468 pOut_buf_cur[1] = pSrc[1];
469 pOut_buf_cur[2] = pSrc[2];
470 pOut_buf_cur += 3; pSrc += 3;
471 }
while ((
int)(counter -= 3) > 2);
472 if ((
int)counter > 0)
474 pOut_buf_cur[0] = pSrc[0];
475 if ((
int)counter > 1)
476 pOut_buf_cur[1] = pSrc[1];
477 pOut_buf_cur += counter;
486 while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8)) { --pIn_buf_cur; num_bits -= 8; } bit_buf &= (
tinfl_bit_buf_t)((1ULL << num_bits) - 1ULL);
489 if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
503 *pIn_buf_size = pIn_buf_cur - pIn_buf_next; *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
506 const mz_uint8 *ptr = pOut_buf_next;
size_t buf_len = *pOut_buf_size;
510 for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
512 s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1;
513 s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1;
515 for (; i < block_len; ++i) s1 += *ptr++, s2 += s1;
516 s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552;
526 tinfl_decompressor decomp;
void *pBuf = NULL, *pNew_buf;
size_t src_buf_ofs = 0, out_buf_capacity = 0;
531 size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity;
536 MZ_FREE(pBuf); *pOut_len = 0;
return NULL;
538 src_buf_ofs += src_buf_size;
539 *pOut_len += dst_buf_size;
541 new_out_buf_capacity = out_buf_capacity * 2;
if (new_out_buf_capacity < 128) new_out_buf_capacity = 128;
542 pNew_buf =
MZ_REALLOC(pBuf, new_out_buf_capacity);
545 MZ_FREE(pBuf); *pOut_len = 0;
return NULL;
547 pBuf = pNew_buf; out_buf_capacity = new_out_buf_capacity;
569 size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size =
TINFL_LZ_DICT_SIZE - dict_ofs;
572 in_buf_ofs += in_buf_size;
573 if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (
int)dst_buf_size, pPut_buf_user)))
583 *pIn_buf_size = in_buf_ofs;
587 #endif // #ifndef TINFL_HEADER_FILE_ONLY