1 /**************************************************************************
2 *
3 * Copyright 2013-2014 RAD Game Tools and Valve Software
4 * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
5 * All Rights Reserved.
6 *
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:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
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.
24 *
25 **************************************************************************/
26
27 #include "miniz_tinfl.h"
28
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32
33 /* ------------------- Low-level Decompression (completely independent from all compression API's) */
34
35 #define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
36 #define TINFL_MEMSET(p, c, l) memset(p, c, l)
37
38 #define TINFL_CR_BEGIN \
39 switch (r->m_state) \
40 { \
41 case 0:
42 #define TINFL_CR_RETURN(state_index, result) \
43 do \
44 { \
45 status = result; \
46 r->m_state = state_index; \
47 goto common_exit; \
48 case state_index:; \
49 } \
50 MZ_MACRO_END
51 #define TINFL_CR_RETURN_FOREVER(state_index, result) \
52 do \
53 { \
54 for (;;) \
55 { \
56 TINFL_CR_RETURN(state_index, result); \
57 } \
58 } \
59 MZ_MACRO_END
60 #define TINFL_CR_FINISH }
61
62 #define TINFL_GET_BYTE(state_index, c) \
63 do \
64 { \
65 while (pIn_buf_cur >= pIn_buf_end) \
66 { \
67 TINFL_CR_RETURN(state_index, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS); \
68 } \
69 c = *pIn_buf_cur++; \
70 } \
71 MZ_MACRO_END
72
73 #define TINFL_NEED_BITS(state_index, n) \
74 do \
75 { \
76 mz_uint c; \
77 TINFL_GET_BYTE(state_index, c); \
78 bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
79 num_bits += 8; \
80 } while (num_bits < (mz_uint)(n))
81 #define TINFL_SKIP_BITS(state_index, n) \
82 do \
83 { \
84 if (num_bits < (mz_uint)(n)) \
85 { \
86 TINFL_NEED_BITS(state_index, n); \
87 } \
88 bit_buf >>= (n); \
89 num_bits -= (n); \
90 } \
91 MZ_MACRO_END
92 #define TINFL_GET_BITS(state_index, b, n) \
93 do \
94 { \
95 if (num_bits < (mz_uint)(n)) \
96 { \
97 TINFL_NEED_BITS(state_index, n); \
98 } \
99 b = bit_buf & ((1 << (n)) - 1); \
100 bit_buf >>= (n); \
101 num_bits -= (n); \
102 } \
103 MZ_MACRO_END
104
105 /* TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2. */
106 /* 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 */
107 /* 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 */
108 /* bit buffer contains >=15 bits (deflate's max. Huffman code size). */
109 #define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \
110 do \
111 { \
112 temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
113 if (temp >= 0) \
114 { \
115 code_len = temp >> 9; \
116 if ((code_len) && (num_bits >= code_len)) \
117 break; \
118 } \
119 else if (num_bits > TINFL_FAST_LOOKUP_BITS) \
120 { \
121 code_len = TINFL_FAST_LOOKUP_BITS; \
122 do \
123 { \
124 temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
125 } while ((temp < 0) && (num_bits >= (code_len + 1))); \
126 if (temp >= 0) \
127 break; \
128 } \
129 TINFL_GET_BYTE(state_index, c); \
130 bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
131 num_bits += 8; \
132 } while (num_bits < 15);
133
134 /* 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 */
135 /* 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 */
136 /* 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. */
137 /* The slow path is only executed at the very end of the input buffer. */
138 /* 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 */
139 /* following the deflate data and our non-conservative read-ahead path won't kick in here on this code. This is much trickier. */
140 #define TINFL_HUFF_DECODE(state_index, sym, pHuff) \
141 do \
142 { \
143 int temp; \
144 mz_uint code_len, c; \
145 if (num_bits < 15) \
146 { \
147 if ((pIn_buf_end - pIn_buf_cur) < 2) \
148 { \
149 TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
150 } \
151 else \
152 { \
153 bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); \
154 pIn_buf_cur += 2; \
155 num_bits += 16; \
156 } \
157 } \
158 if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
159 code_len = temp >> 9, temp &= 511; \
160 else \
161 { \
162 code_len = TINFL_FAST_LOOKUP_BITS; \
163 do \
164 { \
165 temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
166 } while (temp < 0); \
167 } \
168 sym = temp; \
169 bit_buf >>= code_len; \
170 num_bits -= code_len; \
171 } \
172 MZ_MACRO_END
173
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)174 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)
175 {
176 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 };
177 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 };
178 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 };
179 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 };
180 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 };
181 static const int s_min_table_sizes[3] = { 257, 1, 4 };
182
183 tinfl_status status = TINFL_STATUS_FAILED;
184 mz_uint32 num_bits, dist, counter, num_extra;
185 tinfl_bit_buf_t bit_buf;
186 const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size;
187 mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size;
188 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;
189
190 /* 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). */
191 if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start))
192 {
193 *pIn_buf_size = *pOut_buf_size = 0;
194 return TINFL_STATUS_BAD_PARAM;
195 }
196
197 num_bits = r->m_num_bits;
198 bit_buf = r->m_bit_buf;
199 dist = r->m_dist;
200 counter = r->m_counter;
201 num_extra = r->m_num_extra;
202 dist_from_out_buf_start = r->m_dist_from_out_buf_start;
203 TINFL_CR_BEGIN
204
205 bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0;
206 r->m_z_adler32 = r->m_check_adler32 = 1;
207 if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
208 {
209 TINFL_GET_BYTE(1, r->m_zhdr0);
210 TINFL_GET_BYTE(2, r->m_zhdr1);
211 counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8));
212 if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
213 counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1U << (8U + (r->m_zhdr0 >> 4)))));
214 if (counter)
215 {
216 TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED);
217 }
218 }
219
220 do
221 {
222 TINFL_GET_BITS(3, r->m_final, 3);
223 r->m_type = r->m_final >> 1;
224 if (r->m_type == 0)
225 {
226 TINFL_SKIP_BITS(5, num_bits & 7);
227 for (counter = 0; counter < 4; ++counter)
228 {
229 if (num_bits)
230 TINFL_GET_BITS(6, r->m_raw_header[counter], 8);
231 else
232 TINFL_GET_BYTE(7, r->m_raw_header[counter]);
233 }
234 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))))
235 {
236 TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED);
237 }
238 while ((counter) && (num_bits))
239 {
240 TINFL_GET_BITS(51, dist, 8);
241 while (pOut_buf_cur >= pOut_buf_end)
242 {
243 TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT);
244 }
245 *pOut_buf_cur++ = (mz_uint8)dist;
246 counter--;
247 }
248 while (counter)
249 {
250 size_t n;
251 while (pOut_buf_cur >= pOut_buf_end)
252 {
253 TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT);
254 }
255 while (pIn_buf_cur >= pIn_buf_end)
256 {
257 TINFL_CR_RETURN(38, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS);
258 }
259 n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter);
260 TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n);
261 pIn_buf_cur += n;
262 pOut_buf_cur += n;
263 counter -= (mz_uint)n;
264 }
265 }
266 else if (r->m_type == 3)
267 {
268 TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED);
269 }
270 else
271 {
272 if (r->m_type == 1)
273 {
274 mz_uint8 *p = r->m_tables[0].m_code_size;
275 mz_uint i;
276 r->m_table_sizes[0] = 288;
277 r->m_table_sizes[1] = 32;
278 TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32);
279 for (i = 0; i <= 143; ++i)
280 *p++ = 8;
281 for (; i <= 255; ++i)
282 *p++ = 9;
283 for (; i <= 279; ++i)
284 *p++ = 7;
285 for (; i <= 287; ++i)
286 *p++ = 8;
287 }
288 else
289 {
290 for (counter = 0; counter < 3; counter++)
291 {
292 TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]);
293 r->m_table_sizes[counter] += s_min_table_sizes[counter];
294 }
295 MZ_CLEAR_OBJ(r->m_tables[2].m_code_size);
296 for (counter = 0; counter < r->m_table_sizes[2]; counter++)
297 {
298 mz_uint s;
299 TINFL_GET_BITS(14, s, 3);
300 r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s;
301 }
302 r->m_table_sizes[2] = 19;
303 }
304 for (; (int)r->m_type >= 0; r->m_type--)
305 {
306 int tree_next, tree_cur;
307 tinfl_huff_table *pTable;
308 mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16];
309 pTable = &r->m_tables[r->m_type];
310 MZ_CLEAR_OBJ(total_syms);
311 MZ_CLEAR_OBJ(pTable->m_look_up);
312 MZ_CLEAR_OBJ(pTable->m_tree);
313 for (i = 0; i < r->m_table_sizes[r->m_type]; ++i)
314 total_syms[pTable->m_code_size[i]]++;
315 used_syms = 0, total = 0;
316 next_code[0] = next_code[1] = 0;
317 for (i = 1; i <= 15; ++i)
318 {
319 used_syms += total_syms[i];
320 next_code[i + 1] = (total = ((total + total_syms[i]) << 1));
321 }
322 if ((65536 != total) && (used_syms > 1))
323 {
324 TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED);
325 }
326 for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index)
327 {
328 mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index];
329 if (!code_size)
330 continue;
331 cur_code = next_code[code_size]++;
332 for (l = code_size; l > 0; l--, cur_code >>= 1)
333 rev_code = (rev_code << 1) | (cur_code & 1);
334 if (code_size <= TINFL_FAST_LOOKUP_BITS)
335 {
336 mz_int16 k = (mz_int16)((code_size << 9) | sym_index);
337 while (rev_code < TINFL_FAST_LOOKUP_SIZE)
338 {
339 pTable->m_look_up[rev_code] = k;
340 rev_code += (1 << code_size);
341 }
342 continue;
343 }
344 if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)]))
345 {
346 pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next;
347 tree_cur = tree_next;
348 tree_next -= 2;
349 }
350 rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1);
351 for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--)
352 {
353 tree_cur -= ((rev_code >>= 1) & 1);
354 if (!pTable->m_tree[-tree_cur - 1])
355 {
356 pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next;
357 tree_cur = tree_next;
358 tree_next -= 2;
359 }
360 else
361 tree_cur = pTable->m_tree[-tree_cur - 1];
362 }
363 tree_cur -= ((rev_code >>= 1) & 1);
364 pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
365 }
366 if (r->m_type == 2)
367 {
368 for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]);)
369 {
370 mz_uint s;
371 TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]);
372 if (dist < 16)
373 {
374 r->m_len_codes[counter++] = (mz_uint8)dist;
375 continue;
376 }
377 if ((dist == 16) && (!counter))
378 {
379 TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED);
380 }
381 num_extra = "\02\03\07"[dist - 16];
382 TINFL_GET_BITS(18, s, num_extra);
383 s += "\03\03\013"[dist - 16];
384 TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s);
385 counter += s;
386 }
387 if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter)
388 {
389 TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED);
390 }
391 TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]);
392 TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]);
393 }
394 }
395 for (;;)
396 {
397 mz_uint8 *pSrc;
398 for (;;)
399 {
400 if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2))
401 {
402 TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]);
403 if (counter >= 256)
404 break;
405 while (pOut_buf_cur >= pOut_buf_end)
406 {
407 TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT);
408 }
409 *pOut_buf_cur++ = (mz_uint8)counter;
410 }
411 else
412 {
413 int sym2;
414 mz_uint code_len;
415 #if TINFL_USE_64BIT_BITBUF
416 if (num_bits < 30)
417 {
418 bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits);
419 pIn_buf_cur += 4;
420 num_bits += 32;
421 }
422 #else
423 if (num_bits < 15)
424 {
425 bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
426 pIn_buf_cur += 2;
427 num_bits += 16;
428 }
429 #endif
430 if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
431 code_len = sym2 >> 9;
432 else
433 {
434 code_len = TINFL_FAST_LOOKUP_BITS;
435 do
436 {
437 sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)];
438 } while (sym2 < 0);
439 }
440 counter = sym2;
441 bit_buf >>= code_len;
442 num_bits -= code_len;
443 if (counter & 256)
444 break;
445
446 #if !TINFL_USE_64BIT_BITBUF
447 if (num_bits < 15)
448 {
449 bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
450 pIn_buf_cur += 2;
451 num_bits += 16;
452 }
453 #endif
454 if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
455 code_len = sym2 >> 9;
456 else
457 {
458 code_len = TINFL_FAST_LOOKUP_BITS;
459 do
460 {
461 sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)];
462 } while (sym2 < 0);
463 }
464 bit_buf >>= code_len;
465 num_bits -= code_len;
466
467 pOut_buf_cur[0] = (mz_uint8)counter;
468 if (sym2 & 256)
469 {
470 pOut_buf_cur++;
471 counter = sym2;
472 break;
473 }
474 pOut_buf_cur[1] = (mz_uint8)sym2;
475 pOut_buf_cur += 2;
476 }
477 }
478 if ((counter &= 511) == 256)
479 break;
480
481 num_extra = s_length_extra[counter - 257];
482 counter = s_length_base[counter - 257];
483 if (num_extra)
484 {
485 mz_uint extra_bits;
486 TINFL_GET_BITS(25, extra_bits, num_extra);
487 counter += extra_bits;
488 }
489
490 TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]);
491 num_extra = s_dist_extra[dist];
492 dist = s_dist_base[dist];
493 if (num_extra)
494 {
495 mz_uint extra_bits;
496 TINFL_GET_BITS(27, extra_bits, num_extra);
497 dist += extra_bits;
498 }
499
500 dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
501 if ((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
502 {
503 TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED);
504 }
505
506 pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask);
507
508 if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end)
509 {
510 while (counter--)
511 {
512 while (pOut_buf_cur >= pOut_buf_end)
513 {
514 TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT);
515 }
516 *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask];
517 }
518 continue;
519 }
520 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
521 else if ((counter >= 9) && (counter <= dist))
522 {
523 const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
524 do
525 {
526 ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0];
527 ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1];
528 pOut_buf_cur += 8;
529 } while ((pSrc += 8) < pSrc_end);
530 if ((counter &= 7) < 3)
531 {
532 if (counter)
533 {
534 pOut_buf_cur[0] = pSrc[0];
535 if (counter > 1)
536 pOut_buf_cur[1] = pSrc[1];
537 pOut_buf_cur += counter;
538 }
539 continue;
540 }
541 }
542 #endif
543 do
544 {
545 pOut_buf_cur[0] = pSrc[0];
546 pOut_buf_cur[1] = pSrc[1];
547 pOut_buf_cur[2] = pSrc[2];
548 pOut_buf_cur += 3;
549 pSrc += 3;
550 } while ((int)(counter -= 3) > 2);
551 if ((int)counter > 0)
552 {
553 pOut_buf_cur[0] = pSrc[0];
554 if ((int)counter > 1)
555 pOut_buf_cur[1] = pSrc[1];
556 pOut_buf_cur += counter;
557 }
558 }
559 }
560 } while (!(r->m_final & 1));
561
562 /* 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. */
563 /* 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. */
564 TINFL_SKIP_BITS(32, num_bits & 7);
565 while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8))
566 {
567 --pIn_buf_cur;
568 num_bits -= 8;
569 }
570 bit_buf &= (tinfl_bit_buf_t)((((mz_uint64)1) << num_bits) - (mz_uint64)1);
571 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). */
572
573 if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
574 {
575 for (counter = 0; counter < 4; ++counter)
576 {
577 mz_uint s;
578 if (num_bits)
579 TINFL_GET_BITS(41, s, 8);
580 else
581 TINFL_GET_BYTE(42, s);
582 r->m_z_adler32 = (r->m_z_adler32 << 8) | s;
583 }
584 }
585 TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE);
586
587 TINFL_CR_FINISH
588
589 common_exit:
590 /* As long as we aren't telling the caller that we NEED more input to make forward progress: */
591 /* 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. */
592 /* 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. */
593 if ((status != TINFL_STATUS_NEEDS_MORE_INPUT) && (status != TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS))
594 {
595 while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8))
596 {
597 --pIn_buf_cur;
598 num_bits -= 8;
599 }
600 }
601 r->m_num_bits = num_bits;
602 r->m_bit_buf = bit_buf & (tinfl_bit_buf_t)((((mz_uint64)1) << num_bits) - (mz_uint64)1);
603 r->m_dist = dist;
604 r->m_counter = counter;
605 r->m_num_extra = num_extra;
606 r->m_dist_from_out_buf_start = dist_from_out_buf_start;
607 *pIn_buf_size = pIn_buf_cur - pIn_buf_next;
608 *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
609 if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0))
610 {
611 const mz_uint8 *ptr = pOut_buf_next;
612 size_t buf_len = *pOut_buf_size;
613 mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16;
614 size_t block_len = buf_len % 5552;
615 while (buf_len)
616 {
617 for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
618 {
619 s1 += ptr[0], s2 += s1;
620 s1 += ptr[1], s2 += s1;
621 s1 += ptr[2], s2 += s1;
622 s1 += ptr[3], s2 += s1;
623 s1 += ptr[4], s2 += s1;
624 s1 += ptr[5], s2 += s1;
625 s1 += ptr[6], s2 += s1;
626 s1 += ptr[7], s2 += s1;
627 }
628 for (; i < block_len; ++i)
629 s1 += *ptr++, s2 += s1;
630 s1 %= 65521U, s2 %= 65521U;
631 buf_len -= block_len;
632 block_len = 5552;
633 }
634 r->m_check_adler32 = (s2 << 16) + s1;
635 if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32))
636 status = TINFL_STATUS_ADLER32_MISMATCH;
637 }
638 return status;
639 }
640
641 /* Higher level helper functions. */
tinfl_decompress_mem_to_heap(const void * pSrc_buf,size_t src_buf_len,size_t * pOut_len,int flags)642 void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
643 {
644 tinfl_decompressor decomp;
645 void *pBuf = NULL, *pNew_buf;
646 size_t src_buf_ofs = 0, out_buf_capacity = 0;
647 *pOut_len = 0;
648 tinfl_init(&decomp);
649 for (;;)
650 {
651 size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity;
652 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,
653 (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
654 if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT))
655 {
656 MZ_FREE(pBuf);
657 *pOut_len = 0;
658 return NULL;
659 }
660 src_buf_ofs += src_buf_size;
661 *pOut_len += dst_buf_size;
662 if (status == TINFL_STATUS_DONE)
663 break;
664 new_out_buf_capacity = out_buf_capacity * 2;
665 if (new_out_buf_capacity < 128)
666 new_out_buf_capacity = 128;
667 pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity);
668 if (!pNew_buf)
669 {
670 MZ_FREE(pBuf);
671 *pOut_len = 0;
672 return NULL;
673 }
674 pBuf = pNew_buf;
675 out_buf_capacity = new_out_buf_capacity;
676 }
677 return pBuf;
678 }
679
tinfl_decompress_mem_to_mem(void * pOut_buf,size_t out_buf_len,const void * pSrc_buf,size_t src_buf_len,int flags)680 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)
681 {
682 tinfl_decompressor decomp;
683 tinfl_status status;
684 tinfl_init(&decomp);
685 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);
686 return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len;
687 }
688
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)689 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)
690 {
691 int result = 0;
692 tinfl_decompressor decomp;
693 mz_uint8 *pDict = (mz_uint8 *)MZ_MALLOC(TINFL_LZ_DICT_SIZE);
694 size_t in_buf_ofs = 0, dict_ofs = 0;
695 if (!pDict)
696 return TINFL_STATUS_FAILED;
697 tinfl_init(&decomp);
698 for (;;)
699 {
700 size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs;
701 tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8 *)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size,
702 (flags & ~(TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)));
703 in_buf_ofs += in_buf_size;
704 if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user)))
705 break;
706 if (status != TINFL_STATUS_HAS_MORE_OUTPUT)
707 {
708 result = (status == TINFL_STATUS_DONE);
709 break;
710 }
711 dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1);
712 }
713 MZ_FREE(pDict);
714 *pIn_buf_size = in_buf_ofs;
715 return result;
716 }
717
tinfl_decompressor_alloc()718 tinfl_decompressor *tinfl_decompressor_alloc()
719 {
720 tinfl_decompressor *pDecomp = (tinfl_decompressor *)MZ_MALLOC(sizeof(tinfl_decompressor));
721 if (pDecomp)
722 tinfl_init(pDecomp);
723 return pDecomp;
724 }
725
tinfl_decompressor_free(tinfl_decompressor * pDecomp)726 void tinfl_decompressor_free(tinfl_decompressor *pDecomp)
727 {
728 MZ_FREE(pDecomp);
729 }
730
731 #ifdef __cplusplus
732 }
733 #endif
734