hbmap: fix iterator truncation when size_t < 32bit
[rofl0r-agsutils.git] / miniz_tinfl.c
blob5944914c5adefc88bc1c4204f5b2ad04b80429f5
1 /**************************************************************************
3 * Copyright 2013-2014 RAD Game Tools and Valve Software
4 * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
5 * All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
25 **************************************************************************/
27 #define MINIZ_PRIVATE
28 #include "miniz.h"
30 /* ------------------- Low-level Decompression (completely independent from all compression API's) */
32 #define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
33 #define TINFL_MEMSET(p, c, l) memset(p, c, l)
35 #define TINFL_CR_BEGIN \
36 switch (r->m_state) \
37 { \
38 case 0:
39 #define TINFL_CR_RETURN(state_index, result) \
40 do \
41 { \
42 status = result; \
43 r->m_state = state_index; \
44 goto common_exit; \
45 case state_index:; \
46 } \
47 MZ_MACRO_END
48 #define TINFL_CR_RETURN_FOREVER(state_index, result) \
49 do \
50 { \
51 for (;;) \
52 { \
53 TINFL_CR_RETURN(state_index, result); \
54 } \
55 } \
56 MZ_MACRO_END
57 #define TINFL_CR_FINISH }
59 #define TINFL_GET_BYTE(state_index, c) \
60 do \
61 { \
62 while (pIn_buf_cur >= pIn_buf_end) \
63 { \
64 TINFL_CR_RETURN(state_index, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS); \
65 } \
66 c = *pIn_buf_cur++; \
67 } \
68 MZ_MACRO_END
70 #define TINFL_NEED_BITS(state_index, n) \
71 do \
72 { \
73 mz_uint c; \
74 TINFL_GET_BYTE(state_index, c); \
75 bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
76 num_bits += 8; \
77 } while (num_bits < (mz_uint)(n))
78 #define TINFL_SKIP_BITS(state_index, n) \
79 do \
80 { \
81 if (num_bits < (mz_uint)(n)) \
82 { \
83 TINFL_NEED_BITS(state_index, n); \
84 } \
85 bit_buf >>= (n); \
86 num_bits -= (n); \
87 } \
88 MZ_MACRO_END
89 #define TINFL_GET_BITS(state_index, b, n) \
90 do \
91 { \
92 if (num_bits < (mz_uint)(n)) \
93 { \
94 TINFL_NEED_BITS(state_index, n); \
95 } \
96 b = bit_buf & ((1 << (n)) - 1); \
97 bit_buf >>= (n); \
98 num_bits -= (n); \
99 } \
100 MZ_MACRO_END
102 /* TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2. */
103 /* 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 */
104 /* 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 */
105 /* bit buffer contains >=15 bits (deflate's max. Huffman code size). */
106 #define TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree) \
107 do \
109 temp = pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
110 if (temp >= 0) \
112 code_len = temp >> 9; \
113 if ((code_len) && (num_bits >= code_len)) \
114 break; \
116 else if (num_bits > TINFL_FAST_LOOKUP_BITS) \
118 code_len = TINFL_FAST_LOOKUP_BITS; \
119 do \
121 temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \
122 } while ((temp < 0) && (num_bits >= (code_len + 1))); \
123 if (temp >= 0) \
124 break; \
126 TINFL_GET_BYTE(state_index, c); \
127 bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
128 num_bits += 8; \
129 } while (num_bits < 15);
131 /* 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 */
132 /* 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 */
133 /* 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. */
134 /* The slow path is only executed at the very end of the input buffer. */
135 /* 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 */
136 /* following the deflate data and our non-conservative read-ahead path won't kick in here on this code. This is much trickier. */
137 #define TINFL_HUFF_DECODE(state_index, sym, pLookUp, pTree) \
138 do \
140 int temp; \
141 mz_uint code_len, c; \
142 if (num_bits < 15) \
144 if ((pIn_buf_end - pIn_buf_cur) < 2) \
146 TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree); \
148 else \
150 bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); \
151 pIn_buf_cur += 2; \
152 num_bits += 16; \
155 if ((temp = pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
156 code_len = temp >> 9, temp &= 511; \
157 else \
159 code_len = TINFL_FAST_LOOKUP_BITS; \
160 do \
162 temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \
163 } while (temp < 0); \
165 sym = temp; \
166 bit_buf >>= code_len; \
167 num_bits -= code_len; \
169 MZ_MACRO_END
171 static void tinfl_clear_tree(tinfl_decompressor *r)
173 if (r->m_type == 0)
174 MZ_CLEAR_ARR(r->m_tree_0);
175 else if (r->m_type == 1)
176 MZ_CLEAR_ARR(r->m_tree_1);
177 else
178 MZ_CLEAR_ARR(r->m_tree_2);
181 static 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)
183 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 };
184 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 };
185 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 };
186 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 };
187 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 };
188 static const mz_uint16 s_min_table_sizes[3] = { 257, 1, 4 };
190 mz_int16 *pTrees[3];
191 mz_uint8 *pCode_sizes[3];
193 tinfl_status status = TINFL_STATUS_FAILED;
194 mz_uint32 num_bits, dist, counter, num_extra;
195 tinfl_bit_buf_t bit_buf;
196 const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size;
197 mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next ? pOut_buf_next + *pOut_buf_size : NULL;
198 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;
200 /* 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). */
201 if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start))
203 *pIn_buf_size = *pOut_buf_size = 0;
204 return TINFL_STATUS_BAD_PARAM;
207 pTrees[0] = r->m_tree_0;
208 pTrees[1] = r->m_tree_1;
209 pTrees[2] = r->m_tree_2;
210 pCode_sizes[0] = r->m_code_size_0;
211 pCode_sizes[1] = r->m_code_size_1;
212 pCode_sizes[2] = r->m_code_size_2;
214 num_bits = r->m_num_bits;
215 bit_buf = r->m_bit_buf;
216 dist = r->m_dist;
217 counter = r->m_counter;
218 num_extra = r->m_num_extra;
219 dist_from_out_buf_start = r->m_dist_from_out_buf_start;
220 TINFL_CR_BEGIN
222 bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0;
223 r->m_z_adler32 = r->m_check_adler32 = 1;
224 if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
226 TINFL_GET_BYTE(1, r->m_zhdr0);
227 TINFL_GET_BYTE(2, r->m_zhdr1);
228 counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8));
229 if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
230 counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1U << (8U + (r->m_zhdr0 >> 4)))));
231 if (counter)
233 TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED);
239 TINFL_GET_BITS(3, r->m_final, 3);
240 r->m_type = r->m_final >> 1;
241 if (r->m_type == 0)
243 TINFL_SKIP_BITS(5, num_bits & 7);
244 for (counter = 0; counter < 4; ++counter)
246 if (num_bits)
247 TINFL_GET_BITS(6, r->m_raw_header[counter], 8);
248 else
249 TINFL_GET_BYTE(7, r->m_raw_header[counter]);
251 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))))
253 TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED);
255 while ((counter) && (num_bits))
257 TINFL_GET_BITS(51, dist, 8);
258 while (pOut_buf_cur >= pOut_buf_end)
260 TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT);
262 *pOut_buf_cur++ = (mz_uint8)dist;
263 counter--;
265 while (counter)
267 size_t n;
268 while (pOut_buf_cur >= pOut_buf_end)
270 TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT);
272 while (pIn_buf_cur >= pIn_buf_end)
274 TINFL_CR_RETURN(38, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS);
276 n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter);
277 TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n);
278 pIn_buf_cur += n;
279 pOut_buf_cur += n;
280 counter -= (mz_uint)n;
283 else if (r->m_type == 3)
285 TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED);
287 else
289 if (r->m_type == 1)
291 mz_uint8 *p = r->m_code_size_0;
292 mz_uint i;
293 r->m_table_sizes[0] = 288;
294 r->m_table_sizes[1] = 32;
295 TINFL_MEMSET(r->m_code_size_1, 5, 32);
296 for (i = 0; i <= 143; ++i)
297 *p++ = 8;
298 for (; i <= 255; ++i)
299 *p++ = 9;
300 for (; i <= 279; ++i)
301 *p++ = 7;
302 for (; i <= 287; ++i)
303 *p++ = 8;
305 else
307 for (counter = 0; counter < 3; counter++)
309 TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]);
310 r->m_table_sizes[counter] += s_min_table_sizes[counter];
312 MZ_CLEAR_ARR(r->m_code_size_2);
313 for (counter = 0; counter < r->m_table_sizes[2]; counter++)
315 mz_uint s;
316 TINFL_GET_BITS(14, s, 3);
317 r->m_code_size_2[s_length_dezigzag[counter]] = (mz_uint8)s;
319 r->m_table_sizes[2] = 19;
321 for (; (int)r->m_type >= 0; r->m_type--)
323 int tree_next, tree_cur;
324 mz_int16 *pLookUp;
325 mz_int16 *pTree;
326 mz_uint8 *pCode_size;
327 mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16];
328 pLookUp = r->m_look_up[r->m_type];
329 pTree = pTrees[r->m_type];
330 pCode_size = pCode_sizes[r->m_type];
331 MZ_CLEAR_ARR(total_syms);
332 TINFL_MEMSET(pLookUp, 0, sizeof(r->m_look_up[0]));
333 tinfl_clear_tree(r);
334 for (i = 0; i < r->m_table_sizes[r->m_type]; ++i)
335 total_syms[pCode_size[i]]++;
336 used_syms = 0, total = 0;
337 next_code[0] = next_code[1] = 0;
338 for (i = 1; i <= 15; ++i)
340 used_syms += total_syms[i];
341 next_code[i + 1] = (total = ((total + total_syms[i]) << 1));
343 if ((65536 != total) && (used_syms > 1))
345 TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED);
347 for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index)
349 mz_uint rev_code = 0, l, cur_code, code_size = pCode_size[sym_index];
350 if (!code_size)
351 continue;
352 cur_code = next_code[code_size]++;
353 for (l = code_size; l > 0; l--, cur_code >>= 1)
354 rev_code = (rev_code << 1) | (cur_code & 1);
355 if (code_size <= TINFL_FAST_LOOKUP_BITS)
357 mz_int16 k = (mz_int16)((code_size << 9) | sym_index);
358 while (rev_code < TINFL_FAST_LOOKUP_SIZE)
360 pLookUp[rev_code] = k;
361 rev_code += (1 << code_size);
363 continue;
365 if (0 == (tree_cur = pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)]))
367 pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next;
368 tree_cur = tree_next;
369 tree_next -= 2;
371 rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1);
372 for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--)
374 tree_cur -= ((rev_code >>= 1) & 1);
375 if (!pTree[-tree_cur - 1])
377 pTree[-tree_cur - 1] = (mz_int16)tree_next;
378 tree_cur = tree_next;
379 tree_next -= 2;
381 else
382 tree_cur = pTree[-tree_cur - 1];
384 tree_cur -= ((rev_code >>= 1) & 1);
385 pTree[-tree_cur - 1] = (mz_int16)sym_index;
387 if (r->m_type == 2)
389 for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]);)
391 mz_uint s;
392 TINFL_HUFF_DECODE(16, dist, r->m_look_up[2], r->m_tree_2);
393 if (dist < 16)
395 r->m_len_codes[counter++] = (mz_uint8)dist;
396 continue;
398 if ((dist == 16) && (!counter))
400 TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED);
402 num_extra = "\02\03\07"[dist - 16];
403 TINFL_GET_BITS(18, s, num_extra);
404 s += "\03\03\013"[dist - 16];
405 TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s);
406 counter += s;
408 if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter)
410 TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED);
412 TINFL_MEMCPY(r->m_code_size_0, r->m_len_codes, r->m_table_sizes[0]);
413 TINFL_MEMCPY(r->m_code_size_1, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]);
416 for (;;)
418 mz_uint8 *pSrc;
419 for (;;)
421 if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2))
423 TINFL_HUFF_DECODE(23, counter, r->m_look_up[0], r->m_tree_0);
424 if (counter >= 256)
425 break;
426 while (pOut_buf_cur >= pOut_buf_end)
428 TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT);
430 *pOut_buf_cur++ = (mz_uint8)counter;
432 else
434 int sym2;
435 mz_uint code_len;
436 #if TINFL_USE_64BIT_BITBUF
437 if (num_bits < 30)
439 bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits);
440 pIn_buf_cur += 4;
441 num_bits += 32;
443 #else
444 if (num_bits < 15)
446 bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
447 pIn_buf_cur += 2;
448 num_bits += 16;
450 #endif
451 if ((sym2 = r->m_look_up[0][bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
452 code_len = sym2 >> 9;
453 else
455 code_len = TINFL_FAST_LOOKUP_BITS;
458 sym2 = r->m_tree_0[~sym2 + ((bit_buf >> code_len++) & 1)];
459 } while (sym2 < 0);
461 counter = sym2;
462 bit_buf >>= code_len;
463 num_bits -= code_len;
464 if (counter & 256)
465 break;
467 #if !TINFL_USE_64BIT_BITBUF
468 if (num_bits < 15)
470 bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
471 pIn_buf_cur += 2;
472 num_bits += 16;
474 #endif
475 if ((sym2 = r->m_look_up[0][bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
476 code_len = sym2 >> 9;
477 else
479 code_len = TINFL_FAST_LOOKUP_BITS;
482 sym2 = r->m_tree_0[~sym2 + ((bit_buf >> code_len++) & 1)];
483 } while (sym2 < 0);
485 bit_buf >>= code_len;
486 num_bits -= code_len;
488 pOut_buf_cur[0] = (mz_uint8)counter;
489 if (sym2 & 256)
491 pOut_buf_cur++;
492 counter = sym2;
493 break;
495 pOut_buf_cur[1] = (mz_uint8)sym2;
496 pOut_buf_cur += 2;
499 if ((counter &= 511) == 256)
500 break;
502 num_extra = s_length_extra[counter - 257];
503 counter = s_length_base[counter - 257];
504 if (num_extra)
506 mz_uint extra_bits;
507 TINFL_GET_BITS(25, extra_bits, num_extra);
508 counter += extra_bits;
511 TINFL_HUFF_DECODE(26, dist, r->m_look_up[1], r->m_tree_1);
512 num_extra = s_dist_extra[dist];
513 dist = s_dist_base[dist];
514 if (num_extra)
516 mz_uint extra_bits;
517 TINFL_GET_BITS(27, extra_bits, num_extra);
518 dist += extra_bits;
521 dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
522 if ((dist == 0 || dist > dist_from_out_buf_start || dist_from_out_buf_start == 0) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
524 TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED);
527 pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask);
529 if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end)
531 while (counter--)
533 while (pOut_buf_cur >= pOut_buf_end)
535 TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT);
537 *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask];
539 continue;
541 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
542 else if ((counter >= 9) && (counter <= dist))
544 const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
547 #ifdef MINIZ_UNALIGNED_USE_MEMCPY
548 memcpy(pOut_buf_cur, pSrc, sizeof(mz_uint32)*2);
549 #else
550 ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0];
551 ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1];
552 #endif
553 pOut_buf_cur += 8;
554 } while ((pSrc += 8) < pSrc_end);
555 if ((counter &= 7) < 3)
557 if (counter)
559 pOut_buf_cur[0] = pSrc[0];
560 if (counter > 1)
561 pOut_buf_cur[1] = pSrc[1];
562 pOut_buf_cur += counter;
564 continue;
567 #endif
568 while(counter>2)
570 pOut_buf_cur[0] = pSrc[0];
571 pOut_buf_cur[1] = pSrc[1];
572 pOut_buf_cur[2] = pSrc[2];
573 pOut_buf_cur += 3;
574 pSrc += 3;
575 counter -= 3;
577 if (counter > 0)
579 pOut_buf_cur[0] = pSrc[0];
580 if (counter > 1)
581 pOut_buf_cur[1] = pSrc[1];
582 pOut_buf_cur += counter;
586 } while (!(r->m_final & 1));
588 /* 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. */
589 /* 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. */
590 TINFL_SKIP_BITS(32, num_bits & 7);
591 while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8))
593 --pIn_buf_cur;
594 num_bits -= 8;
596 bit_buf &= ~(~(tinfl_bit_buf_t)0 << num_bits);
597 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). */
599 if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
601 for (counter = 0; counter < 4; ++counter)
603 mz_uint s;
604 if (num_bits)
605 TINFL_GET_BITS(41, s, 8);
606 else
607 TINFL_GET_BYTE(42, s);
608 r->m_z_adler32 = (r->m_z_adler32 << 8) | s;
611 TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE);
613 TINFL_CR_FINISH
615 common_exit:
616 /* As long as we aren't telling the caller that we NEED more input to make forward progress: */
617 /* 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. */
618 /* 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. */
619 if ((status != TINFL_STATUS_NEEDS_MORE_INPUT) && (status != TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS))
621 while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8))
623 --pIn_buf_cur;
624 num_bits -= 8;
627 r->m_num_bits = num_bits;
628 r->m_bit_buf = bit_buf & ~(~(tinfl_bit_buf_t)0 << num_bits);
629 r->m_dist = dist;
630 r->m_counter = counter;
631 r->m_num_extra = num_extra;
632 r->m_dist_from_out_buf_start = dist_from_out_buf_start;
633 *pIn_buf_size = pIn_buf_cur - pIn_buf_next;
634 *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
635 if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0))
637 const mz_uint8 *ptr = pOut_buf_next;
638 size_t buf_len = *pOut_buf_size;
639 mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16;
640 size_t block_len = buf_len % 5552;
641 while (buf_len)
643 for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
645 s1 += ptr[0], s2 += s1;
646 s1 += ptr[1], s2 += s1;
647 s1 += ptr[2], s2 += s1;
648 s1 += ptr[3], s2 += s1;
649 s1 += ptr[4], s2 += s1;
650 s1 += ptr[5], s2 += s1;
651 s1 += ptr[6], s2 += s1;
652 s1 += ptr[7], s2 += s1;
654 for (; i < block_len; ++i)
655 s1 += *ptr++, s2 += s1;
656 s1 %= 65521U, s2 %= 65521U;
657 buf_len -= block_len;
658 block_len = 5552;
660 r->m_check_adler32 = (s2 << 16) + s1;
661 if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32))
662 status = TINFL_STATUS_ADLER32_MISMATCH;
664 return status;
667 /* Higher level helper functions. */
668 void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
670 tinfl_decompressor decomp;
671 void *pBuf = NULL, *pNew_buf;
672 size_t src_buf_ofs = 0, out_buf_capacity = 0;
673 *pOut_len = 0;
674 tinfl_init(&decomp);
675 for (;;)
677 size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity;
678 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,
679 (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
680 if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT))
682 MZ_FREE(pBuf);
683 *pOut_len = 0;
684 return NULL;
686 src_buf_ofs += src_buf_size;
687 *pOut_len += dst_buf_size;
688 if (status == TINFL_STATUS_DONE)
689 break;
690 new_out_buf_capacity = out_buf_capacity * 2;
691 if (new_out_buf_capacity < 128)
692 new_out_buf_capacity = 128;
693 pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity);
694 if (!pNew_buf)
696 MZ_FREE(pBuf);
697 *pOut_len = 0;
698 return NULL;
700 pBuf = pNew_buf;
701 out_buf_capacity = new_out_buf_capacity;
703 return pBuf;
706 #if 0
707 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)
709 tinfl_decompressor decomp;
710 tinfl_status status;
711 tinfl_init(&decomp);
712 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);
713 return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len;
716 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)
718 int result = 0;
719 tinfl_decompressor decomp;
720 mz_uint8 *pDict = (mz_uint8 *)MZ_MALLOC(TINFL_LZ_DICT_SIZE);
721 size_t in_buf_ofs = 0, dict_ofs = 0;
722 if (!pDict)
723 return TINFL_STATUS_FAILED;
724 memset(pDict,0,TINFL_LZ_DICT_SIZE);
725 tinfl_init(&decomp);
726 for (;;)
728 size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs;
729 tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8 *)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size,
730 (flags & ~(TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)));
731 in_buf_ofs += in_buf_size;
732 if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user)))
733 break;
734 if (status != TINFL_STATUS_HAS_MORE_OUTPUT)
736 result = (status == TINFL_STATUS_DONE);
737 break;
739 dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1);
741 MZ_FREE(pDict);
742 *pIn_buf_size = in_buf_ofs;
743 return result;
745 #endif