NCBI C++ ToolKit
miniz.c
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #include "miniz.h"
2 /**************************************************************************
3  *
4  * Copyright 2013-2014 RAD Game Tools and Valve Software
5  * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
6  * All Rights Reserved.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24  * THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28 
29 
30 typedef unsigned char mz_validate_uint16[sizeof(mz_uint16) == 2 ? 1 : -1];
31 typedef unsigned char mz_validate_uint32[sizeof(mz_uint32) == 4 ? 1 : -1];
32 typedef unsigned char mz_validate_uint64[sizeof(mz_uint64) == 8 ? 1 : -1];
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 /* ------------------- zlib-style API's */
39 
40 mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len)
41 {
42  mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16);
43  size_t block_len = buf_len % 5552;
44  if (!ptr)
45  return MZ_ADLER32_INIT;
46  while (buf_len)
47  {
48  for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
49  {
50  s1 += ptr[0], s2 += s1;
51  s1 += ptr[1], s2 += s1;
52  s1 += ptr[2], s2 += s1;
53  s1 += ptr[3], s2 += s1;
54  s1 += ptr[4], s2 += s1;
55  s1 += ptr[5], s2 += s1;
56  s1 += ptr[6], s2 += s1;
57  s1 += ptr[7], s2 += s1;
58  }
59  for (; i < block_len; ++i)
60  s1 += *ptr++, s2 += s1;
61  s1 %= 65521U, s2 %= 65521U;
62  buf_len -= block_len;
63  block_len = 5552;
64  }
65  return (s2 << 16) + s1;
66 }
67 
68 /* Karl Malbrain's compact CRC-32. See "A compact CCITT crc16 and crc32 C implementation that balances processor cache usage against speed": http://www.geocities.com/malbrain/ */
69 #if 0
70  mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
71  {
72  static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
73  0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c };
74  mz_uint32 crcu32 = (mz_uint32)crc;
75  if (!ptr)
76  return MZ_CRC32_INIT;
77  crcu32 = ~crcu32;
78  while (buf_len--)
79  {
80  mz_uint8 b = *ptr++;
81  crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)];
82  crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)];
83  }
84  return ~crcu32;
85  }
86 #elif defined(USE_EXTERNAL_MZCRC)
87 /* If USE_EXTERNAL_CRC is defined, an external module will export the
88  * mz_crc32() symbol for us to use, e.g. an SSE-accelerated version.
89  * Depending on the impl, it may be necessary to ~ the input/output crc values.
90  */
91 mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len);
92 #else
93 /* Faster, but larger CPU cache footprint.
94  */
95 mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
96 {
97  static const mz_uint32 s_crc_table[256] =
98  {
99  0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535,
100  0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
101  0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D,
102  0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
103  0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4,
104  0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
105  0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC,
106  0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
107  0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB,
108  0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
109  0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB,
110  0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
111  0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA,
112  0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE,
113  0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A,
114  0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
115  0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409,
116  0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
117  0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739,
118  0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
119  0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268,
120  0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0,
121  0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8,
122  0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
123  0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF,
124  0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
125  0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7,
126  0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
127  0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE,
128  0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
129  0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6,
130  0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
131  0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D,
132  0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
133  0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605,
134  0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
135  0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
136  };
137 
138  mz_uint32 crc32 = (mz_uint32)crc ^ 0xFFFFFFFF;
139  const mz_uint8 *pByte_buf = (const mz_uint8 *)ptr;
140 
141  while (buf_len >= 4)
142  {
143  crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF];
144  crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[1]) & 0xFF];
145  crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[2]) & 0xFF];
146  crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[3]) & 0xFF];
147  pByte_buf += 4;
148  buf_len -= 4;
149  }
150 
151  while (buf_len)
152  {
153  crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF];
154  ++pByte_buf;
155  --buf_len;
156  }
157 
158  return ~crc32;
159 }
160 #endif
161 
162 void mz_free(void *p)
163 {
164  MZ_FREE(p);
165 }
166 
167 MINIZ_EXPORT void *miniz_def_alloc_func(void *opaque, size_t items, size_t size)
168 {
169  (void)opaque, (void)items, (void)size;
170  return MZ_MALLOC(items * size);
171 }
172 MINIZ_EXPORT void miniz_def_free_func(void *opaque, void *address)
173 {
174  (void)opaque, (void)address;
175  MZ_FREE(address);
176 }
177 MINIZ_EXPORT void *miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size)
178 {
179  (void)opaque, (void)address, (void)items, (void)size;
180  return MZ_REALLOC(address, items * size);
181 }
182 
183 const char *mz_version(void)
184 {
185  return MZ_VERSION;
186 }
187 
188 #ifndef MINIZ_NO_ZLIB_APIS
189 
190 int mz_deflateInit(mz_streamp pStream, int level)
191 {
193 }
194 
195 int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy)
196 {
197  tdefl_compressor *pComp;
199 
200  if (!pStream)
201  return MZ_STREAM_ERROR;
202  if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) || ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)))
203  return MZ_PARAM_ERROR;
204 
205  pStream->data_type = 0;
206  pStream->adler = MZ_ADLER32_INIT;
207  pStream->msg = NULL;
208  pStream->reserved = 0;
209  pStream->total_in = 0;
210  pStream->total_out = 0;
211  if (!pStream->zalloc)
212  pStream->zalloc = miniz_def_alloc_func;
213  if (!pStream->zfree)
214  pStream->zfree = miniz_def_free_func;
215 
216  pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, sizeof(tdefl_compressor));
217  if (!pComp)
218  return MZ_MEM_ERROR;
219 
220  pStream->state = (struct mz_internal_state *)pComp;
221 
222  if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY)
223  {
224  mz_deflateEnd(pStream);
225  return MZ_PARAM_ERROR;
226  }
227 
228  return MZ_OK;
229 }
230 
231 int mz_deflateReset(mz_streamp pStream)
232 {
233  if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree))
234  return MZ_STREAM_ERROR;
235  pStream->total_in = pStream->total_out = 0;
236  tdefl_init((tdefl_compressor *)pStream->state, NULL, NULL, ((tdefl_compressor *)pStream->state)->m_flags);
237  return MZ_OK;
238 }
239 
240 int mz_deflate(mz_streamp pStream, int flush)
241 {
242  size_t in_bytes, out_bytes;
243  mz_ulong orig_total_in, orig_total_out;
244  int mz_status = MZ_OK;
245 
246  if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || (!pStream->next_out))
247  return MZ_STREAM_ERROR;
248  if (!pStream->avail_out)
249  return MZ_BUF_ERROR;
250 
251  if (flush == MZ_PARTIAL_FLUSH)
252  flush = MZ_SYNC_FLUSH;
253 
254  if (((tdefl_compressor *)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE)
255  return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR;
256 
257  orig_total_in = pStream->total_in;
258  orig_total_out = pStream->total_out;
259  for (;;)
260  {
261  tdefl_status defl_status;
262  in_bytes = pStream->avail_in;
263  out_bytes = pStream->avail_out;
264 
265  defl_status = tdefl_compress((tdefl_compressor *)pStream->state, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, (tdefl_flush)flush);
266  pStream->next_in += (mz_uint)in_bytes;
267  pStream->avail_in -= (mz_uint)in_bytes;
268  pStream->total_in += (mz_uint)in_bytes;
269  pStream->adler = tdefl_get_adler32((tdefl_compressor *)pStream->state);
270 
271  pStream->next_out += (mz_uint)out_bytes;
272  pStream->avail_out -= (mz_uint)out_bytes;
273  pStream->total_out += (mz_uint)out_bytes;
274 
275  if (defl_status < 0)
276  {
277  mz_status = MZ_STREAM_ERROR;
278  break;
279  }
280  else if (defl_status == TDEFL_STATUS_DONE)
281  {
282  mz_status = MZ_STREAM_END;
283  break;
284  }
285  else if (!pStream->avail_out)
286  break;
287  else if ((!pStream->avail_in) && (flush != MZ_FINISH))
288  {
289  if ((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out))
290  break;
291  return MZ_BUF_ERROR; /* Can't make forward progress without some input.
292  */
293  }
294  }
295  return mz_status;
296 }
297 
298 int mz_deflateEnd(mz_streamp pStream)
299 {
300  if (!pStream)
301  return MZ_STREAM_ERROR;
302  if (pStream->state)
303  {
304  pStream->zfree(pStream->opaque, pStream->state);
305  pStream->state = NULL;
306  }
307  return MZ_OK;
308 }
309 
310 mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len)
311 {
312  (void)pStream;
313  /* This is really over conservative. (And lame, but it's actually pretty tricky to compute a true upper bound given the way tdefl's blocking works.) */
314  return MZ_MAX(128 + (source_len * 110) / 100, 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5);
315 }
316 
317 int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level)
318 {
319  int status;
320  mz_stream stream;
321  memset(&stream, 0, sizeof(stream));
322 
323  /* In case mz_ulong is 64-bits (argh I hate longs). */
324  if ((source_len | *pDest_len) > 0xFFFFFFFFU)
325  return MZ_PARAM_ERROR;
326 
327  stream.next_in = pSource;
328  stream.avail_in = (mz_uint32)source_len;
329  stream.next_out = pDest;
330  stream.avail_out = (mz_uint32)*pDest_len;
331 
332  status = mz_deflateInit(&stream, level);
333  if (status != MZ_OK)
334  return status;
335 
336  status = mz_deflate(&stream, MZ_FINISH);
337  if (status != MZ_STREAM_END)
338  {
339  mz_deflateEnd(&stream);
340  return (status == MZ_OK) ? MZ_BUF_ERROR : status;
341  }
342 
343  *pDest_len = stream.total_out;
344  return mz_deflateEnd(&stream);
345 }
346 
347 int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
348 {
349  return mz_compress2(pDest, pDest_len, pSource, source_len, MZ_DEFAULT_COMPRESSION);
350 }
351 
353 {
354  return mz_deflateBound(NULL, source_len);
355 }
356 
357 typedef struct
358 {
359  tinfl_decompressor m_decomp;
360  mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed;
361  int m_window_bits;
363  tinfl_status m_last_status;
364 } inflate_state;
365 
366 int mz_inflateInit2(mz_streamp pStream, int window_bits)
367 {
368  inflate_state *pDecomp;
369  if (!pStream)
370  return MZ_STREAM_ERROR;
371  if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS))
372  return MZ_PARAM_ERROR;
373 
374  pStream->data_type = 0;
375  pStream->adler = 0;
376  pStream->msg = NULL;
377  pStream->total_in = 0;
378  pStream->total_out = 0;
379  pStream->reserved = 0;
380  if (!pStream->zalloc)
381  pStream->zalloc = miniz_def_alloc_func;
382  if (!pStream->zfree)
383  pStream->zfree = miniz_def_free_func;
384 
385  pDecomp = (inflate_state *)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state));
386  if (!pDecomp)
387  return MZ_MEM_ERROR;
388 
389  pStream->state = (struct mz_internal_state *)pDecomp;
390 
391  tinfl_init(&pDecomp->m_decomp);
392  pDecomp->m_dict_ofs = 0;
393  pDecomp->m_dict_avail = 0;
394  pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
395  pDecomp->m_first_call = 1;
396  pDecomp->m_has_flushed = 0;
397  pDecomp->m_window_bits = window_bits;
398 
399  return MZ_OK;
400 }
401 
402 int mz_inflateInit(mz_streamp pStream)
403 {
404  return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS);
405 }
406 
407 int mz_inflateReset(mz_streamp pStream)
408 {
409  inflate_state *pDecomp;
410  if (!pStream)
411  return MZ_STREAM_ERROR;
412 
413  pStream->data_type = 0;
414  pStream->adler = 0;
415  pStream->msg = NULL;
416  pStream->total_in = 0;
417  pStream->total_out = 0;
418  pStream->reserved = 0;
419 
420  pDecomp = (inflate_state *)pStream->state;
421 
422  tinfl_init(&pDecomp->m_decomp);
423  pDecomp->m_dict_ofs = 0;
424  pDecomp->m_dict_avail = 0;
425  pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
426  pDecomp->m_first_call = 1;
427  pDecomp->m_has_flushed = 0;
428  /* pDecomp->m_window_bits = window_bits */;
429 
430  return MZ_OK;
431 }
432 
433 int mz_inflate(mz_streamp pStream, int flush)
434 {
435  inflate_state *pState;
436  mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32;
437  size_t in_bytes, out_bytes, orig_avail_in;
438  tinfl_status status;
439 
440  if ((!pStream) || (!pStream->state))
441  return MZ_STREAM_ERROR;
442  if (flush == MZ_PARTIAL_FLUSH)
443  flush = MZ_SYNC_FLUSH;
444  if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH))
445  return MZ_STREAM_ERROR;
446 
447  pState = (inflate_state *)pStream->state;
448  if (pState->m_window_bits > 0)
449  decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER;
450  orig_avail_in = pStream->avail_in;
451 
452  first_call = pState->m_first_call;
453  pState->m_first_call = 0;
454  if (pState->m_last_status < 0)
455  return MZ_DATA_ERROR;
456 
457  if (pState->m_has_flushed && (flush != MZ_FINISH))
458  return MZ_STREAM_ERROR;
459  pState->m_has_flushed |= (flush == MZ_FINISH);
460 
461  if ((flush == MZ_FINISH) && (first_call))
462  {
463  /* MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file. */
465  in_bytes = pStream->avail_in;
466  out_bytes = pStream->avail_out;
467  status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags);
468  pState->m_last_status = status;
469  pStream->next_in += (mz_uint)in_bytes;
470  pStream->avail_in -= (mz_uint)in_bytes;
471  pStream->total_in += (mz_uint)in_bytes;
472  pStream->adler = tinfl_get_adler32(&pState->m_decomp);
473  pStream->next_out += (mz_uint)out_bytes;
474  pStream->avail_out -= (mz_uint)out_bytes;
475  pStream->total_out += (mz_uint)out_bytes;
476 
477  if (status < 0)
478  return MZ_DATA_ERROR;
479  else if (status != TINFL_STATUS_DONE)
480  {
481  pState->m_last_status = TINFL_STATUS_FAILED;
482  return MZ_BUF_ERROR;
483  }
484  return MZ_STREAM_END;
485  }
486  /* flush != MZ_FINISH then we must assume there's more input. */
487  if (flush != MZ_FINISH)
488  decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT;
489 
490  if (pState->m_dict_avail)
491  {
492  n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
493  memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
494  pStream->next_out += n;
495  pStream->avail_out -= n;
496  pStream->total_out += n;
497  pState->m_dict_avail -= n;
498  pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
499  return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
500  }
501 
502  for (;;)
503  {
504  in_bytes = pStream->avail_in;
505  out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs;
506 
507  status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict, pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags);
508  pState->m_last_status = status;
509 
510  pStream->next_in += (mz_uint)in_bytes;
511  pStream->avail_in -= (mz_uint)in_bytes;
512  pStream->total_in += (mz_uint)in_bytes;
513  pStream->adler = tinfl_get_adler32(&pState->m_decomp);
514 
515  pState->m_dict_avail = (mz_uint)out_bytes;
516 
517  n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
518  memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
519  pStream->next_out += n;
520  pStream->avail_out -= n;
521  pStream->total_out += n;
522  pState->m_dict_avail -= n;
523  pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
524 
525  if (status < 0)
526  return MZ_DATA_ERROR; /* Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well). */
527  else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in))
528  return MZ_BUF_ERROR; /* Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH. */
529  else if (flush == MZ_FINISH)
530  {
531  /* The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH. */
532  if (status == TINFL_STATUS_DONE)
533  return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END;
534  /* status here must be TINFL_STATUS_HAS_MORE_OUTPUT, which means there's at least 1 more byte on the way. If there's no more room left in the output buffer then something is wrong. */
535  else if (!pStream->avail_out)
536  return MZ_BUF_ERROR;
537  }
538  else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail))
539  break;
540  }
541 
542  return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
543 }
544 
545 int mz_inflateEnd(mz_streamp pStream)
546 {
547  if (!pStream)
548  return MZ_STREAM_ERROR;
549  if (pStream->state)
550  {
551  pStream->zfree(pStream->opaque, pStream->state);
552  pStream->state = NULL;
553  }
554  return MZ_OK;
555 }
556 int mz_uncompress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong *pSource_len)
557 {
558  mz_stream stream;
559  int status;
560  memset(&stream, 0, sizeof(stream));
561 
562  /* In case mz_ulong is 64-bits (argh I hate longs). */
563  if ((*pSource_len | *pDest_len) > 0xFFFFFFFFU)
564  return MZ_PARAM_ERROR;
565 
566  stream.next_in = pSource;
567  stream.avail_in = (mz_uint32)*pSource_len;
568  stream.next_out = pDest;
569  stream.avail_out = (mz_uint32)*pDest_len;
570 
571  status = mz_inflateInit(&stream);
572  if (status != MZ_OK)
573  return status;
574 
575  status = mz_inflate(&stream, MZ_FINISH);
576  *pSource_len = *pSource_len - stream.avail_in;
577  if (status != MZ_STREAM_END)
578  {
579  mz_inflateEnd(&stream);
580  return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status;
581  }
582  *pDest_len = stream.total_out;
583 
584  return mz_inflateEnd(&stream);
585 }
586 
587 int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
588 {
589  return mz_uncompress2(pDest, pDest_len, pSource, &source_len);
590 }
591 
592 const char *mz_error(int err)
593 {
594  static struct
595  {
596  int m_err;
597  const char *m_pDesc;
598  } s_error_descs[] =
599  {
600  { MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" }, { MZ_DATA_ERROR, "data error" }, { MZ_MEM_ERROR, "out of memory" }, { MZ_BUF_ERROR, "buf error" }, { MZ_VERSION_ERROR, "version error" }, { MZ_PARAM_ERROR, "parameter error" }
601  };
602  mz_uint i;
603  for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i)
604  if (s_error_descs[i].m_err == err)
605  return s_error_descs[i].m_pDesc;
606  return NULL;
607 }
608 
609 #endif /*MINIZ_NO_ZLIB_APIS */
610 
611 #ifdef __cplusplus
612 }
613 #endif
614 
615 /*
616  This is free and unencumbered software released into the public domain.
617 
618  Anyone is free to copy, modify, publish, use, compile, sell, or
619  distribute this software, either in source code form or as a compiled
620  binary, for any purpose, commercial or non-commercial, and by any
621  means.
622 
623  In jurisdictions that recognize copyright laws, the author or authors
624  of this software dedicate any and all copyright interest in the
625  software to the public domain. We make this dedication for the benefit
626  of the public at large and to the detriment of our heirs and
627  successors. We intend this dedication to be an overt act of
628  relinquishment in perpetuity of all present and future rights to this
629  software under copyright law.
630 
631  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
632  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
633  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
634  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
635  OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
636  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
637  OTHER DEALINGS IN THE SOFTWARE.
638 
639  For more information, please refer to <http://unlicense.org/>
640 */
641 /**************************************************************************
642  *
643  * Copyright 2013-2014 RAD Game Tools and Valve Software
644  * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
645  * All Rights Reserved.
646  *
647  * Permission is hereby granted, free of charge, to any person obtaining a copy
648  * of this software and associated documentation files (the "Software"), to deal
649  * in the Software without restriction, including without limitation the rights
650  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
651  * copies of the Software, and to permit persons to whom the Software is
652  * furnished to do so, subject to the following conditions:
653  *
654  * The above copyright notice and this permission notice shall be included in
655  * all copies or substantial portions of the Software.
656  *
657  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
658  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
659  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
660  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
661  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
662  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
663  * THE SOFTWARE.
664  *
665  **************************************************************************/
666 
667 
668 
669 #ifdef __cplusplus
670 extern "C" {
671 #endif
672 
673 /* ------------------- Low-level Compression (independent from all decompression API's) */
674 
675 /* Purposely making these tables static for faster init and thread safety. */
676 static const mz_uint16 s_tdefl_len_sym[256] =
677  {
678  257, 258, 259, 260, 261, 262, 263, 264, 265, 265, 266, 266, 267, 267, 268, 268, 269, 269, 269, 269, 270, 270, 270, 270, 271, 271, 271, 271, 272, 272, 272, 272,
679  273, 273, 273, 273, 273, 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, 274, 275, 275, 275, 275, 275, 275, 275, 275, 276, 276, 276, 276, 276, 276, 276, 276,
680  277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
681  279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280,
682  281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281,
683  282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282,
684  283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283,
685  284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 285
686  };
687 
688 static const mz_uint8 s_tdefl_len_extra[256] =
689  {
690  0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
691  4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
692  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
693  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0
694  };
695 
696 static const mz_uint8 s_tdefl_small_dist_sym[512] =
697  {
698  0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11,
699  11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13,
700  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
701  14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
702  14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
703  15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
704  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
705  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
706  16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
707  17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
708  17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
709  17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17
710  };
711 
713  {
714  0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
715  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
716  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
717  6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
718  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
719  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
720  7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
721  7, 7, 7, 7, 7, 7, 7, 7
722  };
723 
724 static const mz_uint8 s_tdefl_large_dist_sym[128] =
725  {
726  0, 0, 18, 19, 20, 20, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
727  26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
728  28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
729  };
730 
732  {
733  0, 0, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
734  12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
735  13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13
736  };
737 
738 /* Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted values. */
739 typedef struct
740 {
744 {
745  mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2];
746  tdefl_sym_freq *pCur_syms = pSyms0, *pNew_syms = pSyms1;
747  MZ_CLEAR_OBJ(hist);
748  for (i = 0; i < num_syms; i++)
749  {
750  mz_uint freq = pSyms0[i].m_key;
751  hist[freq & 0xFF]++;
752  hist[256 + ((freq >> 8) & 0xFF)]++;
753  }
754  while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256]))
755  total_passes--;
756  for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8)
757  {
758  const mz_uint32 *pHist = &hist[pass << 8];
759  mz_uint offsets[256], cur_ofs = 0;
760  for (i = 0; i < 256; i++)
761  {
762  offsets[i] = cur_ofs;
763  cur_ofs += pHist[i];
764  }
765  for (i = 0; i < num_syms; i++)
766  pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = pCur_syms[i];
767  {
768  tdefl_sym_freq *t = pCur_syms;
769  pCur_syms = pNew_syms;
770  pNew_syms = t;
771  }
772  }
773  return pCur_syms;
774 }
775 
776 /* tdefl_calculate_minimum_redundancy() originally written by: Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996. */
778 {
779  int root, leaf, next, avbl, used, dpth;
780  if (n == 0)
781  return;
782  else if (n == 1)
783  {
784  A[0].m_key = 1;
785  return;
786  }
787  A[0].m_key += A[1].m_key;
788  root = 0;
789  leaf = 2;
790  for (next = 1; next < n - 1; next++)
791  {
792  if (leaf >= n || A[root].m_key < A[leaf].m_key)
793  {
794  A[next].m_key = A[root].m_key;
795  A[root++].m_key = (mz_uint16)next;
796  }
797  else
798  A[next].m_key = A[leaf++].m_key;
799  if (leaf >= n || (root < next && A[root].m_key < A[leaf].m_key))
800  {
801  A[next].m_key = (mz_uint16)(A[next].m_key + A[root].m_key);
802  A[root++].m_key = (mz_uint16)next;
803  }
804  else
805  A[next].m_key = (mz_uint16)(A[next].m_key + A[leaf++].m_key);
806  }
807  A[n - 2].m_key = 0;
808  for (next = n - 3; next >= 0; next--)
809  A[next].m_key = A[A[next].m_key].m_key + 1;
810  avbl = 1;
811  used = dpth = 0;
812  root = n - 2;
813  next = n - 1;
814  while (avbl > 0)
815  {
816  while (root >= 0 && (int)A[root].m_key == dpth)
817  {
818  used++;
819  root--;
820  }
821  while (avbl > used)
822  {
823  A[next--].m_key = (mz_uint16)(dpth);
824  avbl--;
825  }
826  avbl = 2 * used;
827  dpth++;
828  used = 0;
829  }
830 }
831 
832 /* Limits canonical Huffman code table's max code size. */
833 enum
834 {
836 };
837 static void tdefl_huffman_enforce_max_code_size(int *pNum_codes, int code_list_len, int max_code_size)
838 {
839  int i;
840  mz_uint32 total = 0;
841  if (code_list_len <= 1)
842  return;
843  for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++)
844  pNum_codes[max_code_size] += pNum_codes[i];
845  for (i = max_code_size; i > 0; i--)
846  total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i));
847  while (total != (1UL << max_code_size))
848  {
849  pNum_codes[max_code_size]--;
850  for (i = max_code_size - 1; i > 0; i--)
851  if (pNum_codes[i])
852  {
853  pNum_codes[i]--;
854  pNum_codes[i + 1] += 2;
855  break;
856  }
857  total--;
858  }
859 }
860 
861 static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int table_len, int code_size_limit, int static_table)
862 {
863  int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE];
865  MZ_CLEAR_OBJ(num_codes);
866  if (static_table)
867  {
868  for (i = 0; i < table_len; i++)
869  num_codes[d->m_huff_code_sizes[table_num][i]]++;
870  }
871  else
872  {
874  int num_used_syms = 0;
875  const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0];
876  for (i = 0; i < table_len; i++)
877  if (pSym_count[i])
878  {
879  syms0[num_used_syms].m_key = (mz_uint16)pSym_count[i];
880  syms0[num_used_syms++].m_sym_index = (mz_uint16)i;
881  }
882 
883  pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1);
884  tdefl_calculate_minimum_redundancy(pSyms, num_used_syms);
885 
886  for (i = 0; i < num_used_syms; i++)
887  num_codes[pSyms[i].m_key]++;
888 
889  tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, code_size_limit);
890 
891  MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]);
892  MZ_CLEAR_OBJ(d->m_huff_codes[table_num]);
893  for (i = 1, j = num_used_syms; i <= code_size_limit; i++)
894  for (l = num_codes[i]; l > 0; l--)
895  d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i);
896  }
897 
898  next_code[1] = 0;
899  for (j = 0, i = 2; i <= code_size_limit; i++)
900  next_code[i] = j = ((j + num_codes[i - 1]) << 1);
901 
902  for (i = 0; i < table_len; i++)
903  {
904  mz_uint rev_code = 0, code, code_size;
905  if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0)
906  continue;
907  code = next_code[code_size]++;
908  for (l = code_size; l > 0; l--, code >>= 1)
909  rev_code = (rev_code << 1) | (code & 1);
910  d->m_huff_codes[table_num][i] = (mz_uint16)rev_code;
911  }
912 }
913 
914 #define TDEFL_PUT_BITS(b, l) \
915  do \
916  { \
917  mz_uint bits = b; \
918  mz_uint len = l; \
919  MZ_ASSERT(bits <= ((1U << len) - 1U)); \
920  d->m_bit_buffer |= (bits << d->m_bits_in); \
921  d->m_bits_in += len; \
922  while (d->m_bits_in >= 8) \
923  { \
924  if (d->m_pOutput_buf < d->m_pOutput_buf_end) \
925  *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \
926  d->m_bit_buffer >>= 8; \
927  d->m_bits_in -= 8; \
928  } \
929  } \
930  MZ_MACRO_END
931 
932 #define TDEFL_RLE_PREV_CODE_SIZE() \
933  { \
934  if (rle_repeat_count) \
935  { \
936  if (rle_repeat_count < 3) \
937  { \
938  d->m_huff_count[2][prev_code_size] = (mz_uint16)(d->m_huff_count[2][prev_code_size] + rle_repeat_count); \
939  while (rle_repeat_count--) \
940  packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \
941  } \
942  else \
943  { \
944  d->m_huff_count[2][16] = (mz_uint16)(d->m_huff_count[2][16] + 1); \
945  packed_code_sizes[num_packed_code_sizes++] = 16; \
946  packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_repeat_count - 3); \
947  } \
948  rle_repeat_count = 0; \
949  } \
950  }
951 
952 #define TDEFL_RLE_ZERO_CODE_SIZE() \
953  { \
954  if (rle_z_count) \
955  { \
956  if (rle_z_count < 3) \
957  { \
958  d->m_huff_count[2][0] = (mz_uint16)(d->m_huff_count[2][0] + rle_z_count); \
959  while (rle_z_count--) \
960  packed_code_sizes[num_packed_code_sizes++] = 0; \
961  } \
962  else if (rle_z_count <= 10) \
963  { \
964  d->m_huff_count[2][17] = (mz_uint16)(d->m_huff_count[2][17] + 1); \
965  packed_code_sizes[num_packed_code_sizes++] = 17; \
966  packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 3); \
967  } \
968  else \
969  { \
970  d->m_huff_count[2][18] = (mz_uint16)(d->m_huff_count[2][18] + 1); \
971  packed_code_sizes[num_packed_code_sizes++] = 18; \
972  packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 11); \
973  } \
974  rle_z_count = 0; \
975  } \
976  }
977 
978 static mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
979 
981 {
982  int num_lit_codes, num_dist_codes, num_bit_lengths;
983  mz_uint i, total_code_sizes_to_pack, num_packed_code_sizes, rle_z_count, rle_repeat_count, packed_code_sizes_index;
984  mz_uint8 code_sizes_to_pack[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], packed_code_sizes[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], prev_code_size = 0xFF;
985 
986  d->m_huff_count[0][256] = 1;
987 
990 
991  for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--)
992  if (d->m_huff_code_sizes[0][num_lit_codes - 1])
993  break;
994  for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--)
995  if (d->m_huff_code_sizes[1][num_dist_codes - 1])
996  break;
997 
998  memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes);
999  memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0], num_dist_codes);
1000  total_code_sizes_to_pack = num_lit_codes + num_dist_codes;
1001  num_packed_code_sizes = 0;
1002  rle_z_count = 0;
1003  rle_repeat_count = 0;
1004 
1005  memset(&d->m_huff_count[2][0], 0, sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2);
1006  for (i = 0; i < total_code_sizes_to_pack; i++)
1007  {
1008  mz_uint8 code_size = code_sizes_to_pack[i];
1009  if (!code_size)
1010  {
1012  if (++rle_z_count == 138)
1013  {
1015  }
1016  }
1017  else
1018  {
1020  if (code_size != prev_code_size)
1021  {
1023  d->m_huff_count[2][code_size] = (mz_uint16)(d->m_huff_count[2][code_size] + 1);
1024  packed_code_sizes[num_packed_code_sizes++] = code_size;
1025  }
1026  else if (++rle_repeat_count == 6)
1027  {
1029  }
1030  }
1031  prev_code_size = code_size;
1032  }
1033  if (rle_repeat_count)
1034  {
1036  }
1037  else
1038  {
1040  }
1041 
1043 
1044  TDEFL_PUT_BITS(2, 2);
1045 
1046  TDEFL_PUT_BITS(num_lit_codes - 257, 5);
1047  TDEFL_PUT_BITS(num_dist_codes - 1, 5);
1048 
1049  for (num_bit_lengths = 18; num_bit_lengths >= 0; num_bit_lengths--)
1050  if (d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[num_bit_lengths]])
1051  break;
1052  num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1));
1053  TDEFL_PUT_BITS(num_bit_lengths - 4, 4);
1054  for (i = 0; (int)i < num_bit_lengths; i++)
1056 
1057  for (packed_code_sizes_index = 0; packed_code_sizes_index < num_packed_code_sizes;)
1058  {
1059  mz_uint code = packed_code_sizes[packed_code_sizes_index++];
1062  if (code >= 16)
1063  TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++], "\02\03\07"[code - 16]);
1064  }
1065 }
1066 
1068 {
1069  mz_uint i;
1070  mz_uint8 *p = &d->m_huff_code_sizes[0][0];
1071 
1072  for (i = 0; i <= 143; ++i)
1073  *p++ = 8;
1074  for (; i <= 255; ++i)
1075  *p++ = 9;
1076  for (; i <= 279; ++i)
1077  *p++ = 7;
1078  for (; i <= 287; ++i)
1079  *p++ = 8;
1080 
1081  memset(d->m_huff_code_sizes[1], 5, 32);
1082 
1083  tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE);
1084  tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE);
1085 
1086  TDEFL_PUT_BITS(1, 2);
1087 }
1088 
1089 static const mz_uint mz_bitmasks[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
1090 
1091 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS
1093 {
1094  mz_uint flags;
1095  mz_uint8 *pLZ_codes;
1096  mz_uint8 *pOutput_buf = d->m_pOutput_buf;
1097  mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf;
1098  mz_uint64 bit_buffer = d->m_bit_buffer;
1099  mz_uint bits_in = d->m_bits_in;
1100 
1101 #define TDEFL_PUT_BITS_FAST(b, l) \
1102  { \
1103  bit_buffer |= (((mz_uint64)(b)) << bits_in); \
1104  bits_in += (l); \
1105  }
1106 
1107  flags = 1;
1108  for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end; flags >>= 1)
1109  {
1110  if (flags == 1)
1111  flags = *pLZ_codes++ | 0x100;
1112 
1113  if (flags & 1)
1114  {
1115  mz_uint s0, s1, n0, n1, sym, num_extra_bits;
1116  mz_uint match_len = pLZ_codes[0], match_dist = *(const mz_uint16 *)(pLZ_codes + 1);
1117  pLZ_codes += 3;
1118 
1119  MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
1120  TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
1121  TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]);
1122 
1123  /* This sequence coaxes MSVC into using cmov's vs. jmp's. */
1124  s0 = s_tdefl_small_dist_sym[match_dist & 511];
1125  n0 = s_tdefl_small_dist_extra[match_dist & 511];
1126  s1 = s_tdefl_large_dist_sym[match_dist >> 8];
1127  n1 = s_tdefl_large_dist_extra[match_dist >> 8];
1128  sym = (match_dist < 512) ? s0 : s1;
1129  num_extra_bits = (match_dist < 512) ? n0 : n1;
1130 
1131  MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
1132  TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
1133  TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
1134  }
1135  else
1136  {
1137  mz_uint lit = *pLZ_codes++;
1138  MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
1139  TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
1140 
1141  if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
1142  {
1143  flags >>= 1;
1144  lit = *pLZ_codes++;
1145  MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
1146  TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
1147 
1148  if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
1149  {
1150  flags >>= 1;
1151  lit = *pLZ_codes++;
1152  MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
1153  TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
1154  }
1155  }
1156  }
1157 
1158  if (pOutput_buf >= d->m_pOutput_buf_end)
1159  return MZ_FALSE;
1160 
1161  *(mz_uint64 *)pOutput_buf = bit_buffer;
1162  pOutput_buf += (bits_in >> 3);
1163  bit_buffer >>= (bits_in & ~7);
1164  bits_in &= 7;
1165  }
1166 
1167 #undef TDEFL_PUT_BITS_FAST
1168 
1169  d->m_pOutput_buf = pOutput_buf;
1170  d->m_bits_in = 0;
1171  d->m_bit_buffer = 0;
1172 
1173  while (bits_in)
1174  {
1175  mz_uint32 n = MZ_MIN(bits_in, 16);
1176  TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n);
1177  bit_buffer >>= n;
1178  bits_in -= n;
1179  }
1180 
1181  TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
1182 
1183  return (d->m_pOutput_buf < d->m_pOutput_buf_end);
1184 }
1185 #else
1187 {
1188  mz_uint flags;
1189  mz_uint8 *pLZ_codes;
1190 
1191  flags = 1;
1192  for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf; flags >>= 1)
1193  {
1194  if (flags == 1)
1195  flags = *pLZ_codes++ | 0x100;
1196  if (flags & 1)
1197  {
1198  mz_uint sym, num_extra_bits;
1199  mz_uint match_len = pLZ_codes[0], match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8));
1200  pLZ_codes += 3;
1201 
1202  MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
1203  TDEFL_PUT_BITS(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
1204  TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]);
1205 
1206  if (match_dist < 512)
1207  {
1208  sym = s_tdefl_small_dist_sym[match_dist];
1209  num_extra_bits = s_tdefl_small_dist_extra[match_dist];
1210  }
1211  else
1212  {
1213  sym = s_tdefl_large_dist_sym[match_dist >> 8];
1214  num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8];
1215  }
1216  MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
1217  TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
1218  TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
1219  }
1220  else
1221  {
1222  mz_uint lit = *pLZ_codes++;
1223  MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
1224  TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
1225  }
1226  }
1227 
1228  TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
1229 
1230  return (d->m_pOutput_buf < d->m_pOutput_buf_end);
1231 }
1232 #endif /* MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS */
1233 
1235 {
1236  if (static_block)
1238  else
1240  return tdefl_compress_lz_codes(d);
1241 }
1242 
1243 static int tdefl_flush_block(tdefl_compressor *d, int flush)
1244 {
1245  mz_uint saved_bit_buf, saved_bits_in;
1246  mz_uint8 *pSaved_output_buf;
1247  mz_bool comp_block_succeeded = MZ_FALSE;
1248  int n, use_raw_block = ((d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS) != 0) && (d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size;
1249  mz_uint8 *pOutput_buf_start = ((d->m_pPut_buf_func == NULL) && ((*d->m_pOut_buf_size - d->m_out_buf_ofs) >= TDEFL_OUT_BUF_SIZE)) ? ((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs) : d->m_output_buf;
1250 
1251  d->m_pOutput_buf = pOutput_buf_start;
1253 
1255  d->m_output_flush_ofs = 0;
1256  d->m_output_flush_remaining = 0;
1257 
1258  *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left);
1259  d->m_pLZ_code_buf -= (d->m_num_flags_left == 8);
1260 
1261  if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index))
1262  {
1263  TDEFL_PUT_BITS(0x78, 8);
1264  TDEFL_PUT_BITS(0x01, 8);
1265  }
1266 
1267  TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1);
1268 
1269  pSaved_output_buf = d->m_pOutput_buf;
1270  saved_bit_buf = d->m_bit_buffer;
1271  saved_bits_in = d->m_bits_in;
1272 
1273  if (!use_raw_block)
1274  comp_block_succeeded = tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || (d->m_total_lz_bytes < 48));
1275 
1276  /* If the block gets expanded, forget the current contents of the output buffer and send a raw block instead. */
1277  if (((use_raw_block) || ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >= d->m_total_lz_bytes))) &&
1279  {
1280  mz_uint i;
1281  d->m_pOutput_buf = pSaved_output_buf;
1282  d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
1283  TDEFL_PUT_BITS(0, 2);
1284  if (d->m_bits_in)
1285  {
1286  TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
1287  }
1288  for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF)
1289  {
1290  TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16);
1291  }
1292  for (i = 0; i < d->m_total_lz_bytes; ++i)
1293  {
1295  }
1296  }
1297  /* Check for the extremely unlikely (if not impossible) case of the compressed block not fitting into the output buffer when using dynamic codes. */
1298  else if (!comp_block_succeeded)
1299  {
1300  d->m_pOutput_buf = pSaved_output_buf;
1301  d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
1303  }
1304 
1305  if (flush)
1306  {
1307  if (flush == TDEFL_FINISH)
1308  {
1309  if (d->m_bits_in)
1310  {
1311  TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
1312  }
1314  {
1315  mz_uint i, a = d->m_adler32;
1316  for (i = 0; i < 4; i++)
1317  {
1318  TDEFL_PUT_BITS((a >> 24) & 0xFF, 8);
1319  a <<= 8;
1320  }
1321  }
1322  }
1323  else
1324  {
1325  mz_uint i, z = 0;
1326  TDEFL_PUT_BITS(0, 3);
1327  if (d->m_bits_in)
1328  {
1329  TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
1330  }
1331  for (i = 2; i; --i, z ^= 0xFFFF)
1332  {
1333  TDEFL_PUT_BITS(z & 0xFFFF, 16);
1334  }
1335  }
1336  }
1337 
1339 
1340  memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
1341  memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
1342 
1343  d->m_pLZ_code_buf = d->m_lz_code_buf + 1;
1344  d->m_pLZ_flags = d->m_lz_code_buf;
1345  d->m_num_flags_left = 8;
1347  d->m_total_lz_bytes = 0;
1348  d->m_block_index++;
1349 
1350  if ((n = (int)(d->m_pOutput_buf - pOutput_buf_start)) != 0)
1351  {
1352  if (d->m_pPut_buf_func)
1353  {
1354  *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf;
1355  if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user))
1357  }
1358  else if (pOutput_buf_start == d->m_output_buf)
1359  {
1360  int bytes_to_copy = (int)MZ_MIN((size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs));
1361  memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf, bytes_to_copy);
1362  d->m_out_buf_ofs += bytes_to_copy;
1363  if ((n -= bytes_to_copy) != 0)
1364  {
1365  d->m_output_flush_ofs = bytes_to_copy;
1367  }
1368  }
1369  else
1370  {
1371  d->m_out_buf_ofs += n;
1372  }
1373  }
1374 
1375  return d->m_output_flush_remaining;
1376 }
1377 
1378 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
1379 #ifdef MINIZ_UNALIGNED_USE_MEMCPY
1380 static mz_uint16 TDEFL_READ_UNALIGNED_WORD(const mz_uint8* p)
1381 {
1382  mz_uint16 ret;
1383  memcpy(&ret, p, sizeof(mz_uint16));
1384  return ret;
1385 }
1386 static mz_uint16 TDEFL_READ_UNALIGNED_WORD2(const mz_uint16* p)
1387 {
1388  mz_uint16 ret;
1389  memcpy(&ret, p, sizeof(mz_uint16));
1390  return ret;
1391 }
1392 #else
1393 #define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16 *)(p)
1394 #define TDEFL_READ_UNALIGNED_WORD2(p) *(const mz_uint16 *)(p)
1395 #endif
1396 static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len)
1397 {
1398  mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len;
1399  mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
1400  const mz_uint16 *s = (const mz_uint16 *)(d->m_dict + pos), *p, *q;
1401  mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]), s01 = TDEFL_READ_UNALIGNED_WORD2(s);
1402  MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN);
1403  if (max_match_len <= match_len)
1404  return;
1405  for (;;)
1406  {
1407  for (;;)
1408  {
1409  if (--num_probes_left == 0)
1410  return;
1411 #define TDEFL_PROBE \
1412  next_probe_pos = d->m_next[probe_pos]; \
1413  if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \
1414  return; \
1415  probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
1416  if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) \
1417  break;
1418  TDEFL_PROBE;
1419  TDEFL_PROBE;
1420  TDEFL_PROBE;
1421  }
1422  if (!dist)
1423  break;
1424  q = (const mz_uint16 *)(d->m_dict + probe_pos);
1425  if (TDEFL_READ_UNALIGNED_WORD2(q) != s01)
1426  continue;
1427  p = s;
1428  probe_len = 32;
1429  do
1430  {
1431  } while ((TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) &&
1432  (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (--probe_len > 0));
1433  if (!probe_len)
1434  {
1435  *pMatch_dist = dist;
1436  *pMatch_len = MZ_MIN(max_match_len, (mz_uint)TDEFL_MAX_MATCH_LEN);
1437  break;
1438  }
1439  else if ((probe_len = ((mz_uint)(p - s) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q)) > match_len)
1440  {
1441  *pMatch_dist = dist;
1442  if ((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) == max_match_len)
1443  break;
1444  c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]);
1445  }
1446  }
1447 }
1448 #else
1449 static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len)
1450 {
1451  mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len;
1452  mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
1453  const mz_uint8 *s = d->m_dict + pos, *p, *q;
1454  mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1];
1455  MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN);
1456  if (max_match_len <= match_len)
1457  return;
1458  for (;;)
1459  {
1460  for (;;)
1461  {
1462  if (--num_probes_left == 0)
1463  return;
1464 #define TDEFL_PROBE \
1465  next_probe_pos = d->m_next[probe_pos]; \
1466  if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \
1467  return; \
1468  probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
1469  if ((d->m_dict[probe_pos + match_len] == c0) && (d->m_dict[probe_pos + match_len - 1] == c1)) \
1470  break;
1471  TDEFL_PROBE;
1472  TDEFL_PROBE;
1473  TDEFL_PROBE;
1474  }
1475  if (!dist)
1476  break;
1477  p = s;
1478  q = d->m_dict + probe_pos;
1479  for (probe_len = 0; probe_len < max_match_len; probe_len++)
1480  if (*p++ != *q++)
1481  break;
1482  if (probe_len > match_len)
1483  {
1484  *pMatch_dist = dist;
1485  if ((*pMatch_len = match_len = probe_len) == max_match_len)
1486  return;
1487  c0 = d->m_dict[pos + match_len];
1488  c1 = d->m_dict[pos + match_len - 1];
1489  }
1490  }
1491 }
1492 #endif /* #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES */
1493 
1494 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
1495 #ifdef MINIZ_UNALIGNED_USE_MEMCPY
1496 static mz_uint32 TDEFL_READ_UNALIGNED_WORD32(const mz_uint8* p)
1497 {
1498  mz_uint32 ret;
1499  memcpy(&ret, p, sizeof(mz_uint32));
1500  return ret;
1501 }
1502 #else
1503 #define TDEFL_READ_UNALIGNED_WORD32(p) *(const mz_uint32 *)(p)
1504 #endif
1505 static mz_bool tdefl_compress_fast(tdefl_compressor *d)
1506 {
1507  /* Faster, minimally featured LZRW1-style match+parse loop with better register utilization. Intended for applications where raw throughput is valued more highly than ratio. */
1508  mz_uint lookahead_pos = d->m_lookahead_pos, lookahead_size = d->m_lookahead_size, dict_size = d->m_dict_size, total_lz_bytes = d->m_total_lz_bytes, num_flags_left = d->m_num_flags_left;
1509  mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags;
1510  mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
1511 
1512  while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size)))
1513  {
1514  const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096;
1515  mz_uint dst_pos = (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK;
1516  mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size);
1517  d->m_src_buf_left -= num_bytes_to_process;
1518  lookahead_size += num_bytes_to_process;
1519 
1520  while (num_bytes_to_process)
1521  {
1522  mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process);
1523  memcpy(d->m_dict + dst_pos, d->m_pSrc, n);
1524  if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
1525  memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc, MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos));
1526  d->m_pSrc += n;
1527  dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK;
1528  num_bytes_to_process -= n;
1529  }
1530 
1531  dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size);
1532  if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE))
1533  break;
1534 
1535  while (lookahead_size >= 4)
1536  {
1537  mz_uint cur_match_dist, cur_match_len = 1;
1538  mz_uint8 *pCur_dict = d->m_dict + cur_pos;
1539  mz_uint first_trigram = TDEFL_READ_UNALIGNED_WORD32(pCur_dict) & 0xFFFFFF;
1540  mz_uint hash = (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) & TDEFL_LEVEL1_HASH_SIZE_MASK;
1541  mz_uint probe_pos = d->m_hash[hash];
1542  d->m_hash[hash] = (mz_uint16)lookahead_pos;
1543 
1544  if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <= dict_size) && ((TDEFL_READ_UNALIGNED_WORD32(d->m_dict + (probe_pos &= TDEFL_LZ_DICT_SIZE_MASK)) & 0xFFFFFF) == first_trigram))
1545  {
1546  const mz_uint16 *p = (const mz_uint16 *)pCur_dict;
1547  const mz_uint16 *q = (const mz_uint16 *)(d->m_dict + probe_pos);
1548  mz_uint32 probe_len = 32;
1549  do
1550  {
1551  } while ((TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) &&
1552  (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (--probe_len > 0));
1553  cur_match_len = ((mz_uint)(p - (const mz_uint16 *)pCur_dict) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q);
1554  if (!probe_len)
1555  cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0;
1556 
1557  if ((cur_match_len < TDEFL_MIN_MATCH_LEN) || ((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U * 1024U)))
1558  {
1559  cur_match_len = 1;
1560  *pLZ_code_buf++ = (mz_uint8)first_trigram;
1561  *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
1562  d->m_huff_count[0][(mz_uint8)first_trigram]++;
1563  }
1564  else
1565  {
1566  mz_uint32 s0, s1;
1567  cur_match_len = MZ_MIN(cur_match_len, lookahead_size);
1568 
1569  MZ_ASSERT((cur_match_len >= TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 1) && (cur_match_dist <= TDEFL_LZ_DICT_SIZE));
1570 
1571  cur_match_dist--;
1572 
1573  pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN);
1574 #ifdef MINIZ_UNALIGNED_USE_MEMCPY
1575  memcpy(&pLZ_code_buf[1], &cur_match_dist, sizeof(cur_match_dist));
1576 #else
1577  *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist;
1578 #endif
1579  pLZ_code_buf += 3;
1580  *pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80);
1581 
1582  s0 = s_tdefl_small_dist_sym[cur_match_dist & 511];
1583  s1 = s_tdefl_large_dist_sym[cur_match_dist >> 8];
1584  d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++;
1585 
1586  d->m_huff_count[0][s_tdefl_len_sym[cur_match_len - TDEFL_MIN_MATCH_LEN]]++;
1587  }
1588  }
1589  else
1590  {
1591  *pLZ_code_buf++ = (mz_uint8)first_trigram;
1592  *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
1593  d->m_huff_count[0][(mz_uint8)first_trigram]++;
1594  }
1595 
1596  if (--num_flags_left == 0)
1597  {
1598  num_flags_left = 8;
1599  pLZ_flags = pLZ_code_buf++;
1600  }
1601 
1602  total_lz_bytes += cur_match_len;
1603  lookahead_pos += cur_match_len;
1604  dict_size = MZ_MIN(dict_size + cur_match_len, (mz_uint)TDEFL_LZ_DICT_SIZE);
1605  cur_pos = (cur_pos + cur_match_len) & TDEFL_LZ_DICT_SIZE_MASK;
1606  MZ_ASSERT(lookahead_size >= cur_match_len);
1607  lookahead_size -= cur_match_len;
1608 
1609  if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8])
1610  {
1611  int n;
1612  d->m_lookahead_pos = lookahead_pos;
1613  d->m_lookahead_size = lookahead_size;
1614  d->m_dict_size = dict_size;
1615  d->m_total_lz_bytes = total_lz_bytes;
1616  d->m_pLZ_code_buf = pLZ_code_buf;
1617  d->m_pLZ_flags = pLZ_flags;
1618  d->m_num_flags_left = num_flags_left;
1619  if ((n = tdefl_flush_block(d, 0)) != 0)
1620  return (n < 0) ? MZ_FALSE : MZ_TRUE;
1621  total_lz_bytes = d->m_total_lz_bytes;
1622  pLZ_code_buf = d->m_pLZ_code_buf;
1623  pLZ_flags = d->m_pLZ_flags;
1624  num_flags_left = d->m_num_flags_left;
1625  }
1626  }
1627 
1628  while (lookahead_size)
1629  {
1630  mz_uint8 lit = d->m_dict[cur_pos];
1631 
1632  total_lz_bytes++;
1633  *pLZ_code_buf++ = lit;
1634  *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
1635  if (--num_flags_left == 0)
1636  {
1637  num_flags_left = 8;
1638  pLZ_flags = pLZ_code_buf++;
1639  }
1640 
1641  d->m_huff_count[0][lit]++;
1642 
1643  lookahead_pos++;
1644  dict_size = MZ_MIN(dict_size + 1, (mz_uint)TDEFL_LZ_DICT_SIZE);
1645  cur_pos = (cur_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK;
1646  lookahead_size--;
1647 
1648  if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8])
1649  {
1650  int n;
1651  d->m_lookahead_pos = lookahead_pos;
1652  d->m_lookahead_size = lookahead_size;
1653  d->m_dict_size = dict_size;
1654  d->m_total_lz_bytes = total_lz_bytes;
1655  d->m_pLZ_code_buf = pLZ_code_buf;
1656  d->m_pLZ_flags = pLZ_flags;
1657  d->m_num_flags_left = num_flags_left;
1658  if ((n = tdefl_flush_block(d, 0)) != 0)
1659  return (n < 0) ? MZ_FALSE : MZ_TRUE;
1660  total_lz_bytes = d->m_total_lz_bytes;
1661  pLZ_code_buf = d->m_pLZ_code_buf;
1662  pLZ_flags = d->m_pLZ_flags;
1663  num_flags_left = d->m_num_flags_left;
1664  }
1665  }
1666  }
1667 
1668  d->m_lookahead_pos = lookahead_pos;
1669  d->m_lookahead_size = lookahead_size;
1670  d->m_dict_size = dict_size;
1671  d->m_total_lz_bytes = total_lz_bytes;
1672  d->m_pLZ_code_buf = pLZ_code_buf;
1673  d->m_pLZ_flags = pLZ_flags;
1674  d->m_num_flags_left = num_flags_left;
1675  return MZ_TRUE;
1676 }
1677 #endif /* MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN */
1678 
1680 {
1681  d->m_total_lz_bytes++;
1682  *d->m_pLZ_code_buf++ = lit;
1683  *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1);
1684  if (--d->m_num_flags_left == 0)
1685  {
1686  d->m_num_flags_left = 8;
1687  d->m_pLZ_flags = d->m_pLZ_code_buf++;
1688  }
1689  d->m_huff_count[0][lit]++;
1690 }
1691 
1692 static MZ_FORCEINLINE void tdefl_record_match(tdefl_compressor *d, mz_uint match_len, mz_uint match_dist)
1693 {
1694  mz_uint32 s0, s1;
1695 
1696  MZ_ASSERT((match_len >= TDEFL_MIN_MATCH_LEN) && (match_dist >= 1) && (match_dist <= TDEFL_LZ_DICT_SIZE));
1697 
1698  d->m_total_lz_bytes += match_len;
1699 
1700  d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN);
1701 
1702  match_dist -= 1;
1703  d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF);
1704  d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8);
1705  d->m_pLZ_code_buf += 3;
1706 
1707  *d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80);
1708  if (--d->m_num_flags_left == 0)
1709  {
1710  d->m_num_flags_left = 8;
1711  d->m_pLZ_flags = d->m_pLZ_code_buf++;
1712  }
1713 
1714  s0 = s_tdefl_small_dist_sym[match_dist & 511];
1715  s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127];
1716  d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++;
1717  d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++;
1718 }
1719 
1721 {
1722  const mz_uint8 *pSrc = d->m_pSrc;
1723  size_t src_buf_left = d->m_src_buf_left;
1724  tdefl_flush flush = d->m_flush;
1725 
1726  while ((src_buf_left) || ((flush) && (d->m_lookahead_size)))
1727  {
1728  mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos;
1729  /* Update dictionary and hash chains. Keeps the lookahead size equal to TDEFL_MAX_MATCH_LEN. */
1730  if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1))
1731  {
1734  mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size);
1735  const mz_uint8 *pSrc_end = pSrc + num_bytes_to_process;
1736  src_buf_left -= num_bytes_to_process;
1737  d->m_lookahead_size += num_bytes_to_process;
1738  while (pSrc != pSrc_end)
1739  {
1740  mz_uint8 c = *pSrc++;
1741  d->m_dict[dst_pos] = c;
1742  if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
1743  d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
1744  hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1);
1745  d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash];
1746  d->m_hash[hash] = (mz_uint16)(ins_pos);
1747  dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK;
1748  ins_pos++;
1749  }
1750  }
1751  else
1752  {
1753  while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
1754  {
1755  mz_uint8 c = *pSrc++;
1757  src_buf_left--;
1758  d->m_dict[dst_pos] = c;
1759  if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
1760  d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
1762  {
1763  mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2;
1764  mz_uint hash = ((d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << (TDEFL_LZ_HASH_SHIFT * 2)) ^ (d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1);
1765  d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash];
1766  d->m_hash[hash] = (mz_uint16)(ins_pos);
1767  }
1768  }
1769  }
1771  if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
1772  break;
1773 
1774  /* Simple lazy/greedy parsing state machine. */
1775  len_to_move = 1;
1776  cur_match_dist = 0;
1777  cur_match_len = d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1);
1780  {
1781  if ((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS)))
1782  {
1783  mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK];
1784  cur_match_len = 0;
1785  while (cur_match_len < d->m_lookahead_size)
1786  {
1787  if (d->m_dict[cur_pos + cur_match_len] != c)
1788  break;
1789  cur_match_len++;
1790  }
1791  if (cur_match_len < TDEFL_MIN_MATCH_LEN)
1792  cur_match_len = 0;
1793  else
1794  cur_match_dist = 1;
1795  }
1796  }
1797  else
1798  {
1799  tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size, d->m_lookahead_size, &cur_match_dist, &cur_match_len);
1800  }
1801  if (((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U * 1024U)) || (cur_pos == cur_match_dist) || ((d->m_flags & TDEFL_FILTER_MATCHES) && (cur_match_len <= 5)))
1802  {
1803  cur_match_dist = cur_match_len = 0;
1804  }
1805  if (d->m_saved_match_len)
1806  {
1807  if (cur_match_len > d->m_saved_match_len)
1808  {
1810  if (cur_match_len >= 128)
1811  {
1812  tdefl_record_match(d, cur_match_len, cur_match_dist);
1813  d->m_saved_match_len = 0;
1814  len_to_move = cur_match_len;
1815  }
1816  else
1817  {
1818  d->m_saved_lit = d->m_dict[cur_pos];
1819  d->m_saved_match_dist = cur_match_dist;
1820  d->m_saved_match_len = cur_match_len;
1821  }
1822  }
1823  else
1824  {
1826  len_to_move = d->m_saved_match_len - 1;
1827  d->m_saved_match_len = 0;
1828  }
1829  }
1830  else if (!cur_match_dist)
1831  tdefl_record_literal(d, d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]);
1832  else if ((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) || (cur_match_len >= 128))
1833  {
1834  tdefl_record_match(d, cur_match_len, cur_match_dist);
1835  len_to_move = cur_match_len;
1836  }
1837  else
1838  {
1839  d->m_saved_lit = d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)];
1840  d->m_saved_match_dist = cur_match_dist;
1841  d->m_saved_match_len = cur_match_len;
1842  }
1843  /* Move the lookahead forward by len_to_move bytes. */
1844  d->m_lookahead_pos += len_to_move;
1845  MZ_ASSERT(d->m_lookahead_size >= len_to_move);
1846  d->m_lookahead_size -= len_to_move;
1847  d->m_dict_size = MZ_MIN(d->m_dict_size + len_to_move, (mz_uint)TDEFL_LZ_DICT_SIZE);
1848  /* Check if it's time to flush the current LZ codes to the internal output buffer. */
1849  if ((d->m_pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) ||
1850  ((d->m_total_lz_bytes > 31 * 1024) && (((((mz_uint)(d->m_pLZ_code_buf - d->m_lz_code_buf) * 115) >> 7) >= d->m_total_lz_bytes) || (d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))))
1851  {
1852  int n;
1853  d->m_pSrc = pSrc;
1854  d->m_src_buf_left = src_buf_left;
1855  if ((n = tdefl_flush_block(d, 0)) != 0)
1856  return (n < 0) ? MZ_FALSE : MZ_TRUE;
1857  }
1858  }
1859 
1860  d->m_pSrc = pSrc;
1861  d->m_src_buf_left = src_buf_left;
1862  return MZ_TRUE;
1863 }
1864 
1866 {
1867  if (d->m_pIn_buf_size)
1868  {
1869  *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf;
1870  }
1871 
1872  if (d->m_pOut_buf_size)
1873  {
1875  memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf + d->m_output_flush_ofs, n);
1876  d->m_output_flush_ofs += (mz_uint)n;
1878  d->m_out_buf_ofs += n;
1879 
1880  *d->m_pOut_buf_size = d->m_out_buf_ofs;
1881  }
1882 
1884 }
1885 
1886 tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush)
1887 {
1888  if (!d)
1889  {
1890  if (pIn_buf_size)
1891  *pIn_buf_size = 0;
1892  if (pOut_buf_size)
1893  *pOut_buf_size = 0;
1894  return TDEFL_STATUS_BAD_PARAM;
1895  }
1896 
1897  d->m_pIn_buf = pIn_buf;
1898  d->m_pIn_buf_size = pIn_buf_size;
1899  d->m_pOut_buf = pOut_buf;
1900  d->m_pOut_buf_size = pOut_buf_size;
1901  d->m_pSrc = (const mz_uint8 *)(pIn_buf);
1902  d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0;
1903  d->m_out_buf_ofs = 0;
1904  d->m_flush = flush;
1905 
1906  if (((d->m_pPut_buf_func != NULL) == ((pOut_buf != NULL) || (pOut_buf_size != NULL))) || (d->m_prev_return_status != TDEFL_STATUS_OKAY) ||
1907  (d->m_wants_to_finish && (flush != TDEFL_FINISH)) || (pIn_buf_size && *pIn_buf_size && !pIn_buf) || (pOut_buf_size && *pOut_buf_size && !pOut_buf))
1908  {
1909  if (pIn_buf_size)
1910  *pIn_buf_size = 0;
1911  if (pOut_buf_size)
1912  *pOut_buf_size = 0;
1914  }
1915  d->m_wants_to_finish |= (flush == TDEFL_FINISH);
1916 
1917  if ((d->m_output_flush_remaining) || (d->m_finished))
1919 
1920 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
1921  if (((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) &&
1922  ((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) &&
1924  {
1925  if (!tdefl_compress_fast(d))
1926  return d->m_prev_return_status;
1927  }
1928  else
1929 #endif /* #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN */
1930  {
1931  if (!tdefl_compress_normal(d))
1932  return d->m_prev_return_status;
1933  }
1934 
1935  if ((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) && (pIn_buf))
1936  d->m_adler32 = (mz_uint32)mz_adler32(d->m_adler32, (const mz_uint8 *)pIn_buf, d->m_pSrc - (const mz_uint8 *)pIn_buf);
1937 
1938  if ((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) && (!d->m_output_flush_remaining))
1939  {
1940  if (tdefl_flush_block(d, flush) < 0)
1941  return d->m_prev_return_status;
1942  d->m_finished = (flush == TDEFL_FINISH);
1943  if (flush == TDEFL_FULL_FLUSH)
1944  {
1945  MZ_CLEAR_OBJ(d->m_hash);
1946  MZ_CLEAR_OBJ(d->m_next);
1947  d->m_dict_size = 0;
1948  }
1949  }
1950 
1952 }
1953 
1954 tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush)
1955 {
1957  return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush);
1958 }
1959 
1960 tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
1961 {
1962  d->m_pPut_buf_func = pPut_buf_func;
1963  d->m_pPut_buf_user = pPut_buf_user;
1964  d->m_flags = (mz_uint)(flags);
1965  d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3;
1967  d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3;
1969  MZ_CLEAR_OBJ(d->m_hash);
1972  d->m_pLZ_code_buf = d->m_lz_code_buf + 1;
1973  d->m_pLZ_flags = d->m_lz_code_buf;
1974  *d->m_pLZ_flags = 0;
1975  d->m_num_flags_left = 8;
1976  d->m_pOutput_buf = d->m_output_buf;
1980  d->m_adler32 = 1;
1981  d->m_pIn_buf = NULL;
1982  d->m_pOut_buf = NULL;
1983  d->m_pIn_buf_size = NULL;
1984  d->m_pOut_buf_size = NULL;
1985  d->m_flush = TDEFL_NO_FLUSH;
1986  d->m_pSrc = NULL;
1987  d->m_src_buf_left = 0;
1988  d->m_out_buf_ofs = 0;
1990  MZ_CLEAR_OBJ(d->m_dict);
1991  memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
1992  memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
1993  return TDEFL_STATUS_OKAY;
1994 }
1995 
1997 {
1998  return d->m_prev_return_status;
1999 }
2000 
2002 {
2003  return d->m_adler32;
2004 }
2005 
2006 mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
2007 {
2008  tdefl_compressor *pComp;
2009  mz_bool succeeded;
2010  if (((buf_len) && (!pBuf)) || (!pPut_buf_func))
2011  return MZ_FALSE;
2012  pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor));
2013  if (!pComp)
2014  return MZ_FALSE;
2015  succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags) == TDEFL_STATUS_OKAY);
2016  succeeded = succeeded && (tdefl_compress_buffer(pComp, pBuf, buf_len, TDEFL_FINISH) == TDEFL_STATUS_DONE);
2017  MZ_FREE(pComp);
2018  return succeeded;
2019 }
2020 
2021 typedef struct
2022 {
2023  size_t m_size, m_capacity;
2027 
2028 static mz_bool tdefl_output_buffer_putter(const void *pBuf, int len, void *pUser)
2029 {
2031  size_t new_size = p->m_size + len;
2032  if (new_size > p->m_capacity)
2033  {
2034  size_t new_capacity = p->m_capacity;
2035  mz_uint8 *pNew_buf;
2036  if (!p->m_expandable)
2037  return MZ_FALSE;
2038  do
2039  {
2040  new_capacity = MZ_MAX(128U, new_capacity << 1U);
2041  } while (new_size > new_capacity);
2042  pNew_buf = (mz_uint8 *)MZ_REALLOC(p->m_pBuf, new_capacity);
2043  if (!pNew_buf)
2044  return MZ_FALSE;
2045  p->m_pBuf = pNew_buf;
2046  p->m_capacity = new_capacity;
2047  }
2048  memcpy((mz_uint8 *)p->m_pBuf + p->m_size, pBuf, len);
2049  p->m_size = new_size;
2050  return MZ_TRUE;
2051 }
2052 
2053 void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
2054 {
2055  tdefl_output_buffer out_buf;
2056  MZ_CLEAR_OBJ(out_buf);
2057  if (!pOut_len)
2058  return MZ_FALSE;
2059  else
2060  *pOut_len = 0;
2061  out_buf.m_expandable = MZ_TRUE;
2062  if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags))
2063  return NULL;
2064  *pOut_len = out_buf.m_size;
2065  return out_buf.m_pBuf;
2066 }
2067 
2068 size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags)
2069 {
2070  tdefl_output_buffer out_buf;
2071  MZ_CLEAR_OBJ(out_buf);
2072  if (!pOut_buf)
2073  return 0;
2074  out_buf.m_pBuf = (mz_uint8 *)pOut_buf;
2075  out_buf.m_capacity = out_buf_len;
2076  if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags))
2077  return 0;
2078  return out_buf.m_size;
2079 }
2080 
2081 static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
2082 
2083 /* level may actually range from [0,10] (10 is a "hidden" max level, where we want a bit more compression and it's fine if throughput to fall off a cliff on some files). */
2085 {
2086  mz_uint comp_flags = s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0);
2087  if (window_bits > 0)
2088  comp_flags |= TDEFL_WRITE_ZLIB_HEADER;
2089 
2090  if (!level)
2091  comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS;
2092  else if (strategy == MZ_FILTERED)
2093  comp_flags |= TDEFL_FILTER_MATCHES;
2094  else if (strategy == MZ_HUFFMAN_ONLY)
2095  comp_flags &= ~TDEFL_MAX_PROBES_MASK;
2096  else if (strategy == MZ_FIXED)
2097  comp_flags |= TDEFL_FORCE_ALL_STATIC_BLOCKS;
2098  else if (strategy == MZ_RLE)
2099  comp_flags |= TDEFL_RLE_MATCHES;
2100 
2101  return comp_flags;
2102 }
2103 
2104 #ifdef _MSC_VER
2105 #pragma warning(push)
2106 #pragma warning(disable : 4204) /* nonstandard extension used : non-constant aggregate initializer (also supported by GNU C and C99, so no big deal) */
2107 #endif
2108 
2109 /* Simple PNG writer function by Alex Evans, 2011. Released into the public domain: https://gist.github.com/908299, more context at
2110  http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/.
2111  This is actually a modification of Alex's original code so PNG files generated by this function pass pngcheck. */
2112 void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip)
2113 {
2114  /* Using a local copy of this array here in case MINIZ_NO_ZLIB_APIS was defined. */
2115  static const mz_uint s_tdefl_png_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
2117  tdefl_output_buffer out_buf;
2118  int i, bpl = w * num_chans, y, z;
2119  mz_uint32 c;
2120  *pLen_out = 0;
2121  if (!pComp)
2122  return NULL;
2123  MZ_CLEAR_OBJ(out_buf);
2124  out_buf.m_expandable = MZ_TRUE;
2125  out_buf.m_capacity = 57 + MZ_MAX(64, (1 + bpl) * h);
2126  if (NULL == (out_buf.m_pBuf = (mz_uint8 *)MZ_MALLOC(out_buf.m_capacity)))
2127  {
2128  MZ_FREE(pComp);
2129  return NULL;
2130  }
2131  /* write dummy header */
2132  for (z = 41; z; --z)
2133  tdefl_output_buffer_putter(&z, 1, &out_buf);
2134  /* compress image data */
2135  tdefl_init(pComp, tdefl_output_buffer_putter, &out_buf, s_tdefl_png_num_probes[MZ_MIN(10, level)] | TDEFL_WRITE_ZLIB_HEADER);
2136  for (y = 0; y < h; ++y)
2137  {
2138  tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH);
2139  tdefl_compress_buffer(pComp, (mz_uint8 *)pImage + (flip ? (h - 1 - y) : y) * bpl, bpl, TDEFL_NO_FLUSH);
2140  }
2142  {
2143  MZ_FREE(pComp);
2144  MZ_FREE(out_buf.m_pBuf);
2145  return NULL;
2146  }
2147  /* write real header */
2148  *pLen_out = out_buf.m_size - 41;
2149  {
2150  static const mz_uint8 chans[] = { 0x00, 0x00, 0x04, 0x02, 0x06 };
2151  mz_uint8 pnghdr[41] = { 0x89, 0x50, 0x4e, 0x47, 0x0d,
2152  0x0a, 0x1a, 0x0a, 0x00, 0x00,
2153  0x00, 0x0d, 0x49, 0x48, 0x44,
2154  0x52, 0x00, 0x00, 0x00, 0x00,
2155  0x00, 0x00, 0x00, 0x00, 0x08,
2156  0x00, 0x00, 0x00, 0x00, 0x00,
2157  0x00, 0x00, 0x00, 0x00, 0x00,
2158  0x00, 0x00, 0x49, 0x44, 0x41,
2159  0x54 };
2160  pnghdr[18] = (mz_uint8)(w >> 8);
2161  pnghdr[19] = (mz_uint8)w;
2162  pnghdr[22] = (mz_uint8)(h >> 8);
2163  pnghdr[23] = (mz_uint8)h;
2164  pnghdr[25] = chans[num_chans];
2165  pnghdr[33] = (mz_uint8)(*pLen_out >> 24);
2166  pnghdr[34] = (mz_uint8)(*pLen_out >> 16);
2167  pnghdr[35] = (mz_uint8)(*pLen_out >> 8);
2168  pnghdr[36] = (mz_uint8)*pLen_out;
2169  c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, pnghdr + 12, 17);
2170  for (i = 0; i < 4; ++i, c <<= 8)
2171  ((mz_uint8 *)(pnghdr + 29))[i] = (mz_uint8)(c >> 24);
2172  memcpy(out_buf.m_pBuf, pnghdr, 41);
2173  }
2174  /* write footer (IDAT CRC-32, followed by IEND chunk) */
2175  if (!tdefl_output_buffer_putter("\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf))
2176  {
2177  *pLen_out = 0;
2178  MZ_FREE(pComp);
2179  MZ_FREE(out_buf.m_pBuf);
2180  return NULL;
2181  }
2182  c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, out_buf.m_pBuf + 41 - 4, *pLen_out + 4);
2183  for (i = 0; i < 4; ++i, c <<= 8)
2184  (out_buf.m_pBuf + out_buf.m_size - 16)[i] = (mz_uint8)(c >> 24);
2185  /* compute final size of file, grab compressed data buffer and return */
2186  *pLen_out += 57;
2187  MZ_FREE(pComp);
2188  return out_buf.m_pBuf;
2189 }
2190 void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out)
2191 {
2192  /* Level 6 corresponds to TDEFL_DEFAULT_MAX_PROBES or MZ_DEFAULT_LEVEL (but we can't depend on MZ_DEFAULT_LEVEL being available in case the zlib API's where #defined out) */
2193  return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans, pLen_out, 6, MZ_FALSE);
2194 }
2195 
2196 #ifndef MINIZ_NO_MALLOC
2197 /* Allocate the tdefl_compressor and tinfl_decompressor structures in C so that */
2198 /* non-C language bindings to tdefL_ and tinfl_ API don't need to worry about */
2199 /* structure size and allocation mechanism. */
2201 {
2202  return (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor));
2203 }
2204 
2206 {
2207  MZ_FREE(pComp);
2208 }
2209 #endif
2210 
2211 #ifdef _MSC_VER
2212 #pragma warning(pop)
2213 #endif
2214 
2215 #ifdef __cplusplus
2216 }
2217 #endif
2218  /**************************************************************************
2219  *
2220  * Copyright 2013-2014 RAD Game Tools and Valve Software
2221  * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
2222  * All Rights Reserved.
2223  *
2224  * Permission is hereby granted, free of charge, to any person obtaining a copy
2225  * of this software and associated documentation files (the "Software"), to deal
2226  * in the Software without restriction, including without limitation the rights
2227  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2228  * copies of the Software, and to permit persons to whom the Software is
2229  * furnished to do so, subject to the following conditions:
2230  *
2231  * The above copyright notice and this permission notice shall be included in
2232  * all copies or substantial portions of the Software.
2233  *
2234  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2235  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2236  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2237  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2238  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2239  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2240  * THE SOFTWARE.
2241  *
2242  **************************************************************************/
2243 
2244 
2245 
2246 #ifdef __cplusplus
2247 extern "C" {
2248 #endif
2249 
2250 /* ------------------- Low-level Decompression (completely independent from all compression API's) */
2251 
2252 #define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
2253 #define TINFL_MEMSET(p, c, l) memset(p, c, l)
2254 
2255 #define TINFL_CR_BEGIN \
2256  switch (r->m_state) \
2257  { \
2258  case 0:
2259 #define TINFL_CR_RETURN(state_index, result) \
2260  do \
2261  { \
2262  status = result; \
2263  r->m_state = state_index; \
2264  goto common_exit; \
2265  case state_index:; \
2266  } \
2267  MZ_MACRO_END
2268 #define TINFL_CR_RETURN_FOREVER(state_index, result) \
2269  do \
2270  { \
2271  for (;;) \
2272  { \
2273  TINFL_CR_RETURN(state_index, result); \
2274  } \
2275  } \
2276  MZ_MACRO_END
2277 #define TINFL_CR_FINISH }
2278 
2279 #define TINFL_GET_BYTE(state_index, c) \
2280  do \
2281  { \
2282  while (pIn_buf_cur >= pIn_buf_end) \
2283  { \
2284  TINFL_CR_RETURN(state_index, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS); \
2285  } \
2286  c = *pIn_buf_cur++; \
2287  } \
2288  MZ_MACRO_END
2289 
2290 #define TINFL_NEED_BITS(state_index, n) \
2291  do \
2292  { \
2293  mz_uint c; \
2294  TINFL_GET_BYTE(state_index, c); \
2295  bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
2296  num_bits += 8; \
2297  } while (num_bits < (mz_uint)(n))
2298 #define TINFL_SKIP_BITS(state_index, n) \
2299  do \
2300  { \
2301  if (num_bits < (mz_uint)(n)) \
2302  { \
2303  TINFL_NEED_BITS(state_index, n); \
2304  } \
2305  bit_buf >>= (n); \
2306  num_bits -= (n); \
2307  } \
2308  MZ_MACRO_END
2309 #define TINFL_GET_BITS(state_index, b, n) \
2310  do \
2311  { \
2312  if (num_bits < (mz_uint)(n)) \
2313  { \
2314  TINFL_NEED_BITS(state_index, n); \
2315  } \
2316  b = bit_buf & ((1 << (n)) - 1); \
2317  bit_buf >>= (n); \
2318  num_bits -= (n); \
2319  } \
2320  MZ_MACRO_END
2321 
2322 /* TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2. */
2323 /* 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 */
2324 /* 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 */
2325 /* bit buffer contains >=15 bits (deflate's max. Huffman code size). */
2326 #define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \
2327  do \
2328  { \
2329  temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
2330  if (temp >= 0) \
2331  { \
2332  code_len = temp >> 9; \
2333  if ((code_len) && (num_bits >= code_len)) \
2334  break; \
2335  } \
2336  else if (num_bits > TINFL_FAST_LOOKUP_BITS) \
2337  { \
2338  code_len = TINFL_FAST_LOOKUP_BITS; \
2339  do \
2340  { \
2341  temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
2342  } while ((temp < 0) && (num_bits >= (code_len + 1))); \
2343  if (temp >= 0) \
2344  break; \
2345  } \
2346  TINFL_GET_BYTE(state_index, c); \
2347  bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
2348  num_bits += 8; \
2349  } while (num_bits < 15);
2350 
2351 /* 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 */
2352 /* 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 */
2353 /* 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. */
2354 /* The slow path is only executed at the very end of the input buffer. */
2355 /* 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 */
2356 /* following the deflate data and our non-conservative read-ahead path won't kick in here on this code. This is much trickier. */
2357 #define TINFL_HUFF_DECODE(state_index, sym, pHuff) \
2358  do \
2359  { \
2360  int temp; \
2361  mz_uint code_len, c; \
2362  if (num_bits < 15) \
2363  { \
2364  if ((pIn_buf_end - pIn_buf_cur) < 2) \
2365  { \
2366  TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
2367  } \
2368  else \
2369  { \
2370  bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); \
2371  pIn_buf_cur += 2; \
2372  num_bits += 16; \
2373  } \
2374  } \
2375  if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
2376  code_len = temp >> 9, temp &= 511; \
2377  else \
2378  { \
2379  code_len = TINFL_FAST_LOOKUP_BITS; \
2380  do \
2381  { \
2382  temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
2383  } while (temp < 0); \
2384  } \
2385  sym = temp; \
2386  bit_buf >>= code_len; \
2387  num_bits -= code_len; \
2388  } \
2389  MZ_MACRO_END
2390 
2391 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)
2392 {
2393  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 };
2394  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 };
2395  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 };
2396  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 };
2397  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 };
2398  static const int s_min_table_sizes[3] = { 257, 1, 4 };
2399 
2401  mz_uint32 num_bits, dist, counter, num_extra;
2402  tinfl_bit_buf_t bit_buf;
2403  const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size;
2404  mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size;
2405  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;
2406 
2407  /* 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). */
2408  if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start))
2409  {
2410  *pIn_buf_size = *pOut_buf_size = 0;
2411  return TINFL_STATUS_BAD_PARAM;
2412  }
2413 
2414  num_bits = r->m_num_bits;
2415  bit_buf = r->m_bit_buf;
2416  dist = r->m_dist;
2417  counter = r->m_counter;
2418  num_extra = r->m_num_extra;
2419  dist_from_out_buf_start = r->m_dist_from_out_buf_start;
2421 
2422  bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0;
2423  r->m_z_adler32 = r->m_check_adler32 = 1;
2424  if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
2425  {
2426  TINFL_GET_BYTE(1, r->m_zhdr0);
2427  TINFL_GET_BYTE(2, r->m_zhdr1);
2428  counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8));
2429 #if 0
2430  /* original */
2431  if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
2432  counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1U << (8U + (r->m_zhdr0 >> 4)))));
2433 #else
2434  /* rewritten to avoid compilation warning */
2435  if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) {
2436  mz_uint32 t = (1U << (8U + (r->m_zhdr0 >> 4)));
2437  counter |= ((t > 32768U) || ((out_buf_size_mask + 1) < (size_t)(t)));
2438  }
2439 #endif
2440  if (counter)
2441  {
2443  }
2444  }
2445 
2446  do
2447  {
2448  TINFL_GET_BITS(3, r->m_final, 3);
2449  r->m_type = r->m_final >> 1;
2450  if (r->m_type == 0)
2451  {
2452  TINFL_SKIP_BITS(5, num_bits & 7);
2453  for (counter = 0; counter < 4; ++counter)
2454  {
2455  if (num_bits)
2456  TINFL_GET_BITS(6, r->m_raw_header[counter], 8);
2457  else
2458  TINFL_GET_BYTE(7, r->m_raw_header[counter]);
2459  }
2460  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))))
2461  {
2463  }
2464  while ((counter) && (num_bits))
2465  {
2466  TINFL_GET_BITS(51, dist, 8);
2467  while (pOut_buf_cur >= pOut_buf_end)
2468  {
2470  }
2471  *pOut_buf_cur++ = (mz_uint8)dist;
2472  counter--;
2473  }
2474  while (counter)
2475  {
2476  size_t n;
2477  while (pOut_buf_cur >= pOut_buf_end)
2478  {
2480  }
2481  while (pIn_buf_cur >= pIn_buf_end)
2482  {
2484  }
2485  n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter);
2486  TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n);
2487  pIn_buf_cur += n;
2488  pOut_buf_cur += n;
2489  counter -= (mz_uint)n;
2490  }
2491  }
2492  else if (r->m_type == 3)
2493  {
2495  }
2496  else
2497  {
2498  if (r->m_type == 1)
2499  {
2500  mz_uint8 *p = r->m_tables[0].m_code_size;
2501  mz_uint i;
2502  r->m_table_sizes[0] = 288;
2503  r->m_table_sizes[1] = 32;
2504  TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32);
2505  for (i = 0; i <= 143; ++i)
2506  *p++ = 8;
2507  for (; i <= 255; ++i)
2508  *p++ = 9;
2509  for (; i <= 279; ++i)
2510  *p++ = 7;
2511  for (; i <= 287; ++i)
2512  *p++ = 8;
2513  }
2514  else
2515  {
2516  for (counter = 0; counter < 3; counter++)
2517  {
2518  TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]);
2519  r->m_table_sizes[counter] += s_min_table_sizes[counter];
2520  }
2521  MZ_CLEAR_OBJ(r->m_tables[2].m_code_size);
2522  for (counter = 0; counter < r->m_table_sizes[2]; counter++)
2523  {
2524  mz_uint s;
2525  TINFL_GET_BITS(14, s, 3);
2526  r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s;
2527  }
2528  r->m_table_sizes[2] = 19;
2529  }
2530  for (; (int)r->m_type >= 0; r->m_type--)
2531  {
2532  int tree_next, tree_cur;
2533  tinfl_huff_table *pTable;
2534  mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16];
2535  pTable = &r->m_tables[r->m_type];
2536  MZ_CLEAR_OBJ(total_syms);
2537  MZ_CLEAR_OBJ(pTable->m_look_up);
2538  MZ_CLEAR_OBJ(pTable->m_tree);
2539  for (i = 0; i < r->m_table_sizes[r->m_type]; ++i)
2540  total_syms[pTable->m_code_size[i]]++;
2541  used_syms = 0, total = 0;
2542  next_code[0] = next_code[1] = 0;
2543  for (i = 1; i <= 15; ++i)
2544  {
2545  used_syms += total_syms[i];
2546  next_code[i + 1] = (total = ((total + total_syms[i]) << 1));
2547  }
2548  if ((65536 != total) && (used_syms > 1))
2549  {
2551  }
2552  for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index)
2553  {
2554  mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index];
2555  if (!code_size)
2556  continue;
2557  cur_code = next_code[code_size]++;
2558  for (l = code_size; l > 0; l--, cur_code >>= 1)
2559  rev_code = (rev_code << 1) | (cur_code & 1);
2560  if (code_size <= TINFL_FAST_LOOKUP_BITS)
2561  {
2562  mz_int16 k = (mz_int16)((code_size << 9) | sym_index);
2563  while (rev_code < TINFL_FAST_LOOKUP_SIZE)
2564  {
2565  pTable->m_look_up[rev_code] = k;
2566  rev_code += (1 << code_size);
2567  }
2568  continue;
2569  }
2570  if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)]))
2571  {
2572  pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next;
2573  tree_cur = tree_next;
2574  tree_next -= 2;
2575  }
2576  rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1);
2577  for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--)
2578  {
2579  tree_cur -= ((rev_code >>= 1) & 1);
2580  if (!pTable->m_tree[-tree_cur - 1])
2581  {
2582  pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next;
2583  tree_cur = tree_next;
2584  tree_next -= 2;
2585  }
2586  else
2587  tree_cur = pTable->m_tree[-tree_cur - 1];
2588  }
2589  tree_cur -= ((rev_code >>= 1) & 1);
2590  pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
2591  }
2592  if (r->m_type == 2)
2593  {
2594  for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]);)
2595  {
2596  mz_uint s;
2597  TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]);
2598  if (dist < 16)
2599  {
2600  r->m_len_codes[counter++] = (mz_uint8)dist;
2601  continue;
2602  }
2603  if ((dist == 16) && (!counter))
2604  {
2606  }
2607  num_extra = "\02\03\07"[dist - 16];
2608  TINFL_GET_BITS(18, s, num_extra);
2609  s += "\03\03\013"[dist - 16];
2610  TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s);
2611  counter += s;
2612  }
2613  if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter)
2614  {
2616  }
2617  TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]);
2618  TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]);
2619  }
2620  }
2621  for (;;)
2622  {
2623  mz_uint8 *pSrc;
2624  for (;;)
2625  {
2626  if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2))
2627  {
2628  TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]);
2629  if (counter >= 256)
2630  break;
2631  while (pOut_buf_cur >= pOut_buf_end)
2632  {
2634  }
2635  *pOut_buf_cur++ = (mz_uint8)counter;
2636  }
2637  else
2638  {
2639  int sym2;
2640  mz_uint code_len;
2641 #if TINFL_USE_64BIT_BITBUF
2642  if (num_bits < 30)
2643  {
2644  bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits);
2645  pIn_buf_cur += 4;
2646  num_bits += 32;
2647  }
2648 #else
2649  if (num_bits < 15)
2650  {
2651  bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
2652  pIn_buf_cur += 2;
2653  num_bits += 16;
2654  }
2655 #endif
2656  if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
2657  code_len = sym2 >> 9;
2658  else
2659  {
2660  code_len = TINFL_FAST_LOOKUP_BITS;
2661  do
2662  {
2663  sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)];
2664  } while (sym2 < 0);
2665  }
2666  counter = sym2;
2667  bit_buf >>= code_len;
2668  num_bits -= code_len;
2669  if (counter & 256)
2670  break;
2671 
2672 #if !TINFL_USE_64BIT_BITBUF
2673  if (num_bits < 15)
2674  {
2675  bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
2676  pIn_buf_cur += 2;
2677  num_bits += 16;
2678  }
2679 #endif
2680  if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
2681  code_len = sym2 >> 9;
2682  else
2683  {
2684  code_len = TINFL_FAST_LOOKUP_BITS;
2685  do
2686  {
2687  sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)];
2688  } while (sym2 < 0);
2689  }
2690  bit_buf >>= code_len;
2691  num_bits -= code_len;
2692 
2693  pOut_buf_cur[0] = (mz_uint8)counter;
2694  if (sym2 & 256)
2695  {
2696  pOut_buf_cur++;
2697  counter = sym2;
2698  break;
2699  }
2700  pOut_buf_cur[1] = (mz_uint8)sym2;
2701  pOut_buf_cur += 2;
2702  }
2703  }
2704  if ((counter &= 511) == 256)
2705  break;
2706 
2707  num_extra = s_length_extra[counter - 257];
2708  counter = s_length_base[counter - 257];
2709  if (num_extra)
2710  {
2711  mz_uint extra_bits;
2712  TINFL_GET_BITS(25, extra_bits, num_extra);
2713  counter += extra_bits;
2714  }
2715 
2716  TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]);
2717  num_extra = s_dist_extra[dist];
2718  dist = s_dist_base[dist];
2719  if (num_extra)
2720  {
2721  mz_uint extra_bits;
2722  TINFL_GET_BITS(27, extra_bits, num_extra);
2723  dist += extra_bits;
2724  }
2725 
2726  dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
2727  if ((dist == 0 || dist > dist_from_out_buf_start || dist_from_out_buf_start == 0) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
2728  {
2730  }
2731 
2732  pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask);
2733 
2734  if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end)
2735  {
2736  while (counter--)
2737  {
2738  while (pOut_buf_cur >= pOut_buf_end)
2739  {
2741  }
2742  *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask];
2743  }
2744  continue;
2745  }
2746 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
2747  else if ((counter >= 9) && (counter <= dist))
2748  {
2749  const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
2750  do
2751  {
2752 #ifdef MINIZ_UNALIGNED_USE_MEMCPY
2753  memcpy(pOut_buf_cur, pSrc, sizeof(mz_uint32)*2);
2754 #else
2755  ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0];
2756  ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1];
2757 #endif
2758  pOut_buf_cur += 8;
2759  } while ((pSrc += 8) < pSrc_end);
2760  if ((counter &= 7) < 3)
2761  {
2762  if (counter)
2763  {
2764  pOut_buf_cur[0] = pSrc[0];
2765  if (counter > 1)
2766  pOut_buf_cur[1] = pSrc[1];
2767  pOut_buf_cur += counter;
2768  }
2769  continue;
2770  }
2771  }
2772 #endif
2773  while(counter>2)
2774  {
2775  pOut_buf_cur[0] = pSrc[0];
2776  pOut_buf_cur[1] = pSrc[1];
2777  pOut_buf_cur[2] = pSrc[2];
2778  pOut_buf_cur += 3;
2779  pSrc += 3;
2780  counter -= 3;
2781  }
2782  if (counter > 0)
2783  {
2784  pOut_buf_cur[0] = pSrc[0];
2785  if (counter > 1)
2786  pOut_buf_cur[1] = pSrc[1];
2787  pOut_buf_cur += counter;
2788  }
2789  }
2790  }
2791  } while (!(r->m_final & 1));
2792 
2793  /* 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. */
2794  /* 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. */
2795  TINFL_SKIP_BITS(32, num_bits & 7);
2796  while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8))
2797  {
2798  --pIn_buf_cur;
2799  num_bits -= 8;
2800  }
2801  bit_buf &= (tinfl_bit_buf_t)((((mz_uint64)1) << num_bits) - (mz_uint64)1);
2802  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). */
2803 
2804  if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
2805  {
2806  for (counter = 0; counter < 4; ++counter)
2807  {
2808  mz_uint s;
2809  if (num_bits)
2810  TINFL_GET_BITS(41, s, 8);
2811  else
2812  TINFL_GET_BYTE(42, s);
2813  r->m_z_adler32 = (r->m_z_adler32 << 8) | s;
2814  }
2815  }
2817 
2819 
2820 common_exit:
2821  /* As long as we aren't telling the caller that we NEED more input to make forward progress: */
2822  /* 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. */
2823  /* 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. */
2825  {
2826  while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8))
2827  {
2828  --pIn_buf_cur;
2829  num_bits -= 8;
2830  }
2831  }
2832  r->m_num_bits = num_bits;
2833  r->m_bit_buf = bit_buf & (tinfl_bit_buf_t)((((mz_uint64)1) << num_bits) - (mz_uint64)1);
2834  r->m_dist = dist;
2835  r->m_counter = counter;
2836  r->m_num_extra = num_extra;
2837  r->m_dist_from_out_buf_start = dist_from_out_buf_start;
2838  *pIn_buf_size = pIn_buf_cur - pIn_buf_next;
2839  *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
2840  if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0))
2841  {
2842  const mz_uint8 *ptr = pOut_buf_next;
2843  size_t buf_len = *pOut_buf_size;
2844  mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16;
2845  size_t block_len = buf_len % 5552;
2846  while (buf_len)
2847  {
2848  for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
2849  {
2850  s1 += ptr[0], s2 += s1;
2851  s1 += ptr[1], s2 += s1;
2852  s1 += ptr[2], s2 += s1;
2853  s1 += ptr[3], s2 += s1;
2854  s1 += ptr[4], s2 += s1;
2855  s1 += ptr[5], s2 += s1;
2856  s1 += ptr[6], s2 += s1;
2857  s1 += ptr[7], s2 += s1;
2858  }
2859  for (; i < block_len; ++i)
2860  s1 += *ptr++, s2 += s1;
2861  s1 %= 65521U, s2 %= 65521U;
2862  buf_len -= block_len;
2863  block_len = 5552;
2864  }
2865  r->m_check_adler32 = (s2 << 16) + s1;
2866  if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32))
2868  }
2869  return status;
2870 }
2871 
2872 /* Higher level helper functions. */
2873 void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
2874 {
2875  tinfl_decompressor decomp;
2876  void *pBuf = NULL, *pNew_buf;
2877  size_t src_buf_ofs = 0, out_buf_capacity = 0;
2878  *pOut_len = 0;
2879  tinfl_init(&decomp);
2880  for (;;)
2881  {
2882  size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity;
2883  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,
2885  if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT))
2886  {
2887  MZ_FREE(pBuf);
2888  *pOut_len = 0;
2889  return NULL;
2890  }
2891  src_buf_ofs += src_buf_size;
2892  *pOut_len += dst_buf_size;
2893  if (status == TINFL_STATUS_DONE)
2894  break;
2895  new_out_buf_capacity = out_buf_capacity * 2;
2896  if (new_out_buf_capacity < 128)
2897  new_out_buf_capacity = 128;
2898  pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity);
2899  if (!pNew_buf)
2900  {
2901  MZ_FREE(pBuf);
2902  *pOut_len = 0;
2903  return NULL;
2904  }
2905  pBuf = pNew_buf;
2906  out_buf_capacity = new_out_buf_capacity;
2907  }
2908  return pBuf;
2909 }
2910 
2911 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)
2912 {
2913  tinfl_decompressor decomp;
2914  tinfl_status status;
2915  tinfl_init(&decomp);
2916  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);
2917  return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len;
2918 }
2919 
2920 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)
2921 {
2922  int result = 0;
2923  tinfl_decompressor decomp;
2925  size_t in_buf_ofs = 0, dict_ofs = 0;
2926  if (!pDict)
2927  return TINFL_STATUS_FAILED;
2928  tinfl_init(&decomp);
2929  for (;;)
2930  {
2931  size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs;
2932  tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8 *)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size,
2934  in_buf_ofs += in_buf_size;
2935  if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user)))
2936  break;
2937  if (status != TINFL_STATUS_HAS_MORE_OUTPUT)
2938  {
2939  result = (status == TINFL_STATUS_DONE);
2940  break;
2941  }
2942  dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1);
2943  }
2944  MZ_FREE(pDict);
2945  *pIn_buf_size = in_buf_ofs;
2946  return result;
2947 }
2948 
2949 #ifndef MINIZ_NO_MALLOC
2951 {
2953  if (pDecomp)
2954  tinfl_init(pDecomp);
2955  return pDecomp;
2956 }
2957 
2959 {
2960  MZ_FREE(pDecomp);
2961 }
2962 #endif
2963 
2964 #ifdef __cplusplus
2965 }
2966 #endif
2967  /**************************************************************************
2968  *
2969  * Copyright 2013-2014 RAD Game Tools and Valve Software
2970  * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
2971  * Copyright 2016 Martin Raiber
2972  * All Rights Reserved.
2973  *
2974  * Permission is hereby granted, free of charge, to any person obtaining a copy
2975  * of this software and associated documentation files (the "Software"), to deal
2976  * in the Software without restriction, including without limitation the rights
2977  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2978  * copies of the Software, and to permit persons to whom the Software is
2979  * furnished to do so, subject to the following conditions:
2980  *
2981  * The above copyright notice and this permission notice shall be included in
2982  * all copies or substantial portions of the Software.
2983  *
2984  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2985  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2986  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2987  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2988  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2989  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2990  * THE SOFTWARE.
2991  *
2992  **************************************************************************/
2993 
2994 
2995 #ifndef MINIZ_NO_ARCHIVE_APIS
2996 
2997 #ifdef __cplusplus
2998 extern "C" {
2999 #endif
3000 
3001 /* ------------------- .ZIP archive reading */
3002 
3003 #ifdef MINIZ_NO_STDIO
3004 #define MZ_FILE void *
3005 #else
3006 #include <sys/stat.h>
3007 
3008 #if defined(_MSC_VER) || defined(__MINGW64__)
3009 static FILE *mz_fopen(const char *pFilename, const char *pMode)
3010 {
3011  FILE *pFile = NULL;
3012  fopen_s(&pFile, pFilename, pMode);
3013  return pFile;
3014 }
3015 static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream)
3016 {
3017  FILE *pFile = NULL;
3018  if (freopen_s(&pFile, pPath, pMode, pStream))
3019  return NULL;
3020  return pFile;
3021 }
3022 #ifndef MINIZ_NO_TIME
3023 #include <sys/utime.h>
3024 #endif
3025 #define MZ_FOPEN mz_fopen
3026 #define MZ_FCLOSE fclose
3027 #define MZ_FREAD fread
3028 #define MZ_FWRITE fwrite
3029 #define MZ_FTELL64 _ftelli64
3030 #define MZ_FSEEK64 _fseeki64
3031 #define MZ_FILE_STAT_STRUCT _stat64
3032 #define MZ_FILE_STAT _stat64
3033 #define MZ_FFLUSH fflush
3034 #define MZ_FREOPEN mz_freopen
3035 #define MZ_DELETE_FILE remove
3036 #elif defined(__MINGW32__)
3037 #ifndef MINIZ_NO_TIME
3038 #include <sys/utime.h>
3039 #endif
3040 #define MZ_FOPEN(f, m) fopen(f, m)
3041 #define MZ_FCLOSE fclose
3042 #define MZ_FREAD fread
3043 #define MZ_FWRITE fwrite
3044 #define MZ_FTELL64 ftello64
3045 #define MZ_FSEEK64 fseeko64
3046 #define MZ_FILE_STAT_STRUCT _stat
3047 #define MZ_FILE_STAT _stat
3048 #define MZ_FFLUSH fflush
3049 #define MZ_FREOPEN(f, m, s) freopen(f, m, s)
3050 #define MZ_DELETE_FILE remove
3051 #elif defined(__TINYC__)
3052 #ifndef MINIZ_NO_TIME
3053 #include <sys/utime.h>
3054 #endif
3055 #define MZ_FOPEN(f, m) fopen(f, m)
3056 #define MZ_FCLOSE fclose
3057 #define MZ_FREAD fread
3058 #define MZ_FWRITE fwrite
3059 #define MZ_FTELL64 ftell
3060 #define MZ_FSEEK64 fseek
3061 #define MZ_FILE_STAT_STRUCT stat
3062 #define MZ_FILE_STAT stat
3063 #define MZ_FFLUSH fflush
3064 #define MZ_FREOPEN(f, m, s) freopen(f, m, s)
3065 #define MZ_DELETE_FILE remove
3066 #elif defined(__USE_LARGEFILE64) /* gcc, clang */
3067 #ifndef MINIZ_NO_TIME
3068 #include <utime.h>
3069 #endif
3070 #define MZ_FOPEN(f, m) fopen64(f, m)
3071 #define MZ_FCLOSE fclose
3072 #define MZ_FREAD fread
3073 #define MZ_FWRITE fwrite
3074 #define MZ_FTELL64 ftello64
3075 #define MZ_FSEEK64 fseeko64
3076 #define MZ_FILE_STAT_STRUCT stat64
3077 #define MZ_FILE_STAT stat64
3078 #define MZ_FFLUSH fflush
3079 #define MZ_FREOPEN(p, m, s) freopen64(p, m, s)
3080 #define MZ_DELETE_FILE remove
3081 #elif defined(__APPLE__)
3082 #ifndef MINIZ_NO_TIME
3083 #include <utime.h>
3084 #endif
3085 #define MZ_FOPEN(f, m) fopen(f, m)
3086 #define MZ_FCLOSE fclose
3087 #define MZ_FREAD fread
3088 #define MZ_FWRITE fwrite
3089 #define MZ_FTELL64 ftello
3090 #define MZ_FSEEK64 fseeko
3091 #define MZ_FILE_STAT_STRUCT stat
3092 #define MZ_FILE_STAT stat
3093 #define MZ_FFLUSH fflush
3094 #define MZ_FREOPEN(p, m, s) freopen(p, m, s)
3095 #define MZ_DELETE_FILE remove
3096 
3097 #else
3098 #pragma message("Using fopen, ftello, fseeko, stat() etc. path for file I/O - this path may not support large files.")
3099 #ifndef MINIZ_NO_TIME
3100 #include <utime.h>
3101 #endif
3102 #define MZ_FOPEN(f, m) fopen(f, m)
3103 #define MZ_FCLOSE fclose
3104 #define MZ_FREAD fread
3105 #define MZ_FWRITE fwrite
3106 #ifdef __STRICT_ANSI__
3107 #define MZ_FTELL64 ftell
3108 #define MZ_FSEEK64 fseek
3109 #else
3110 #define MZ_FTELL64 ftello
3111 #define MZ_FSEEK64 fseeko
3112 #endif
3113 #define MZ_FILE_STAT_STRUCT stat
3114 #define MZ_FILE_STAT stat
3115 #define MZ_FFLUSH fflush
3116 #define MZ_FREOPEN(f, m, s) freopen(f, m, s)
3117 #define MZ_DELETE_FILE remove
3118 #endif /* #ifdef _MSC_VER */
3119 #endif /* #ifdef MINIZ_NO_STDIO */
3120 
3121 #define MZ_TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c))
3122 
3123 /* Various ZIP archive enums. To completely avoid cross platform compiler alignment and platform endian issues, miniz.c doesn't use structs for any of this stuff. */
3124 enum
3125 {
3126  /* ZIP archive identifiers and record sizes */
3133 
3134  /* ZIP64 archive identifier and record sizes */
3143 
3144  /* Central directory header record offsets */
3162 
3163  /* Local directory header offsets */
3176 
3177  /* End of central directory offsets */
3186 
3187  /* ZIP64 End of central directory locator offsets */
3188  MZ_ZIP64_ECDL_SIG_OFS = 0, /* 4 bytes */
3192 
3193  /* ZIP64 End of central directory header offsets */
3194  MZ_ZIP64_ECDH_SIG_OFS = 0, /* 4 bytes */
3202  MZ_ZIP64_ECDH_CDIR_SIZE_OFS = 40, /* 8 bytes */
3203  MZ_ZIP64_ECDH_CDIR_OFS_OFS = 48, /* 8 bytes */
3211 };
3212 
3213 typedef struct
3214 {
3215  void *m_p;
3216  size_t m_size, m_capacity;
3218 } mz_zip_array;
3219 
3221 {
3225 
3226  /* The flags passed in when the archive is initially opened. */
3228 
3229  /* MZ_TRUE if the archive has a zip64 end of central directory headers, etc. */
3231 
3232  /* MZ_TRUE if we found zip64 extended info in the central directory (m_zip64 will also be slammed to true too, even if we didn't find a zip64 end of central dir header, etc.) */
3234 
3235  /* These fields are used by the file, FILE, memory, and memory/heap read/write helpers. */
3238 
3239  void *m_pMem;
3240  size_t m_mem_size;
3242 };
3243 
3244 #define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size) (array_ptr)->m_element_size = element_size
3245 
3246 #if defined(DEBUG) || defined(_DEBUG)
3248 {
3249  MZ_ASSERT(index < pArray->m_size);
3250  return index;
3251 }
3252 #define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[mz_zip_array_range_check(array_ptr, index)]
3253 #else
3254 #define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[index]
3255 #endif
3256 
3257 static MZ_FORCEINLINE void mz_zip_array_init(mz_zip_array *pArray, mz_uint32 element_size)
3258 {
3259  memset(pArray, 0, sizeof(mz_zip_array));
3260  pArray->m_element_size = element_size;
3261 }
3262 
3264 {
3265  pZip->m_pFree(pZip->m_pAlloc_opaque, pArray->m_p);
3266  memset(pArray, 0, sizeof(mz_zip_array));
3267 }
3268 
3269 static mz_bool mz_zip_array_ensure_capacity(mz_zip_archive *pZip, mz_zip_array *pArray, size_t min_new_capacity, mz_uint growing)
3270 {
3271  void *pNew_p;
3272  size_t new_capacity = min_new_capacity;
3273  MZ_ASSERT(pArray->m_element_size);
3274  if (pArray->m_capacity >= min_new_capacity)
3275  return MZ_TRUE;
3276  if (growing)
3277  {
3278  new_capacity = MZ_MAX(1, pArray->m_capacity);
3279  while (new_capacity < min_new_capacity)
3280  new_capacity *= 2;
3281  }
3282  if (NULL == (pNew_p = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pArray->m_p, pArray->m_element_size, new_capacity)))
3283  return MZ_FALSE;
3284  pArray->m_p = pNew_p;
3285  pArray->m_capacity = new_capacity;
3286  return MZ_TRUE;
3287 }
3288 
3289 static MZ_FORCEINLINE mz_bool mz_zip_array_reserve(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_capacity, mz_uint growing)
3290 {
3291  if (new_capacity > pArray->m_capacity)
3292  {
3293  if (!mz_zip_array_ensure_capacity(pZip, pArray, new_capacity, growing))
3294  return MZ_FALSE;
3295  }
3296  return MZ_TRUE;
3297 }
3298 
3299 static MZ_FORCEINLINE mz_bool mz_zip_array_resize(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_size, mz_uint growing)
3300 {
3301  if (new_size > pArray->m_capacity)
3302  {
3303  if (!mz_zip_array_ensure_capacity(pZip, pArray, new_size, growing))
3304  return MZ_FALSE;
3305  }
3306  pArray->m_size = new_size;
3307  return MZ_TRUE;
3308 }
3309 
3311 {
3312  return mz_zip_array_reserve(pZip, pArray, pArray->m_size + n, MZ_TRUE);
3313 }
3314 
3315 static MZ_FORCEINLINE mz_bool mz_zip_array_push_back(mz_zip_archive *pZip, mz_zip_array *pArray, const void *pElements, size_t n)
3316 {
3317  size_t orig_size = pArray->m_size;
3318  if (!mz_zip_array_resize(pZip, pArray, orig_size + n, MZ_TRUE))
3319  return MZ_FALSE;
3320  if (n > 0)
3321  memcpy((mz_uint8 *)pArray->m_p + orig_size * pArray->m_element_size, pElements, n * pArray->m_element_size);
3322  return MZ_TRUE;
3323 }
3324 
3325 #ifndef MINIZ_NO_TIME
3326 static MZ_TIME_T mz_zip_dos_to_time_t(int dos_time, int dos_date)
3327 {
3328  struct tm tm;
3329  memset(&tm, 0, sizeof(tm));
3330  tm.tm_isdst = -1;
3331  tm.tm_year = ((dos_date >> 9) & 127) + 1980 - 1900;
3332  tm.tm_mon = ((dos_date >> 5) & 15) - 1;
3333  tm.tm_mday = dos_date & 31;
3334  tm.tm_hour = (dos_time >> 11) & 31;
3335  tm.tm_min = (dos_time >> 5) & 63;
3336  tm.tm_sec = (dos_time << 1) & 62;
3337  return mktime(&tm);
3338 }
3339 
3340 #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
3341 static void mz_zip_time_t_to_dos_time(MZ_TIME_T time, mz_uint16 *pDOS_time, mz_uint16 *pDOS_date)
3342 {
3343 #ifdef _MSC_VER
3344  struct tm tm_struct;
3345  struct tm *tm = &tm_struct;
3346  errno_t err = localtime_s(tm, &time);
3347  if (err)
3348  {
3349  *pDOS_date = 0;
3350  *pDOS_time = 0;
3351  return;
3352  }
3353 #else
3354  struct tm *tm = localtime(&time);
3355 #endif /* #ifdef _MSC_VER */
3356 
3357  *pDOS_time = (mz_uint16)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) + ((tm->tm_sec) >> 1));
3358  *pDOS_date = (mz_uint16)(((tm->tm_year + 1900 - 1980) << 9) + ((tm->tm_mon + 1) << 5) + tm->tm_mday);
3359 }
3360 #endif /* MINIZ_NO_ARCHIVE_WRITING_APIS */
3361 
3362 #ifndef MINIZ_NO_STDIO
3363 #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
3364 static mz_bool mz_zip_get_file_modified_time(const char *pFilename, MZ_TIME_T *pTime)
3365 {
3366  struct MZ_FILE_STAT_STRUCT file_stat;
3367 
3368  /* On Linux with x86 glibc, this call will fail on large files (I think >= 0x80000000 bytes) unless you compiled with _LARGEFILE64_SOURCE. Argh. */
3369  if (MZ_FILE_STAT(pFilename, &file_stat) != 0)
3370  return MZ_FALSE;
3371 
3372  *pTime = file_stat.st_mtime;
3373 
3374  return MZ_TRUE;
3375 }
3376 #endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS*/
3377 
3378 static mz_bool mz_zip_set_file_times(const char *pFilename, MZ_TIME_T access_time, MZ_TIME_T modified_time)
3379 {
3380  struct utimbuf t;
3381 
3382  memset(&t, 0, sizeof(t));
3383  t.actime = access_time;
3384  t.modtime = modified_time;
3385 
3386  return !utime(pFilename, &t);
3387 }
3388 #endif /* #ifndef MINIZ_NO_STDIO */
3389 #endif /* #ifndef MINIZ_NO_TIME */
3390 
3392 {
3393  if (pZip)
3394  pZip->m_last_error = err_num;
3395  return MZ_FALSE;
3396 }
3397 
3399 {
3400  (void)flags;
3401  if ((!pZip) || (pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
3403 
3404  if (!pZip->m_pAlloc)
3406  if (!pZip->m_pFree)
3407  pZip->m_pFree = miniz_def_free_func;
3408  if (!pZip->m_pRealloc)
3410 
3411  pZip->m_archive_size = 0;
3412  pZip->m_central_directory_file_ofs = 0;
3413  pZip->m_total_files = 0;
3414  pZip->m_last_error = MZ_ZIP_NO_ERROR;
3415 
3416  if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state))))
3417  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
3418 
3419  memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state));
3423  pZip->m_pState->m_init_flags = flags;
3424  pZip->m_pState->m_zip64 = MZ_FALSE;
3426 
3428 
3429  return MZ_TRUE;
3430 }
3431 
3432 static MZ_FORCEINLINE mz_bool mz_zip_reader_filename_less(const mz_zip_array *pCentral_dir_array, const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, mz_uint r_index)
3433 {
3434  const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE;
3435  const mz_uint8 *pR = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, r_index));
3437  mz_uint8 l = 0, r = 0;
3440  pE = pL + MZ_MIN(l_len, r_len);
3441  while (pL < pE)
3442  {
3443  if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR)))
3444  break;
3445  pL++;
3446  pR++;
3447  }
3448  return (pL == pE) ? (l_len < r_len) : (l < r);
3449 }
3450 
3451 #define MZ_SWAP_UINT32(a, b) \
3452  do \
3453  { \
3454  mz_uint32 t = a; \
3455  a = b; \
3456  b = t; \
3457  } \
3458  MZ_MACRO_END
3459 
3460 /* Heap sort of lowercased filenames, used to help accelerate plain central directory searches by mz_zip_reader_locate_file(). (Could also use qsort(), but it could allocate memory.) */
3462 {
3463  mz_zip_internal_state *pState = pZip->m_pState;
3464  const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
3465  const mz_zip_array *pCentral_dir = &pState->m_central_dir;
3466  mz_uint32 *pIndices;
3467  mz_uint32 start, end;
3468  const mz_uint32 size = pZip->m_total_files;
3469 
3470  if (size <= 1U)
3471  return;
3472 
3474 
3475  start = (size - 2U) >> 1U;
3476  for (;;)
3477  {
3478  mz_uint64 child, root = start;
3479  for (;;)
3480  {
3481  if ((child = (root << 1U) + 1U) >= size)
3482  break;
3483  child += (((child + 1U) < size) && (mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1U])));
3484  if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child]))
3485  break;
3486  MZ_SWAP_UINT32(pIndices[root], pIndices[child]);
3487  root = child;
3488  }
3489  if (!start)
3490  break;
3491  start--;
3492  }
3493 
3494  end = size - 1;
3495  while (end > 0)
3496  {
3497  mz_uint64 child, root = 0;
3498  MZ_SWAP_UINT32(pIndices[end], pIndices[0]);
3499  for (;;)
3500  {
3501  if ((child = (root << 1U) + 1U) >= end)
3502  break;
3503  child += (((child + 1U) < end) && mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1U]));
3504  if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child]))
3505  break;
3506  MZ_SWAP_UINT32(pIndices[root], pIndices[child]);
3507  root = child;
3508  }
3509  end--;
3510  }
3511 }
3512 
3514 {
3515  mz_int64 cur_file_ofs;
3516  mz_uint32 buf_u32[4096 / sizeof(mz_uint32)];
3517  mz_uint8 *pBuf = (mz_uint8 *)buf_u32;
3518 
3519  /* Basic sanity checks - reject files which are too small */
3520  if (pZip->m_archive_size < record_size)
3521  return MZ_FALSE;
3522 
3523  /* Find the record by scanning the file from the end towards the beginning. */
3524  cur_file_ofs = MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)sizeof(buf_u32), 0);
3525  for (;;)
3526  {
3527  int i, n = (int)MZ_MIN(sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs);
3528 
3529  if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n)
3530  return MZ_FALSE;
3531 
3532  for (i = n - 4; i >= 0; --i)
3533  {
3534  mz_uint s = MZ_READ_LE32(pBuf + i);
3535  if (s == record_sig)
3536  {
3537  if ((pZip->m_archive_size - (cur_file_ofs + i)) >= record_size)
3538  break;
3539  }
3540  }
3541 
3542  if (i >= 0)
3543  {
3544  cur_file_ofs += i;
3545  break;
3546  }
3547 
3548  /* Give up if we've searched the entire file, or we've gone back "too far" (~64kb) */
3549  if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >= (MZ_UINT16_MAX + record_size)))
3550  return MZ_FALSE;
3551 
3552  cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0);
3553  }
3554 
3555  *pOfs = cur_file_ofs;
3556  return MZ_TRUE;
3557 }
3558 
3560 {
3561  mz_uint cdir_size = 0, cdir_entries_on_this_disk = 0, num_this_disk = 0, cdir_disk_index = 0;
3562  mz_uint64 cdir_ofs = 0;
3563  mz_int64 cur_file_ofs = 0;
3564  const mz_uint8 *p;
3565 
3566  mz_uint32 buf_u32[4096 / sizeof(mz_uint32)];
3567  mz_uint8 *pBuf = (mz_uint8 *)buf_u32;
3568  mz_bool sort_central_dir = ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0);
3569  mz_uint32 zip64_end_of_central_dir_locator_u32[(MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
3570  mz_uint8 *pZip64_locator = (mz_uint8 *)zip64_end_of_central_dir_locator_u32;
3571 
3572  mz_uint32 zip64_end_of_central_dir_header_u32[(MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
3573  mz_uint8 *pZip64_end_of_central_dir = (mz_uint8 *)zip64_end_of_central_dir_header_u32;
3574 
3575  mz_uint64 zip64_end_of_central_dir_ofs = 0;
3576 
3577  /* Basic sanity checks - reject files which are too small, and check the first 4 bytes of the file to make sure a local header is there. */
3580 
3583 
3584  /* Read and verify the end of central directory record. */
3587 
3590 
3592  {
3594  {
3596  {
3597  zip64_end_of_central_dir_ofs = MZ_READ_LE64(pZip64_locator + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS);
3598  if (zip64_end_of_central_dir_ofs > (pZip->m_archive_size - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE))
3600 
3601  if (pZip->m_pRead(pZip->m_pIO_opaque, zip64_end_of_central_dir_ofs, pZip64_end_of_central_dir, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) == MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)
3602  {
3604  {
3605  pZip->m_pState->m_zip64 = MZ_TRUE;
3606  }
3607  }
3608  }
3609  }
3610  }
3611 
3613  cdir_entries_on_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS);
3614  num_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS);
3615  cdir_disk_index = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS);
3616  cdir_size = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_SIZE_OFS);
3617  cdir_ofs = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS);
3618 
3619  if (pZip->m_pState->m_zip64)
3620  {
3621  mz_uint32 zip64_total_num_of_disks = MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS);
3622  mz_uint64 zip64_cdir_total_entries = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS);
3623  mz_uint64 zip64_cdir_total_entries_on_this_disk = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS);
3624  mz_uint64 zip64_size_of_end_of_central_dir_record = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS);
3625  mz_uint64 zip64_size_of_central_directory = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_SIZE_OFS);
3626 
3627  if (zip64_size_of_end_of_central_dir_record < (MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE - 12))
3629 
3630  if (zip64_total_num_of_disks != 1U)
3632 
3633  /* Check for miniz's practical limits */
3634  if (zip64_cdir_total_entries > MZ_UINT32_MAX)
3636 
3637  pZip->m_total_files = (mz_uint32)zip64_cdir_total_entries;
3638 
3639  if (zip64_cdir_total_entries_on_this_disk > MZ_UINT32_MAX)
3641 
3642  cdir_entries_on_this_disk = (mz_uint32)zip64_cdir_total_entries_on_this_disk;
3643 
3644  /* Check for miniz's current practical limits (sorry, this should be enough for millions of files) */
3645  if (zip64_size_of_central_directory > MZ_UINT32_MAX)
3647 
3648  cdir_size = (mz_uint32)zip64_size_of_central_directory;
3649 
3650  num_this_disk = MZ_READ_LE32(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_NUM_THIS_DISK_OFS);
3651 
3652  cdir_disk_index = MZ_READ_LE32(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_NUM_DISK_CDIR_OFS);
3653 
3654  cdir_ofs = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_OFS_OFS);
3655  }
3656 
3657  if (pZip->m_total_files != cdir_entries_on_this_disk)
3659 
3660  if (((num_this_disk | cdir_disk_index) != 0) && ((num_this_disk != 1) || (cdir_disk_index != 1)))
3662 
3663  if (cdir_size < pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)
3665 
3666  if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size)
3668 
3669  pZip->m_central_directory_file_ofs = cdir_ofs;
3670 
3671  if (pZip->m_total_files)
3672  {
3673  mz_uint i, n;
3674  /* Read the entire central directory into a heap block, and allocate another heap block to hold the unsorted central dir file record offsets, and possibly another to hold the sorted indices. */
3675  if ((!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir, cdir_size, MZ_FALSE)) ||
3677  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
3678 
3679  if (sort_central_dir)
3680  {
3682  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
3683  }
3684 
3685  if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs, pZip->m_pState->m_central_dir.m_p, cdir_size) != cdir_size)
3687 
3688  /* Now create an index into the central directory file records, do some basic sanity checking on each record */
3689  p = (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p;
3690  for (n = cdir_size, i = 0; i < pZip->m_total_files; ++i)
3691  {
3692  mz_uint total_header_size, disk_index, bit_flags, filename_size, ext_data_size;
3693  mz_uint64 comp_size, decomp_size, local_header_ofs;
3694 
3697 
3699 
3700  if (sort_central_dir)
3702 
3705  local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
3706  filename_size = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
3707  ext_data_size = MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS);
3708 
3710  (ext_data_size) &&
3711  (MZ_MAX(MZ_MAX(comp_size, decomp_size), local_header_ofs) == MZ_UINT32_MAX))
3712  {
3713  /* Attempt to find zip64 extended information field in the entry's extra data */
3714  mz_uint32 extra_size_remaining = ext_data_size;
3715 
3716  if (extra_size_remaining)
3717  {
3718  const mz_uint8 *pExtra_data;
3719  void* buf = NULL;
3720 
3721  if (MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + ext_data_size > n)
3722  {
3723  buf = MZ_MALLOC(ext_data_size);
3724  if(buf==NULL)
3725  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
3726 
3727  if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size, buf, ext_data_size) != ext_data_size)
3728  {
3729  MZ_FREE(buf);
3731  }
3732 
3733  pExtra_data = (mz_uint8*)buf;
3734  }
3735  else
3736  {
3737  pExtra_data = p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size;
3738  }
3739 
3740  do
3741  {
3742  mz_uint32 field_id;
3743  mz_uint32 field_data_size;
3744 
3745  if (extra_size_remaining < (sizeof(mz_uint16) * 2))
3746  {
3747  MZ_FREE(buf);
3749  }
3750 
3751  field_id = MZ_READ_LE16(pExtra_data);
3752  field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16));
3753 
3754  if ((field_data_size + sizeof(mz_uint16) * 2) > extra_size_remaining)
3755  {
3756  MZ_FREE(buf);
3758  }
3759 
3761  {
3762  /* Ok, the archive didn't have any zip64 headers but it uses a zip64 extended information field so mark it as zip64 anyway (this can occur with infozip's zip util when it reads compresses files from stdin). */
3763  pZip->m_pState->m_zip64 = MZ_TRUE;
3765  break;
3766  }
3767 
3768  pExtra_data += sizeof(mz_uint16) * 2 + field_data_size;
3769  extra_size_remaining = extra_size_remaining - sizeof(mz_uint16) * 2 - field_data_size;
3770  } while (extra_size_remaining);
3771 
3772  MZ_FREE(buf);
3773  }
3774  }
3775 
3776  /* I've seen archives that aren't marked as zip64 that uses zip64 ext data, argh */
3777  if ((comp_size != MZ_UINT32_MAX) && (decomp_size != MZ_UINT32_MAX))
3778  {
3779  if (((!MZ_READ_LE32(p + MZ_ZIP_CDH_METHOD_OFS)) && (decomp_size != comp_size)) || (decomp_size && !comp_size))
3781  }
3782 
3783  disk_index = MZ_READ_LE16(p + MZ_ZIP_CDH_DISK_START_OFS);
3784  if ((disk_index == MZ_UINT16_MAX) || ((disk_index != num_this_disk) && (disk_index != 1)))
3786 
3787  if (comp_size != MZ_UINT32_MAX)
3788  {
3791  }
3792 
3793  bit_flags = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
3796 
3799 
3800  n -= total_header_size;
3801  p += total_header_size;
3802  }
3803  }
3804 
3805  if (sort_central_dir)
3807 
3808  return MZ_TRUE;
3809 }
3810 
3812 {
3813  if (pZip)
3814  MZ_CLEAR_OBJ(*pZip);
3815 }
3816 
3818 {
3819  mz_bool status = MZ_TRUE;
3820 
3821  if (!pZip)
3822  return MZ_FALSE;
3823 
3824  if ((!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
3825  {
3826  if (set_last_error)
3828 
3829  return MZ_FALSE;
3830  }
3831 
3832  if (pZip->m_pState)
3833  {
3834  mz_zip_internal_state *pState = pZip->m_pState;
3835  pZip->m_pState = NULL;
3836 
3837  mz_zip_array_clear(pZip, &pState->m_central_dir);
3838  mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
3840 
3841 #ifndef MINIZ_NO_STDIO
3842  if (pState->m_pFile)
3843  {
3844  if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE)
3845  {
3846  if (MZ_FCLOSE(pState->m_pFile) == EOF)
3847  {
3848  if (set_last_error)
3850  status = MZ_FALSE;
3851  }
3852  }
3853  pState->m_pFile = NULL;
3854  }
3855 #endif /* #ifndef MINIZ_NO_STDIO */
3856 
3857  pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
3858  }
3860 
3861  return status;
3862 }
3863 
3865 {
3866  return mz_zip_reader_end_internal(pZip, MZ_TRUE);
3867 }
3869 {
3870  if ((!pZip) || (!pZip->m_pRead))
3872 
3873  if (!mz_zip_reader_init_internal(pZip, flags))
3874  return MZ_FALSE;
3875 
3876  pZip->m_zip_type = MZ_ZIP_TYPE_USER;
3877  pZip->m_archive_size = size;
3878 
3880  {
3882  return MZ_FALSE;
3883  }
3884 
3885  return MZ_TRUE;
3886 }
3887 
3888 static size_t mz_zip_mem_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
3889 {
3890  mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
3891  size_t s = (file_ofs >= pZip->m_archive_size) ? 0 : (size_t)MZ_MIN(pZip->m_archive_size - file_ofs, n);
3892  memcpy(pBuf, (const mz_uint8 *)pZip->m_pState->m_pMem + file_ofs, s);
3893  return s;
3894 }
3895 
3897 {
3898  if (!pMem)
3900 
3903 
3904  if (!mz_zip_reader_init_internal(pZip, flags))
3905  return MZ_FALSE;
3906 
3908  pZip->m_archive_size = size;
3909  pZip->m_pRead = mz_zip_mem_read_func;
3910  pZip->m_pIO_opaque = pZip;
3911  pZip->m_pNeeds_keepalive = NULL;
3912 
3913 #ifdef __cplusplus
3914  pZip->m_pState->m_pMem = const_cast<void *>(pMem);
3915 #else
3916  pZip->m_pState->m_pMem = (void *)pMem;
3917 #endif
3918 
3919  pZip->m_pState->m_mem_size = size;
3920 
3922  {
3924  return MZ_FALSE;
3925  }
3926 
3927  return MZ_TRUE;
3928 }
3929 
3930 #ifndef MINIZ_NO_STDIO
3931 static size_t mz_zip_file_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
3932 {
3933  mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
3934  mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
3935 
3936  file_ofs += pZip->m_pState->m_file_archive_start_ofs;
3937 
3938  if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET))))
3939  return 0;
3940 
3941  return MZ_FREAD(pBuf, 1, n, pZip->m_pState->m_pFile);
3942 }
3943 
3945 {
3946  return mz_zip_reader_init_file_v2(pZip, pFilename, flags, 0, 0);
3947 }
3948 
3949 mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags, mz_uint64 file_start_ofs, mz_uint64 archive_size)
3950 {
3951  mz_uint64 file_size;
3952  MZ_FILE *pFile;
3953 
3954  if ((!pZip) || (!pFilename) || ((archive_size) && (archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)))
3956 
3957  pFile = MZ_FOPEN(pFilename, "rb");
3958  if (!pFile)
3960 
3961  file_size = archive_size;
3962  if (!file_size)
3963  {
3964  if (MZ_FSEEK64(pFile, 0, SEEK_END))
3965  {
3966  MZ_FCLOSE(pFile);
3968  }
3969 
3970  file_size = MZ_FTELL64(pFile);
3971  }
3972 
3973  /* TODO: Better sanity check archive_size and the # of actual remaining bytes */
3974 
3975  if (file_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
3976  {
3977  MZ_FCLOSE(pFile);
3979  }
3980 
3981  if (!mz_zip_reader_init_internal(pZip, flags))
3982  {
3983  MZ_FCLOSE(pFile);
3984  return MZ_FALSE;
3985  }
3986 
3987  pZip->m_zip_type = MZ_ZIP_TYPE_FILE;
3989  pZip->m_pIO_opaque = pZip;
3990  pZip->m_pState->m_pFile = pFile;
3991  pZip->m_archive_size = file_size;
3992  pZip->m_pState->m_file_archive_start_ofs = file_start_ofs;
3993 
3995  {
3997  return MZ_FALSE;
3998  }
3999 
4000  return MZ_TRUE;
4001 }
4002 
4004 {
4005  mz_uint64 cur_file_ofs;
4006 
4007  if ((!pZip) || (!pFile))
4009 
4010  cur_file_ofs = MZ_FTELL64(pFile);
4011 
4012  if (!archive_size)
4013  {
4014  if (MZ_FSEEK64(pFile, 0, SEEK_END))
4016 
4017  archive_size = MZ_FTELL64(pFile) - cur_file_ofs;
4018 
4019  if (archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
4021  }
4022 
4023  if (!mz_zip_reader_init_internal(pZip, flags))
4024  return MZ_FALSE;
4025 
4026  pZip->m_zip_type = MZ_ZIP_TYPE_CFILE;
4028 
4029  pZip->m_pIO_opaque = pZip;
4030  pZip->m_pState->m_pFile = pFile;
4031  pZip->m_archive_size = archive_size;
4032  pZip->m_pState->m_file_archive_start_ofs = cur_file_ofs;
4033 
4035  {
4037  return MZ_FALSE;
4038  }
4039 
4040  return MZ_TRUE;
4041 }
4042 
4043 #endif /* #ifndef MINIZ_NO_STDIO */
4044 
4046 {
4047  if ((!pZip) || (!pZip->m_pState) || (file_index >= pZip->m_total_files))
4048  return NULL;
4050 }
4051 
4053 {
4054  mz_uint m_bit_flag;
4055  const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
4056  if (!p)
4057  {
4059  return MZ_FALSE;
4060  }
4061 
4062  m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
4064 }
4065 
4067 {
4068  mz_uint bit_flag;
4069  mz_uint method;
4070 
4071  const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
4072  if (!p)
4073  {
4075  return MZ_FALSE;
4076  }
4077 
4078  method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS);
4079  bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
4080 
4081  if ((method != 0) && (method != MZ_DEFLATED))
4082  {
4084  return MZ_FALSE;
4085  }
4086 
4088  {
4090  return MZ_FALSE;
4091  }
4092 
4094  {
4096  return MZ_FALSE;
4097  }
4098 
4099  return MZ_TRUE;
4100 }
4101 
4103 {
4104  mz_uint filename_len, attribute_mapping_id, external_attr;
4105  const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
4106  if (!p)
4107  {
4109  return MZ_FALSE;
4110  }
4111 
4112  filename_len = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
4113  if (filename_len)
4114  {
4115  if (*(p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_len - 1) == '/')
4116  return MZ_TRUE;
4117  }
4118 
4119  /* Bugfix: This code was also checking if the internal attribute was non-zero, which wasn't correct. */
4120  /* Most/all zip writers (hopefully) set DOS file/directory attributes in the low 16-bits, so check for the DOS directory flag and ignore the source OS ID in the created by field. */
4121  /* FIXME: Remove this check? Is it necessary - we already check the filename. */
4122  attribute_mapping_id = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS) >> 8;
4123  (void)attribute_mapping_id;
4124 
4125  external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS);
4126  if ((external_attr & MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG) != 0)
4127  {
4128  return MZ_TRUE;
4129  }
4130 
4131  return MZ_FALSE;
4132 }
4133 
4134 static mz_bool mz_zip_file_stat_internal(mz_zip_archive *pZip, mz_uint file_index, const mz_uint8 *pCentral_dir_header, mz_zip_archive_file_stat *pStat, mz_bool *pFound_zip64_extra_data)
4135 {
4136  mz_uint n;
4137  const mz_uint8 *p = pCentral_dir_header;
4138 
4139  if (pFound_zip64_extra_data)
4140  *pFound_zip64_extra_data = MZ_FALSE;
4141 
4142  if ((!p) || (!pStat))
4144 
4145  /* Extract fields from the central directory record. */
4146  pStat->m_file_index = file_index;
4152 #ifndef MINIZ_NO_TIME
4154 #endif
4161 
4162  /* Copy as much of the filename and comment as possible. */
4165  memcpy(pStat->m_filename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n);
4166  pStat->m_filename[n] = '\0';
4167 
4170  pStat->m_comment_size = n;
4172  pStat->m_comment[n] = '\0';
4173 
4174  /* Set some flags for convienance */
4175  pStat->m_is_directory = mz_zip_reader_is_file_a_directory(pZip, file_index);
4176  pStat->m_is_encrypted = mz_zip_reader_is_file_encrypted(pZip, file_index);
4177  pStat->m_is_supported = mz_zip_reader_is_file_supported(pZip, file_index);
4178 
4179  /* See if we need to read any zip64 extended information fields. */
4180  /* Confusingly, these zip64 fields can be present even on non-zip64 archives (Debian zip on a huge files from stdin piped to stdout creates them). */
4181  if (MZ_MAX(MZ_MAX(pStat->m_comp_size, pStat->m_uncomp_size), pStat->m_local_header_ofs) == MZ_UINT32_MAX)
4182  {
4183  /* Attempt to find zip64 extended information field in the entry's extra data */
4184  mz_uint32 extra_size_remaining = MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS);
4185 
4186  if (extra_size_remaining)
4187  {
4189 
4190  do
4191  {
4192  mz_uint32 field_id;
4193  mz_uint32 field_data_size;
4194 
4195  if (extra_size_remaining < (sizeof(mz_uint16) * 2))
4197 
4198  field_id = MZ_READ_LE16(pExtra_data);
4199  field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16));
4200 
4201  if ((field_data_size + sizeof(mz_uint16) * 2) > extra_size_remaining)
4203 
4205  {
4206  const mz_uint8 *pField_data = pExtra_data + sizeof(mz_uint16) * 2;
4207  mz_uint32 field_data_remaining = field_data_size;
4208 
4209  if (pFound_zip64_extra_data)
4210  *pFound_zip64_extra_data = MZ_TRUE;
4211 
4212  if (pStat->m_uncomp_size == MZ_UINT32_MAX)
4213  {
4214  if (field_data_remaining < sizeof(mz_uint64))
4216 
4217  pStat->m_uncomp_size = MZ_READ_LE64(pField_data);
4218  pField_data += sizeof(mz_uint64);
4219  field_data_remaining -= sizeof(mz_uint64);
4220  }
4221 
4222  if (pStat->m_comp_size == MZ_UINT32_MAX)
4223  {
4224  if (field_data_remaining < sizeof(mz_uint64))
4226 
4227  pStat->m_comp_size = MZ_READ_LE64(pField_data);
4228  pField_data += sizeof(mz_uint64);
4229  field_data_remaining -= sizeof(mz_uint64);
4230  }
4231 
4232  if (pStat->m_local_header_ofs == MZ_UINT32_MAX)
4233  {
4234  if (field_data_remaining < sizeof(mz_uint64))
4236 
4237  pStat->m_local_header_ofs = MZ_READ_LE64(pField_data);
4238  pField_data += sizeof(mz_uint64);
4239  field_data_remaining -= sizeof(mz_uint64);
4240  }
4241 
4242  break;
4243  }
4244 
4245  pExtra_data += sizeof(mz_uint16) * 2 + field_data_size;
4246  extra_size_remaining = extra_size_remaining - sizeof(mz_uint16) * 2 - field_data_size;
4247  } while (extra_size_remaining);
4248  }
4249  }
4250 
4251  return MZ_TRUE;
4252 }
4253 
4254 static MZ_FORCEINLINE mz_bool mz_zip_string_equal(const char *pA, const char *pB, mz_uint len, mz_uint flags)
4255 {
4256  mz_uint i;
4258  return 0 == memcmp(pA, pB, len);
4259  for (i = 0; i < len; ++i)
4260  if (MZ_TOLOWER(pA[i]) != MZ_TOLOWER(pB[i]))
4261  return MZ_FALSE;
4262  return MZ_TRUE;
4263 }
4264 
4265 static MZ_FORCEINLINE int mz_zip_filename_compare(const mz_zip_array *pCentral_dir_array, const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, const char *pR, mz_uint r_len)
4266 {
4267  const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE;
4269  mz_uint8 l = 0, r = 0;
4271  pE = pL + MZ_MIN(l_len, r_len);
4272  while (pL < pE)
4273  {
4274  if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR)))
4275  break;
4276  pL++;
4277  pR++;
4278  }
4279  return (pL == pE) ? (int)(l_len - r_len) : (l - r);
4280 }
4281 
4282 static mz_bool mz_zip_locate_file_binary_search(mz_zip_archive *pZip, const char *pFilename, mz_uint32 *pIndex)
4283 {
4284  mz_zip_internal_state *pState = pZip->m_pState;
4285  const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
4286  const mz_zip_array *pCentral_dir = &pState->m_central_dir;
4288  const uint32_t size = pZip->m_total_files;
4289  const mz_uint filename_len = (mz_uint)strlen(pFilename);
4290 
4291  if (pIndex)
4292  *pIndex = 0;
4293 
4294  if (size)
4295  {
4296  /* yes I could use uint32_t's, but then we would have to add some special case checks in the loop, argh, and */
4297  /* honestly the major expense here on 32-bit CPU's will still be the filename compare */
4298  mz_int64 l = 0, h = (mz_int64)size - 1;
4299 
4300  while (l <= h)
4301  {
4302  mz_int64 m = l + ((h - l) >> 1);
4303  uint32_t file_index = pIndices[(uint32_t)m];
4304 
4305  int comp = mz_zip_filename_compare(pCentral_dir, pCentral_dir_offsets, file_index, pFilename, filename_len);
4306  if (!comp)
4307  {
4308  if (pIndex)
4309  *pIndex = file_index;
4310  return MZ_TRUE;
4311  }
4312  else if (comp < 0)
4313  l = m + 1;
4314  else
4315  h = m - 1;
4316  }
4317  }
4318 
4320 }
4321 
4322 int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags)
4323 {
4324  mz_uint32 index;
4325  if (!mz_zip_reader_locate_file_v2(pZip, pName, pComment, flags, &index))
4326  return -1;
4327  else
4328  return (int)index;
4329 }
4330 
4331 mz_bool mz_zip_reader_locate_file_v2(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags, mz_uint32 *pIndex)
4332 {
4333  mz_uint file_index;
4334  size_t name_len, comment_len;
4335 
4336  if (pIndex)
4337  *pIndex = 0;
4338 
4339  if ((!pZip) || (!pZip->m_pState) || (!pName))
4341 
4342  /* See if we can use a binary search */
4344  (pZip->m_zip_mode == MZ_ZIP_MODE_READING) &&
4346  {
4347  return mz_zip_locate_file_binary_search(pZip, pName, pIndex);
4348  }
4349 
4350  /* Locate the entry by scanning the entire central directory */
4351  name_len = strlen(pName);
4352  if (name_len > MZ_UINT16_MAX)
4354 
4355  comment_len = pComment ? strlen(pComment) : 0;
4356  if (comment_len > MZ_UINT16_MAX)
4358 
4359  for (file_index = 0; file_index < pZip->m_total_files; file_index++)
4360  {
4362  mz_uint filename_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_FILENAME_LEN_OFS);
4363  const char *pFilename = (const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
4364  if (filename_len < name_len)
4365  continue;
4366  if (comment_len)
4367  {
4368  mz_uint file_extra_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_EXTRA_LEN_OFS), file_comment_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_COMMENT_LEN_OFS);
4369  const char *pFile_comment = pFilename + filename_len + file_extra_len;
4370  if ((file_comment_len != comment_len) || (!mz_zip_string_equal(pComment, pFile_comment, file_comment_len, flags)))
4371  continue;
4372  }
4373  if ((flags & MZ_ZIP_FLAG_IGNORE_PATH) && (filename_len))
4374  {
4375  int ofs = filename_len - 1;
4376  do
4377  {
4378  if ((pFilename[ofs] == '/') || (pFilename[ofs] == '\\') || (pFilename[ofs] == ':'))
4379  break;
4380  } while (--ofs >= 0);
4381  ofs++;
4382  pFilename += ofs;
4383  filename_len -= ofs;
4384  }
4385  if ((filename_len == name_len) && (mz_zip_string_equal(pName, pFilename, filename_len, flags)))
4386  {
4387  if (pIndex)
4388  *pIndex = file_index;
4389  return MZ_TRUE;
4390  }
4391  }
4392 
4394 }
4395 
4396 mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size)
4397 {
4398  int status = TINFL_STATUS_DONE;
4399  mz_uint64 needed_size, cur_file_ofs, comp_remaining, out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail;
4400  mz_zip_archive_file_stat file_stat;
4401  void *pRead_buf;
4402  mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
4403  mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
4404  tinfl_decompressor inflator;
4405 
4406  if ((!pZip) || (!pZip->m_pState) || ((buf_size) && (!pBuf)) || ((user_read_buf_size) && (!pUser_read_buf)) || (!pZip->m_pRead))
4408 
4409  if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
4410  return MZ_FALSE;
4411 
4412  /* A directory or zero length file */
4413  if ((file_stat.m_is_directory) || (!file_stat.m_comp_size))
4414  return MZ_TRUE;
4415 
4416  /* Encryption and patch files are not supported. */
4419 
4420  /* This function only supports decompressing stored and deflate. */
4421  if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
4423 
4424  /* Ensure supplied output buffer is large enough. */
4425  needed_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size : file_stat.m_uncomp_size;
4426  if (buf_size < needed_size)
4427  return mz_zip_set_error(pZip, MZ_ZIP_BUF_TOO_SMALL);
4428 
4429  /* Read and parse the local directory entry. */
4430  cur_file_ofs = file_stat.m_local_header_ofs;
4431  if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
4433 
4434  if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
4436 
4438  if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
4440 
4441  if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method))
4442  {
4443  /* The file is stored or the caller has requested the compressed data. */
4444  if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, (size_t)needed_size) != needed_size)
4446 
4447 #ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4448  if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) == 0)
4449  {
4450  if (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32)
4452  }
4453 #endif
4454 
4455  return MZ_TRUE;
4456  }
4457 
4458  /* Decompress the file either directly from memory or from a file input buffer. */
4459  tinfl_init(&inflator);
4460 
4461  if (pZip->m_pState->m_pMem)
4462  {
4463  /* Read directly from the archive in memory. */
4464  pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
4465  read_buf_size = read_buf_avail = file_stat.m_comp_size;
4466  comp_remaining = 0;
4467  }
4468  else if (pUser_read_buf)
4469  {
4470  /* Use a user provided read buffer. */
4471  if (!user_read_buf_size)
4472  return MZ_FALSE;
4473  pRead_buf = (mz_uint8 *)pUser_read_buf;
4474  read_buf_size = user_read_buf_size;
4475  read_buf_avail = 0;
4476  comp_remaining = file_stat.m_comp_size;
4477  }
4478  else
4479  {
4480  /* Temporarily allocate a read buffer. */
4481  read_buf_size = MZ_MIN(file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
4482  if (((sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
4484 
4485  if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size)))
4486  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
4487 
4488  read_buf_avail = 0;
4489  comp_remaining = file_stat.m_comp_size;
4490  }
4491 
4492  do
4493  {
4494  /* The size_t cast here should be OK because we've verified that the output buffer is >= file_stat.m_uncomp_size above */
4495  size_t in_buf_size, out_buf_size = (size_t)(file_stat.m_uncomp_size - out_buf_ofs);
4496  if ((!read_buf_avail) && (!pZip->m_pState->m_pMem))
4497  {
4498  read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
4499  if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
4500  {
4501  status = TINFL_STATUS_FAILED;
4503  break;
4504  }
4505  cur_file_ofs += read_buf_avail;
4506  comp_remaining -= read_buf_avail;
4507  read_buf_ofs = 0;
4508  }
4509  in_buf_size = (size_t)read_buf_avail;
4510  status = tinfl_decompress(&inflator, (mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pBuf, (mz_uint8 *)pBuf + out_buf_ofs, &out_buf_size, TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF | (comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0));
4511  read_buf_avail -= in_buf_size;
4512  read_buf_ofs += in_buf_size;
4513  out_buf_ofs += out_buf_size;
4514  } while (status == TINFL_STATUS_NEEDS_MORE_INPUT);
4515 
4516  if (status == TINFL_STATUS_DONE)
4517  {
4518  /* Make sure the entire file was decompressed, and check its CRC. */
4519  if (out_buf_ofs != file_stat.m_uncomp_size)
4520  {
4522  status = TINFL_STATUS_FAILED;
4523  }
4524 #ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4525  else if (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32)
4526  {
4528  status = TINFL_STATUS_FAILED;
4529  }
4530 #endif
4531  }
4532 
4533  if ((!pZip->m_pState->m_pMem) && (!pUser_read_buf))
4534  pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
4535 
4536  return status == TINFL_STATUS_DONE;
4537 }
4538 
4539 mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size)
4540 {
4541  mz_uint32 file_index;
4542  if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index))
4543  return MZ_FALSE;
4544  return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, pUser_read_buf, user_read_buf_size);
4545 }
4546 
4547 mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags)
4548 {
4549  return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, NULL, 0);
4550 }
4551 
4552 mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags)
4553 {
4554  return mz_zip_reader_extract_file_to_mem_no_alloc(pZip, pFilename, pBuf, buf_size, flags, NULL, 0);
4555 }
4556 
4557 void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags)
4558 {
4559  mz_uint64 comp_size, uncomp_size, alloc_size;
4560  const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
4561  void *pBuf;
4562 
4563  if (pSize)
4564  *pSize = 0;
4565 
4566  if (!p)
4567  {
4569  return NULL;
4570  }
4571 
4574 
4575  alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size;
4576  if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
4577  {
4579  return NULL;
4580  }
4581 
4582  if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size)))
4583  {
4585  return NULL;
4586  }
4587 
4588  if (!mz_zip_reader_extract_to_mem(pZip, file_index, pBuf, (size_t)alloc_size, flags))
4589  {
4590  pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
4591  return NULL;
4592  }
4593 
4594  if (pSize)
4595  *pSize = (size_t)alloc_size;
4596  return pBuf;
4597 }
4598 
4599 void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags)
4600 {
4601  mz_uint32 file_index;
4602  if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index))
4603  {
4604  if (pSize)
4605  *pSize = 0;
4606  return MZ_FALSE;
4607  }
4608  return mz_zip_reader_extract_to_heap(pZip, file_index, pSize, flags);
4609 }
4610 
4612 {
4613  int status = TINFL_STATUS_DONE;
4614 #ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4615  mz_uint file_crc32 = MZ_CRC32_INIT;
4616 #endif
4617  mz_uint64 read_buf_size, read_buf_ofs = 0, read_buf_avail, comp_remaining, out_buf_ofs = 0, cur_file_ofs;
4618  mz_zip_archive_file_stat file_stat;
4619  void *pRead_buf = NULL;
4620  void *pWrite_buf = NULL;
4621  mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
4622  mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
4623 
4624  if ((!pZip) || (!pZip->m_pState) || (!pCallback) || (!pZip->m_pRead))
4626 
4627  if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
4628  return MZ_FALSE;
4629 
4630  /* A directory or zero length file */
4631  if ((file_stat.m_is_directory) || (!file_stat.m_comp_size))
4632  return MZ_TRUE;
4633 
4634  /* Encryption and patch files are not supported. */
4637 
4638  /* This function only supports decompressing stored and deflate. */
4639  if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
4641 
4642  /* Read and do some minimal validation of the local directory entry (this doesn't crack the zip64 stuff, which we already have from the central dir) */
4643  cur_file_ofs = file_stat.m_local_header_ofs;
4644  if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
4646 
4647  if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
4649 
4651  if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
4653 
4654  /* Decompress the file either directly from memory or from a file input buffer. */
4655  if (pZip->m_pState->m_pMem)
4656  {
4657  pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
4658  read_buf_size = read_buf_avail = file_stat.m_comp_size;
4659  comp_remaining = 0;
4660  }
4661  else
4662  {
4663  read_buf_size = MZ_MIN(file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
4664  if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size)))
4665  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
4666 
4667  read_buf_avail = 0;
4668  comp_remaining = file_stat.m_comp_size;
4669  }
4670 
4671  if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method))
4672  {
4673  /* The file is stored or the caller has requested the compressed data. */
4674  if (pZip->m_pState->m_pMem)
4675  {
4676  if (((sizeof(size_t) == sizeof(mz_uint32))) && (file_stat.m_comp_size > MZ_UINT32_MAX))
4678 
4679  if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)file_stat.m_comp_size) != file_stat.m_comp_size)
4680  {
4682  status = TINFL_STATUS_FAILED;
4683  }
4684  else if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
4685  {
4686 #ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4687  file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)file_stat.m_comp_size);
4688 #endif
4689  }
4690 
4691  cur_file_ofs += file_stat.m_comp_size;
4692  out_buf_ofs += file_stat.m_comp_size;
4693  comp_remaining = 0;
4694  }
4695  else
4696  {
4697  while (comp_remaining)
4698  {
4699  read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
4700  if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
4701  {
4703  status = TINFL_STATUS_FAILED;
4704  break;
4705  }
4706 
4707 #ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4709  {
4710  file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)read_buf_avail);
4711  }
4712 #endif
4713 
4714  if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
4715  {
4717  status = TINFL_STATUS_FAILED;
4718  break;
4719  }
4720 
4721  cur_file_ofs += read_buf_avail;
4722  out_buf_ofs += read_buf_avail;
4723  comp_remaining -= read_buf_avail;
4724  }
4725  }
4726  }
4727  else
4728  {
4729  tinfl_decompressor inflator;
4730  tinfl_init(&inflator);
4731 
4732  if (NULL == (pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, TINFL_LZ_DICT_SIZE)))
4733  {
4735  status = TINFL_STATUS_FAILED;
4736  }
4737  else
4738  {
4739  do
4740  {
4741  mz_uint8 *pWrite_buf_cur = (mz_uint8 *)pWrite_buf + (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
4742  size_t in_buf_size, out_buf_size = TINFL_LZ_DICT_SIZE - (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
4743  if ((!read_buf_avail) && (!pZip->m_pState->m_pMem))
4744  {
4745  read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
4746  if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
4747  {
4749  status = TINFL_STATUS_FAILED;
4750  break;
4751  }
4752  cur_file_ofs += read_buf_avail;
4753  comp_remaining -= read_buf_avail;
4754  read_buf_ofs = 0;
4755  }
4756 
4757  in_buf_size = (size_t)read_buf_avail;
4758  status = tinfl_decompress(&inflator, (const mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pWrite_buf, pWrite_buf_cur, &out_buf_size, comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0);
4759  read_buf_avail -= in_buf_size;
4760  read_buf_ofs += in_buf_size;
4761 
4762  if (out_buf_size)
4763  {
4764  if (pCallback(pOpaque, out_buf_ofs, pWrite_buf_cur, out_buf_size) != out_buf_size)
4765  {
4767  status = TINFL_STATUS_FAILED;
4768  break;
4769  }
4770 
4771 #ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4772  file_crc32 = (mz_uint32)mz_crc32(file_crc32, pWrite_buf_cur, out_buf_size);
4773 #endif
4774  if ((out_buf_ofs += out_buf_size) > file_stat.m_uncomp_size)
4775  {
4777  status = TINFL_STATUS_FAILED;
4778  break;
4779  }
4780  }
4781  } while ((status == TINFL_STATUS_NEEDS_MORE_INPUT) || (status == TINFL_STATUS_HAS_MORE_OUTPUT));
4782  }
4783  }
4784 
4785  if ((status == TINFL_STATUS_DONE) && (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)))
4786  {
4787  /* Make sure the entire file was decompressed, and check its CRC. */
4788  if (out_buf_ofs != file_stat.m_uncomp_size)
4789  {
4791  status = TINFL_STATUS_FAILED;
4792  }
4793 #ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4794  else if (file_crc32 != file_stat.m_crc32)
4795  {
4797  status = TINFL_STATUS_FAILED;
4798  }
4799 #endif
4800  }
4801 
4802  if (!pZip->m_pState->m_pMem)
4803  pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
4804 
4805  if (pWrite_buf)
4806  pZip->m_pFree(pZip->m_pAlloc_opaque, pWrite_buf);
4807 
4808  return status == TINFL_STATUS_DONE;
4809 }
4810 
4811 mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags)
4812 {
4813  mz_uint32 file_index;
4814  if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL,