CBMC
miniz.cpp
Go to the documentation of this file.
1 /**************************************************************************
2  *
3  * Copyright 2013-2014 RAD Game Tools and Valve Software
4  * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
5  * All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  *
25  **************************************************************************/
26 
27 #ifdef _MSC_VER
28 // conversion warnings
29 #pragma warning(disable:4242)
30 // possible loss of data
31 #pragma warning(disable:4244)
32 // possible loss of data
33 #pragma warning(disable:4365)
34 // signed/unsigned mismatch
35 #pragma warning(disable:4548)
36 // expression before comma has no effect
37 #pragma warning(disable:4061)
38 // enum case is not handled in switch
39 #pragma warning(disable:4334)
40 // result of 32-bit shift implicitly converted to 64 bits
41 #pragma warning(disable:5039)
42 // pointer or reference to potentially throwing function passed to extern C
43 #endif
44 
45 #include "miniz.h"
46 
47 typedef unsigned char mz_validate_uint16[sizeof(mz_uint16) == 2 ? 1 : -1];
48 typedef unsigned char mz_validate_uint32[sizeof(mz_uint32) == 4 ? 1 : -1];
49 typedef unsigned char mz_validate_uint64[sizeof(mz_uint64) == 8 ? 1 : -1];
50 
51 #ifdef __cplusplus
52 extern "C" {
53 #endif
54 
55 /* ------------------- zlib-style API's */
56 
57 mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len)
58 {
59  mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16);
60  size_t block_len = buf_len % 5552;
61  if(!ptr)
62  return MZ_ADLER32_INIT;
63  while(buf_len)
64  {
65  for(i = 0; i + 7 < block_len; i += 8, ptr += 8)
66  {
67  s1 += ptr[0], s2 += s1;
68  s1 += ptr[1], s2 += s1;
69  s1 += ptr[2], s2 += s1;
70  s1 += ptr[3], s2 += s1;
71  s1 += ptr[4], s2 += s1;
72  s1 += ptr[5], s2 += s1;
73  s1 += ptr[6], s2 += s1;
74  s1 += ptr[7], s2 += s1;
75  }
76  for(; i < block_len; ++i)
77  s1 += *ptr++, s2 += s1;
78  s1 %= 65521U, s2 %= 65521U;
79  buf_len -= block_len;
80  block_len = 5552;
81  }
82  return (s2 << 16) + s1;
83 }
84 
85 /* 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/ */
86 #if 0
87  mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
88  {
89  static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
90  0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c };
91  mz_uint32 crcu32 = (mz_uint32)crc;
92  if(!ptr)
93  return MZ_CRC32_INIT;
94  crcu32 = ~crcu32;
95  while(buf_len--)
96  {
97  mz_uint8 b = *ptr++;
98  crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)];
99  crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)];
100  }
101  return ~crcu32;
102  }
103 #else
104 /* Faster, but larger CPU cache footprint.
105  */
106 mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
107 {
108  static const mz_uint32 s_crc_table[256] =
109  {
110  0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535,
111  0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
112  0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D,
113  0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
114  0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4,
115  0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
116  0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC,
117  0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
118  0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB,
119  0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
120  0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB,
121  0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
122  0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA,
123  0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE,
124  0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A,
125  0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
126  0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409,
127  0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
128  0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739,
129  0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
130  0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268,
131  0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0,
132  0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8,
133  0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
134  0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF,
135  0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
136  0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7,
137  0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
138  0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE,
139  0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
140  0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6,
141  0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
142  0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D,
143  0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
144  0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605,
145  0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
146  0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
147  };
148 
149  mz_uint32 crc32 = (mz_uint32)crc ^ 0xFFFFFFFF;
150  const mz_uint8 *pByte_buf = (const mz_uint8 *)ptr;
151 
152  while(buf_len >= 4)
153  {
154  crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF];
155  crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[1]) & 0xFF];
156  crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[2]) & 0xFF];
157  crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[3]) & 0xFF];
158  pByte_buf += 4;
159  buf_len -= 4;
160  }
161 
162  while(buf_len)
163  {
164  crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF];
165  ++pByte_buf;
166  --buf_len;
167  }
168 
169  return ~crc32;
170 }
171 #endif
172 
173 void mz_free(void *p)
174 {
175  MZ_FREE(p);
176 }
177 
178 #ifndef MINIZ_NO_ZLIB_APIS
179 
180 void *miniz_def_alloc_func(void *opaque, size_t items, size_t size)
181 {
182  (void)opaque, (void)items, (void)size;
183  return MZ_MALLOC(items * size);
184 }
185 void miniz_def_free_func(void *opaque, void *address)
186 {
187  (void)opaque, (void)address;
188  MZ_FREE(address);
189 }
190 void *miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size)
191 {
192  (void)opaque, (void)address, (void)items, (void)size;
193  return MZ_REALLOC(address, items * size);
194 }
195 
196 const char *mz_version(void)
197 {
198  return MZ_VERSION;
199 }
200 
201 int mz_deflateInit(mz_streamp pStream, int level)
202 {
204 }
205 
206 int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy)
207 {
208  tdefl_compressor *pComp;
209  mz_uint comp_flags = TDEFL_COMPUTE_ADLER32 | tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy);
210 
211  if(!pStream)
212  return MZ_STREAM_ERROR;
213  if((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) || ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)))
214  return MZ_PARAM_ERROR;
215 
216  pStream->data_type = 0;
217  pStream->adler = MZ_ADLER32_INIT;
218  pStream->msg = NULL;
219  pStream->reserved = 0;
220  pStream->total_in = 0;
221  pStream->total_out = 0;
222  if(!pStream->zalloc)
223  pStream->zalloc = miniz_def_alloc_func;
224  if(!pStream->zfree)
225  pStream->zfree = miniz_def_free_func;
226 
227  pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, sizeof(tdefl_compressor));
228  if(!pComp)
229  return MZ_MEM_ERROR;
230 
231  pStream->state = (struct mz_internal_state *)pComp;
232 
233  if(tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY)
234  {
235  mz_deflateEnd(pStream);
236  return MZ_PARAM_ERROR;
237  }
238 
239  return MZ_OK;
240 }
241 
243 {
244  if((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree))
245  return MZ_STREAM_ERROR;
246  pStream->total_in = pStream->total_out = 0;
247  tdefl_init((tdefl_compressor *)pStream->state, NULL, NULL, ((tdefl_compressor *)pStream->state)->m_flags);
248  return MZ_OK;
249 }
250 
251 int mz_deflate(mz_streamp pStream, int flush)
252 {
253  size_t in_bytes, out_bytes;
254  mz_ulong orig_total_in, orig_total_out;
255  int mz_status = MZ_OK;
256 
257  if((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || (!pStream->next_out))
258  return MZ_STREAM_ERROR;
259  if(!pStream->avail_out)
260  return MZ_BUF_ERROR;
261 
262  if(flush == MZ_PARTIAL_FLUSH)
263  flush = MZ_SYNC_FLUSH;
264 
265  if(((tdefl_compressor *)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE)
266  return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR;
267 
268  orig_total_in = pStream->total_in;
269  orig_total_out = pStream->total_out;
270  for(;;)
271  {
272  tdefl_status defl_status;
273  in_bytes = pStream->avail_in;
274  out_bytes = pStream->avail_out;
275 
276  defl_status = tdefl_compress((tdefl_compressor *)pStream->state, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, (tdefl_flush)flush);
277  pStream->next_in += (mz_uint)in_bytes;
278  pStream->avail_in -= (mz_uint)in_bytes;
279  pStream->total_in += (mz_uint)in_bytes;
280  pStream->adler = tdefl_get_adler32((tdefl_compressor *)pStream->state);
281 
282  pStream->next_out += (mz_uint)out_bytes;
283  pStream->avail_out -= (mz_uint)out_bytes;
284  pStream->total_out += (mz_uint)out_bytes;
285 
286  if(defl_status < 0)
287  {
288  mz_status = MZ_STREAM_ERROR;
289  break;
290  }
291  else if(defl_status == TDEFL_STATUS_DONE)
292  {
293  mz_status = MZ_STREAM_END;
294  break;
295  }
296  else if(!pStream->avail_out)
297  break;
298  else if((!pStream->avail_in) && (flush != MZ_FINISH))
299  {
300  if((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out))
301  break;
302  return MZ_BUF_ERROR; /* Can't make forward progress without some input.
303  */
304  }
305  }
306  return mz_status;
307 }
308 
310 {
311  if(!pStream)
312  return MZ_STREAM_ERROR;
313  if(pStream->state)
314  {
315  pStream->zfree(pStream->opaque, pStream->state);
316  pStream->state = NULL;
317  }
318  return MZ_OK;
319 }
320 
322 {
323  (void)pStream;
324  /* 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.) */
325  return MZ_MAX(128 + (source_len * 110) / 100, 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5);
326 }
327 
328 int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level)
329 {
330  int status;
331  mz_stream stream;
332  memset(&stream, 0, sizeof(stream));
333 
334  /* In case mz_ulong is 64-bits (argh I hate longs). */
335  if((source_len | *pDest_len) > 0xFFFFFFFFU)
336  return MZ_PARAM_ERROR;
337 
338  stream.next_in = pSource;
339  stream.avail_in = (mz_uint32)source_len;
340  stream.next_out = pDest;
341  stream.avail_out = (mz_uint32) * pDest_len;
342 
343  status = mz_deflateInit(&stream, level);
344  if(status != MZ_OK)
345  return status;
346 
347  status = mz_deflate(&stream, MZ_FINISH);
348  if(status != MZ_STREAM_END)
349  {
350  mz_deflateEnd(&stream);
351  return (status == MZ_OK) ? MZ_BUF_ERROR : status;
352  }
353 
354  *pDest_len = stream.total_out;
355  return mz_deflateEnd(&stream);
356 }
357 
358 int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
359 {
360  return mz_compress2(pDest, pDest_len, pSource, source_len, MZ_DEFAULT_COMPRESSION);
361 }
362 
364 {
365  return mz_deflateBound(NULL, source_len);
366 }
367 
368 typedef struct
369 {
371  mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed;
375 } inflate_state;
376 
377 int mz_inflateInit2(mz_streamp pStream, int window_bits)
378 {
379  inflate_state *pDecomp;
380  if(!pStream)
381  return MZ_STREAM_ERROR;
382  if((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS))
383  return MZ_PARAM_ERROR;
384 
385  pStream->data_type = 0;
386  pStream->adler = 0;
387  pStream->msg = NULL;
388  pStream->total_in = 0;
389  pStream->total_out = 0;
390  pStream->reserved = 0;
391  if(!pStream->zalloc)
392  pStream->zalloc = miniz_def_alloc_func;
393  if(!pStream->zfree)
394  pStream->zfree = miniz_def_free_func;
395 
396  pDecomp = (inflate_state *)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state));
397  if(!pDecomp)
398  return MZ_MEM_ERROR;
399 
400  pStream->state = (struct mz_internal_state *)pDecomp;
401 
402  tinfl_init(&pDecomp->m_decomp);
403  pDecomp->m_dict_ofs = 0;
404  pDecomp->m_dict_avail = 0;
406  pDecomp->m_first_call = 1;
407  pDecomp->m_has_flushed = 0;
408  pDecomp->m_window_bits = window_bits;
409 
410  return MZ_OK;
411 }
412 
414 {
415  return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS);
416 }
417 
418 int mz_inflate(mz_streamp pStream, int flush)
419 {
420  inflate_state *pState;
421  mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32;
422  size_t in_bytes, out_bytes, orig_avail_in;
423  tinfl_status status;
424 
425  if((!pStream) || (!pStream->state))
426  return MZ_STREAM_ERROR;
427  if(flush == MZ_PARTIAL_FLUSH)
428  flush = MZ_SYNC_FLUSH;
429  if((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH))
430  return MZ_STREAM_ERROR;
431 
432  pState = (inflate_state *)pStream->state;
433  if(pState->m_window_bits > 0)
434  decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER;
435  orig_avail_in = pStream->avail_in;
436 
437  first_call = pState->m_first_call;
438  pState->m_first_call = 0;
439  if(pState->m_last_status < 0)
440  return MZ_DATA_ERROR;
441 
442  if(pState->m_has_flushed && (flush != MZ_FINISH))
443  return MZ_STREAM_ERROR;
444  pState->m_has_flushed |= (flush == MZ_FINISH);
445 
446  if((flush == MZ_FINISH) && (first_call))
447  {
448  /* MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file. */
450  in_bytes = pStream->avail_in;
451  out_bytes = pStream->avail_out;
452  status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags);
453  pState->m_last_status = status;
454  pStream->next_in += (mz_uint)in_bytes;
455  pStream->avail_in -= (mz_uint)in_bytes;
456  pStream->total_in += (mz_uint)in_bytes;
457  pStream->adler = tinfl_get_adler32(&pState->m_decomp);
458  pStream->next_out += (mz_uint)out_bytes;
459  pStream->avail_out -= (mz_uint)out_bytes;
460  pStream->total_out += (mz_uint)out_bytes;
461 
462  if(status < 0)
463  return MZ_DATA_ERROR;
464  else if(status != TINFL_STATUS_DONE)
465  {
467  return MZ_BUF_ERROR;
468  }
469  return MZ_STREAM_END;
470  }
471  /* flush != MZ_FINISH then we must assume there's more input. */
472  if(flush != MZ_FINISH)
473  decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT;
474 
475  if(pState->m_dict_avail)
476  {
477  n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
478  memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
479  pStream->next_out += n;
480  pStream->avail_out -= n;
481  pStream->total_out += n;
482  pState->m_dict_avail -= n;
483  pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
484  return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
485  }
486 
487  for(;;)
488  {
489  in_bytes = pStream->avail_in;
490  out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs;
491 
492  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);
493  pState->m_last_status = status;
494 
495  pStream->next_in += (mz_uint)in_bytes;
496  pStream->avail_in -= (mz_uint)in_bytes;
497  pStream->total_in += (mz_uint)in_bytes;
498  pStream->adler = tinfl_get_adler32(&pState->m_decomp);
499 
500  pState->m_dict_avail = (mz_uint)out_bytes;
501 
502  n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
503  memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
504  pStream->next_out += n;
505  pStream->avail_out -= n;
506  pStream->total_out += n;
507  pState->m_dict_avail -= n;
508  pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
509 
510  if(status < 0)
511  return MZ_DATA_ERROR; /* Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well). */
512  else if((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in))
513  return MZ_BUF_ERROR; /* Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH. */
514  else if(flush == MZ_FINISH)
515  {
516  /* The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH. */
517  if(status == TINFL_STATUS_DONE)
518  return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END;
519  /* 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. */
520  else if(!pStream->avail_out)
521  return MZ_BUF_ERROR;
522  }
523  else if((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail))
524  break;
525  }
526 
527  return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
528 }
529 
531 {
532  if(!pStream)
533  return MZ_STREAM_ERROR;
534  if(pStream->state)
535  {
536  pStream->zfree(pStream->opaque, pStream->state);
537  pStream->state = NULL;
538  }
539  return MZ_OK;
540 }
541 
542 int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
543 {
544  mz_stream stream;
545  int status;
546  memset(&stream, 0, sizeof(stream));
547 
548  /* In case mz_ulong is 64-bits (argh I hate longs). */
549  if((source_len | *pDest_len) > 0xFFFFFFFFU)
550  return MZ_PARAM_ERROR;
551 
552  stream.next_in = pSource;
553  stream.avail_in = (mz_uint32)source_len;
554  stream.next_out = pDest;
555  stream.avail_out = (mz_uint32) * pDest_len;
556 
557  status = mz_inflateInit(&stream);
558  if(status != MZ_OK)
559  return status;
560 
561  status = mz_inflate(&stream, MZ_FINISH);
562  if(status != MZ_STREAM_END)
563  {
564  mz_inflateEnd(&stream);
565  return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status;
566  }
567  *pDest_len = stream.total_out;
568 
569  return mz_inflateEnd(&stream);
570 }
571 
572 const char *mz_error(int err)
573 {
574  static struct
575  {
576  int m_err;
577  const char *m_pDesc;
578  } s_error_descs[] =
579  {
580  { MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" },
581  { 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" }
582  };
583  mz_uint i;
584  for(i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i)
585  if(s_error_descs[i].m_err == err)
586  return s_error_descs[i].m_pDesc;
587  return NULL;
588 }
589 
590 #endif /*MINIZ_NO_ZLIB_APIS */
591 
592 #ifdef __cplusplus
593 }
594 #endif
595 
596 /*
597  This is free and unencumbered software released into the public domain.
598 
599  Anyone is free to copy, modify, publish, use, compile, sell, or
600  distribute this software, either in source code form or as a compiled
601  binary, for any purpose, commercial or non-commercial, and by any
602  means.
603 
604  In jurisdictions that recognize copyright laws, the author or authors
605  of this software dedicate any and all copyright interest in the
606  software to the public domain. We make this dedication for the benefit
607  of the public at large and to the detriment of our heirs and
608  successors. We intend this dedication to be an overt act of
609  relinquishment in perpetuity of all present and future rights to this
610  software under copyright law.
611 
612  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
613  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
614  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
615  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
616  OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
617  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
618  OTHER DEALINGS IN THE SOFTWARE.
619 
620  For more information, please refer to <http://unlicense.org/>
621 */
622 /**************************************************************************
623  *
624  * Copyright 2013-2014 RAD Game Tools and Valve Software
625  * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
626  * All Rights Reserved.
627  *
628  * Permission is hereby granted, free of charge, to any person obtaining a copy
629  * of this software and associated documentation files (the "Software"), to deal
630  * in the Software without restriction, including without limitation the rights
631  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
632  * copies of the Software, and to permit persons to whom the Software is
633  * furnished to do so, subject to the following conditions:
634  *
635  * The above copyright notice and this permission notice shall be included in
636  * all copies or substantial portions of the Software.
637  *
638  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
639  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
640  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
641  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
642  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
643  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
644  * THE SOFTWARE.
645  *
646  **************************************************************************/
647 
648 
649 
650 
651 #ifdef __cplusplus
652 extern "C" {
653 #endif
654 
655 /* ------------------- Low-level Compression (independent from all decompression API's) */
656 
657 /* Purposely making these tables static for faster init and thread safety. */
658 static const mz_uint16 s_tdefl_len_sym[256] =
659  {
660  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,
661  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,
662  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,
663  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,
664  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,
665  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,
666  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,
667  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
668  };
669 
670 static const mz_uint8 s_tdefl_len_extra[256] =
671  {
672  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,
673  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,
674  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,
675  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
676  };
677 
678 static const mz_uint8 s_tdefl_small_dist_sym[512] =
679  {
680  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,
681  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,
682  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,
683  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,
684  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,
685  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,
686  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,
687  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,
688  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,
689  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,
690  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,
691  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
692  };
693 
695  {
696  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,
697  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,
698  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,
699  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,
700  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,
701  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,
702  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,
703  7, 7, 7, 7, 7, 7, 7, 7
704  };
705 
706 static const mz_uint8 s_tdefl_large_dist_sym[128] =
707  {
708  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,
709  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,
710  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
711  };
712 
714  {
715  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,
716  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,
717  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
718  };
719 
720 /* Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted values. */
721 typedef struct
722 {
723  mz_uint16 m_key, m_sym_index;
726 {
727  mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2];
728  tdefl_sym_freq *pCur_syms = pSyms0, *pNew_syms = pSyms1;
729  MZ_CLEAR_OBJ(hist);
730  for(i = 0; i < num_syms; i++)
731  {
732  mz_uint freq = pSyms0[i].m_key;
733  hist[freq & 0xFF]++;
734  hist[256 + ((freq >> 8) & 0xFF)]++;
735  }
736  while((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256]))
737  total_passes--;
738  for(pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8)
739  {
740  const mz_uint32 *pHist = &hist[pass << 8];
741  mz_uint offsets[256], cur_ofs = 0;
742  for(i = 0; i < 256; i++)
743  {
744  offsets[i] = cur_ofs;
745  cur_ofs += pHist[i];
746  }
747  for(i = 0; i < num_syms; i++)
748  pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = pCur_syms[i];
749  {
750  tdefl_sym_freq *t = pCur_syms;
751  pCur_syms = pNew_syms;
752  pNew_syms = t;
753  }
754  }
755  return pCur_syms;
756 }
757 
758 /* tdefl_calculate_minimum_redundancy() originally written by: Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996. */
760 {
761  int root, leaf, next, avbl, used, dpth;
762  if(n == 0)
763  return;
764  else if(n == 1)
765  {
766  A[0].m_key = 1;
767  return;
768  }
769  A[0].m_key += A[1].m_key;
770  root = 0;
771  leaf = 2;
772  for(next = 1; next < n - 1; next++)
773  {
774  if(leaf >= n || A[root].m_key < A[leaf].m_key)
775  {
776  A[next].m_key = A[root].m_key;
777  A[root++].m_key = (mz_uint16)next;
778  }
779  else
780  A[next].m_key = A[leaf++].m_key;
781  if(leaf >= n || (root < next && A[root].m_key < A[leaf].m_key))
782  {
783  A[next].m_key = (mz_uint16)(A[next].m_key + A[root].m_key);
784  A[root++].m_key = (mz_uint16)next;
785  }
786  else
787  A[next].m_key = (mz_uint16)(A[next].m_key + A[leaf++].m_key);
788  }
789  A[n - 2].m_key = 0;
790  for(next = n - 3; next >= 0; next--)
791  A[next].m_key = A[A[next].m_key].m_key + 1;
792  avbl = 1;
793  used = dpth = 0;
794  root = n - 2;
795  next = n - 1;
796  while(avbl > 0)
797  {
798  while(root >= 0 && (int)A[root].m_key == dpth)
799  {
800  used++;
801  root--;
802  }
803  while(avbl > used)
804  {
805  A[next--].m_key = (mz_uint16)(dpth);
806  avbl--;
807  }
808  avbl = 2 * used;
809  dpth++;
810  used = 0;
811  }
812 }
813 
814 /* Limits canonical Huffman code table's max code size. */
815 enum
816 {
818 };
819 static void tdefl_huffman_enforce_max_code_size(int *pNum_codes, int code_list_len, int max_code_size)
820 {
821  int i;
822  mz_uint32 total = 0;
823  if(code_list_len <= 1)
824  return;
825  for(i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++)
826  pNum_codes[max_code_size] += pNum_codes[i];
827  for(i = max_code_size; i > 0; i--)
828  total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i));
829  while(total != (1UL << max_code_size))
830  {
831  pNum_codes[max_code_size]--;
832  for(i = max_code_size - 1; i > 0; i--)
833  if(pNum_codes[i])
834  {
835  pNum_codes[i]--;
836  pNum_codes[i + 1] += 2;
837  break;
838  }
839  total--;
840  }
841 }
842 
843 static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int table_len, int code_size_limit, int static_table)
844 {
845  int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE];
847  MZ_CLEAR_OBJ(num_codes);
848  if(static_table)
849  {
850  for(i = 0; i < table_len; i++)
851  num_codes[d->m_huff_code_sizes[table_num][i]]++;
852  }
853  else
854  {
856  int num_used_syms = 0;
857  const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0];
858  for(i = 0; i < table_len; i++)
859  if(pSym_count[i])
860  {
861  syms0[num_used_syms].m_key = (mz_uint16)pSym_count[i];
862  syms0[num_used_syms++].m_sym_index = (mz_uint16)i;
863  }
864 
865  pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1);
866  tdefl_calculate_minimum_redundancy(pSyms, num_used_syms);
867 
868  for(i = 0; i < num_used_syms; i++)
869  num_codes[pSyms[i].m_key]++;
870 
871  tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, code_size_limit);
872 
873  MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]);
874  MZ_CLEAR_OBJ(d->m_huff_codes[table_num]);
875  for(i = 1, j = num_used_syms; i <= code_size_limit; i++)
876  for(l = num_codes[i]; l > 0; l--)
877  d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i);
878  }
879 
880  next_code[1] = 0;
881  for(j = 0, i = 2; i <= code_size_limit; i++)
882  next_code[i] = j = ((j + num_codes[i - 1]) << 1);
883 
884  for(i = 0; i < table_len; i++)
885  {
886  mz_uint rev_code = 0, code, code_size;
887  if((code_size = d->m_huff_code_sizes[table_num][i]) == 0)
888  continue;
889  code = next_code[code_size]++;
890  for(l = code_size; l > 0; l--, code >>= 1)
891  rev_code = (rev_code << 1) | (code & 1);
892  d->m_huff_codes[table_num][i] = (mz_uint16)rev_code;
893  }
894 }
895 
896 #define TDEFL_PUT_BITS(b, l) \
897  do \
898  { \
899  mz_uint bits = b; \
900  mz_uint len = l; \
901  MZ_ASSERT(bits <= ((1U << len) - 1U)); \
902  d->m_bit_buffer |= (bits << d->m_bits_in); \
903  d->m_bits_in += len; \
904  while(d->m_bits_in >= 8) \
905  { \
906  if(d->m_pOutput_buf < d->m_pOutput_buf_end) \
907  *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \
908  d->m_bit_buffer >>= 8; \
909  d->m_bits_in -= 8; \
910  } \
911  } \
912  MZ_MACRO_END
913 
914 #define TDEFL_RLE_PREV_CODE_SIZE() \
915  { \
916  if(rle_repeat_count) \
917  { \
918  if(rle_repeat_count < 3) \
919  { \
920  d->m_huff_count[2][prev_code_size] = (mz_uint16)(d->m_huff_count[2][prev_code_size] + rle_repeat_count); \
921  while(rle_repeat_count--) \
922  packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \
923  } \
924  else \
925  { \
926  d->m_huff_count[2][16] = (mz_uint16)(d->m_huff_count[2][16] + 1); \
927  packed_code_sizes[num_packed_code_sizes++] = 16; \
928  packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_repeat_count - 3); \
929  } \
930  rle_repeat_count = 0; \
931  } \
932  }
933 
934 #define TDEFL_RLE_ZERO_CODE_SIZE() \
935  { \
936  if(rle_z_count) \
937  { \
938  if(rle_z_count < 3) \
939  { \
940  d->m_huff_count[2][0] = (mz_uint16)(d->m_huff_count[2][0] + rle_z_count); \
941  while(rle_z_count--) \
942  packed_code_sizes[num_packed_code_sizes++] = 0; \
943  } \
944  else if(rle_z_count <= 10) \
945  { \
946  d->m_huff_count[2][17] = (mz_uint16)(d->m_huff_count[2][17] + 1); \
947  packed_code_sizes[num_packed_code_sizes++] = 17; \
948  packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 3); \
949  } \
950  else \
951  { \
952  d->m_huff_count[2][18] = (mz_uint16)(d->m_huff_count[2][18] + 1); \
953  packed_code_sizes[num_packed_code_sizes++] = 18; \
954  packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 11); \
955  } \
956  rle_z_count = 0; \
957  } \
958  }
959 
960 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 };
961 
963 {
964  int num_lit_codes, num_dist_codes, num_bit_lengths;
965  mz_uint i, total_code_sizes_to_pack, num_packed_code_sizes, rle_z_count, rle_repeat_count, packed_code_sizes_index;
966  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;
967 
968  d->m_huff_count[0][256] = 1;
969 
972 
973  for(num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--)
974  if(d->m_huff_code_sizes[0][num_lit_codes - 1])
975  break;
976  for(num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--)
977  if(d->m_huff_code_sizes[1][num_dist_codes - 1])
978  break;
979 
980  memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes);
981  memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0], num_dist_codes);
982  total_code_sizes_to_pack = num_lit_codes + num_dist_codes;
983  num_packed_code_sizes = 0;
984  rle_z_count = 0;
985  rle_repeat_count = 0;
986 
987  memset(&d->m_huff_count[2][0], 0, sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2);
988  for(i = 0; i < total_code_sizes_to_pack; i++)
989  {
990  mz_uint8 code_size = code_sizes_to_pack[i];
991  if(!code_size)
992  {
994  if(++rle_z_count == 138)
995  {
997  }
998  }
999  else
1000  {
1002  if(code_size != prev_code_size)
1003  {
1005  d->m_huff_count[2][code_size] = (mz_uint16)(d->m_huff_count[2][code_size] + 1);
1006  packed_code_sizes[num_packed_code_sizes++] = code_size;
1007  }
1008  else if(++rle_repeat_count == 6)
1009  {
1011  }
1012  }
1013  prev_code_size = code_size;
1014  }
1015  if(rle_repeat_count)
1016  {
1018  }
1019  else
1020  {
1022  }
1023 
1025 
1026  TDEFL_PUT_BITS(2, 2);
1027 
1028  TDEFL_PUT_BITS(num_lit_codes - 257, 5);
1029  TDEFL_PUT_BITS(num_dist_codes - 1, 5);
1030 
1031  for(num_bit_lengths = 18; num_bit_lengths >= 0; num_bit_lengths--)
1032  if(d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[num_bit_lengths]])
1033  break;
1034  num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1));
1035  TDEFL_PUT_BITS(num_bit_lengths - 4, 4);
1036  for(i = 0; (int)i < num_bit_lengths; i++)
1038 
1039  for(packed_code_sizes_index = 0; packed_code_sizes_index < num_packed_code_sizes;)
1040  {
1041  mz_uint code = packed_code_sizes[packed_code_sizes_index++];
1043  TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]);
1044  if(code >= 16)
1045  TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++], "\02\03\07"[code - 16]);
1046  }
1047 }
1048 
1050 {
1051  mz_uint i;
1052  mz_uint8 *p = &d->m_huff_code_sizes[0][0];
1053 
1054  for(i = 0; i <= 143; ++i)
1055  *p++ = 8;
1056  for(; i <= 255; ++i)
1057  *p++ = 9;
1058  for(; i <= 279; ++i)
1059  *p++ = 7;
1060  for(; i <= 287; ++i)
1061  *p++ = 8;
1062 
1063  memset(d->m_huff_code_sizes[1], 5, 32);
1064 
1065  tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE);
1066  tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE);
1067 
1068  TDEFL_PUT_BITS(1, 2);
1069 }
1070 
1071 static const mz_uint mz_bitmasks[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
1072 
1073 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES &&MINIZ_LITTLE_ENDIAN &&MINIZ_HAS_64BIT_REGISTERS
1075 {
1076  mz_uint flags;
1077  mz_uint8 *pLZ_codes;
1078  mz_uint8 *pOutput_buf = d->m_pOutput_buf;
1079  mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf;
1080  mz_uint64 bit_buffer = d->m_bit_buffer;
1081  mz_uint bits_in = d->m_bits_in;
1082 
1083 #define TDEFL_PUT_BITS_FAST(b, l) \
1084  { \
1085  bit_buffer |= (((mz_uint64)(b)) << bits_in); \
1086  bits_in += (l); \
1087  }
1088 
1089  flags = 1;
1090  for(pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end; flags >>= 1)
1091  {
1092  if(flags == 1)
1093  flags = *pLZ_codes++ | 0x100;
1094 
1095  if(flags & 1)
1096  {
1097  mz_uint s0, s1, n0, n1, sym, num_extra_bits;
1098  mz_uint match_len = pLZ_codes[0], match_dist = *(const mz_uint16 *)(pLZ_codes + 1);
1099  pLZ_codes += 3;
1100 
1101  MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
1102  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]]);
1103  TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]);
1104 
1105  /* This sequence coaxes MSVC into using cmov's vs. jmp's. */
1106  s0 = s_tdefl_small_dist_sym[match_dist & 511];
1107  n0 = s_tdefl_small_dist_extra[match_dist & 511];
1108  s1 = s_tdefl_large_dist_sym[match_dist >> 8];
1109  n1 = s_tdefl_large_dist_extra[match_dist >> 8];
1110  sym = (match_dist < 512) ? s0 : s1;
1111  num_extra_bits = (match_dist < 512) ? n0 : n1;
1112 
1113  MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
1114  TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
1115  TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
1116  }
1117  else
1118  {
1119  mz_uint lit = *pLZ_codes++;
1120  MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
1121  TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
1122 
1123  if(((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
1124  {
1125  flags >>= 1;
1126  lit = *pLZ_codes++;
1127  MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
1128  TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
1129 
1130  if(((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
1131  {
1132  flags >>= 1;
1133  lit = *pLZ_codes++;
1134  MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
1135  TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
1136  }
1137  }
1138  }
1139 
1140  if(pOutput_buf >= d->m_pOutput_buf_end)
1141  return MZ_FALSE;
1142 
1143  *(mz_uint64 *)pOutput_buf = bit_buffer;
1144  pOutput_buf += (bits_in >> 3);
1145  bit_buffer >>= (bits_in & ~7);
1146  bits_in &= 7;
1147  }
1148 
1149 #undef TDEFL_PUT_BITS_FAST
1150 
1151  d->m_pOutput_buf = pOutput_buf;
1152  d->m_bits_in = 0;
1153  d->m_bit_buffer = 0;
1154 
1155  while(bits_in)
1156  {
1157  mz_uint32 n = MZ_MIN(bits_in, 16);
1158  TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n);
1159  bit_buffer >>= n;
1160  bits_in -= n;
1161  }
1162 
1163  TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
1164 
1165  return (d->m_pOutput_buf < d->m_pOutput_buf_end);
1166 }
1167 #else
1169 {
1170  mz_uint flags;
1171  mz_uint8 *pLZ_codes;
1172 
1173  flags = 1;
1174  for(pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf; flags >>= 1)
1175  {
1176  if(flags == 1)
1177  flags = *pLZ_codes++ | 0x100;
1178  if(flags & 1)
1179  {
1180  mz_uint sym, num_extra_bits;
1181  mz_uint match_len = pLZ_codes[0], match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8));
1182  pLZ_codes += 3;
1183 
1184  MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
1185  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]]);
1186  TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]);
1187 
1188  if(match_dist < 512)
1189  {
1190  sym = s_tdefl_small_dist_sym[match_dist];
1191  num_extra_bits = s_tdefl_small_dist_extra[match_dist];
1192  }
1193  else
1194  {
1195  sym = s_tdefl_large_dist_sym[match_dist >> 8];
1196  num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8];
1197  }
1198  MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
1199  TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
1200  TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
1201  }
1202  else
1203  {
1204  mz_uint lit = *pLZ_codes++;
1205  MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
1206  TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
1207  }
1208  }
1209 
1210  TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
1211 
1212  return (d->m_pOutput_buf < d->m_pOutput_buf_end);
1213 }
1214 #endif /* MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS */
1215 
1217 {
1218  if(static_block)
1220  else
1222  return tdefl_compress_lz_codes(d);
1223 }
1224 
1225 static int tdefl_flush_block(tdefl_compressor *d, int flush)
1226 {
1227  mz_uint saved_bit_buf, saved_bits_in;
1228  mz_uint8 *pSaved_output_buf;
1229  mz_bool comp_block_succeeded = MZ_FALSE;
1230  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;
1231  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;
1232 
1233  d->m_pOutput_buf = pOutput_buf_start;
1235 
1237  d->m_output_flush_ofs = 0;
1238  d->m_output_flush_remaining = 0;
1239 
1240  *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left);
1241  d->m_pLZ_code_buf -= (d->m_num_flags_left == 8);
1242 
1243  if((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index))
1244  {
1245  TDEFL_PUT_BITS(0x78, 8);
1246  TDEFL_PUT_BITS(0x01, 8);
1247  }
1248 
1249  TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1);
1250 
1251  pSaved_output_buf = d->m_pOutput_buf;
1252  saved_bit_buf = d->m_bit_buffer;
1253  saved_bits_in = d->m_bits_in;
1254 
1255  if(!use_raw_block)
1256  comp_block_succeeded = tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || (d->m_total_lz_bytes < 48));
1257 
1258  /* If the block gets expanded, forget the current contents of the output buffer and send a raw block instead. */
1259  if(((use_raw_block) || ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >= d->m_total_lz_bytes))) &&
1261  {
1262  mz_uint i;
1263  d->m_pOutput_buf = pSaved_output_buf;
1264  d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
1265  TDEFL_PUT_BITS(0, 2);
1266  if(d->m_bits_in)
1267  {
1268  TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
1269  }
1270  for(i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF)
1271  {
1272  TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16);
1273  }
1274  for(i = 0; i < d->m_total_lz_bytes; ++i)
1275  {
1277  }
1278  }
1279  /* Check for the extremely unlikely (if not impossible) case of the compressed block not fitting into the output buffer when using dynamic codes. */
1280  else if(!comp_block_succeeded)
1281  {
1282  d->m_pOutput_buf = pSaved_output_buf;
1283  d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
1285  }
1286 
1287  if(flush)
1288  {
1289  if(flush == TDEFL_FINISH)
1290  {
1291  if(d->m_bits_in)
1292  {
1293  TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
1294  }
1296  {
1297  mz_uint i, a = d->m_adler32;
1298  for(i = 0; i < 4; i++)
1299  {
1300  TDEFL_PUT_BITS((a >> 24) & 0xFF, 8);
1301  a <<= 8;
1302  }
1303  }
1304  }
1305  else
1306  {
1307  mz_uint i, z = 0;
1308  TDEFL_PUT_BITS(0, 3);
1309  if(d->m_bits_in)
1310  {
1311  TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
1312  }
1313  for(i = 2; i; --i, z ^= 0xFFFF)
1314  {
1315  TDEFL_PUT_BITS(z & 0xFFFF, 16);
1316  }
1317  }
1318  }
1319 
1321 
1322  memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
1323  memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
1324 
1325  d->m_pLZ_code_buf = d->m_lz_code_buf + 1;
1326  d->m_pLZ_flags = d->m_lz_code_buf;
1327  d->m_num_flags_left = 8;
1329  d->m_total_lz_bytes = 0;
1330  d->m_block_index++;
1331 
1332  if((n = (int)(d->m_pOutput_buf - pOutput_buf_start)) != 0)
1333  {
1334  if(d->m_pPut_buf_func)
1335  {
1336  *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf;
1337  if(!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user))
1339  }
1340  else if(pOutput_buf_start == d->m_output_buf)
1341  {
1342  int bytes_to_copy = (int)MZ_MIN((size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs));
1343  memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf, bytes_to_copy);
1344  d->m_out_buf_ofs += bytes_to_copy;
1345  if((n -= bytes_to_copy) != 0)
1346  {
1347  d->m_output_flush_ofs = bytes_to_copy;
1348  d->m_output_flush_remaining = n;
1349  }
1350  }
1351  else
1352  {
1353  d->m_out_buf_ofs += n;
1354  }
1355  }
1356 
1357  return d->m_output_flush_remaining;
1358 }
1359 
1360 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
1361 #define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16 *)(p)
1362 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)
1363 {
1364  mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len;
1365  mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
1366  const mz_uint16 *s = (const mz_uint16 *)(d->m_dict + pos), *p, *q;
1367  mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]), s01 = TDEFL_READ_UNALIGNED_WORD(s);
1368  MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN);
1369  if(max_match_len <= match_len)
1370  return;
1371  for(;;)
1372  {
1373  for(;;)
1374  {
1375  if(--num_probes_left == 0)
1376  return;
1377 #define TDEFL_PROBE \
1378  next_probe_pos = d->m_next[probe_pos]; \
1379  if((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \
1380  return; \
1381  probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
1382  if(TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) \
1383  break;
1384  TDEFL_PROBE;
1385  TDEFL_PROBE;
1386  TDEFL_PROBE;
1387  }
1388  if(!dist)
1389  break;
1390  q = (const mz_uint16 *)(d->m_dict + probe_pos);
1391  if(TDEFL_READ_UNALIGNED_WORD(q) != s01)
1392  continue;
1393  p = s;
1394  probe_len = 32;
1395  do
1396  {
1397  } while((TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) &&
1398  (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0));
1399  if(!probe_len)
1400  {
1401  *pMatch_dist = dist;
1402  *pMatch_len = MZ_MIN(max_match_len, (mz_uint)TDEFL_MAX_MATCH_LEN);
1403  break;
1404  }
1405  else if((probe_len = ((mz_uint)(p - s) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q)) > match_len)
1406  {
1407  *pMatch_dist = dist;
1408  if((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) == max_match_len)
1409  break;
1410  c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]);
1411  }
1412  }
1413 }
1414 #else
1415 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)
1416 {
1417  mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len;
1418  mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
1419  const mz_uint8 *s = d->m_dict + pos, *p, *q;
1420  mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1];
1421  MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN);
1422  if(max_match_len <= match_len)
1423  return;
1424  for(;;)
1425  {
1426  for(;;)
1427  {
1428  if(--num_probes_left == 0)
1429  return;
1430 #define TDEFL_PROBE \
1431  next_probe_pos = d->m_next[probe_pos]; \
1432  if((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \
1433  return; \
1434  probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
1435  if((d->m_dict[probe_pos + match_len] == c0) && (d->m_dict[probe_pos + match_len - 1] == c1)) \
1436  break;
1437  TDEFL_PROBE;
1438  TDEFL_PROBE;
1439  TDEFL_PROBE;
1440  }
1441  if(!dist)
1442  break;
1443  p = s;
1444  q = d->m_dict + probe_pos;
1445  for(probe_len = 0; probe_len < max_match_len; probe_len++)
1446  if(*p++ != *q++)
1447  break;
1448  if(probe_len > match_len)
1449  {
1450  *pMatch_dist = dist;
1451  if((*pMatch_len = match_len = probe_len) == max_match_len)
1452  return;
1453  c0 = d->m_dict[pos + match_len];
1454  c1 = d->m_dict[pos + match_len - 1];
1455  }
1456  }
1457 }
1458 #endif /* #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES */
1459 
1460 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES &&MINIZ_LITTLE_ENDIAN
1461 static mz_bool tdefl_compress_fast(tdefl_compressor *d)
1462 {
1463  /* Faster, minimally featured LZRW1-style match+parse loop with better register utilization. Intended for applications where raw throughput is valued more highly than ratio. */
1464  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;
1465  mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags;
1466  mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
1467 
1468  while((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size)))
1469  {
1470  const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096;
1471  mz_uint dst_pos = (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK;
1472  mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size);
1473  d->m_src_buf_left -= num_bytes_to_process;
1474  lookahead_size += num_bytes_to_process;
1475 
1476  while(num_bytes_to_process)
1477  {
1478  mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process);
1479  memcpy(d->m_dict + dst_pos, d->m_pSrc, n);
1480  if(dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
1481  memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc, MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos));
1482  d->m_pSrc += n;
1483  dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK;
1484  num_bytes_to_process -= n;
1485  }
1486 
1487  dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size);
1488  if((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE))
1489  break;
1490 
1491  while(lookahead_size >= 4)
1492  {
1493  mz_uint cur_match_dist, cur_match_len = 1;
1494  mz_uint8 *pCur_dict = d->m_dict + cur_pos;
1495  mz_uint first_trigram = (*(const mz_uint32 *)pCur_dict) & 0xFFFFFF;
1496  mz_uint hash = (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) & TDEFL_LEVEL1_HASH_SIZE_MASK;
1497  mz_uint probe_pos = d->m_hash[hash];
1498  d->m_hash[hash] = (mz_uint16)lookahead_pos;
1499 
1500  if(((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <= dict_size) && ((*(const mz_uint32 *)(d->m_dict + (probe_pos &= TDEFL_LZ_DICT_SIZE_MASK)) & 0xFFFFFF) == first_trigram))
1501  {
1502  const mz_uint16 *p = (const mz_uint16 *)pCur_dict;
1503  const mz_uint16 *q = (const mz_uint16 *)(d->m_dict + probe_pos);
1504  mz_uint32 probe_len = 32;
1505  do
1506  {
1507  } while((TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) &&
1508  (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0));
1509  cur_match_len = ((mz_uint)(p - (const mz_uint16 *)pCur_dict) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q);
1510  if(!probe_len)
1511  cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0;
1512 
1513  if((cur_match_len < TDEFL_MIN_MATCH_LEN) || ((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U * 1024U)))
1514  {
1515  cur_match_len = 1;
1516  *pLZ_code_buf++ = (mz_uint8)first_trigram;
1517  *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
1518  d->m_huff_count[0][(mz_uint8)first_trigram]++;
1519  }
1520  else
1521  {
1522  mz_uint32 s0, s1;
1523  cur_match_len = MZ_MIN(cur_match_len, lookahead_size);
1524 
1525  MZ_ASSERT((cur_match_len >= TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 1) && (cur_match_dist <= TDEFL_LZ_DICT_SIZE));
1526 
1527  cur_match_dist--;
1528 
1529  pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN);
1530  *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist;
1531  pLZ_code_buf += 3;
1532  *pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80);
1533 
1534  s0 = s_tdefl_small_dist_sym[cur_match_dist & 511];
1535  s1 = s_tdefl_large_dist_sym[cur_match_dist >> 8];
1536  d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++;
1537 
1538  d->m_huff_count[0][s_tdefl_len_sym[cur_match_len - TDEFL_MIN_MATCH_LEN]]++;
1539  }
1540  }
1541  else
1542  {
1543  *pLZ_code_buf++ = (mz_uint8)first_trigram;
1544  *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
1545  d->m_huff_count[0][(mz_uint8)first_trigram]++;
1546  }
1547 
1548  if(--num_flags_left == 0)
1549  {
1550  num_flags_left = 8;
1551  pLZ_flags = pLZ_code_buf++;
1552  }
1553 
1554  total_lz_bytes += cur_match_len;
1555  lookahead_pos += cur_match_len;
1556  dict_size = MZ_MIN(dict_size + cur_match_len, (mz_uint)TDEFL_LZ_DICT_SIZE);
1557  cur_pos = (cur_pos + cur_match_len) & TDEFL_LZ_DICT_SIZE_MASK;
1558  MZ_ASSERT(lookahead_size >= cur_match_len);
1559  lookahead_size -= cur_match_len;
1560 
1561  if(pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8])
1562  {
1563  int n;
1564  d->m_lookahead_pos = lookahead_pos;
1565  d->m_lookahead_size = lookahead_size;
1566  d->m_dict_size = dict_size;
1567  d->m_total_lz_bytes = total_lz_bytes;
1568  d->m_pLZ_code_buf = pLZ_code_buf;
1569  d->m_pLZ_flags = pLZ_flags;
1570  d->m_num_flags_left = num_flags_left;
1571  if((n = tdefl_flush_block(d, 0)) != 0)
1572  return (n < 0) ? MZ_FALSE : MZ_TRUE;
1573  total_lz_bytes = d->m_total_lz_bytes;
1574  pLZ_code_buf = d->m_pLZ_code_buf;
1575  pLZ_flags = d->m_pLZ_flags;
1576  num_flags_left = d->m_num_flags_left;
1577  }
1578  }
1579 
1580  while(lookahead_size)
1581  {
1582  mz_uint8 lit = d->m_dict[cur_pos];
1583 
1584  total_lz_bytes++;
1585  *pLZ_code_buf++ = lit;
1586  *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
1587  if(--num_flags_left == 0)
1588  {
1589  num_flags_left = 8;
1590  pLZ_flags = pLZ_code_buf++;
1591  }
1592 
1593  d->m_huff_count[0][lit]++;
1594 
1595  lookahead_pos++;
1596  dict_size = MZ_MIN(dict_size + 1, (mz_uint)TDEFL_LZ_DICT_SIZE);
1597  cur_pos = (cur_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK;
1598  lookahead_size--;
1599 
1600  if(pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8])
1601  {
1602  int n;
1603  d->m_lookahead_pos = lookahead_pos;
1604  d->m_lookahead_size = lookahead_size;
1605  d->m_dict_size = dict_size;
1606  d->m_total_lz_bytes = total_lz_bytes;
1607  d->m_pLZ_code_buf = pLZ_code_buf;
1608  d->m_pLZ_flags = pLZ_flags;
1609  d->m_num_flags_left = num_flags_left;
1610  if((n = tdefl_flush_block(d, 0)) != 0)
1611  return (n < 0) ? MZ_FALSE : MZ_TRUE;
1612  total_lz_bytes = d->m_total_lz_bytes;
1613  pLZ_code_buf = d->m_pLZ_code_buf;
1614  pLZ_flags = d->m_pLZ_flags;
1615  num_flags_left = d->m_num_flags_left;
1616  }
1617  }
1618  }
1619 
1620  d->m_lookahead_pos = lookahead_pos;
1621  d->m_lookahead_size = lookahead_size;
1622  d->m_dict_size = dict_size;
1623  d->m_total_lz_bytes = total_lz_bytes;
1624  d->m_pLZ_code_buf = pLZ_code_buf;
1625  d->m_pLZ_flags = pLZ_flags;
1626  d->m_num_flags_left = num_flags_left;
1627  return MZ_TRUE;
1628 }
1629 #endif /* MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN */
1630 
1632 {
1633  d->m_total_lz_bytes++;
1634  *d->m_pLZ_code_buf++ = lit;
1635  *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1);
1636  if(--d->m_num_flags_left == 0)
1637  {
1638  d->m_num_flags_left = 8;
1639  d->m_pLZ_flags = d->m_pLZ_code_buf++;
1640  }
1641  d->m_huff_count[0][lit]++;
1642 }
1643 
1644 static MZ_FORCEINLINE void tdefl_record_match(tdefl_compressor *d, mz_uint match_len, mz_uint match_dist)
1645 {
1646  mz_uint32 s0, s1;
1647 
1648  MZ_ASSERT((match_len >= TDEFL_MIN_MATCH_LEN) && (match_dist >= 1) && (match_dist <= TDEFL_LZ_DICT_SIZE));
1649 
1650  d->m_total_lz_bytes += match_len;
1651 
1652  d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN);
1653 
1654  match_dist -= 1;
1655  d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF);
1656  d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8);
1657  d->m_pLZ_code_buf += 3;
1658 
1659  *d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80);
1660  if(--d->m_num_flags_left == 0)
1661  {
1662  d->m_num_flags_left = 8;
1663  d->m_pLZ_flags = d->m_pLZ_code_buf++;
1664  }
1665 
1666  s0 = s_tdefl_small_dist_sym[match_dist & 511];
1667  s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127];
1668  d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++;
1669 
1670  if(match_len >= TDEFL_MIN_MATCH_LEN)
1671  d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++;
1672 }
1673 
1675 {
1676  const mz_uint8 *pSrc = d->m_pSrc;
1677  size_t src_buf_left = d->m_src_buf_left;
1678  tdefl_flush flush = d->m_flush;
1679 
1680  while((src_buf_left) || ((flush) && (d->m_lookahead_size)))
1681  {
1682  mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos;
1683  /* Update dictionary and hash chains. Keeps the lookahead size equal to TDEFL_MAX_MATCH_LEN. */
1684  if((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1))
1685  {
1687  mz_uint hash = (d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK];
1688  mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size);
1689  const mz_uint8 *pSrc_end = pSrc + num_bytes_to_process;
1690  src_buf_left -= num_bytes_to_process;
1691  d->m_lookahead_size += num_bytes_to_process;
1692  while(pSrc != pSrc_end)
1693  {
1694  mz_uint8 c = *pSrc++;
1695  d->m_dict[dst_pos] = c;
1696  if(dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
1697  d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
1698  hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1);
1699  d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash];
1700  d->m_hash[hash] = (mz_uint16)(ins_pos);
1701  dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK;
1702  ins_pos++;
1703  }
1704  }
1705  else
1706  {
1707  while((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
1708  {
1709  mz_uint8 c = *pSrc++;
1711  src_buf_left--;
1712  d->m_dict[dst_pos] = c;
1713  if(dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
1714  d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
1716  {
1717  mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2;
1718  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);
1719  d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash];
1720  d->m_hash[hash] = (mz_uint16)(ins_pos);
1721  }
1722  }
1723  }
1725  if((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
1726  break;
1727 
1728  /* Simple lazy/greedy parsing state machine. */
1729  len_to_move = 1;
1730  cur_match_dist = 0;
1731  cur_match_len = d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1);
1734  {
1735  if((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS)))
1736  {
1737  mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK];
1738  cur_match_len = 0;
1739  while(cur_match_len < d->m_lookahead_size)
1740  {
1741  if(d->m_dict[cur_pos + cur_match_len] != c)
1742  break;
1743  cur_match_len++;
1744  }
1745  if(cur_match_len < TDEFL_MIN_MATCH_LEN)
1746  cur_match_len = 0;
1747  else
1748  cur_match_dist = 1;
1749  }
1750  }
1751  else
1752  {
1753  tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size, d->m_lookahead_size, &cur_match_dist, &cur_match_len);
1754  }
1755  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)))
1756  {
1757  cur_match_dist = cur_match_len = 0;
1758  }
1759  if(d->m_saved_match_len)
1760  {
1761  if(cur_match_len > d->m_saved_match_len)
1762  {
1764  if(cur_match_len >= 128)
1765  {
1766  tdefl_record_match(d, cur_match_len, cur_match_dist);
1767  d->m_saved_match_len = 0;
1768  len_to_move = cur_match_len;
1769  }
1770  else
1771  {
1772  d->m_saved_lit = d->m_dict[cur_pos];
1773  d->m_saved_match_dist = cur_match_dist;
1774  d->m_saved_match_len = cur_match_len;
1775  }
1776  }
1777  else
1778  {
1780  len_to_move = d->m_saved_match_len - 1;
1781  d->m_saved_match_len = 0;
1782  }
1783  }
1784  else if(!cur_match_dist)
1785  tdefl_record_literal(d, d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]);
1786  else if((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) || (cur_match_len >= 128))
1787  {
1788  tdefl_record_match(d, cur_match_len, cur_match_dist);
1789  len_to_move = cur_match_len;
1790  }
1791  else
1792  {
1793  d->m_saved_lit = d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)];
1794  d->m_saved_match_dist = cur_match_dist;
1795  d->m_saved_match_len = cur_match_len;
1796  }
1797  /* Move the lookahead forward by len_to_move bytes. */
1798  d->m_lookahead_pos += len_to_move;
1799  MZ_ASSERT(d->m_lookahead_size >= len_to_move);
1800  d->m_lookahead_size -= len_to_move;
1801  d->m_dict_size = MZ_MIN(d->m_dict_size + len_to_move, (mz_uint)TDEFL_LZ_DICT_SIZE);
1802  /* Check if it's time to flush the current LZ codes to the internal output buffer. */
1804  ((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))))
1805  {
1806  int n;
1807  d->m_pSrc = pSrc;
1808  d->m_src_buf_left = src_buf_left;
1809  if((n = tdefl_flush_block(d, 0)) != 0)
1810  return (n < 0) ? MZ_FALSE : MZ_TRUE;
1811  }
1812  }
1813 
1814  d->m_pSrc = pSrc;
1815  d->m_src_buf_left = src_buf_left;
1816  return MZ_TRUE;
1817 }
1818 
1820 {
1821  if(d->m_pIn_buf_size)
1822  {
1823  *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf;
1824  }
1825 
1826  if(d->m_pOut_buf_size)
1827  {
1830  d->m_output_flush_ofs += (mz_uint)n;
1832  d->m_out_buf_ofs += n;
1833 
1834  *d->m_pOut_buf_size = d->m_out_buf_ofs;
1835  }
1836 
1838 }
1839 
1840 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)
1841 {
1842  if(!d)
1843  {
1844  if(pIn_buf_size)
1845  *pIn_buf_size = 0;
1846  if(pOut_buf_size)
1847  *pOut_buf_size = 0;
1848  return TDEFL_STATUS_BAD_PARAM;
1849  }
1850 
1851  d->m_pIn_buf = pIn_buf;
1852  d->m_pIn_buf_size = pIn_buf_size;
1853  d->m_pOut_buf = pOut_buf;
1854  d->m_pOut_buf_size = pOut_buf_size;
1855  d->m_pSrc = (const mz_uint8 *)(pIn_buf);
1856  d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0;
1857  d->m_out_buf_ofs = 0;
1858  d->m_flush = flush;
1859 
1860  if(((d->m_pPut_buf_func != NULL) == ((pOut_buf != NULL) || (pOut_buf_size != NULL))) || (d->m_prev_return_status != TDEFL_STATUS_OKAY) ||
1861  (d->m_wants_to_finish && (flush != TDEFL_FINISH)) || (pIn_buf_size && *pIn_buf_size && !pIn_buf) || (pOut_buf_size && *pOut_buf_size && !pOut_buf))
1862  {
1863  if(pIn_buf_size)
1864  *pIn_buf_size = 0;
1865  if(pOut_buf_size)
1866  *pOut_buf_size = 0;
1868  }
1869  d->m_wants_to_finish |= (flush == TDEFL_FINISH);
1870 
1871  if((d->m_output_flush_remaining) || (d->m_finished))
1873 
1874 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES &&MINIZ_LITTLE_ENDIAN
1875  if(((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) &&
1876  ((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) &&
1878  {
1879  if(!tdefl_compress_fast(d))
1880  return d->m_prev_return_status;
1881  }
1882  else
1883 #endif /* #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN */
1884  {
1885  if(!tdefl_compress_normal(d))
1886  return d->m_prev_return_status;
1887  }
1888 
1889  if((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) && (pIn_buf))
1890  d->m_adler32 = (mz_uint32)mz_adler32(d->m_adler32, (const mz_uint8 *)pIn_buf, d->m_pSrc - (const mz_uint8 *)pIn_buf);
1891 
1892  if((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) && (!d->m_output_flush_remaining))
1893  {
1894  if(tdefl_flush_block(d, flush) < 0)
1895  return d->m_prev_return_status;
1896  d->m_finished = (flush == TDEFL_FINISH);
1897  if(flush == TDEFL_FULL_FLUSH)
1898  {
1899  MZ_CLEAR_OBJ(d->m_hash);
1900  MZ_CLEAR_OBJ(d->m_next);
1901  d->m_dict_size = 0;
1902  }
1903  }
1904 
1906 }
1907 
1908 tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush)
1909 {
1911  return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush);
1912 }
1913 
1914 tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
1915 {
1916  d->m_pPut_buf_func = pPut_buf_func;
1917  d->m_pPut_buf_user = pPut_buf_user;
1918  d->m_flags = (mz_uint)(flags);
1919  d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3;
1920  d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0;
1921  d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3;
1923  MZ_CLEAR_OBJ(d->m_hash);
1926  d->m_pLZ_code_buf = d->m_lz_code_buf + 1;
1927  d->m_pLZ_flags = d->m_lz_code_buf;
1928  d->m_num_flags_left = 8;
1929  d->m_pOutput_buf = d->m_output_buf;
1933  d->m_adler32 = 1;
1934  d->m_pIn_buf = NULL;
1935  d->m_pOut_buf = NULL;
1936  d->m_pIn_buf_size = NULL;
1937  d->m_pOut_buf_size = NULL;
1938  d->m_flush = TDEFL_NO_FLUSH;
1939  d->m_pSrc = NULL;
1940  d->m_src_buf_left = 0;
1941  d->m_out_buf_ofs = 0;
1942  memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
1943  memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
1944  return TDEFL_STATUS_OKAY;
1945 }
1946 
1948 {
1949  return d->m_prev_return_status;
1950 }
1951 
1953 {
1954  return d->m_adler32;
1955 }
1956 
1957 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)
1958 {
1959  tdefl_compressor *pComp;
1960  mz_bool succeeded;
1961  if(((buf_len) && (!pBuf)) || (!pPut_buf_func))
1962  return MZ_FALSE;
1963  pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor));
1964  if(!pComp)
1965  return MZ_FALSE;
1966  succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags) == TDEFL_STATUS_OKAY);
1967  succeeded = succeeded && (tdefl_compress_buffer(pComp, pBuf, buf_len, TDEFL_FINISH) == TDEFL_STATUS_DONE);
1968  MZ_FREE(pComp);
1969  return succeeded;
1970 }
1971 
1972 typedef struct
1973 {
1974  size_t m_size, m_capacity;
1978 
1979 static mz_bool tdefl_output_buffer_putter(const void *pBuf, int len, void *pUser)
1980 {
1982  size_t new_size = p->m_size + len;
1983  if(new_size > p->m_capacity)
1984  {
1985  size_t new_capacity = p->m_capacity;
1986  mz_uint8 *pNew_buf;
1987  if(!p->m_expandable)
1988  return MZ_FALSE;
1989  do
1990  {
1991  new_capacity = MZ_MAX(128U, new_capacity << 1U);
1992  } while(new_size > new_capacity);
1993  pNew_buf = (mz_uint8 *)MZ_REALLOC(p->m_pBuf, new_capacity);
1994  if(!pNew_buf)
1995  return MZ_FALSE;
1996  p->m_pBuf = pNew_buf;
1997  p->m_capacity = new_capacity;
1998  }
1999  memcpy((mz_uint8 *)p->m_pBuf + p->m_size, pBuf, len);
2000  p->m_size = new_size;
2001  return MZ_TRUE;
2002 }
2003 
2004 void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
2005 {
2006  tdefl_output_buffer out_buf;
2007  MZ_CLEAR_OBJ(out_buf);
2008  if(!pOut_len)
2009  return nullptr;
2010  else
2011  *pOut_len = 0;
2012  out_buf.m_expandable = MZ_TRUE;
2013  if(!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags))
2014  return NULL;
2015  *pOut_len = out_buf.m_size;
2016  return out_buf.m_pBuf;
2017 }
2018 
2019 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)
2020 {
2021  tdefl_output_buffer out_buf;
2022  MZ_CLEAR_OBJ(out_buf);
2023  if(!pOut_buf)
2024  return 0;
2025  out_buf.m_pBuf = (mz_uint8 *)pOut_buf;
2026  out_buf.m_capacity = out_buf_len;
2027  if(!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags))
2028  return 0;
2029  return out_buf.m_size;
2030 }
2031 
2032 #ifndef MINIZ_NO_ZLIB_APIS
2033 static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
2034 
2035 /* 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). */
2036 mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy)
2037 {
2038  mz_uint comp_flags = s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0);
2039  if(window_bits > 0)
2040  comp_flags |= TDEFL_WRITE_ZLIB_HEADER;
2041 
2042  if(!level)
2043  comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS;
2044  else if(strategy == MZ_FILTERED)
2045  comp_flags |= TDEFL_FILTER_MATCHES;
2046  else if(strategy == MZ_HUFFMAN_ONLY)
2047  comp_flags &= ~TDEFL_MAX_PROBES_MASK;
2048  else if(strategy == MZ_FIXED)
2049  comp_flags |= TDEFL_FORCE_ALL_STATIC_BLOCKS;
2050  else if(strategy == MZ_RLE)
2051  comp_flags |= TDEFL_RLE_MATCHES;
2052 
2053  return comp_flags;
2054 }
2055 #endif /*MINIZ_NO_ZLIB_APIS */
2056 
2057 #ifdef _MSC_VER
2058 #pragma warning(push)
2059 #pragma warning(disable : 4204) /* nonstandard extension used : non-constant aggregate initializer (also supported by GNU C and C99, so no big deal) */
2060 #endif
2061 
2062 /* Simple PNG writer function by Alex Evans, 2011. Released into the public domain: https://gist.github.com/908299, more context at
2063  http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/.
2064  This is actually a modification of Alex's original code so PNG files generated by this function pass pngcheck. */
2065 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)
2066 {
2067  /* Using a local copy of this array here in case MINIZ_NO_ZLIB_APIS was defined. */
2068  static const mz_uint s_tdefl_png_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
2070  tdefl_output_buffer out_buf;
2071  int i, bpl = w * num_chans, y, z;
2072  mz_uint32 c;
2073  *pLen_out = 0;
2074  if(!pComp)
2075  return NULL;
2076  MZ_CLEAR_OBJ(out_buf);
2077  out_buf.m_expandable = MZ_TRUE;
2078  out_buf.m_capacity = 57 + MZ_MAX(64, (1 + bpl) * h);
2079  if(NULL == (out_buf.m_pBuf = (mz_uint8 *)MZ_MALLOC(out_buf.m_capacity)))
2080  {
2081  MZ_FREE(pComp);
2082  return NULL;
2083  }
2084  /* write dummy header */
2085  for(z = 41; z; --z)
2086  tdefl_output_buffer_putter(&z, 1, &out_buf);
2087  /* compress image data */
2088  tdefl_init(pComp, tdefl_output_buffer_putter, &out_buf, s_tdefl_png_num_probes[MZ_MIN(10, level)] | TDEFL_WRITE_ZLIB_HEADER);
2089  for(y = 0; y < h; ++y)
2090  {
2091  tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH);
2092  tdefl_compress_buffer(pComp, (mz_uint8 *)pImage + (flip ? (h - 1 - y) : y) * bpl, bpl, TDEFL_NO_FLUSH);
2093  }
2094  if(tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) != TDEFL_STATUS_DONE)
2095  {
2096  MZ_FREE(pComp);
2097  MZ_FREE(out_buf.m_pBuf);
2098  return NULL;
2099  }
2100  /* write real header */
2101  *pLen_out = out_buf.m_size - 41;
2102  {
2103  static const mz_uint8 chans[] = { 0x00, 0x00, 0x04, 0x02, 0x06 };
2104  mz_uint8 pnghdr[41] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
2105  0, 0, (mz_uint8)(w >> 8), (mz_uint8)w, 0, 0, (mz_uint8)(h >> 8), (mz_uint8)h, 8, chans[num_chans], 0, 0, 0, 0, 0, 0, 0,
2106  (mz_uint8)(*pLen_out >> 24), (mz_uint8)(*pLen_out >> 16), (mz_uint8)(*pLen_out >> 8), (mz_uint8) * pLen_out, 0x49, 0x44, 0x41, 0x54 };
2107  c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, pnghdr + 12, 17);
2108  for(i = 0; i < 4; ++i, c <<= 8)
2109  ((mz_uint8 *)(pnghdr + 29))[i] = (mz_uint8)(c >> 24);
2110  memcpy(out_buf.m_pBuf, pnghdr, 41);
2111  }
2112  /* write footer (IDAT CRC-32, followed by IEND chunk) */
2113  if(!tdefl_output_buffer_putter("\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf))
2114  {
2115  *pLen_out = 0;
2116  MZ_FREE(pComp);
2117  MZ_FREE(out_buf.m_pBuf);
2118  return NULL;
2119  }
2120  c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, out_buf.m_pBuf + 41 - 4, *pLen_out + 4);
2121  for(i = 0; i < 4; ++i, c <<= 8)
2122  (out_buf.m_pBuf + out_buf.m_size - 16)[i] = (mz_uint8)(c >> 24);
2123  /* compute final size of file, grab compressed data buffer and return */
2124  *pLen_out += 57;
2125  MZ_FREE(pComp);
2126  return out_buf.m_pBuf;
2127 }
2128 void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out)
2129 {
2130  /* 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) */
2131  return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans, pLen_out, 6, MZ_FALSE);
2132 }
2133 
2134 /* Allocate the tdefl_compressor and tinfl_decompressor structures in C so that */
2135 /* non-C language bindings to tdefL_ and tinfl_ API don't need to worry about */
2136 /* structure size and allocation mechanism. */
2138 {
2139  return (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor));
2140 }
2141 
2143 {
2144  MZ_FREE(pComp);
2145 }
2146 
2147 #ifdef _MSC_VER
2148 #pragma warning(pop)
2149 #endif
2150 
2151 #ifdef __cplusplus
2152 }
2153 #endif
2154 /**************************************************************************
2155  *
2156  * Copyright 2013-2014 RAD Game Tools and Valve Software
2157  * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
2158  * All Rights Reserved.
2159  *
2160  * Permission is hereby granted, free of charge, to any person obtaining a copy
2161  * of this software and associated documentation files (the "Software"), to deal
2162  * in the Software without restriction, including without limitation the rights
2163  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2164  * copies of the Software, and to permit persons to whom the Software is
2165  * furnished to do so, subject to the following conditions:
2166  *
2167  * The above copyright notice and this permission notice shall be included in
2168  * all copies or substantial portions of the Software.
2169  *
2170  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2171  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2172  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2173  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2174  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2175  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2176  * THE SOFTWARE.
2177  *
2178  **************************************************************************/
2179 
2180 
2181 
2182 #ifdef __cplusplus
2183 extern "C" {
2184 #endif
2185 
2186 /* ------------------- Low-level Decompression (completely independent from all compression API's) */
2187 
2188 #define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
2189 #define TINFL_MEMSET(p, c, l) memset(p, c, l)
2190 
2191 #define TINFL_CR_BEGIN \
2192  switch(r->m_state) \
2193  { \
2194  case 0:
2195 #define TINFL_CR_RETURN(state_index, result) \
2196  do \
2197  { \
2198  status = result; \
2199  r->m_state = state_index; \
2200  goto common_exit; \
2201  case state_index: \
2202  ; \
2203  } \
2204  MZ_MACRO_END
2205 #define TINFL_CR_RETURN_FOREVER(state_index, result) \
2206  do \
2207  { \
2208  for(;;) \
2209  { \
2210  TINFL_CR_RETURN(state_index, result); \
2211  } \
2212  } \
2213  MZ_MACRO_END
2214 #define TINFL_CR_FINISH }
2215 
2216 #define TINFL_GET_BYTE(state_index, c) \
2217  do \
2218  { \
2219  while(pIn_buf_cur >= pIn_buf_end) \
2220  { \
2221  TINFL_CR_RETURN(state_index, (decomp_flags &TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS); \
2222  } \
2223  c = *pIn_buf_cur++; \
2224  } \
2225  MZ_MACRO_END
2226 
2227 #define TINFL_NEED_BITS(state_index, n) \
2228  do \
2229  { \
2230  mz_uint c; \
2231  TINFL_GET_BYTE(state_index, c); \
2232  bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
2233  num_bits += 8; \
2234  } while(num_bits < (mz_uint)(n))
2235 #define TINFL_SKIP_BITS(state_index, n) \
2236  do \
2237  { \
2238  if(num_bits < (mz_uint)(n)) \
2239  { \
2240  TINFL_NEED_BITS(state_index, n); \
2241  } \
2242  bit_buf >>= (n); \
2243  num_bits -= (n); \
2244  } \
2245  MZ_MACRO_END
2246 #define TINFL_GET_BITS(state_index, b, n) \
2247  do \
2248  { \
2249  if(num_bits < (mz_uint)(n)) \
2250  { \
2251  TINFL_NEED_BITS(state_index, n); \
2252  } \
2253  b = bit_buf & ((1 << (n)) - 1); \
2254  bit_buf >>= (n); \
2255  num_bits -= (n); \
2256  } \
2257  MZ_MACRO_END
2258 
2259 /* TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2. */
2260 /* 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 */
2261 /* 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 */
2262 /* bit buffer contains >=15 bits (deflate's max. Huffman code size). */
2263 #define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \
2264  do \
2265  { \
2266  temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
2267  if(temp >= 0) \
2268  { \
2269  code_len = temp >> 9; \
2270  if((code_len) && (num_bits >= code_len)) \
2271  break; \
2272  } \
2273  else if(num_bits > TINFL_FAST_LOOKUP_BITS) \
2274  { \
2275  code_len = TINFL_FAST_LOOKUP_BITS; \
2276  do \
2277  { \
2278  temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
2279  } while((temp < 0) && (num_bits >= (code_len + 1))); \
2280  if(temp >= 0) \
2281  break; \
2282  } \
2283  TINFL_GET_BYTE(state_index, c); \
2284  bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
2285  num_bits += 8; \
2286  } while(num_bits < 15);
2287 
2288 /* 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 */
2289 /* 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 */
2290 /* 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. */
2291 /* The slow path is only executed at the very end of the input buffer. */
2292 /* 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 */
2293 /* following the deflate data and our non-conservative read-ahead path won't kick in here on this code. This is much trickier. */
2294 #define TINFL_HUFF_DECODE(state_index, sym, pHuff) \
2295  do \
2296  { \
2297  int temp; \
2298  mz_uint code_len, c; \
2299  if(num_bits < 15) \
2300  { \
2301  if((pIn_buf_end - pIn_buf_cur) < 2) \
2302  { \
2303  TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
2304  } \
2305  else \
2306  { \
2307  bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); \
2308  pIn_buf_cur += 2; \
2309  num_bits += 16; \
2310  } \
2311  } \
2312  if((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
2313  code_len = temp >> 9, temp &= 511; \
2314  else \
2315  { \
2316  code_len = TINFL_FAST_LOOKUP_BITS; \
2317  do \
2318  { \
2319  temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
2320  } while(temp < 0); \
2321  } \
2322  sym = temp; \
2323  bit_buf >>= code_len; \
2324  num_bits -= code_len; \
2325  } \
2326  MZ_MACRO_END
2327 
2328 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)
2329 {
2330  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 };
2331  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 };
2332  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 };
2333  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 };
2334  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 };
2335  static const int s_min_table_sizes[3] = { 257, 1, 4 };
2336 
2338  mz_uint32 num_bits, dist, counter, num_extra;
2339  tinfl_bit_buf_t bit_buf;
2340  const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size;
2341  mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size;
2342  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;
2343 
2344  /* 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). */
2345  if(((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start))
2346  {
2347  *pIn_buf_size = *pOut_buf_size = 0;
2348  return TINFL_STATUS_BAD_PARAM;
2349  }
2350 
2351  num_bits = r->m_num_bits;
2352  bit_buf = r->m_bit_buf;
2353  dist = r->m_dist;
2354  counter = r->m_counter;
2355  num_extra = r->m_num_extra;
2356  dist_from_out_buf_start = r->m_dist_from_out_buf_start;
2358 
2359  bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0;
2360  r->m_z_adler32 = r->m_check_adler32 = 1;
2361  if(decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
2362  {
2363  TINFL_GET_BYTE(1, r->m_zhdr0);
2364  TINFL_GET_BYTE(2, r->m_zhdr1);
2365  counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8));
2366  if(!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
2367  counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1U << (8U + (r->m_zhdr0 >> 4)))));
2368  if(counter)
2369  {
2371  }
2372  }
2373 
2374  do
2375  {
2376  TINFL_GET_BITS(3, r->m_final, 3);
2377  r->m_type = r->m_final >> 1;
2378  if(r->m_type == 0)
2379  {
2380  TINFL_SKIP_BITS(5, num_bits & 7);
2381  for(counter = 0; counter < 4; ++counter)
2382  {
2383  if(num_bits)
2384  TINFL_GET_BITS(6, r->m_raw_header[counter], 8);
2385  else
2386  TINFL_GET_BYTE(7, r->m_raw_header[counter]);
2387  }
2388  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))))
2389  {
2391  }
2392  while((counter) && (num_bits))
2393  {
2394  TINFL_GET_BITS(51, dist, 8);
2395  while(pOut_buf_cur >= pOut_buf_end)
2396  {
2398  }
2399  *pOut_buf_cur++ = (mz_uint8)dist;
2400  counter--;
2401  }
2402  while(counter)
2403  {
2404  size_t n;
2405  while(pOut_buf_cur >= pOut_buf_end)
2406  {
2408  }
2409  while(pIn_buf_cur >= pIn_buf_end)
2410  {
2412  }
2413  n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter);
2414  TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n);
2415  pIn_buf_cur += n;
2416  pOut_buf_cur += n;
2417  counter -= (mz_uint)n;
2418  }
2419  }
2420  else if(r->m_type == 3)
2421  {
2423  }
2424  else
2425  {
2426  if(r->m_type == 1)
2427  {
2428  mz_uint8 *p = r->m_tables[0].m_code_size;
2429  mz_uint i;
2430  r->m_table_sizes[0] = 288;
2431  r->m_table_sizes[1] = 32;
2432  TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32);
2433  for(i = 0; i <= 143; ++i)
2434  *p++ = 8;
2435  for(; i <= 255; ++i)
2436  *p++ = 9;
2437  for(; i <= 279; ++i)
2438  *p++ = 7;
2439  for(; i <= 287; ++i)
2440  *p++ = 8;
2441  }
2442  else
2443  {
2444  for(counter = 0; counter < 3; counter++)
2445  {
2446  TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]);
2447  r->m_table_sizes[counter] += s_min_table_sizes[counter];
2448  }
2449  MZ_CLEAR_OBJ(r->m_tables[2].m_code_size);
2450  for(counter = 0; counter < r->m_table_sizes[2]; counter++)
2451  {
2452  mz_uint s;
2453  TINFL_GET_BITS(14, s, 3);
2454  r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s;
2455  }
2456  r->m_table_sizes[2] = 19;
2457  }
2458  for(; (int)r->m_type >= 0; r->m_type--)
2459  {
2460  int tree_next, tree_cur;
2461  tinfl_huff_table *pTable;
2462  mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16];
2463  pTable = &r->m_tables[r->m_type];
2464  MZ_CLEAR_OBJ(total_syms);
2465  MZ_CLEAR_OBJ(pTable->m_look_up);
2466  MZ_CLEAR_OBJ(pTable->m_tree);
2467  for(i = 0; i < r->m_table_sizes[r->m_type]; ++i)
2468  total_syms[pTable->m_code_size[i]]++;
2469  used_syms = 0, total = 0;
2470  next_code[0] = next_code[1] = 0;
2471  for(i = 1; i <= 15; ++i)
2472  {
2473  used_syms += total_syms[i];
2474  next_code[i + 1] = (total = ((total + total_syms[i]) << 1));
2475  }
2476  if((65536 != total) && (used_syms > 1))
2477  {
2479  }
2480  for(tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index)
2481  {
2482  mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index];
2483  if(!code_size)
2484  continue;
2485  cur_code = next_code[code_size]++;
2486  for(l = code_size; l > 0; l--, cur_code >>= 1)
2487  rev_code = (rev_code << 1) | (cur_code & 1);
2488  if(code_size <= TINFL_FAST_LOOKUP_BITS)
2489  {
2490  mz_int16 k = (mz_int16)((code_size << 9) | sym_index);
2491  while(rev_code < TINFL_FAST_LOOKUP_SIZE)
2492  {
2493  pTable->m_look_up[rev_code] = k;
2494  rev_code += (1 << code_size);
2495  }
2496  continue;
2497  }
2498  if(0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)]))
2499  {
2500  pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next;
2501  tree_cur = tree_next;
2502  tree_next -= 2;
2503  }
2504  rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1);
2505  for(j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--)
2506  {
2507  tree_cur -= ((rev_code >>= 1) & 1);
2508  if(!pTable->m_tree[-tree_cur - 1])
2509  {
2510  pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next;
2511  tree_cur = tree_next;
2512  tree_next -= 2;
2513  }
2514  else
2515  tree_cur = pTable->m_tree[-tree_cur - 1];
2516  }
2517  tree_cur -= ((rev_code >>= 1) & 1);
2518  pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
2519  }
2520  if(r->m_type == 2)
2521  {
2522  for(counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]);)
2523  {
2524  mz_uint s;
2525  TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]);
2526  if(dist < 16)
2527  {
2528  r->m_len_codes[counter++] = (mz_uint8)dist;
2529  continue;
2530  }
2531  if((dist == 16) && (!counter))
2532  {
2534  }
2535  num_extra = "\02\03\07"[dist - 16];
2536  TINFL_GET_BITS(18, s, num_extra);
2537  s += "\03\03\013"[dist - 16];
2538  TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s);
2539  counter += s;
2540  }
2541  if((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter)
2542  {
2544  }
2545  TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]);
2546  TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]);
2547  }
2548  }
2549  for(;;)
2550  {
2551  mz_uint8 *pSrc;
2552  for(;;)
2553  {
2554  if(((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2))
2555  {
2556  TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]);
2557  if(counter >= 256)
2558  break;
2559  while(pOut_buf_cur >= pOut_buf_end)
2560  {
2562  }
2563  *pOut_buf_cur++ = (mz_uint8)counter;
2564  }
2565  else
2566  {
2567  int sym2;
2568  mz_uint code_len;
2569 #if TINFL_USE_64BIT_BITBUF
2570  if(num_bits < 30)
2571  {
2572  bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits);
2573  pIn_buf_cur += 4;
2574  num_bits += 32;
2575  }
2576 #else
2577  if(num_bits < 15)
2578  {
2579  bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
2580  pIn_buf_cur += 2;
2581  num_bits += 16;
2582  }
2583 #endif
2584  if((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
2585  code_len = sym2 >> 9;
2586  else
2587  {
2588  code_len = TINFL_FAST_LOOKUP_BITS;
2589  do
2590  {
2591  sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)];
2592  } while(sym2 < 0);
2593  }
2594  counter = sym2;
2595  bit_buf >>= code_len;
2596  num_bits -= code_len;
2597  if(counter & 256)
2598  break;
2599 
2600 #if !TINFL_USE_64BIT_BITBUF
2601  if(num_bits < 15)
2602  {
2603  bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
2604  pIn_buf_cur += 2;
2605  num_bits += 16;
2606  }
2607 #endif
2608  if((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
2609  code_len = sym2 >> 9;
2610  else
2611  {
2612  code_len = TINFL_FAST_LOOKUP_BITS;
2613  do
2614  {
2615  sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)];
2616  } while(sym2 < 0);
2617  }
2618  bit_buf >>= code_len;
2619  num_bits -= code_len;
2620 
2621  pOut_buf_cur[0] = (mz_uint8)counter;
2622  if(sym2 & 256)
2623  {
2624  pOut_buf_cur++;
2625  counter = sym2;
2626  break;
2627  }
2628  pOut_buf_cur[1] = (mz_uint8)sym2;
2629  pOut_buf_cur += 2;
2630  }
2631  }
2632  if((counter &= 511) == 256)
2633  break;
2634 
2635  num_extra = s_length_extra[counter - 257];
2636  counter = s_length_base[counter - 257];
2637  if(num_extra)
2638  {
2639  mz_uint extra_bits;
2640  TINFL_GET_BITS(25, extra_bits, num_extra);
2641  counter += extra_bits;
2642  }
2643 
2644  TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]);
2645  num_extra = s_dist_extra[dist];
2646  dist = s_dist_base[dist];
2647  if(num_extra)
2648  {
2649  mz_uint extra_bits;
2650  TINFL_GET_BITS(27, extra_bits, num_extra);
2651  dist += extra_bits;
2652  }
2653 
2654  dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
2655  if((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
2656  {
2658  }
2659 
2660  pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask);
2661 
2662  if((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end)
2663  {
2664  while(counter--)
2665  {
2666  while(pOut_buf_cur >= pOut_buf_end)
2667  {
2669  }
2670  *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask];
2671  }
2672  continue;
2673  }
2674 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
2675  else if((counter >= 9) && (counter <= dist))
2676  {
2677  const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
2678  do
2679  {
2680  ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0];
2681  ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1];
2682  pOut_buf_cur += 8;
2683  } while((pSrc += 8) < pSrc_end);
2684  if((counter &= 7) < 3)
2685  {
2686  if(counter)
2687  {
2688  pOut_buf_cur[0] = pSrc[0];
2689  if(counter > 1)
2690  pOut_buf_cur[1] = pSrc[1];
2691  pOut_buf_cur += counter;
2692  }
2693  continue;
2694  }
2695  }
2696 #endif
2697  do
2698  {
2699  pOut_buf_cur[0] = pSrc[0];
2700  pOut_buf_cur[1] = pSrc[1];
2701  pOut_buf_cur[2] = pSrc[2];
2702  pOut_buf_cur += 3;
2703  pSrc += 3;
2704  } while((int)(counter -= 3) > 2);
2705  if((int)counter > 0)
2706  {
2707  pOut_buf_cur[0] = pSrc[0];
2708  if((int)counter > 1)
2709  pOut_buf_cur[1] = pSrc[1];
2710  pOut_buf_cur += counter;
2711  }
2712  }
2713  }
2714  } while(!(r->m_final & 1));
2715 
2716  /* 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. */
2717  /* 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. */
2718  TINFL_SKIP_BITS(32, num_bits & 7);
2719  while((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8))
2720  {
2721  --pIn_buf_cur;
2722  num_bits -= 8;
2723  }
2724  bit_buf &= (tinfl_bit_buf_t)((1ULL << num_bits) - 1ULL);
2725  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). */
2726 
2727  if(decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
2728  {
2729  for(counter = 0; counter < 4; ++counter)
2730  {
2731  mz_uint s;
2732  if(num_bits)
2733  TINFL_GET_BITS(41, s, 8);
2734  else
2735  TINFL_GET_BYTE(42, s);
2736  r->m_z_adler32 = (r->m_z_adler32 << 8) | s;
2737  }
2738  }
2740 
2742 
2743 common_exit:
2744  /* As long as we aren't telling the caller that we NEED more input to make forward progress: */
2745  /* 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. */
2746  /* 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. */
2748  {
2749  while((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8))
2750  {
2751  --pIn_buf_cur;
2752  num_bits -= 8;
2753  }
2754  }
2755  r->m_num_bits = num_bits;
2756  r->m_bit_buf = bit_buf & (tinfl_bit_buf_t)((1ULL << num_bits) - 1ULL);
2757  r->m_dist = dist;
2758  r->m_counter = counter;
2759  r->m_num_extra = num_extra;
2760  r->m_dist_from_out_buf_start = dist_from_out_buf_start;
2761  *pIn_buf_size = pIn_buf_cur - pIn_buf_next;
2762  *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
2763  if((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0))
2764  {
2765  const mz_uint8 *ptr = pOut_buf_next;
2766  size_t buf_len = *pOut_buf_size;
2767  mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16;
2768  size_t block_len = buf_len % 5552;
2769  while(buf_len)
2770  {
2771  for(i = 0; i + 7 < block_len; i += 8, ptr += 8)
2772  {
2773  s1 += ptr[0], s2 += s1;
2774  s1 += ptr[1], s2 += s1;
2775  s1 += ptr[2], s2 += s1;
2776  s1 += ptr[3], s2 += s1;
2777  s1 += ptr[4], s2 += s1;
2778  s1 += ptr[5], s2 += s1;
2779  s1 += ptr[6], s2 += s1;
2780  s1 += ptr[7], s2 += s1;
2781  }
2782  for(; i < block_len; ++i)
2783  s1 += *ptr++, s2 += s1;
2784  s1 %= 65521U, s2 %= 65521U;
2785  buf_len -= block_len;
2786  block_len = 5552;
2787  }
2788  r->m_check_adler32 = (s2 << 16) + s1;
2789  if((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32))
2791  }
2792  return status;
2793 }
2794 
2795 /* Higher level helper functions. */
2796 void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
2797 {
2798  tinfl_decompressor decomp;
2799  void *pBuf = NULL, *pNew_buf;
2800  size_t src_buf_ofs = 0, out_buf_capacity = 0;
2801  *pOut_len = 0;
2802  tinfl_init(&decomp);
2803  for(;;)
2804  {
2805  size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity;
2806  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,
2808  if((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT))
2809  {
2810  MZ_FREE(pBuf);
2811  *pOut_len = 0;
2812  return NULL;
2813  }
2814  src_buf_ofs += src_buf_size;
2815  *pOut_len += dst_buf_size;
2816  if(status == TINFL_STATUS_DONE)
2817  break;
2818  new_out_buf_capacity = out_buf_capacity * 2;
2819  if(new_out_buf_capacity < 128)
2820  new_out_buf_capacity = 128;
2821  pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity);
2822  if(!pNew_buf)
2823  {
2824  MZ_FREE(pBuf);
2825  *pOut_len = 0;
2826  return NULL;
2827  }
2828  pBuf = pNew_buf;
2829  out_buf_capacity = new_out_buf_capacity;
2830  }
2831  return pBuf;
2832 }
2833 
2834 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)
2835 {
2836  tinfl_decompressor decomp;
2837  tinfl_status status;
2838  tinfl_init(&decomp);
2839  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);
2840  return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len;
2841 }
2842 
2843 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)
2844 {
2845  int result = 0;
2846  tinfl_decompressor decomp;
2848  size_t in_buf_ofs = 0, dict_ofs = 0;
2849  if(!pDict)
2850  return TINFL_STATUS_FAILED;
2851  tinfl_init(&decomp);
2852  for(;;)
2853  {
2854  size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs;
2855  tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8 *)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size,
2857  in_buf_ofs += in_buf_size;
2858  if((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user)))
2859  break;
2860  if(status != TINFL_STATUS_HAS_MORE_OUTPUT)
2861  {
2862  result = (status == TINFL_STATUS_DONE);
2863  break;
2864  }
2865  dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1);
2866  }
2867  MZ_FREE(pDict);
2868  *pIn_buf_size = in_buf_ofs;
2869  return result;
2870 }
2871 
2873 {
2875  if(pDecomp)
2876  tinfl_init(pDecomp);
2877  return pDecomp;
2878 }
2879 
2881 {
2882  MZ_FREE(pDecomp);
2883 }
2884 
2885 #ifdef __cplusplus
2886 }
2887 #endif
2888 /**************************************************************************
2889  *
2890  * Copyright 2013-2014 RAD Game Tools and Valve Software
2891  * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
2892  * Copyright 2016 Martin Raiber
2893  * All Rights Reserved.
2894  *
2895  * Permission is hereby granted, free of charge, to any person obtaining a copy
2896  * of this software and associated documentation files (the "Software"), to deal
2897  * in the Software without restriction, including without limitation the rights
2898  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2899  * copies of the Software, and to permit persons to whom the Software is
2900  * furnished to do so, subject to the following conditions:
2901  *
2902  * The above copyright notice and this permission notice shall be included in
2903  * all copies or substantial portions of the Software.
2904  *
2905  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2906  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2907  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2908  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2909  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2910  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2911  * THE SOFTWARE.
2912  *
2913  **************************************************************************/
2914 
2915 
2916 #ifdef __cplusplus
2917 extern "C" {
2918 #endif
2919 
2920 /* ------------------- .ZIP archive reading */
2921 
2922 #ifdef MINIZ_NO_STDIO
2923 #define MZ_FILE void *
2924 #else
2925 #include <sys/stat.h>
2926 
2927 #if defined(_MSC_VER) || defined(__MINGW64__)
2928 static FILE *mz_fopen(const char *pFilename, const char *pMode)
2929 {
2930  FILE *pFile = NULL;
2931  fopen_s(&pFile, pFilename, pMode);
2932  return pFile;
2933 }
2934 static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream)
2935 {
2936  FILE *pFile = NULL;
2937  if(freopen_s(&pFile, pPath, pMode, pStream))
2938  return NULL;
2939  return pFile;
2940 }
2941 #ifndef MINIZ_NO_TIME
2942 #include <sys/utime.h>
2943 #endif
2944 #define MZ_FOPEN mz_fopen
2945 #define MZ_FCLOSE fclose
2946 #define MZ_FREAD fread
2947 #define MZ_FWRITE fwrite
2948 #define MZ_FTELL64 _ftelli64
2949 #define MZ_FSEEK64 _fseeki64
2950 #define MZ_FILE_STAT_STRUCT _stat
2951 #define MZ_FILE_STAT _stat
2952 #define MZ_FFLUSH fflush
2953 #define MZ_FREOPEN mz_freopen
2954 #define MZ_DELETE_FILE remove
2955 #elif defined(__MINGW32__)
2956 #ifndef MINIZ_NO_TIME
2957 #include <sys/utime.h>
2958 #endif
2959 #define MZ_FOPEN(f, m) fopen(f, m)
2960 #define MZ_FCLOSE fclose
2961 #define MZ_FREAD fread
2962 #define MZ_FWRITE fwrite
2963 #define MZ_FTELL64 ftello64
2964 #define MZ_FSEEK64 fseeko64
2965 #define MZ_FILE_STAT_STRUCT _stat
2966 #define MZ_FILE_STAT _stat
2967 #define MZ_FFLUSH fflush
2968 #define MZ_FREOPEN(f, m, s) freopen(f, m, s)
2969 #define MZ_DELETE_FILE remove
2970 #elif defined(__TINYC__)
2971 #ifndef MINIZ_NO_TIME
2972 #include <sys/utime.h>
2973 #endif
2974 #define MZ_FOPEN(f, m) fopen(f, m)
2975 #define MZ_FCLOSE fclose
2976 #define MZ_FREAD fread
2977 #define MZ_FWRITE fwrite
2978 #define MZ_FTELL64 ftell
2979 #define MZ_FSEEK64 fseek
2980 #define MZ_FILE_STAT_STRUCT stat
2981 #define MZ_FILE_STAT stat
2982 #define MZ_FFLUSH fflush
2983 #define MZ_FREOPEN(f, m, s) freopen(f, m, s)
2984 #define MZ_DELETE_FILE remove
2985 #elif defined(__GNUC__) && _LARGEFILE64_SOURCE
2986 #ifndef MINIZ_NO_TIME
2987 #include <utime.h>
2988 #endif
2989 #define MZ_FOPEN(f, m) fopen64(f, m)
2990 #define MZ_FCLOSE fclose
2991 #define MZ_FREAD fread
2992 #define MZ_FWRITE fwrite
2993 #define MZ_FTELL64 ftello64
2994 #define MZ_FSEEK64 fseeko64
2995 #define MZ_FILE_STAT_STRUCT stat64
2996 #define MZ_FILE_STAT stat64
2997 #define MZ_FFLUSH fflush
2998 #define MZ_FREOPEN(p, m, s) freopen64(p, m, s)
2999 #define MZ_DELETE_FILE remove
3000 #elif defined(__APPLE__) && _LARGEFILE64_SOURCE
3001 #ifndef MINIZ_NO_TIME
3002 #include <utime.h>
3003 #endif
3004 #define MZ_FOPEN(f, m) fopen(f, m)
3005 #define MZ_FCLOSE fclose
3006 #define MZ_FREAD fread
3007 #define MZ_FWRITE fwrite
3008 #define MZ_FTELL64 ftello
3009 #define MZ_FSEEK64 fseeko
3010 #define MZ_FILE_STAT_STRUCT stat
3011 #define MZ_FILE_STAT stat
3012 #define MZ_FFLUSH fflush
3013 #define MZ_FREOPEN(p, m, s) freopen(p, m, s)
3014 #define MZ_DELETE_FILE remove
3015 
3016 #else
3017 #pragma message("Using fopen, ftello, fseeko, stat() etc. path for file I/O - this path may not support large files.")
3018 #ifndef MINIZ_NO_TIME
3019 #include <utime.h>
3020 #endif
3021 #define MZ_FOPEN(f, m) fopen(f, m)
3022 #define MZ_FCLOSE fclose
3023 #define MZ_FREAD fread
3024 #define MZ_FWRITE fwrite
3025 #define MZ_FTELL64 ftello
3026 #define MZ_FSEEK64 fseeko
3027 #define MZ_FILE_STAT_STRUCT stat
3028 #define MZ_FILE_STAT stat
3029 #define MZ_FFLUSH fflush
3030 #define MZ_FREOPEN(f, m, s) freopen(f, m, s)
3031 #define MZ_DELETE_FILE remove
3032 #endif /* #ifdef _MSC_VER */
3033 #endif /* #ifdef MINIZ_NO_STDIO */
3034 
3035 #define MZ_TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c))
3036 
3037 /* 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. */
3038 enum
3039 {
3040  /* ZIP archive identifiers and record sizes */
3047 
3048  /* ZIP64 archive identifier and record sizes */
3057 
3058  /* Central directory header record offsets */
3076 
3077  /* Local directory header offsets */
3090 
3091  /* End of central directory offsets */
3100 
3101  /* ZIP64 End of central directory locator offsets */
3102  MZ_ZIP64_ECDL_SIG_OFS = 0, /* 4 bytes */
3106 
3107  /* ZIP64 End of central directory header offsets */
3108  MZ_ZIP64_ECDH_SIG_OFS = 0, /* 4 bytes */
3116  MZ_ZIP64_ECDH_CDIR_SIZE_OFS = 40, /* 8 bytes */
3117  MZ_ZIP64_ECDH_CDIR_OFS_OFS = 48, /* 8 bytes */
3125 };
3126 
3127 typedef struct
3128 {
3129  void *m_p;
3130  size_t m_size, m_capacity;
3132 } mz_zip_array;
3133 
3135 {
3139 
3140  /* The flags passed in when the archive is initially opened. */
3141  uint32_t m_init_flags;
3142 
3143  /* MZ_TRUE if the archive has a zip64 end of central directory headers, etc. */
3145 
3146  /* 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.) */
3148 
3149  /* These fields are used by the file, FILE, memory, and memory/heap read/write helpers. */
3152 
3153  void *m_pMem;
3154  size_t m_mem_size;
3156 };
3157 
3158 #define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size) (array_ptr)->m_element_size = element_size
3159 
3160 #if defined(DEBUG) || defined(_DEBUG) || defined(NDEBUG)
3161 static MZ_FORCEINLINE mz_uint mz_zip_array_range_check(const mz_zip_array *pArray, mz_uint index)
3162 {
3163  MZ_ASSERT(index < pArray->m_size);
3164  return index;
3165 }
3166 #define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[mz_zip_array_range_check(array_ptr, index)]
3167 #else
3168 #define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[index]
3169 #endif
3170 
3171 static MZ_FORCEINLINE void mz_zip_array_init(mz_zip_array *pArray, mz_uint32 element_size)
3172 {
3173  memset(pArray, 0, sizeof(mz_zip_array));
3174  pArray->m_element_size = element_size;
3175 }
3176 
3178 {
3179  pZip->m_pFree(pZip->m_pAlloc_opaque, pArray->m_p);
3180  memset(pArray, 0, sizeof(mz_zip_array));
3181 }
3182 
3183 static mz_bool mz_zip_array_ensure_capacity(mz_zip_archive *pZip, mz_zip_array *pArray, size_t min_new_capacity, mz_uint growing)
3184 {
3185  void *pNew_p;
3186  size_t new_capacity = min_new_capacity;
3187  MZ_ASSERT(pArray->m_element_size);
3188  if(pArray->m_capacity >= min_new_capacity)
3189  return MZ_TRUE;
3190  if(growing)
3191  {
3192  new_capacity = MZ_MAX(1, pArray->m_capacity);
3193  while(new_capacity < min_new_capacity)
3194  new_capacity *= 2;
3195  }
3196  if(NULL == (pNew_p = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pArray->m_p, pArray->m_element_size, new_capacity)))
3197  return MZ_FALSE;
3198  pArray->m_p = pNew_p;
3199  pArray->m_capacity = new_capacity;
3200  return MZ_TRUE;
3201 }
3202 
3203 static MZ_FORCEINLINE mz_bool mz_zip_array_reserve(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_capacity, mz_uint growing)
3204 {
3205  if(new_capacity > pArray->m_capacity)
3206  {
3207  if(!mz_zip_array_ensure_capacity(pZip, pArray, new_capacity, growing))
3208  return MZ_FALSE;
3209  }
3210  return MZ_TRUE;
3211 }
3212 
3213 static MZ_FORCEINLINE mz_bool mz_zip_array_resize(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_size, mz_uint growing)
3214 {
3215  if(new_size > pArray->m_capacity)
3216  {
3217  if(!mz_zip_array_ensure_capacity(pZip, pArray, new_size, growing))
3218  return MZ_FALSE;
3219  }
3220  pArray->m_size = new_size;
3221  return MZ_TRUE;
3222 }
3223 
3225 {
3226  return mz_zip_array_reserve(pZip, pArray, pArray->m_size + n, MZ_TRUE);
3227 }
3228 
3229 static MZ_FORCEINLINE mz_bool mz_zip_array_push_back(mz_zip_archive *pZip, mz_zip_array *pArray, const void *pElements, size_t n)
3230 {
3231  size_t orig_size = pArray->m_size;
3232  if(!mz_zip_array_resize(pZip, pArray, orig_size + n, MZ_TRUE))
3233  return MZ_FALSE;
3234  memcpy((mz_uint8 *)pArray->m_p + orig_size * pArray->m_element_size, pElements, n * pArray->m_element_size);
3235  return MZ_TRUE;
3236 }
3237 
3238 #ifndef MINIZ_NO_TIME
3239 static MZ_TIME_T mz_zip_dos_to_time_t(int dos_time, int dos_date)
3240 {
3241  struct tm tm;
3242  memset(&tm, 0, sizeof(tm));
3243  tm.tm_isdst = -1;
3244  tm.tm_year = ((dos_date >> 9) & 127) + 1980 - 1900;
3245  tm.tm_mon = ((dos_date >> 5) & 15) - 1;
3246  tm.tm_mday = dos_date & 31;
3247  tm.tm_hour = (dos_time >> 11) & 31;
3248  tm.tm_min = (dos_time >> 5) & 63;
3249  tm.tm_sec = (dos_time << 1) & 62;
3250  return mktime(&tm);
3251 }
3252 
3253 static void mz_zip_time_t_to_dos_time(MZ_TIME_T time, mz_uint16 *pDOS_time, mz_uint16 *pDOS_date)
3254 {
3255 #ifdef _MSC_VER
3256  struct tm tm_struct;
3257  struct tm *tm = &tm_struct;
3258  errno_t err = localtime_s(tm, &time);
3259  if(err)
3260  {
3261  *pDOS_date = 0;
3262  *pDOS_time = 0;
3263  return;
3264  }
3265 #else
3266  struct tm *tm = localtime(&time);
3267 #endif /* #ifdef _MSC_VER */
3268 
3269  *pDOS_time = (mz_uint16)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) + ((tm->tm_sec) >> 1));
3270  *pDOS_date = (mz_uint16)(((tm->tm_year + 1900 - 1980) << 9) + ((tm->tm_mon + 1) << 5) + tm->tm_mday);
3271 }
3272 
3273 #ifndef MINIZ_NO_STDIO
3274 static mz_bool mz_zip_get_file_modified_time(const char *pFilename, MZ_TIME_T *pTime)
3275 {
3276  struct MZ_FILE_STAT_STRUCT file_stat;
3277 
3278  /* On Linux with x86 glibc, this call will fail on large files (I think >= 0x80000000 bytes) unless you compiled with _LARGEFILE64_SOURCE. Argh. */
3279  if(MZ_FILE_STAT(pFilename, &file_stat) != 0)
3280  return MZ_FALSE;
3281 
3282  *pTime = file_stat.st_mtime;
3283 
3284  return MZ_TRUE;
3285 }
3286 
3287 static mz_bool mz_zip_set_file_times(const char *pFilename, MZ_TIME_T access_time, MZ_TIME_T modified_time)
3288 {
3289  struct utimbuf t;
3290 
3291  memset(&t, 0, sizeof(t));
3292  t.actime = access_time;
3293  t.modtime = modified_time;
3294 
3295  return !utime(pFilename, &t);
3296 }
3297 #endif /* #ifndef MINIZ_NO_STDIO */
3298 #endif /* #ifndef MINIZ_NO_TIME */
3299 
3301 {
3302  if(pZip)
3303  pZip->m_last_error = err_num;
3304  return MZ_FALSE;
3305 }
3306 
3308 {
3309  (void)flags;
3310  if((!pZip) || (pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
3312 
3313  if(!pZip->m_pAlloc)
3315  if(!pZip->m_pFree)
3316  pZip->m_pFree = miniz_def_free_func;
3317  if(!pZip->m_pRealloc)
3319 
3320  pZip->m_archive_size = 0;
3321  pZip->m_central_directory_file_ofs = 0;
3322  pZip->m_total_files = 0;
3323  pZip->m_last_error = MZ_ZIP_NO_ERROR;
3324 
3325  if(NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state))))
3326  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
3327 
3328  memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state));
3332  pZip->m_pState->m_init_flags = flags;
3333  pZip->m_pState->m_zip64 = MZ_FALSE;
3335 
3337 
3338  return MZ_TRUE;
3339 }
3340 
3341 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)
3342 {
3343  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;
3344  const mz_uint8 *pR = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, r_index));
3346  mz_uint8 l = 0, r = 0;
3349  pE = pL + MZ_MIN(l_len, r_len);
3350  while(pL < pE)
3351  {
3352  if((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR)))
3353  break;
3354  pL++;
3355  pR++;
3356  }
3357  return (pL == pE) ? (l_len < r_len) : (l < r);
3358 }
3359 
3360 #define MZ_SWAP_UINT32(a, b) \
3361  do \
3362  { \
3363  mz_uint32 t = a; \
3364  a = b; \
3365  b = t; \
3366  } \
3367  MZ_MACRO_END
3368 
3369 /* 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.) */
3371 {
3372  mz_zip_internal_state *pState = pZip->m_pState;
3373  const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
3374  const mz_zip_array *pCentral_dir = &pState->m_central_dir;
3375  mz_uint32 *pIndices;
3376  mz_uint32 start, end;
3377  const mz_uint32 size = pZip->m_total_files;
3378 
3379  if(size <= 1U)
3380  return;
3381 
3383 
3384  start = (size - 2U) >> 1U;
3385  for(;;)
3386  {
3387  mz_uint64 child, root = start;
3388  for(;;)
3389  {
3390  if((child = (root << 1U) + 1U) >= size)
3391  break;
3392  child += (((child + 1U) < size) && (mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1U])));
3393  if(!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child]))
3394  break;
3395  MZ_SWAP_UINT32(pIndices[root], pIndices[child]);
3396  root = child;
3397  }
3398  if(!start)
3399  break;
3400  start--;
3401  }
3402 
3403  end = size - 1;
3404  while(end > 0)
3405  {
3406  mz_uint64 child, root = 0;
3407  MZ_SWAP_UINT32(pIndices[end], pIndices[0]);
3408  for(;;)
3409  {
3410  if((child = (root << 1U) + 1U) >= end)
3411  break;
3412  child += (((child + 1U) < end) && mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1U]));
3413  if(!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child]))
3414  break;
3415  MZ_SWAP_UINT32(pIndices[root], pIndices[child]);
3416  root = child;
3417  }
3418  end--;
3419  }
3420 }
3421 
3423 {
3424  mz_int64 cur_file_ofs;
3425  mz_uint32 buf_u32[4096 / sizeof(mz_uint32)];
3426  mz_uint8 *pBuf = (mz_uint8 *)buf_u32;
3427 
3428  /* Basic sanity checks - reject files which are too small */
3429  if(pZip->m_archive_size < record_size)
3430  return MZ_FALSE;
3431 
3432  /* Find the record by scanning the file from the end towards the beginning. */
3433  cur_file_ofs = MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)sizeof(buf_u32), 0);
3434  for(;;)
3435  {
3436  int i, n = (int)MZ_MIN(sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs);
3437 
3438  if(pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n)
3439  return MZ_FALSE;
3440 
3441  for(i = n - 4; i >= 0; --i)
3442  {
3443  mz_uint s = MZ_READ_LE32(pBuf + i);
3444  if(s == record_sig)
3445  {
3446  if((pZip->m_archive_size - (cur_file_ofs + i)) >= record_size)
3447  break;
3448  }
3449  }
3450 
3451  if(i >= 0)
3452  {
3453  cur_file_ofs += i;
3454  break;
3455  }
3456 
3457  /* Give up if we've searched the entire file, or we've gone back "too far" (~64kb) */
3458  if((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >= (MZ_UINT16_MAX + record_size)))
3459  return MZ_FALSE;
3460 
3461  cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0);
3462  }
3463 
3464  *pOfs = cur_file_ofs;
3465  return MZ_TRUE;
3466 }
3467 
3469 {
3470  mz_uint cdir_size = 0, cdir_entries_on_this_disk = 0, num_this_disk = 0, cdir_disk_index = 0;
3471  mz_uint64 cdir_ofs = 0;
3472  mz_int64 cur_file_ofs = 0;
3473  const mz_uint8 *p;
3474 
3475  mz_uint32 buf_u32[4096 / sizeof(mz_uint32)];
3476  mz_uint8 *pBuf = (mz_uint8 *)buf_u32;
3477  mz_bool sort_central_dir = ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0);
3478  mz_uint32 zip64_end_of_central_dir_locator_u32[(MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
3479  mz_uint8 *pZip64_locator = (mz_uint8 *)zip64_end_of_central_dir_locator_u32;
3480 
3481  mz_uint32 zip64_end_of_central_dir_header_u32[(MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
3482  mz_uint8 *pZip64_end_of_central_dir = (mz_uint8 *)zip64_end_of_central_dir_header_u32;
3483 
3484  mz_uint64 zip64_end_of_central_dir_ofs = 0;
3485 
3486  /* 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. */
3489 
3492 
3493  /* Read and verify the end of central directory record. */
3496 
3499 
3501  {
3503  {
3505  {
3506  zip64_end_of_central_dir_ofs = MZ_READ_LE64(pZip64_locator + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS);
3507  if(zip64_end_of_central_dir_ofs > (pZip->m_archive_size - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE))
3509 
3510  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)
3511  {
3513  {
3514  pZip->m_pState->m_zip64 = MZ_TRUE;
3515  }
3516  }
3517  }
3518  }
3519  }
3520 
3522  cdir_entries_on_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS);
3523  num_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS);
3524  cdir_disk_index = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS);
3525  cdir_size = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_SIZE_OFS);
3526  cdir_ofs = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS);
3527 
3528  if(pZip->m_pState->m_zip64)
3529  {
3530  mz_uint32 zip64_total_num_of_disks = MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS);
3531  mz_uint64 zip64_cdir_total_entries = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS);
3532  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);
3533  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);
3534  mz_uint64 zip64_size_of_central_directory = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_SIZE_OFS);
3535 
3536  if(zip64_size_of_end_of_central_dir_record < (MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE - 12))
3538 
3539  if(zip64_total_num_of_disks != 1U)
3541 
3542  /* Check for miniz's practical limits */
3543  if(zip64_cdir_total_entries > MZ_UINT32_MAX)
3545 
3546  pZip->m_total_files = (mz_uint32)zip64_cdir_total_entries;
3547 
3548  if(zip64_cdir_total_entries_on_this_disk > MZ_UINT32_MAX)
3550 
3551  cdir_entries_on_this_disk = (mz_uint32)zip64_cdir_total_entries_on_this_disk;
3552 
3553  /* Check for miniz's current practical limits (sorry, this should be enough for millions of files) */
3554  if(zip64_size_of_central_directory > MZ_UINT32_MAX)
3556 
3557  cdir_size = (mz_uint32)zip64_size_of_central_directory;
3558 
3559  num_this_disk = MZ_READ_LE32(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_NUM_THIS_DISK_OFS);
3560 
3561  cdir_disk_index = MZ_READ_LE32(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_NUM_DISK_CDIR_OFS);
3562 
3563  cdir_ofs = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_OFS_OFS);
3564  }
3565 
3566  if(pZip->m_total_files != cdir_entries_on_this_disk)
3568 
3569  if(((num_this_disk | cdir_disk_index) != 0) && ((num_this_disk != 1) || (cdir_disk_index != 1)))
3571 
3572  if(cdir_size < pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)
3574 
3575  if((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size)
3577 
3578  pZip->m_central_directory_file_ofs = cdir_ofs;
3579 
3580  if(pZip->m_total_files)
3581  {
3582  mz_uint i, n;
3583  /* 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. */
3584  if((!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir, cdir_size, MZ_FALSE)) ||
3586  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
3587 
3588  if(sort_central_dir)
3589  {
3591  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
3592  }
3593 
3594  if(pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs, pZip->m_pState->m_central_dir.m_p, cdir_size) != cdir_size)
3596 
3597  /* Now create an index into the central directory file records, do some basic sanity checking on each record */
3598  p = (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p;
3599  for(n = cdir_size, i = 0; i < pZip->m_total_files; ++i)
3600  {
3601  mz_uint total_header_size, disk_index, bit_flags, filename_size, ext_data_size;
3602  mz_uint64 comp_size, decomp_size, local_header_ofs;
3603 
3606 
3608 
3609  if(sort_central_dir)
3611 
3614  local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
3615  filename_size = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
3616  ext_data_size = MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS);
3617 
3619  (ext_data_size) &&
3620  (MZ_MAX(MZ_MAX(comp_size, decomp_size), local_header_ofs) == MZ_UINT32_MAX))
3621  {
3622  /* Attempt to find zip64 extended information field in the entry's extra data */
3623  mz_uint32 extra_size_remaining = ext_data_size;
3624 
3625  if(extra_size_remaining)
3626  {
3627  const mz_uint8 *pExtra_data = p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size;
3628 
3629  do
3630  {
3631  if(extra_size_remaining < (sizeof(mz_uint16) * 2))
3633 
3634  mz_uint32 field_id = MZ_READ_LE16(pExtra_data);
3635  mz_uint32 field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16));
3636 
3637  if((field_data_size + sizeof(mz_uint16) * 2) > extra_size_remaining)
3639 
3641  {
3642  /* 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). */
3643  pZip->m_pState->m_zip64 = MZ_TRUE;
3645  break;
3646  }
3647 
3648  pExtra_data += sizeof(mz_uint16) * 2 + field_data_size;
3649  extra_size_remaining = extra_size_remaining - sizeof(mz_uint16) * 2 - field_data_size;
3650  } while(extra_size_remaining);
3651  }
3652  }
3653 
3654  /* I've seen archives that aren't marked as zip64 that uses zip64 ext data, argh */
3655  if((comp_size != MZ_UINT32_MAX) && (decomp_size != MZ_UINT32_MAX))
3656  {
3657  if(((!MZ_READ_LE32(p + MZ_ZIP_CDH_METHOD_OFS)) && (decomp_size != comp_size)) || (decomp_size && !comp_size))
3659  }
3660 
3661  disk_index = MZ_READ_LE16(p + MZ_ZIP_CDH_DISK_START_OFS);
3662  if((disk_index == MZ_UINT16_MAX) || ((disk_index != num_this_disk) && (disk_index != 1)))
3664 
3665  if(comp_size != MZ_UINT32_MAX)
3666  {
3669  }
3670 
3671  bit_flags = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
3674 
3677 
3678  n -= total_header_size;
3679  p += total_header_size;
3680  }
3681  }
3682 
3683  if(sort_central_dir)
3685 
3686  return MZ_TRUE;
3687 }
3688 
3690 {
3691  if(pZip)
3692  MZ_CLEAR_OBJ(*pZip);
3693 }
3694 
3696 {
3697  mz_bool status = MZ_TRUE;
3698 
3699  if(!pZip)
3700  return MZ_FALSE;
3701 
3702  if((!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
3703  {
3704  if(set_last_error)
3706 
3707  return MZ_FALSE;
3708  }
3709 
3710  if(pZip->m_pState)
3711  {
3712  mz_zip_internal_state *pState = pZip->m_pState;
3713  pZip->m_pState = NULL;
3714 
3715  mz_zip_array_clear(pZip, &pState->m_central_dir);
3716  mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
3718 
3719 #ifndef MINIZ_NO_STDIO
3720  if(pState->m_pFile)
3721  {
3722  if(pZip->m_zip_type == MZ_ZIP_TYPE_FILE)
3723  {
3724  if(MZ_FCLOSE(pState->m_pFile) == EOF)
3725  {
3726  if(set_last_error)
3728  status = MZ_FALSE;
3729  }
3730  }
3731  pState->m_pFile = NULL;
3732  }
3733 #endif /* #ifndef MINIZ_NO_STDIO */
3734 
3735  pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
3736  }
3738 
3739  return status;
3740 }
3741 
3743 {
3744  return mz_zip_reader_end_internal(pZip, MZ_TRUE);
3745 }
3747 {
3748  if((!pZip) || (!pZip->m_pRead))
3750 
3751  if(!mz_zip_reader_init_internal(pZip, flags))
3752  return MZ_FALSE;
3753 
3754  pZip->m_zip_type = MZ_ZIP_TYPE_USER;
3755  pZip->m_archive_size = size;
3756 
3757  if(!mz_zip_reader_read_central_dir(pZip, flags))
3758  {
3760  return MZ_FALSE;
3761  }
3762 
3763  return MZ_TRUE;
3764 }
3765 
3766 static size_t mz_zip_mem_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
3767 {
3768  mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
3769  size_t s = (file_ofs >= pZip->m_archive_size) ? 0 : (size_t)MZ_MIN(pZip->m_archive_size - file_ofs, n);
3770  memcpy(pBuf, (const mz_uint8 *)pZip->m_pState->m_pMem + file_ofs, s);
3771  return s;
3772 }
3773 
3774 mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint flags)
3775 {
3776  if(!pMem)
3778 
3781 
3782  if(!mz_zip_reader_init_internal(pZip, flags))
3783  return MZ_FALSE;
3784 
3786  pZip->m_archive_size = size;
3787  pZip->m_pRead = mz_zip_mem_read_func;
3788  pZip->m_pIO_opaque = pZip;
3789 
3790 #ifdef __cplusplus
3791  pZip->m_pState->m_pMem = const_cast<void *>(pMem);
3792 #else
3793  pZip->m_pState->m_pMem = (void *)pMem;
3794 #endif
3795 
3796  pZip->m_pState->m_mem_size = size;
3797 
3798  if(!mz_zip_reader_read_central_dir(pZip, flags))
3799  {
3801  return MZ_FALSE;
3802  }
3803 
3804  return MZ_TRUE;
3805 }
3806 
3807 #ifndef MINIZ_NO_STDIO
3808 static size_t mz_zip_file_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
3809 {
3810  mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
3811  mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
3812 
3813  file_ofs += pZip->m_pState->m_file_archive_start_ofs;
3814 
3815  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))))
3816  return 0;
3817 
3818  return MZ_FREAD(pBuf, 1, n, pZip->m_pState->m_pFile);
3819 }
3820 
3821 mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags)
3822 {
3823  return mz_zip_reader_init_file_v2(pZip, pFilename, flags, 0, 0);
3824 }
3825 
3826 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)
3827 {
3828  if((!pZip) || (!pFilename) || ((archive_size) && (archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)))
3830 
3831  mz_uint64 file_size;
3832  MZ_FILE *pFile = MZ_FOPEN(pFilename, "rb");
3833  if(!pFile)
3835 
3836  file_size = archive_size;
3837  if(!file_size)
3838  {
3839  if(MZ_FSEEK64(pFile, 0, SEEK_END))
3840  {
3841  MZ_FCLOSE(pFile);
3843  }
3844 
3845  file_size = MZ_FTELL64(pFile);
3846  }
3847 
3848  /* TODO: Better sanity check archive_size and the # of actual remaining bytes */
3849 
3852 
3853  if(!mz_zip_reader_init_internal(pZip, flags))
3854  {
3855  MZ_FCLOSE(pFile);
3856  return MZ_FALSE;
3857  }
3858 
3859  pZip->m_zip_type = MZ_ZIP_TYPE_FILE;
3861  pZip->m_pIO_opaque = pZip;
3862  pZip->m_pState->m_pFile = pFile;
3863  pZip->m_archive_size = file_size;
3864  pZip->m_pState->m_file_archive_start_ofs = file_start_ofs;
3865 
3866  if(!mz_zip_reader_read_central_dir(pZip, flags))
3867  {
3869  return MZ_FALSE;
3870  }
3871 
3872  return MZ_TRUE;
3873 }
3874 
3876 {
3877  mz_uint64 cur_file_ofs;
3878 
3879  if((!pZip) || (!pFile))
3881 
3882  cur_file_ofs = MZ_FTELL64(pFile);
3883 
3884  if(!archive_size)
3885  {
3886  if(MZ_FSEEK64(pFile, 0, SEEK_END))
3888 
3889  archive_size = MZ_FTELL64(pFile) - cur_file_ofs;
3890 
3891  if(archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
3893  }
3894 
3895  if(!mz_zip_reader_init_internal(pZip, flags))
3896  return MZ_FALSE;
3897 
3898  pZip->m_zip_type = MZ_ZIP_TYPE_CFILE;
3900 
3901  pZip->m_pIO_opaque = pZip;
3902  pZip->m_pState->m_pFile = pFile;
3903  pZip->m_archive_size = archive_size;
3904  pZip->m_pState->m_file_archive_start_ofs = cur_file_ofs;
3905 
3906  if(!mz_zip_reader_read_central_dir(pZip, flags))
3907  {
3909  return MZ_FALSE;
3910  }
3911 
3912  return MZ_TRUE;
3913 }
3914 
3915 #endif /* #ifndef MINIZ_NO_STDIO */
3916 
3918 {
3919  if((!pZip) || (!pZip->m_pState) || (file_index >= pZip->m_total_files))
3920  return NULL;
3922 }
3923 
3925 {
3926  mz_uint m_bit_flag;
3927  const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
3928  if(!p)
3929  {
3931  return MZ_FALSE;
3932  }
3933 
3934  m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
3936 }
3937 
3939 {
3940  mz_uint bit_flag;
3941  mz_uint method;
3942 
3943  const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
3944  if(!p)
3945  {
3947  return MZ_FALSE;
3948  }
3949 
3950  method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS);
3951  bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
3952 
3953  if((method != 0) && (method != MZ_DEFLATED))
3954  {
3956  return MZ_FALSE;
3957  }
3958 
3960  {
3962  return MZ_FALSE;
3963  }
3964 
3966  {
3968  return MZ_FALSE;
3969  }
3970 
3971  return MZ_TRUE;
3972 }
3973 
3975 {
3976  mz_uint filename_len, attribute_mapping_id, external_attr;
3977  const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
3978  if(!p)
3979  {
3981  return MZ_FALSE;
3982  }
3983 
3984  filename_len = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
3985  if(filename_len)
3986  {
3987  if(*(p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_len - 1) == '/')
3988  return MZ_TRUE;
3989  }
3990 
3991  /* Bugfix: This code was also checking if the internal attribute was non-zero, which wasn't correct. */
3992  /* 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. */
3993  /* FIXME: Remove this check? Is it necessary - we already check the filename. */
3994  attribute_mapping_id = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS) >> 8;
3995  (void)attribute_mapping_id;
3996 
3997  external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS);
3998  if((external_attr & MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG) != 0)
3999  {
4000  return MZ_TRUE;
4001  }
4002 
4003  return MZ_FALSE;
4004 }
4005 
4006 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)
4007 {
4008  mz_uint n;
4009  const mz_uint8 *p = pCentral_dir_header;
4010 
4011  if(pFound_zip64_extra_data)
4012  *pFound_zip64_extra_data = MZ_FALSE;
4013 
4014  if((!p) || (!pStat))
4016 
4017  /* Extract fields from the central directory record. */
4018  pStat->m_file_index = file_index;
4024 #ifndef MINIZ_NO_TIME
4026 #endif
4033 
4034  /* Copy as much of the filename and comment as possible. */
4038  pStat->m_filename[n] = '\0';
4039 
4042  pStat->m_comment_size = n;
4044  pStat->m_comment[n] = '\0';
4045 
4046  /* Set some flags for convienance */
4047  pStat->m_is_directory = mz_zip_reader_is_file_a_directory(pZip, file_index);
4048  pStat->m_is_encrypted = mz_zip_reader_is_file_encrypted(pZip, file_index);
4049  pStat->m_is_supported = mz_zip_reader_is_file_supported(pZip, file_index);
4050 
4051  /* See if we need to read any zip64 extended information fields. */
4052  /* 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). */
4053  if(MZ_MAX(MZ_MAX(pStat->m_comp_size, pStat->m_uncomp_size), pStat->m_local_header_ofs) == MZ_UINT32_MAX)
4054  {
4055  /* Attempt to find zip64 extended information field in the entry's extra data */
4056  mz_uint32 extra_size_remaining = MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS);
4057 
4058  if(extra_size_remaining)
4059  {
4061 
4062  do
4063  {
4064  if(extra_size_remaining < (sizeof(mz_uint16) * 2))
4066 
4067  mz_uint32 field_id = MZ_READ_LE16(pExtra_data);
4068  mz_uint32 field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16));
4069 
4070  if((field_data_size + sizeof(mz_uint16) * 2) > extra_size_remaining)
4072 
4074  {
4075  const mz_uint8 *pField_data = pExtra_data + sizeof(mz_uint16) * 2;
4076  mz_uint32 field_data_remaining = field_data_size;
4077 
4078  if(pFound_zip64_extra_data)
4079  *pFound_zip64_extra_data = MZ_TRUE;
4080 
4081  if(pStat->m_uncomp_size == MZ_UINT32_MAX)
4082  {
4083  if(field_data_remaining < sizeof(mz_uint64))
4085 
4086  pStat->m_uncomp_size = MZ_READ_LE64(pField_data);
4087  pField_data += sizeof(mz_uint64);
4088  field_data_remaining -= sizeof(mz_uint64);
4089  }
4090 
4091  if(pStat->m_comp_size == MZ_UINT32_MAX)
4092  {
4093  if(field_data_remaining < sizeof(mz_uint64))
4095 
4096  pStat->m_comp_size = MZ_READ_LE64(pField_data);
4097  pField_data += sizeof(mz_uint64);
4098  field_data_remaining -= sizeof(mz_uint64);
4099  }
4100 
4101  if(pStat->m_local_header_ofs == MZ_UINT32_MAX)
4102  {
4103  if(field_data_remaining < sizeof(mz_uint64))
4105 
4106  pStat->m_local_header_ofs = MZ_READ_LE64(pField_data);
4107  pField_data += sizeof(mz_uint64);
4108  field_data_remaining -= sizeof(mz_uint64);
4109  }
4110 
4111  break;
4112  }
4113 
4114  pExtra_data += sizeof(mz_uint16) * 2 + field_data_size;
4115  extra_size_remaining = extra_size_remaining - sizeof(mz_uint16) * 2 - field_data_size;
4116  } while(extra_size_remaining);
4117  }
4118  }
4119 
4120  return MZ_TRUE;
4121 }
4122 
4123 static MZ_FORCEINLINE mz_bool mz_zip_string_equal(const char *pA, const char *pB, mz_uint len, mz_uint flags)
4124 {
4125  mz_uint i;
4126  if(flags & MZ_ZIP_FLAG_CASE_SENSITIVE)
4127  return 0 == memcmp(pA, pB, len);
4128  for(i = 0; i < len; ++i)
4129  if(MZ_TOLOWER(pA[i]) != MZ_TOLOWER(pB[i]))
4130  return MZ_FALSE;
4131  return MZ_TRUE;
4132 }
4133 
4134 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)
4135 {
4136  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;
4138  mz_uint8 l = 0, r = 0;
4140  pE = pL + MZ_MIN(l_len, r_len);
4141  while(pL < pE)
4142  {
4143  if((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR)))
4144  break;
4145  pL++;
4146  pR++;
4147  }
4148  return (pL == pE) ? (int)(l_len - r_len) : (l - r);
4149 }
4150 
4151 static mz_bool mz_zip_locate_file_binary_search(mz_zip_archive *pZip, const char *pFilename, mz_uint32 *pIndex)
4152 {
4153  mz_zip_internal_state *pState = pZip->m_pState;
4154  const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
4155  const mz_zip_array *pCentral_dir = &pState->m_central_dir;
4157  const uint32_t size = pZip->m_total_files;
4158  const mz_uint filename_len = (mz_uint)strlen(pFilename);
4159 
4160  if(pIndex)
4161  *pIndex = 0;
4162 
4163  if(size)
4164  {
4165  /* yes I could use uint32_t's, but then we would have to add some special case checks in the loop, argh, and */
4166  /* honestly the major expense here on 32-bit CPU's will still be the filename compare */
4167  mz_int64 l = 0, h = (mz_int64)size - 1;
4168 
4169  while(l <= h)
4170  {
4171  mz_int64 m = l + ((h - l) >> 1);
4172  uint32_t file_index = pIndices[(uint32_t)m];
4173 
4174  int comp = mz_zip_filename_compare(pCentral_dir, pCentral_dir_offsets, file_index, pFilename, filename_len);
4175  if(!comp)
4176  {
4177  if(pIndex)
4178  *pIndex = file_index;
4179  return MZ_TRUE;
4180  }
4181  else if(comp < 0)
4182  l = m + 1;
4183  else
4184  h = m - 1;
4185  }
4186  }
4187 
4189 }
4190 
4191 int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags)
4192 {
4193  mz_uint32 index;
4194  if(!mz_zip_reader_locate_file_v2(pZip, pName, pComment, flags, &index))
4195  return -1;
4196  else
4197  return (int)index;
4198 }
4199 
4200 mz_bool mz_zip_reader_locate_file_v2(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags, mz_uint32 *pIndex)
4201 {
4202  mz_uint file_index;
4203  size_t name_len, comment_len;
4204 
4205  if(pIndex)
4206  *pIndex = 0;
4207 
4208  if((!pZip) || (!pZip->m_pState) || (!pName))
4210 
4211  /* See if we can use a binary search */
4213  (pZip->m_zip_mode == MZ_ZIP_MODE_READING) &&
4214  ((flags & (MZ_ZIP_FLAG_IGNORE_PATH | MZ_ZIP_FLAG_CASE_SENSITIVE)) == 0) && (!pComment) && (pZip->m_pState->m_sorted_central_dir_offsets.m_size))
4215  {
4216  return mz_zip_locate_file_binary_search(pZip, pName, pIndex);
4217  }
4218 
4219  /* Locate the entry by scanning the entire central directory */
4220  name_len = strlen(pName);
4221  if(name_len > MZ_UINT16_MAX)
4223 
4224  comment_len = pComment ? strlen(pComment) : 0;
4225  if(comment_len > MZ_UINT16_MAX)
4227 
4228  for(file_index = 0; file_index < pZip->m_total_files; file_index++)
4229  {
4231  mz_uint filename_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_FILENAME_LEN_OFS);
4232  const char *pFilename = (const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
4233  if(filename_len < name_len)
4234  continue;
4235  if(comment_len)
4236  {
4237  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);
4238  const char *pFile_comment = pFilename + filename_len + file_extra_len;
4239  if((file_comment_len != comment_len) || (!mz_zip_string_equal(pComment, pFile_comment, file_comment_len, flags)))
4240  continue;
4241  }
4242  if((flags & MZ_ZIP_FLAG_IGNORE_PATH) && (filename_len))
4243  {
4244  int ofs = filename_len - 1;
4245  do
4246  {
4247  if((pFilename[ofs] == '/') || (pFilename[ofs] == '\\') || (pFilename[ofs] == ':'))
4248  break;
4249  } while(--ofs >= 0);
4250  ofs++;
4251  pFilename += ofs;
4252  filename_len -= ofs;
4253  }
4254  if((filename_len == name_len) && (mz_zip_string_equal(pName, pFilename, filename_len, flags)))
4255  {
4256  if(pIndex)
4257  *pIndex = file_index;
4258  return MZ_TRUE;
4259  }
4260  }
4261 
4263 }
4264 
4265 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)
4266 {
4267  int status = TINFL_STATUS_DONE;
4268  mz_uint64 needed_size, cur_file_ofs, comp_remaining, out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail;
4269  mz_zip_archive_file_stat file_stat;
4270  void *pRead_buf;
4271  mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
4272  mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
4273  tinfl_decompressor inflator;
4274 
4275  if((!pZip) || (!pZip->m_pState) || ((buf_size) && (!pBuf)) || ((user_read_buf_size) && (!pUser_read_buf)) || (!pZip->m_pRead))
4277 
4278  if(!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
4279  return MZ_FALSE;
4280 
4281  /* A directory or zero length file */
4282  if((file_stat.m_is_directory) || (!file_stat.m_comp_size))
4283  return MZ_TRUE;
4284 
4285  /* Encryption and patch files are not supported. */
4288 
4289  /* This function only supports decompressing stored and deflate. */
4290  if((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
4292 
4293  /* Ensure supplied output buffer is large enough. */
4294  needed_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size : file_stat.m_uncomp_size;
4295  if(buf_size < needed_size)
4296  return mz_zip_set_error(pZip, MZ_ZIP_BUF_TOO_SMALL);
4297 
4298  /* Read and parse the local directory entry. */
4299  cur_file_ofs = file_stat.m_local_header_ofs;
4300  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)
4302 
4303  if(MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
4305 
4307  if((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
4309 
4310  if((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method))
4311  {
4312  /* The file is stored or the caller has requested the compressed data. */
4313  if(pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, (size_t)needed_size) != needed_size)
4315 
4316 #ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4317  if((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) == 0)
4318  {
4319  if(mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32)
4321  }
4322 #endif
4323 
4324  return MZ_TRUE;
4325  }
4326 
4327  /* Decompress the file either directly from memory or from a file input buffer. */
4328  tinfl_init(&inflator);
4329 
4330  if(pZip->m_pState->m_pMem)
4331  {
4332  /* Read directly from the archive in memory. */
4333  pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
4334  read_buf_size = read_buf_avail = file_stat.m_comp_size;
4335  comp_remaining = 0;
4336  }
4337  else if(pUser_read_buf)
4338  {
4339  /* Use a user provided read buffer. */
4340  if(!user_read_buf_size)
4341  return MZ_FALSE;
4342  pRead_buf = (mz_uint8 *)pUser_read_buf;
4343  read_buf_size = user_read_buf_size;
4344  read_buf_avail = 0;
4345  comp_remaining = file_stat.m_comp_size;
4346  }
4347  else
4348  {
4349  /* Temporarily allocate a read buffer. */
4350  read_buf_size = MZ_MIN(file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
4351  if(((sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
4353 
4354  if(NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size)))
4355  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
4356 
4357  read_buf_avail = 0;
4358  comp_remaining = file_stat.m_comp_size;
4359  }
4360 
4361  do
4362  {
4363  /* The size_t cast here should be OK because we've verified that the output buffer is >= file_stat.m_uncomp_size above */
4364  size_t in_buf_size, out_buf_size = (size_t)(file_stat.m_uncomp_size - out_buf_ofs);
4365  if((!read_buf_avail) && (!pZip->m_pState->m_pMem))
4366  {
4367  read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
4368  if(pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
4369  {
4370  status = TINFL_STATUS_FAILED;
4372  break;
4373  }
4374  cur_file_ofs += read_buf_avail;
4375  comp_remaining -= read_buf_avail;
4376  read_buf_ofs = 0;
4377  }
4378  in_buf_size = (size_t)read_buf_avail;
4379  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));
4380  read_buf_avail -= in_buf_size;
4381  read_buf_ofs += in_buf_size;
4382  out_buf_ofs += out_buf_size;
4383  } while(status == TINFL_STATUS_NEEDS_MORE_INPUT);
4384 
4385  if(status == TINFL_STATUS_DONE)
4386  {
4387  /* Make sure the entire file was decompressed, and check its CRC. */
4388  if(out_buf_ofs != file_stat.m_uncomp_size)
4389  {
4391  status = TINFL_STATUS_FAILED;
4392  }
4393 #ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4394  else if(mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32)
4395  {
4397  status = TINFL_STATUS_FAILED;
4398  }
4399 #endif
4400  }
4401 
4402  if((!pZip->m_pState->m_pMem) && (!pUser_read_buf))
4403  pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
4404 
4405  return status == TINFL_STATUS_DONE;
4406 }
4407 
4408 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)
4409 {
4410  mz_uint32 file_index;
4411  if(!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index))
4412  return MZ_FALSE;
4413  return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, pUser_read_buf, user_read_buf_size);
4414 }
4415 
4416 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)
4417 {
4418  return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, NULL, 0);
4419 }
4420 
4421 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)
4422 {
4423  return mz_zip_reader_extract_file_to_mem_no_alloc(pZip, pFilename, pBuf, buf_size, flags, NULL, 0);
4424 }
4425 
4426 void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags)
4427 {
4428  mz_uint64 comp_size, uncomp_size, alloc_size;
4429  const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
4430  void *pBuf;
4431 
4432  if(pSize)
4433  *pSize = 0;
4434 
4435  if(!p)
4436  {
4438  return NULL;
4439  }
4440 
4443 
4444  alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size;
4445  if(((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
4446  {
4448  return NULL;
4449  }
4450 
4451  if(NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size)))
4452  {
4454  return NULL;
4455  }
4456 
4457  if(!mz_zip_reader_extract_to_mem(pZip, file_index, pBuf, (size_t)alloc_size, flags))
4458  {
4459  pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
4460  return NULL;
4461  }
4462 
4463  if(pSize)
4464  *pSize = (size_t)alloc_size;
4465  return pBuf;
4466 }
4467 
4468 void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags)
4469 {
4470  mz_uint32 file_index;
4471  if(!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index))
4472  {
4473  if(pSize)
4474  *pSize = 0;
4475  return nullptr;
4476  }
4477  return mz_zip_reader_extract_to_heap(pZip, file_index, pSize, flags);
4478 }
4479 
4481 {
4482  int status = TINFL_STATUS_DONE;
4483  mz_uint file_crc32 = MZ_CRC32_INIT;
4484  mz_uint64 read_buf_size, read_buf_ofs = 0, read_buf_avail, comp_remaining, out_buf_ofs = 0, cur_file_ofs;
4485  mz_zip_archive_file_stat file_stat;
4486  void *pRead_buf = NULL;
4487  void *pWrite_buf = NULL;
4488  mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
4489  mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
4490 
4491  if((!pZip) || (!pZip->m_pState) || (!pCallback) || (!pZip->m_pRead))
4493 
4494  if(!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
4495  return MZ_FALSE;
4496 
4497  /* A directory or zero length file */
4498  if((file_stat.m_is_directory) || (!file_stat.m_comp_size))
4499  return MZ_TRUE;
4500 
4501  /* Encryption and patch files are not supported. */
4504 
4505  /* This function only supports decompressing stored and deflate. */
4506  if((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
4508 
4509  /* 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) */
4510  cur_file_ofs = file_stat.m_local_header_ofs;
4511  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)
4513 
4514  if(MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
4516 
4518  if((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
4520 
4521  /* Decompress the file either directly from memory or from a file input buffer. */
4522  if(pZip->m_pState->m_pMem)
4523  {
4524  pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
4525  read_buf_size = read_buf_avail = file_stat.m_comp_size;
4526  comp_remaining = 0;
4527  }
4528  else
4529  {
4530  read_buf_size = MZ_MIN(file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
4531  if(NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size)))
4532  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
4533 
4534  read_buf_avail = 0;
4535  comp_remaining = file_stat.m_comp_size;
4536  }
4537 
4538  if((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method))
4539  {
4540  /* The file is stored or the caller has requested the compressed data. */
4541  if(pZip->m_pState->m_pMem)
4542  {
4543  if(((sizeof(size_t) == sizeof(mz_uint32))) && (file_stat.m_comp_size > MZ_UINT32_MAX))
4545 
4546  if(pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)file_stat.m_comp_size) != file_stat.m_comp_size)
4547  {
4549  status = TINFL_STATUS_FAILED;
4550  }
4551  else if(!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
4552  {
4553 #ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4554  file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)file_stat.m_comp_size);
4555 #endif
4556  }
4557 
4558  cur_file_ofs += file_stat.m_comp_size;
4559  out_buf_ofs += file_stat.m_comp_size;
4560  comp_remaining = 0;
4561  }
4562  else
4563  {
4564  while(comp_remaining)
4565  {
4566  read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
4567  if(pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
4568  {
4570  status = TINFL_STATUS_FAILED;
4571  break;
4572  }
4573 
4574 #ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4575  if(!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
4576  {
4577  file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)read_buf_avail);
4578  }
4579 #endif
4580 
4581  if(pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
4582  {
4584  status = TINFL_STATUS_FAILED;
4585  break;
4586  }
4587 
4588  cur_file_ofs += read_buf_avail;
4589  out_buf_ofs += read_buf_avail;
4590  comp_remaining -= read_buf_avail;
4591  }
4592  }
4593  }
4594  else
4595  {
4596  tinfl_decompressor inflator;
4597  tinfl_init(&inflator);
4598 
4599  if(NULL == (pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, TINFL_LZ_DICT_SIZE)))
4600  {
4602  status = TINFL_STATUS_FAILED;
4603  }
4604  else
4605  {
4606  do
4607  {
4608  mz_uint8 *pWrite_buf_cur = (mz_uint8 *)pWrite_buf + (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
4609  size_t in_buf_size, out_buf_size = TINFL_LZ_DICT_SIZE - (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
4610  if((!read_buf_avail) && (!pZip->m_pState->m_pMem))
4611  {
4612  read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
4613  if(pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
4614  {
4616  status = TINFL_STATUS_FAILED;
4617  break;
4618  }
4619  cur_file_ofs += read_buf_avail;
4620  comp_remaining -= read_buf_avail;
4621  read_buf_ofs = 0;
4622  }
4623 
4624  in_buf_size = (size_t)read_buf_avail;
4625  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);
4626  read_buf_avail -= in_buf_size;
4627  read_buf_ofs += in_buf_size;
4628 
4629  if(out_buf_size)
4630  {
4631  if(pCallback(pOpaque, out_buf_ofs, pWrite_buf_cur, out_buf_size) != out_buf_size)
4632  {
4634  status = TINFL_STATUS_FAILED;
4635  break;
4636  }
4637 
4638 #ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4639  file_crc32 = (mz_uint32)mz_crc32(file_crc32, pWrite_buf_cur, out_buf_size);
4640 #endif
4641  if((out_buf_ofs += out_buf_size) > file_stat.m_uncomp_size)
4642  {
4644  status = TINFL_STATUS_FAILED;
4645  break;
4646  }
4647  }
4648  } while((status == TINFL_STATUS_NEEDS_MORE_INPUT) || (status == TINFL_STATUS_HAS_MORE_OUTPUT));
4649  }
4650  }
4651 
4652  if((status == TINFL_STATUS_DONE) && (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)))
4653  {
4654  /* Make sure the entire file was decompressed, and check its CRC. */
4655  if(out_buf_ofs != file_stat.m_uncomp_size)
4656  {
4658  status = TINFL_STATUS_FAILED;
4659  }
4660 #ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4661  else if(file_crc32 != file_stat.m_crc32)
4662  {
4664  status = TINFL_STATUS_FAILED;
4665  }
4666 #endif
4667  }
4668 
4669  if(!pZip->m_pState->m_pMem)
4670  pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
4671 
4672  if(pWrite_buf)
4673  pZip->m_pFree(pZip->m_pAlloc_opaque, pWrite_buf);
4674 
4675  return status == TINFL_STATUS_DONE;
4676 }
4677 
4678 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)
4679 {
4680  mz_uint32 file_index;
4681  if(!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index))
4682  return MZ_FALSE;
4683 
4684  return mz_zip_reader_extract_to_callback(pZip, file_index, pCallback, pOpaque, flags);
4685 }
4686 
4687 #ifndef MINIZ_NO_STDIO
4688 static size_t mz_zip_file_write_callback(void *pOpaque, mz_uint64 ofs, const void *pBuf, size_t n)
4689 {
4690  (void)ofs;
4691 
4692  return MZ_FWRITE(pBuf, 1, n, (MZ_FILE *)pOpaque);
4693 }
4694 
4695 mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags)
4696 {
4697  mz_bool status;
4698  mz_zip_archive_file_stat file_stat;
4699  MZ_FILE *pFile;
4700 
4701  if(!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
4702  return MZ_FALSE;
4703 
4704  if((file_stat.m_is_directory) || (!file_stat.m_is_supported))
4706 
4707  pFile = MZ_FOPEN(pDst_filename, "wb");
4708  if(!pFile)
4710 
4711  status = mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_file_write_callback, pFile, flags);
4712 
4713  if(MZ_FCLOSE(pFile) == EOF)
4714  {
4715  if(status)
4717 
4718  status = MZ_FALSE;
4719  }
4720 
4721 #if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_STDIO)
4722  if(status)
4723  mz_zip_set_file_times(pDst_filename, file_stat.m_time, file_stat.m_time);
4724 #endif
4725 
4726  return status;
4727 }
4728 
4729 mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags)
4730 {
4731  mz_uint32 file_index;
4732  if(!mz_zip_reader_locate_file_v2(pZip, pArchive_filename, NULL, flags, &file_index))
4733  return MZ_FALSE;
4734 
4735  return mz_zip_reader_extract_to_file(pZip, file_index, pDst_filename, flags);
4736 }
4737 
4739 {
4740  mz_zip_archive_file_stat file_stat;
4741 
4742  if(!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
4743  return MZ_FALSE;
4744 
4745  if((file_stat.m_is_directory) || (!file_stat.m_is_supported))
4747 
4748  return mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_file_write_callback, pFile, flags);
4749 }
4750 
4751 mz_bool mz_zip_reader_extract_file_to_cfile(mz_zip_archive *pZip, const char *pArchive_filename, MZ_FILE *pFile, mz_uint flags)
4752 {
4753  mz_uint32 file_index;
4754  if(!mz_zip_reader_locate_file_v2(pZip, pArchive_filename, NULL, flags, &file_index))
4755  return MZ_FALSE;
4756 
4757  return mz_zip_reader_extract_to_cfile(pZip, file_index, pFile, flags);
4758 }
4759 #endif /* #ifndef MINIZ_NO_STDIO */
4760 
4761 static size_t mz_zip_compute_crc32_callback(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
4762 {
4763  mz_uint32 *p = (mz_uint32 *)pOpaque;
4764  (void)file_ofs;
4765  *p = (mz_uint32)mz_crc32(*p, (const mz_uint8 *)pBuf, n);
4766  return n;
4767 }
4768 
4770 {
4771  mz_zip_archive_file_stat file_stat;
4772  mz_zip_internal_state *pState;
4773  const mz_uint8 *pCentral_dir_header;
4774  mz_bool found_zip64_ext_data_in_cdir = MZ_FALSE;
4775  mz_bool found_zip64_ext_data_in_ldir = MZ_FALSE;
4776  mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
4777  mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
4778  mz_uint64 local_header_ofs = 0;
4779  mz_uint32 local_header_filename_len, local_header_extra_len, local_header_crc32;
4780  mz_uint64 local_header_comp_size, local_header_uncomp_size;
4781  mz_uint32 uncomp_crc32 = MZ_CRC32_INIT;
4782  mz_bool has_data_descriptor;
4783  mz_uint32 local_header_bit_flags;
4784 
4785  mz_zip_array file_data_array;
4786  mz_zip_array_init(&file_data_array, 1);
4787 
4788  if((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (!pZip->m_pRead))
4790 
4791  if(file_index > pZip->m_total_files)
4793 
4794  pState = pZip->m_pState;
4795 
4796  pCentral_dir_header = mz_zip_get_cdh(pZip, file_index);
4797 
4798  if(!mz_zip_file_stat_internal(pZip, file_index, pCentral_dir_header, &file_stat, &found_zip64_ext_data_in_cdir))
4799  return MZ_FALSE;
4800 
4801  /* A directory or zero length file */
4802  if((file_stat.m_is_directory) || (!file_stat.m_uncomp_size))
4803  return MZ_TRUE;
4804 
4805  /* Encryption and patch files are not supported. */
4806  if(file_stat.m_is_encrypted)
4808 
4809  /* This function only supports stored and deflate. */
4810  if((file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
4812 
4813  if(!file_stat.m_is_supported)
4815 
4816  /* Read and parse the local directory entry. */
4817  local_header_ofs = file_stat.m_local_header_ofs;
4818  if(pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
4820 
4821  if(MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
4823 
4824  local_header_filename_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS);
4825  local_header_extra_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
4826  local_header_comp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS);
4827  local_header_uncomp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS);
4828  local_header_crc32 = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_CRC32_OFS);
4829  local_header_bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS);
4830  has_data_descriptor = (local_header_bit_flags & 8) != 0;
4831 
4832  if(local_header_filename_len != strlen(file_stat.m_filename))
4834 
4835  if((local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len + local_header_extra_len + file_stat.m_comp_size) > pZip->m_archive_size)
4837 
4838  if(!mz_zip_array_resize(pZip, &file_data_array, MZ_MAX(local_header_filename_len, local_header_extra_len), MZ_FALSE))
4839  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
4840 
4841  if(local_header_filename_len)
4842  {
4843  if(pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE, file_data_array.m_p, local_header_filename_len) != local_header_filename_len)
4844  {
4846  goto handle_failure;
4847  }
4848 
4849  /* I've seen 1 archive that had the same pathname, but used backslashes in the local dir and forward slashes in the central dir. Do we care about this? For now, this case will fail validation. */
4850  if(memcmp(file_stat.m_filename, file_data_array.m_p, local_header_filename_len) != 0)
4851  {
4853  goto handle_failure;
4854  }
4855  }
4856 
4857  if((local_header_extra_len) && ((local_header_comp_size == MZ_UINT32_MAX) || (local_header_uncomp_size == MZ_UINT32_MAX)))
4858  {
4859  if(pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len, file_data_array.m_p, local_header_extra_len) != local_header_extra_len)
4860  {
4862  goto handle_failure;
4863  }
4864 
4865  mz_uint32 extra_size_remaining = local_header_extra_len;
4866  const mz_uint8 *pExtra_data = (const mz_uint8 *)file_data_array.m_p;
4867 
4868  do
4869  {
4870  mz_uint32 field_id, field_data_size, field_total_size;
4871 
4872  if(extra_size_remaining < (sizeof(mz_uint16) * 2))
4874 
4875  field_id = MZ_READ_LE16(pExtra_data);
4876  field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16));
4877  field_total_size = field_data_size + sizeof(mz_uint16) * 2;
4878 
4879  if(field_total_size > extra_size_remaining)
4881 
4883  {
4884  const mz_uint8 *pSrc_field_data = pExtra_data + sizeof(mz_uint32);
4885 
4886  if(field_data_size < sizeof(mz_uint64) * 2)
4887  {
4889  goto handle_failure;
4890  }
4891 
4892  local_header_uncomp_size = MZ_READ_LE64(pSrc_field_data);
4893  local_header_comp_size = MZ_READ_LE64(pSrc_field_data + sizeof(mz_uint64));
4894 
4895  found_zip64_ext_data_in_ldir = MZ_TRUE;
4896  break;
4897  }
4898 
4899  pExtra_data += field_total_size;
4900  extra_size_remaining -= field_total_size;
4901  } while(extra_size_remaining);
4902  }
4903 
4904  /* TODO: parse local header extra data when local_header_comp_size is 0xFFFFFFFF! (big_descriptor.zip) */
4905  /* I've seen zips in the wild with the data descriptor bit set, but proper local header values and bogus data descriptors */
4906  if((has_data_descriptor) && (!local_header_comp_size) && (!local_header_crc32))
4907  {
4908  mz_uint8 descriptor_buf[32];
4909 
4910  mz_uint32 num_descriptor_uint32s = ((pState->m_zip64) || (found_zip64_ext_data_in_ldir)) ? 6 : 4;
4911 
4912  if(pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len + local_header_extra_len + file_stat.m_comp_size, descriptor_buf, sizeof(mz_uint32) * num_descriptor_uint32s) != (sizeof(mz_uint32) * num_descriptor_uint32s))
4913  {
4915  goto handle_failure;
4916  }
4917 
4918  mz_bool has_id = (MZ_READ_LE32(descriptor_buf) == MZ_ZIP_DATA_DESCRIPTOR_ID);
4919  const mz_uint8 *pSrc = has_id ? (descriptor_buf + sizeof(mz_uint32)) : descriptor_buf;
4920 
4921  mz_uint32 file_crc32 = MZ_READ_LE32(pSrc);
4922  mz_uint64 comp_size = 0, uncomp_size = 0;
4923 
4924  if((pState->m_zip64) || (found_zip64_ext_data_in_ldir))
4925  {
4926  comp_size = MZ_READ_LE64(pSrc + sizeof(mz_uint32));
4927  uncomp_size = MZ_READ_LE64(pSrc + sizeof(mz_uint32) + sizeof(mz_uint64));
4928  }
4929  else
4930  {
4931  comp_size = MZ_READ_LE32(pSrc + sizeof(mz_uint32));
4932  uncomp_size = MZ_READ_LE32(pSrc + sizeof(mz_uint32) + sizeof(mz_uint32));
4933  }
4934 
4935  if((file_crc32 != file_stat.m_crc32) || (comp_size != file_stat.m_comp_size) || (uncomp_size != file_stat.m_uncomp_size))
4936  {
4938  goto handle_failure;
4939  }
4940  }
4941  else
4942  {
4943  if((local_header_crc32 != file_stat.m_crc32) || (local_header_comp_size != file_stat.m_comp_size) || (local_header_uncomp_size != file_stat.m_uncomp_size))
4944  {
4946  goto handle_failure;
4947  }
4948  }
4949 
4950  mz_zip_array_clear(pZip, &file_data_array);
4951 
4952  if((flags & MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY) == 0)
4953  {
4954  if(!mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_compute_crc32_callback, &uncomp_crc32, 0))
4955  return MZ_FALSE;
4956 
4957  /* 1 more check to be sure, although the extract checks too. */
4958  if(uncomp_crc32 != file_stat.m_crc32)
4959  {
4961  return MZ_FALSE;
4962  }
4963  }
4964 
4965  return MZ_TRUE;
4966 
4967 handle_failure:
4968  mz_zip_array_clear(pZip, &file_data_array);
4969  return MZ_FALSE;
4970 }
4971 
4973 {
4974  mz_zip_internal_state *pState;
4975  uint32_t i;
4976 
4977  if((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (!pZip->m_pRead))
4979 
4980  pState = pZip->m_pState;
4981 
4982  /* Basic sanity checks */
4983  if(!pState->m_zip64)
4984  {
4985  if(pZip->m_total_files > MZ_UINT16_MAX)
4987 
4988  if(pZip->m_archive_size > MZ_UINT32_MAX)
4990  }
4991  else
4992  {
4993  if(pZip->m_total_files >= MZ_UINT32_MAX)
4995 
4996  if(pState->m_central_dir.m_size >= MZ_UINT32_MAX)
4998  }
4999 
5000  for(i = 0; i < pZip->m_total_files; i++)
5001  {
5003  {
5004  mz_uint32 found_index;
5006 
5007  if(!mz_zip_reader_file_stat(pZip, i, &stat))
5008  return MZ_FALSE;
5009 
5010  if(!mz_zip_reader_locate_file_v2(pZip, stat.m_filename, NULL, 0, &found_index))
5011  return MZ_FALSE;
5012 
5013  /* This check can fail if there are duplicate filenames in the archive (which we don't check for when writing - that's up to the user) */
5014  if(found_index != i)
5016  }
5017 
5018  if(!mz_zip_validate_file(pZip, i, flags))
5019  return MZ_FALSE;
5020  }
5021 
5022  return MZ_TRUE;
5023 }
5024 
5025 mz_bool mz_zip_validate_mem_archive(const void *pMem, size_t size, mz_uint flags, mz_zip_error *pErr)
5026 {
5027  mz_bool success = MZ_TRUE;
5028  mz_zip_archive zip;
5029  mz_zip_error actual_err = MZ_ZIP_NO_ERROR;
5030 
5031  if((!pMem) || (!size))
5032  {
5033  if(pErr)
5034  *pErr = MZ_ZIP_INVALID_PARAMETER;
5035  return MZ_FALSE;
5036  }
5037 
5038  mz_zip_zero_struct(&zip);
5039 
5040  if(!mz_zip_reader_init_mem(&zip, pMem, size, flags))
5041  {
5042  if(pErr)
5043  *pErr = zip.m_last_error;
5044  return MZ_FALSE;
5045  }
5046 
5047  if(!mz_zip_validate_archive(&zip, flags))
5048  {
5049  actual_err = zip.m_last_error;
5050  success = MZ_FALSE;
5051  }
5052 
5053  if(!mz_zip_reader_end_internal(&zip, success))
5054  {
5055  if(!actual_err)
5056  actual_err = zip.m_last_error;
5057  success = MZ_FALSE;
5058  }
5059 
5060  if(pErr)
5061  *pErr = actual_err;
5062 
5063  return success;
5064 }
5065 
5066 #ifndef MINIZ_NO_STDIO
5067 mz_bool mz_zip_validate_file_archive(const char *pFilename, mz_uint flags, mz_zip_error *pErr)
5068 {
5069  mz_bool success = MZ_TRUE;
5070  mz_zip_archive zip;
5071  mz_zip_error actual_err = MZ_ZIP_NO_ERROR;
5072 
5073  if(!pFilename)
5074  {
5075  if(pErr)
5076  *pErr = MZ_ZIP_INVALID_PARAMETER;
5077  return MZ_FALSE;
5078  }
5079 
5080  mz_zip_zero_struct(&zip);
5081 
5082  if(!mz_zip_reader_init_file_v2(&zip, pFilename, flags, 0, 0))
5083  {
5084  if(pErr)
5085  *pErr = zip.m_last_error;
5086  return MZ_FALSE;
5087  }
5088 
5089  if(!mz_zip_validate_archive(&zip, flags))
5090  {
5091  actual_err = zip.m_last_error;
5092  success = MZ_FALSE;
5093  }
5094 
5095  if(!mz_zip_reader_end_internal(&zip, success))
5096  {
5097  if(!actual_err)
5098  actual_err = zip.m_last_error;
5099  success = MZ_FALSE;
5100  }
5101 
5102  if(pErr)
5103  *pErr = actual_err;
5104 
5105  return success;
5106 }
5107 #endif /* #ifndef MINIZ_NO_STDIO */
5108 
5109 /* ------------------- .ZIP archive writing */
5110 
5111 #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
5112 
5114 {
5115  p[0] = (mz_uint8)v;
5116  p[1] = (mz_uint8)(v >> 8);
5117 }
5119 {
5120  p[0] = (mz_uint8)v;
5121  p[1] = (mz_uint8)(v >> 8);
5122  p[2] = (mz_uint8)(v >> 16);
5123  p[3] = (mz_uint8)(v >> 24);
5124 }
5126 {
5127  mz_write_le32(p, (mz_uint32)v);
5128  mz_write_le32(p + sizeof(mz_uint32), (mz_uint32)(v >> 32));
5129 }
5130 
5131 #define MZ_WRITE_LE16(p, v) mz_write_le16((mz_uint8 *)(p), (mz_uint16)(v))
5132 #define MZ_WRITE_LE32(p, v) mz_write_le32((mz_uint8 *)(p), (mz_uint32)(v))
5133 #define MZ_WRITE_LE64(p, v) mz_write_le64((mz_uint8 *)(p), (mz_uint64)(v))
5134 
5135 static size_t mz_zip_heap_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
5136 {
5137  mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
5138  mz_zip_internal_state *pState = pZip->m_pState;
5139  mz_uint64 new_size = MZ_MAX(file_ofs + n, pState->m_mem_size);
5140 
5141  if(!n)
5142  return 0;
5143 
5144  /* An allocation this big is likely to just fail on 32-bit systems, so don't even go there. */
5145  if((sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF))
5146  {
5148  return 0;
5149  }
5150 
5151  if(new_size > pState->m_mem_capacity)
5152  {
5153  void *pNew_block;
5154  size_t new_capacity = MZ_MAX(64, pState->m_mem_capacity);
5155 
5156  while(new_capacity < new_size)
5157  new_capacity *= 2;
5158 
5159  if(NULL == (pNew_block = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pState->m_pMem, 1, new_capacity)))
5160  {
5162  return 0;
5163  }
5164 
5165  pState->m_pMem = pNew_block;
5166  pState->m_mem_capacity = new_capacity;
5167  }
5168  memcpy((mz_uint8 *)pState->m_pMem + file_ofs, pBuf, n);
5169  pState->m_mem_size = (size_t)new_size;
5170  return n;
5171 }
5172 
5174 {
5175  mz_zip_internal_state *pState;
5176  mz_bool status = MZ_TRUE;
5177 
5178  if((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || ((pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) && (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED)))
5179  {
5180  if(set_last_error)
5182  return MZ_FALSE;
5183  }
5184 
5185  pState = pZip->m_pState;
5186  pZip->m_pState = NULL;
5187  mz_zip_array_clear(pZip, &pState->m_central_dir);
5188  mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
5190 
5191 #ifndef MINIZ_NO_STDIO
5192  if(pState->m_pFile)
5193  {
5194  if(pZip->m_zip_type == MZ_ZIP_TYPE_FILE)
5195  {
5196  if(MZ_FCLOSE(pState->m_pFile) == EOF)
5197  {
5198  if(set_last_error)
5200  status = MZ_FALSE;
5201  }
5202  }
5203 
5204  pState->m_pFile = NULL;
5205  }
5206 #endif /* #ifndef MINIZ_NO_STDIO */
5207 
5208  if((pZip->m_pWrite == mz_zip_heap_write_func) && (pState->m_pMem))
5209  {
5210  pZip->m_pFree(pZip->m_pAlloc_opaque, pState->m_pMem);
5211  pState->m_pMem = NULL;
5212  }
5213 
5214  pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5216  return status;
5217 }
5218 
5220 {
5221  mz_bool zip64 = (flags & MZ_ZIP_FLAG_WRITE_ZIP64) != 0;
5222 
5223  if((!pZip) || (pZip->m_pState) || (!pZip->m_pWrite) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
5225 
5227  {
5228  if(!pZip->m_pRead)
5230  }
5231 
5232  if(pZip->m_file_offset_alignment)
5233  {
5234  /* Ensure user specified file offset alignment is a power of 2. */
5235  if(pZip->m_file_offset_alignment & (pZip->m_file_offset_alignment - 1))
5237  }
5238 
5239  if(!pZip->m_pAlloc)
5241  if(!pZip->m_pFree)
5242  pZip->m_pFree = miniz_def_free_func;
5243  if(!pZip->m_pRealloc)
5245 
5246  pZip->m_archive_size = existing_size;
5247  pZip->m_central_directory_file_ofs = 0;
5248  pZip->m_total_files = 0;
5249 
5250  if(NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state))))
5251  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
5252 
5253  memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state));
5254 
5258 
5259  pZip->m_pState->m_zip64 = zip64;
5261 
5262  pZip->m_zip_type = MZ_ZIP_TYPE_USER;
5264 
5265  return MZ_TRUE;
5266 }
5267 
5269 {
5270  return mz_zip_writer_init_v2(pZip, existing_size, 0);
5271 }
5272 
5273 mz_bool mz_zip_writer_init_heap_v2(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size, mz_uint flags)
5274 {
5276 
5278  pZip->m_pRead = mz_zip_mem_read_func;
5279 
5280  pZip->m_pIO_opaque = pZip;
5281 
5282  if(!mz_zip_writer_init_v2(pZip, size_to_reserve_at_beginning, flags))
5283  return MZ_FALSE;
5284 
5285  pZip->m_zip_type = MZ_ZIP_TYPE_HEAP;
5286 
5287  if(0 != (initial_allocation_size = MZ_MAX(initial_allocation_size, size_to_reserve_at_beginning)))
5288  {
5289  if(NULL == (pZip->m_pState->m_pMem = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, initial_allocation_size)))
5290  {
5292  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
5293  }
5294  pZip->m_pState->m_mem_capacity = initial_allocation_size;
5295  }
5296 
5297  return MZ_TRUE;
5298 }
5299 
5300 mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size)
5301 {
5302  return mz_zip_writer_init_heap_v2(pZip, size_to_reserve_at_beginning, initial_allocation_size, 0);
5303 }
5304 
5305 #ifndef MINIZ_NO_STDIO
5306 static size_t mz_zip_file_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
5307 {
5308  mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
5309  mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
5310 
5311  file_ofs += pZip->m_pState->m_file_archive_start_ofs;
5312 
5313  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))))
5314  {
5316  return 0;
5317  }
5318 
5319  return MZ_FWRITE(pBuf, 1, n, pZip->m_pState->m_pFile);
5320 }
5321 
5322 mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning)
5323 {
5324  return mz_zip_writer_init_file_v2(pZip, pFilename, size_to_reserve_at_beginning, 0);
5325 }
5326 
5327 mz_bool mz_zip_writer_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning, mz_uint flags)
5328 {
5329  MZ_FILE *pFile;
5330 
5332 
5335 
5336  pZip->m_pIO_opaque = pZip;
5337 
5338  if(!mz_zip_writer_init_v2(pZip, size_to_reserve_at_beginning, flags))
5339  return MZ_FALSE;
5340 
5341  if(NULL == (pFile = MZ_FOPEN(pFilename, (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING) ? "w+b" : "wb")))
5342  {
5343  mz_zip_writer_end(pZip);
5345  }
5346 
5347  pZip->m_pState->m_pFile = pFile;
5348  pZip->m_zip_type = MZ_ZIP_TYPE_FILE;
5349 
5350  if(size_to_reserve_at_beginning)
5351  {
5352  mz_uint64 cur_ofs = 0;
5353  char buf[4096];
5354 
5355  MZ_CLEAR_OBJ(buf);
5356 
5357  do
5358  {
5359  size_t n = (size_t)MZ_MIN(sizeof(buf), size_to_reserve_at_beginning);
5360  if(pZip->m_pWrite(pZip->m_pIO_opaque, cur_ofs, buf, n) != n)
5361  {
5362  mz_zip_writer_end(pZip);
5364  }
5365  cur_ofs += n;
5366  size_to_reserve_at_beginning -= n;
5367  } while(size_to_reserve_at_beginning);
5368  }
5369 
5370  return MZ_TRUE;
5371 }
5372 
5374 {
5376 
5379 
5380  pZip->m_pIO_opaque = pZip;
5381 
5382  if(!mz_zip_writer_init_v2(pZip, 0, flags))
5383  return MZ_FALSE;
5384 
5385  pZip->m_pState->m_pFile = pFile;
5387  pZip->m_zip_type = MZ_ZIP_TYPE_CFILE;
5388 
5389  return MZ_TRUE;
5390 }
5391 #endif /* #ifndef MINIZ_NO_STDIO */
5392 
5394 {
5395  mz_zip_internal_state *pState;
5396 
5397  if((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
5399 
5400  if(flags & MZ_ZIP_FLAG_WRITE_ZIP64)
5401  {
5402  /* We don't support converting a non-zip64 file to zip64 - this seems like more trouble than it's worth. (What about the existing 32-bit data descriptors that could follow the compressed data?) */
5403  if(!pZip->m_pState->m_zip64)
5405  }
5406 
5407  /* No sense in trying to write to an archive that's already at the support max size */
5408  if(pZip->m_pState->m_zip64)
5409  {
5410  if(pZip->m_total_files == MZ_UINT32_MAX)
5412  }
5413  else
5414  {
5415  if(pZip->m_total_files == MZ_UINT16_MAX)
5417 
5420  }
5421 
5422  pState = pZip->m_pState;
5423 
5424  if(pState->m_pFile)
5425  {
5426 #ifdef MINIZ_NO_STDIO
5427  (void)pFilename;
5429 #else
5430  if(pZip->m_pIO_opaque != pZip)
5432 
5433  if(pZip->m_zip_type == MZ_ZIP_TYPE_FILE)
5434  {
5435  if(!pFilename)
5437 
5438  /* Archive is being read from stdio and was originally opened only for reading. Try to reopen as writable. */
5439  if(NULL == (pState->m_pFile = MZ_FREOPEN(pFilename, "r+b", pState->m_pFile)))
5440  {
5441  /* The mz_zip_archive is now in a bogus state because pState->m_pFile is NULL, so just close it. */
5444  }
5445  }
5446 
5448 #endif /* #ifdef MINIZ_NO_STDIO */
5449  }
5450  else if(pState->m_pMem)
5451  {
5452  /* Archive lives in a memory block. Assume it's from the heap that we can resize using the realloc callback. */
5453  if(pZip->m_pIO_opaque != pZip)
5455 
5456  pState->m_mem_capacity = pState->m_mem_size;
5458  }
5459  /* Archive is being read via a user provided read function - make sure the user has specified a write function too. */
5460  else if(!pZip->m_pWrite)
5462 
5463  /* Start writing new files at the archive's current central directory location. */
5464  /* TODO: We could add a flag that lets the user start writing immediately AFTER the existing central dir - this would be safer. */
5466  pZip->m_central_directory_file_ofs = 0;
5467 
5468  /* Clear the sorted central dir offsets, they aren't useful or maintained now. */
5469  /* Even though we're now in write mode, files can still be extracted and verified, but file locates will be slow. */
5470  /* TODO: We could easily maintain the sorted central directory offsets. */
5472 
5474 
5475  return MZ_TRUE;
5476 }
5477 
5479 {
5480  return mz_zip_writer_init_from_reader_v2(pZip, pFilename, 0);
5481 }
5482 
5483 /* TODO: pArchive_name is a terrible name here! */
5484 mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags)
5485 {
5486  return mz_zip_writer_add_mem_ex(pZip, pArchive_name, pBuf, buf_size, NULL, 0, level_and_flags, 0, 0);
5487 }
5488 
5489 typedef struct
5490 {
5495 
5496 static mz_bool mz_zip_writer_add_put_buf_callback(const void *pBuf, int len, void *pUser)
5497 {
5499  if((int)pState->m_pZip->m_pWrite(pState->m_pZip->m_pIO_opaque, pState->m_cur_archive_file_ofs, pBuf, len) != len)
5500  return MZ_FALSE;
5501 
5502  pState->m_cur_archive_file_ofs += len;
5503  pState->m_comp_size += len;
5504  return MZ_TRUE;
5505 }
5506 
5507 #define MZ_ZIP64_MAX_LOCAL_EXTRA_FIELD_SIZE (sizeof(mz_uint16) * 2 + sizeof(mz_uint64) * 2)
5508 #define MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE (sizeof(mz_uint16) * 2 + sizeof(mz_uint64) * 3)
5509 static mz_uint32 mz_zip_writer_create_zip64_extra_data(mz_uint8 *pBuf, mz_uint64 *pUncomp_size, mz_uint64 *pComp_size, mz_uint64 *pLocal_header_ofs)
5510 {
5511  mz_uint8 *pDst = pBuf;
5512 
5514  MZ_WRITE_LE16(pDst + 2, 0);
5515  pDst += sizeof(mz_uint16) * 2;
5516 
5517  mz_uint32 field_size = 0;
5518 
5519  if(pUncomp_size)
5520  {
5521  MZ_WRITE_LE64(pDst, *pUncomp_size);
5522  pDst += sizeof(mz_uint64);
5523  field_size += sizeof(mz_uint64);
5524  }
5525 
5526  if(pComp_size)
5527  {
5528  MZ_WRITE_LE64(pDst, *pComp_size);
5529  pDst += sizeof(mz_uint64);
5530  field_size += sizeof(mz_uint64);
5531  }
5532 
5533  if(pLocal_header_ofs)
5534  {
5535  MZ_WRITE_LE64(pDst, *pLocal_header_ofs);
5536  pDst += sizeof(mz_uint64);
5537  field_size += sizeof(mz_uint64);
5538  }
5539 
5540  MZ_WRITE_LE16(pBuf + 2, field_size);
5541 
5542  return (mz_uint32)(pDst - pBuf);
5543 }
5544 
5545 static mz_bool mz_zip_writer_create_local_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, mz_uint16 extra_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date)
5546 {
5547  (void)pZip;
5550  MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_VERSION_NEEDED_OFS, method ? 20 : 0);
5551  MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_BIT_FLAG_OFS, bit_flags);
5552  MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_METHOD_OFS, method);
5553  MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_TIME_OFS, dos_time);
5554  MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_DATE_OFS, dos_date);
5555  MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_CRC32_OFS, uncomp_crc32);
5558  MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILENAME_LEN_OFS, filename_size);
5559  MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_EXTRA_LEN_OFS, extra_size);
5560  return MZ_TRUE;
5561 }
5562 
5564  mz_uint16 filename_size, mz_uint16 extra_size, mz_uint16 comment_size,
5565  mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32,
5566  mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date,
5567  mz_uint64 local_header_ofs, mz_uint32 ext_attributes)
5568 {
5569  (void)pZip;
5572  MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_VERSION_NEEDED_OFS, method ? 20 : 0);
5573  MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_BIT_FLAG_OFS, bit_flags);
5574  MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_METHOD_OFS, method);
5575  MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_TIME_OFS, dos_time);
5576  MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_DATE_OFS, dos_date);
5577  MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_CRC32_OFS, uncomp_crc32);
5580  MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILENAME_LEN_OFS, filename_size);
5581  MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_EXTRA_LEN_OFS, extra_size);
5582  MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_COMMENT_LEN_OFS, comment_size);
5583  MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS, ext_attributes);
5584  MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_LOCAL_HEADER_OFS, MZ_MIN(local_header_ofs, MZ_UINT32_MAX));
5585  return MZ_TRUE;
5586 }
5587 
5588 static mz_bool mz_zip_writer_add_to_central_dir(mz_zip_archive *pZip, const char *pFilename, mz_uint16 filename_size,
5589  const void *pExtra, mz_uint16 extra_size, const void *pComment, mz_uint16 comment_size,
5590  mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32,
5591  mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date,
5592  mz_uint64 local_header_ofs, mz_uint32 ext_attributes,
5593  const char *user_extra_data, mz_uint user_extra_data_len)
5594 {
5595  mz_zip_internal_state *pState = pZip->m_pState;
5596  mz_uint32 central_dir_ofs = (mz_uint32)pState->m_central_dir.m_size;
5597  size_t orig_central_dir_size = pState->m_central_dir.m_size;
5598  mz_uint8 central_dir_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE];
5599 
5600  if(!pZip->m_pState->m_zip64)
5601  {
5602  if(local_header_ofs > 0xFFFFFFFF)
5604  }
5605 
5606  /* miniz doesn't support central dirs >= MZ_UINT32_MAX bytes yet */
5607  if(((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + extra_size + user_extra_data_len + comment_size) >= MZ_UINT32_MAX)
5609 
5610  if(!mz_zip_writer_create_central_dir_header(pZip, central_dir_header, filename_size, extra_size + user_extra_data_len, comment_size, uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, dos_date, local_header_ofs, ext_attributes))
5612 
5613  if((!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_dir_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) ||
5614  (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pFilename, filename_size)) ||
5615  (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pExtra, extra_size)) ||
5616  (!mz_zip_array_push_back(pZip, &pState->m_central_dir, user_extra_data, user_extra_data_len)) ||
5617  (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pComment, comment_size)) ||
5618  (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &central_dir_ofs, 1)))
5619  {
5620  /* Try to resize the central directory array back into its original state. */
5621  mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
5622  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
5623  }
5624 
5625  return MZ_TRUE;
5626 }
5627 
5628 static mz_bool mz_zip_writer_validate_archive_name(const char *pArchive_name)
5629 {
5630  /* Basic ZIP archive filename validity checks: Valid filenames cannot start with a forward slash, cannot contain a drive letter, and cannot use DOS-style backward slashes. */
5631  if(*pArchive_name == '/')
5632  return MZ_FALSE;
5633 
5634  while(*pArchive_name)
5635  {
5636  if((*pArchive_name == '\\') || (*pArchive_name == ':'))
5637  return MZ_FALSE;
5638 
5639  pArchive_name++;
5640  }
5641 
5642  return MZ_TRUE;
5643 }
5644 
5646 {
5647  mz_uint32 n;
5648  if(!pZip->m_file_offset_alignment)
5649  return 0;
5650  n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1));
5651  return (mz_uint)((pZip->m_file_offset_alignment - n) & (pZip->m_file_offset_alignment - 1));
5652 }
5653 
5655 {
5656  char buf[4096];
5657  memset(buf, 0, MZ_MIN(sizeof(buf), n));
5658  while(n)
5659  {
5660  mz_uint32 s = MZ_MIN(sizeof(buf), n);
5661  if(pZip->m_pWrite(pZip->m_pIO_opaque, cur_file_ofs, buf, s) != s)
5663 
5664  cur_file_ofs += s;
5665  n -= s;
5666  }
5667  return MZ_TRUE;
5668 }
5669 
5670 mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
5671  mz_uint64 uncomp_size, mz_uint32 uncomp_crc32)
5672 {
5673  return mz_zip_writer_add_mem_ex_v2(pZip, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, uncomp_size, uncomp_crc32, NULL, NULL, 0, NULL, 0);
5674 }
5675 
5676 mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size,
5677  mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32, MZ_TIME_T *last_modified,
5678  const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len)
5679 {
5680  mz_uint16 method = 0, dos_time = 0, dos_date = 0;
5681  mz_uint level, ext_attributes = 0, num_alignment_padding_bytes;
5682  mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, comp_size = 0;
5683  size_t archive_name_size;
5684  mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
5685  tdefl_compressor *pComp = NULL;
5686  mz_bool store_data_uncompressed;
5687  mz_zip_internal_state *pState;
5688  mz_uint8 *pExtra_data = NULL;
5689  mz_uint32 extra_size = 0;
5691  mz_uint16 bit_flags = 0;
5692 
5693  if(uncomp_size || (buf_size && !(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)))
5694  bit_flags |= MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR;
5695 
5696  if(level_and_flags & MZ_ZIP_FLAG_UTF8_FILENAME)
5698 
5699  if((int)level_and_flags < 0)
5700  level_and_flags = MZ_DEFAULT_LEVEL;
5701  level = level_and_flags & 0xF;
5702  store_data_uncompressed = ((!level) || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA));
5703 
5704  if((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || ((buf_size) && (!pBuf)) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION))
5706 
5707  pState = pZip->m_pState;
5708 
5709  if(pState->m_zip64)
5710  {
5711  if(pZip->m_total_files == MZ_UINT32_MAX)
5713  }
5714  else
5715  {
5716  if(pZip->m_total_files == MZ_UINT16_MAX)
5717  {
5718  pState->m_zip64 = MZ_TRUE;
5719  /*return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); */
5720  }
5721  if((buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF))
5722  {
5723  pState->m_zip64 = MZ_TRUE;
5724  /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
5725  }
5726  }
5727 
5728  if((!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (uncomp_size))
5730 
5731  if(!mz_zip_writer_validate_archive_name(pArchive_name))
5733 
5734  if(last_modified != NULL)
5735  {
5736  mz_zip_time_t_to_dos_time(*last_modified, &dos_time, &dos_date);
5737  }
5738  else
5739  {
5740 #ifndef MINIZ_NO_TIME
5741  {
5742  MZ_TIME_T cur_time;
5743  time(&cur_time);
5744  mz_zip_time_t_to_dos_time(cur_time, &dos_time, &dos_date);
5745  }
5746 #endif /* #ifndef MINIZ_NO_TIME */
5747  }
5748 
5749  archive_name_size = strlen(pArchive_name);
5750  if(archive_name_size > MZ_UINT16_MAX)
5752 
5753  num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
5754 
5755  /* miniz doesn't support central dirs >= MZ_UINT32_MAX bytes yet */
5758 
5759  if(!pState->m_zip64)
5760  {
5761  /* Bail early if the archive would obviously become too large */
5762  if((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF)
5763  {
5764  pState->m_zip64 = MZ_TRUE;
5765  /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
5766  }
5767  }
5768 
5769  if((archive_name_size) && (pArchive_name[archive_name_size - 1] == '/'))
5770  {
5771  /* Set DOS Subdirectory attribute bit. */
5772  ext_attributes |= MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG;
5773 
5774  /* Subdirectories cannot contain data. */
5775  if((buf_size) || (uncomp_size))
5777  }
5778 
5779  /* Try to do any allocations before writing to the archive, so if an allocation fails the file remains unmodified. (A good idea if we're doing an in-place modification.) */
5780  if((!mz_zip_array_ensure_room(pZip, &pState->m_central_dir, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + (pState->m_zip64 ? MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE : 0))) || (!mz_zip_array_ensure_room(pZip, &pState->m_central_dir_offsets, 1)))
5781  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
5782 
5783  if((!store_data_uncompressed) && (buf_size))
5784  {
5785  if(NULL == (pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor))))
5786  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
5787  }
5788 
5789  if(!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes))
5790  {
5791  pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
5792  return MZ_FALSE;
5793  }
5794 
5795  local_dir_header_ofs += num_alignment_padding_bytes;
5796  if(pZip->m_file_offset_alignment)
5797  {
5798  MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0);
5799  }
5800  cur_archive_file_ofs += num_alignment_padding_bytes;
5801 
5802  MZ_CLEAR_OBJ(local_dir_header);
5803 
5804  if(!store_data_uncompressed || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
5805  {
5806  method = MZ_DEFLATED;
5807  }
5808 
5809  if(pState->m_zip64)
5810  {
5811  if(uncomp_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX)
5812  {
5813  pExtra_data = extra_data;
5814  extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
5815  (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
5816  }
5817 
5818  if(!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, extra_size + user_extra_data_len, 0, 0, 0, method, bit_flags, dos_time, dos_date))
5820 
5821  if(pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header))
5823 
5824  cur_archive_file_ofs += sizeof(local_dir_header);
5825 
5826  if(pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
5827  {
5828  pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
5830  }
5831  cur_archive_file_ofs += archive_name_size;
5832 
5833  if(pExtra_data != NULL)
5834  {
5835  if(pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, extra_data, extra_size) != extra_size)
5837 
5838  cur_archive_file_ofs += extra_size;
5839  }
5840  }
5841  else
5842  {
5843  if((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX))
5845  if(!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, user_extra_data_len, 0, 0, 0, method, bit_flags, dos_time, dos_date))
5847 
5848  if(pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header))
5850 
5851  cur_archive_file_ofs += sizeof(local_dir_header);
5852 
5853  if(pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
5854  {
5855  pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
5857  }
5858  cur_archive_file_ofs += archive_name_size;
5859  }
5860 
5861  if(user_extra_data_len > 0)
5862  {
5863  if(pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len)
5865 
5866  cur_archive_file_ofs += user_extra_data_len;
5867  }
5868 
5869  if(!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
5870  {
5871  uncomp_crc32 = (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, buf_size);
5872  uncomp_size = buf_size;
5873  if(uncomp_size <= 3)
5874  {
5875  level = 0;
5876  store_data_uncompressed = MZ_TRUE;
5877  }
5878  }
5879 
5880  if(store_data_uncompressed)
5881  {
5882  if(pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pBuf, buf_size) != buf_size)
5883  {
5884  pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
5886  }
5887 
5888  cur_archive_file_ofs += buf_size;
5889  comp_size = buf_size;
5890  }
5891  else if(buf_size)
5892  {
5894 
5895  state.m_pZip = pZip;
5896  state.m_cur_archive_file_ofs = cur_archive_file_ofs;
5897  state.m_comp_size = 0;
5898 
5900  (tdefl_compress_buffer(pComp, pBuf, buf_size, TDEFL_FINISH) != TDEFL_STATUS_DONE))
5901  {
5902  pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
5904  }
5905 
5906  comp_size = state.m_comp_size;
5907  cur_archive_file_ofs = state.m_cur_archive_file_ofs;
5908  }
5909 
5910  pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
5911  pComp = NULL;
5912 
5913  if(uncomp_size)
5914  {
5916 
5917  mz_uint8 local_dir_footer[MZ_ZIP_DATA_DESCRIPTER_SIZE64];
5918  mz_uint32 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE32;
5919 
5920  MZ_WRITE_LE32(local_dir_footer + 0, MZ_ZIP_DATA_DESCRIPTOR_ID);
5921  MZ_WRITE_LE32(local_dir_footer + 4, uncomp_crc32);
5922  if(pExtra_data == NULL)
5923  {
5924  if((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX))
5926 
5927  MZ_WRITE_LE32(local_dir_footer + 8, comp_size);
5928  MZ_WRITE_LE32(local_dir_footer + 12, uncomp_size);
5929  }
5930  else
5931  {
5932  MZ_WRITE_LE64(local_dir_footer + 8, comp_size);
5933  MZ_WRITE_LE64(local_dir_footer + 16, uncomp_size);
5934  local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE64;
5935  }
5936 
5937  if(pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_footer, local_dir_footer_size) != local_dir_footer_size)
5938  return MZ_FALSE;
5939 
5940  cur_archive_file_ofs += local_dir_footer_size;
5941  }
5942 
5943  if(pExtra_data != NULL)
5944  {
5945  extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
5946  (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
5947  }
5948 
5949  if(!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, pExtra_data, extra_size, pComment,
5950  comment_size, uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, dos_date, local_dir_header_ofs, ext_attributes,
5951  user_extra_data_central, user_extra_data_central_len))
5952  return MZ_FALSE;
5953 
5954  pZip->m_total_files++;
5955  pZip->m_archive_size = cur_archive_file_ofs;
5956 
5957  return MZ_TRUE;
5958 }
5959 
5960 #ifndef MINIZ_NO_STDIO
5961 mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 size_to_add, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
5962  const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len)
5963 {
5965  mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes;
5966  mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0;
5967  mz_uint64 local_dir_header_ofs, cur_archive_file_ofs = pZip->m_archive_size, uncomp_size = size_to_add, comp_size = 0;
5968  size_t archive_name_size;
5969  mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
5970  mz_uint8 *pExtra_data = NULL;
5971  mz_uint32 extra_size = 0;
5973  mz_zip_internal_state *pState;
5974 
5975  if(level_and_flags & MZ_ZIP_FLAG_UTF8_FILENAME)
5977 
5978  if((int)level_and_flags < 0)
5979  level_and_flags = MZ_DEFAULT_LEVEL;
5980  level = level_and_flags & 0xF;
5981 
5982  /* Sanity checks */
5983  if((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION))
5985 
5986  pState = pZip->m_pState;
5987 
5988  if((!pState->m_zip64) && (uncomp_size > MZ_UINT32_MAX))
5989  {
5990  /* Source file is too large for non-zip64 */
5991  /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
5992  pState->m_zip64 = MZ_TRUE;
5993  }
5994 
5995  /* We could support this, but why? */
5996  if(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)
5998 
5999  if(!mz_zip_writer_validate_archive_name(pArchive_name))
6001 
6002  if(pState->m_zip64)
6003  {
6004  if(pZip->m_total_files == MZ_UINT32_MAX)
6006  }
6007  else
6008  {
6009  if(pZip->m_total_files == MZ_UINT16_MAX)
6010  {
6011  pState->m_zip64 = MZ_TRUE;
6012  /*return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); */
6013  }
6014  }
6015 
6016  archive_name_size = strlen(pArchive_name);
6017  if(archive_name_size > MZ_UINT16_MAX)
6019 
6020  num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
6021 
6022  /* miniz doesn't support central dirs >= MZ_UINT32_MAX bytes yet */
6025 
6026  if(!pState->m_zip64)
6027  {
6028  /* Bail early if the archive would obviously become too large */
6029  if((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 1024) > 0xFFFFFFFF)
6030  {
6031  pState->m_zip64 = MZ_TRUE;
6032  /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
6033  }
6034  }
6035 
6036 #ifndef MINIZ_NO_TIME
6037  if(pFile_time)
6038  {
6039  mz_zip_time_t_to_dos_time(*pFile_time, &dos_time, &dos_date);
6040  }
6041 #endif
6042 
6043  if(uncomp_size <= 3)
6044  level = 0;
6045 
6046  if(!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes))
6047  {
6049  }
6050 
6051  cur_archive_file_ofs += num_alignment_padding_bytes;
6052  local_dir_header_ofs = cur_archive_file_ofs;
6053 
6054  if(pZip->m_file_offset_alignment)
6055  {
6056  MZ_ASSERT((cur_archive_file_ofs & (pZip->m_file_offset_alignment - 1)) == 0);
6057  }
6058 
6059  if(uncomp_size && level)
6060  {
6061  method = MZ_DEFLATED;
6062  }
6063 
6064  MZ_CLEAR_OBJ(local_dir_header);
6065  if(pState->m_zip64)
6066  {
6067  if(uncomp_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX)
6068  {
6069  pExtra_data = extra_data;
6070  extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
6071  (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
6072  }
6073 
6074  if(!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, extra_size + user_extra_data_len, 0, 0, 0, method, gen_flags, dos_time, dos_date))
6076 
6077  if(pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header))
6079 
6080  cur_archive_file_ofs += sizeof(local_dir_header);
6081 
6082  if(pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
6083  {
6085  }
6086 
6087  cur_archive_file_ofs += archive_name_size;
6088 
6089  if(pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, extra_data, extra_size) != extra_size)
6091 
6092  cur_archive_file_ofs += extra_size;
6093  }
6094  else
6095  {
6096  if((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX))
6098  if(!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, user_extra_data_len, 0, 0, 0, method, gen_flags, dos_time, dos_date))
6100 
6101  if(pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header))
6103 
6104  cur_archive_file_ofs += sizeof(local_dir_header);
6105 
6106  if(pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
6107  {
6109  }
6110 
6111  cur_archive_file_ofs += archive_name_size;
6112  }
6113 
6114  if(user_extra_data_len > 0)
6115  {
6116  if(pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len)
6118 
6119  cur_archive_file_ofs += user_extra_data_len;
6120  }
6121 
6122  if(uncomp_size)
6123  {
6124  mz_uint64 uncomp_remaining = uncomp_size;
6125  void *pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, MZ_ZIP_MAX_IO_BUF_SIZE);
6126  if(!pRead_buf)
6127  {
6128  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6129  }
6130 
6131  if(!level)
6132  {
6133  while(uncomp_remaining)
6134  {
6135  mz_uint n = (mz_uint)MZ_MIN((mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE, uncomp_remaining);
6136  if((MZ_FREAD(pRead_buf, 1, n, pSrc_file) != n) || (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf, n) != n))
6137  {
6138  pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6140  }
6141  uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n);
6142  uncomp_remaining -= n;
6143  cur_archive_file_ofs += n;
6144  }
6145  comp_size = uncomp_size;
6146  }
6147  else
6148  {
6149  mz_bool result = MZ_FALSE;
6151  tdefl_compressor *pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor));
6152  if(!pComp)
6153  {
6154  pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6155  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6156  }
6157 
6158  state.m_pZip = pZip;
6159  state.m_cur_archive_file_ofs = cur_archive_file_ofs;
6160  state.m_comp_size = 0;
6161 
6163  {
6164  pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6165  pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6167  }
6168 
6169  for(;;)
6170  {
6171  size_t in_buf_size = (mz_uint32)MZ_MIN(uncomp_remaining, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
6172  tdefl_status status;
6173 
6174  if(MZ_FREAD(pRead_buf, 1, in_buf_size, pSrc_file) != in_buf_size)
6175  {
6177  break;
6178  }
6179 
6180  uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, in_buf_size);
6181  uncomp_remaining -= in_buf_size;
6182 
6183  status = tdefl_compress_buffer(pComp, pRead_buf, in_buf_size, uncomp_remaining ? TDEFL_NO_FLUSH : TDEFL_FINISH);
6184  if(status == TDEFL_STATUS_DONE)
6185  {
6186  result = MZ_TRUE;
6187  break;
6188  }
6189  else if(status != TDEFL_STATUS_OKAY)
6190  {
6192  break;
6193  }
6194  }
6195 
6196  pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6197 
6198  if(!result)
6199  {
6200  pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6201  return MZ_FALSE;
6202  }
6203 
6204  comp_size = state.m_comp_size;
6205  cur_archive_file_ofs = state.m_cur_archive_file_ofs;
6206  }
6207 
6208  pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6209  }
6210 
6211  mz_uint8 local_dir_footer[MZ_ZIP_DATA_DESCRIPTER_SIZE64];
6212  mz_uint32 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE32;
6213 
6214  MZ_WRITE_LE32(local_dir_footer + 0, MZ_ZIP_DATA_DESCRIPTOR_ID);
6215  MZ_WRITE_LE32(local_dir_footer + 4, uncomp_crc32);
6216  if(pExtra_data == NULL)
6217  {
6218  if(comp_size > MZ_UINT32_MAX)
6220 
6221  MZ_WRITE_LE32(local_dir_footer + 8, comp_size);
6222  MZ_WRITE_LE32(local_dir_footer + 12, uncomp_size);
6223  }
6224  else
6225  {
6226  MZ_WRITE_LE64(local_dir_footer + 8, comp_size);
6227  MZ_WRITE_LE64(local_dir_footer + 16, uncomp_size);
6228  local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE64;
6229  }
6230 
6231  if(pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_footer, local_dir_footer_size) != local_dir_footer_size)
6232  return MZ_FALSE;
6233 
6234  cur_archive_file_ofs += local_dir_footer_size;
6235 
6236  if(pExtra_data != NULL)
6237  {
6238  extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
6239  (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
6240  }
6241 
6242  if(!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, pExtra_data, extra_size, pComment, comment_size,
6243  uncomp_size, comp_size, uncomp_crc32, method, gen_flags, dos_time, dos_date, local_dir_header_ofs, ext_attributes,
6244  user_extra_data_central, user_extra_data_central_len))
6245  return MZ_FALSE;
6246 
6247  pZip->m_total_files++;
6248  pZip->m_archive_size = cur_archive_file_ofs;
6249 
6250  return MZ_TRUE;
6251 }
6252 
6253 mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags)
6254 {
6255  MZ_FILE *pSrc_file = NULL;
6256  mz_uint64 uncomp_size = 0;
6257  MZ_TIME_T file_modified_time;
6258  MZ_TIME_T *pFile_time = NULL;
6259 
6260  memset(&file_modified_time, 0, sizeof(file_modified_time));
6261 
6262 #if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_STDIO)
6263  pFile_time = &file_modified_time;
6264  if(!mz_zip_get_file_modified_time(pSrc_filename, &file_modified_time))
6266 #endif
6267 
6268  pSrc_file = MZ_FOPEN(pSrc_filename, "rb");
6269  if(!pSrc_file)
6271 
6272  MZ_FSEEK64(pSrc_file, 0, SEEK_END);
6273  uncomp_size = MZ_FTELL64(pSrc_file);
6274  MZ_FSEEK64(pSrc_file, 0, SEEK_SET);
6275 
6276  mz_bool status = mz_zip_writer_add_cfile(pZip, pArchive_name, pSrc_file, uncomp_size, pFile_time, pComment, comment_size, level_and_flags, NULL, 0, NULL, 0);
6277 
6278  MZ_FCLOSE(pSrc_file);
6279 
6280  return status;
6281 }
6282 #endif /* #ifndef MINIZ_NO_STDIO */
6283 
6284 static mz_bool mz_zip_writer_update_zip64_extension_block(mz_zip_array *pNew_ext, mz_zip_archive *pZip, const mz_uint8 *pExt, uint32_t ext_len, mz_uint64 *pComp_size, mz_uint64 *pUncomp_size, mz_uint64 *pLocal_header_ofs, mz_uint32 *pDisk_start)
6285 {
6286  /* + 64 should be enough for any new zip64 data */
6287  if(!mz_zip_array_reserve(pZip, pNew_ext, ext_len + 64, MZ_FALSE))
6288  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6289 
6290  mz_zip_array_resize(pZip, pNew_ext, 0, MZ_FALSE);
6291 
6292  if((pUncomp_size) || (pComp_size) || (pLocal_header_ofs) || (pDisk_start))
6293  {
6294  mz_uint8 new_ext_block[64];
6295  mz_uint8 *pDst = new_ext_block;
6297  mz_write_le16(pDst + sizeof(mz_uint16), 0);
6298  pDst += sizeof(mz_uint16) * 2;
6299 
6300  if(pUncomp_size)
6301  {
6302  mz_write_le64(pDst, *pUncomp_size);
6303  pDst += sizeof(mz_uint64);
6304  }
6305 
6306  if(pComp_size)
6307  {
6308  mz_write_le64(pDst, *pComp_size);
6309  pDst += sizeof(mz_uint64);
6310  }
6311 
6312  if(pLocal_header_ofs)
6313  {
6314  mz_write_le64(pDst, *pLocal_header_ofs);
6315  pDst += sizeof(mz_uint64);
6316  }
6317 
6318  if(pDisk_start)
6319  {
6320  mz_write_le32(pDst, *pDisk_start);
6321  pDst += sizeof(mz_uint32);
6322  }
6323 
6324  mz_write_le16(new_ext_block + sizeof(mz_uint16), (mz_uint16)((pDst - new_ext_block) - sizeof(mz_uint16) * 2));
6325 
6326  if(!mz_zip_array_push_back(pZip, pNew_ext, new_ext_block, pDst - new_ext_block))
6327  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6328  }
6329 
6330  if((pExt) && (ext_len))
6331  {
6332  mz_uint32 extra_size_remaining = ext_len;
6333  const mz_uint8 *pExtra_data = pExt;
6334 
6335  do
6336  {
6337  mz_uint32 field_id, field_data_size, field_total_size;
6338 
6339  if(extra_size_remaining < (sizeof(mz_uint16) * 2))
6341 
6342  field_id = MZ_READ_LE16(pExtra_data);
6343  field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16));
6344  field_total_size = field_data_size + sizeof(mz_uint16) * 2;
6345 
6346  if(field_total_size > extra_size_remaining)
6348 
6350  {
6351  if(!mz_zip_array_push_back(pZip, pNew_ext, pExtra_data, field_total_size))
6352  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6353  }
6354 
6355  pExtra_data += field_total_size;
6356  extra_size_remaining -= field_total_size;
6357  } while(extra_size_remaining);
6358  }
6359 
6360  return MZ_TRUE;
6361 }
6362 
6363 /* TODO: This func is now pretty freakin complex due to zip64, split it up? */
6365 {
6366  mz_uint n, bit_flags, num_alignment_padding_bytes, src_central_dir_following_data_size;
6367  mz_uint64 src_archive_bytes_remaining, local_dir_header_ofs;
6368  mz_uint64 cur_src_file_ofs, cur_dst_file_ofs;
6369  mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)];
6370  mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
6371  mz_uint8 new_central_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE];
6372  size_t orig_central_dir_size;
6373  mz_zip_internal_state *pState;
6374  void *pBuf;
6375  const mz_uint8 *pSrc_central_header;
6376  mz_zip_archive_file_stat src_file_stat;
6377  mz_uint32 src_filename_len, src_comment_len, src_ext_len;
6378  mz_uint32 local_header_filename_size, local_header_extra_len;
6379  mz_uint64 local_header_comp_size, local_header_uncomp_size;
6380  mz_bool found_zip64_ext_data_in_ldir = MZ_FALSE;
6381 
6382  /* Sanity checks */
6383  if((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pSource_zip->m_pRead))
6385 
6386  pState = pZip->m_pState;
6387 
6388  /* Don't support copying files from zip64 archives to non-zip64, even though in some cases this is possible */
6389  if((pSource_zip->m_pState->m_zip64) && (!pZip->m_pState->m_zip64))
6391 
6392  /* Get pointer to the source central dir header and crack it */
6393  if(NULL == (pSrc_central_header = mz_zip_get_cdh(pSource_zip, src_file_index)))
6395 
6396  if(MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_SIG_OFS) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG)
6398 
6399  src_filename_len = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_FILENAME_LEN_OFS);
6400  src_comment_len = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_COMMENT_LEN_OFS);
6401  src_ext_len = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS);
6402  src_central_dir_following_data_size = src_filename_len + src_ext_len + src_comment_len;
6403 
6404  /* TODO: We don't support central dir's >= MZ_UINT32_MAX bytes right now (+32 fudge factor in case we need to add more extra data) */
6405  if((pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_central_dir_following_data_size + 32) >= MZ_UINT32_MAX)
6407 
6408  num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
6409 
6410  if(!pState->m_zip64)
6411  {
6412  if(pZip->m_total_files == MZ_UINT16_MAX)
6414  }
6415  else
6416  {
6417  /* TODO: Our zip64 support still has some 32-bit limits that may not be worth fixing. */
6418  if(pZip->m_total_files == MZ_UINT32_MAX)
6420  }
6421 
6422  if(!mz_zip_file_stat_internal(pSource_zip, src_file_index, pSrc_central_header, &src_file_stat, NULL))
6423  return MZ_FALSE;
6424 
6425  cur_src_file_ofs = src_file_stat.m_local_header_ofs;
6426  cur_dst_file_ofs = pZip->m_archive_size;
6427 
6428  /* Read the source archive's local dir header */
6429  if(pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
6431 
6432  if(MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
6434 
6435  cur_src_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE;
6436 
6437  /* Compute the total size we need to copy (filename+extra data+compressed data) */
6438  local_header_filename_size = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS);
6439  local_header_extra_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
6440  local_header_comp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS);
6441  local_header_uncomp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS);
6442  src_archive_bytes_remaining = local_header_filename_size + local_header_extra_len + src_file_stat.m_comp_size;
6443 
6444  /* Try to find a zip64 extended information field */
6445  if((local_header_extra_len) && ((local_header_comp_size == MZ_UINT32_MAX) || (local_header_uncomp_size == MZ_UINT32_MAX)))
6446  {
6447  mz_zip_array file_data_array;
6448  mz_zip_array_init(&file_data_array, 1);
6449  if(!mz_zip_array_resize(pZip, &file_data_array, local_header_extra_len, MZ_FALSE))
6450  {
6451  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6452  }
6453 
6454  if(pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, src_file_stat.m_local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_size, file_data_array.m_p, local_header_extra_len) != local_header_extra_len)
6455  {
6456  mz_zip_array_clear(pZip, &file_data_array);
6458  }
6459 
6460  mz_uint32 extra_size_remaining = local_header_extra_len;
6461  const mz_uint8 *pExtra_data = (const mz_uint8 *)file_data_array.m_p;
6462 
6463  do
6464  {
6465  mz_uint32 field_id, field_data_size, field_total_size;
6466 
6467  if(extra_size_remaining < (sizeof(mz_uint16) * 2))
6468  {
6469  mz_zip_array_clear(pZip, &file_data_array);
6471  }
6472 
6473  field_id = MZ_READ_LE16(pExtra_data);
6474  field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16));
6475  field_total_size = field_data_size + sizeof(mz_uint16) * 2;
6476 
6477  if(field_total_size > extra_size_remaining)
6478  {
6479  mz_zip_array_clear(pZip, &file_data_array);
6481  }
6482 
6484  {
6485  const mz_uint8 *pSrc_field_data = pExtra_data + sizeof(mz_uint32);
6486 
6487  if(field_data_size < sizeof(mz_uint64) * 2)
6488  {
6489  mz_zip_array_clear(pZip, &file_data_array);
6491  }
6492 
6493  local_header_uncomp_size = MZ_READ_LE64(pSrc_field_data);
6494  local_header_comp_size = MZ_READ_LE64(pSrc_field_data + sizeof(mz_uint64)); /* may be 0 if there's a descriptor */
6495 
6496  found_zip64_ext_data_in_ldir = MZ_TRUE;
6497  break;
6498  }
6499 
6500  pExtra_data += field_total_size;
6501  extra_size_remaining -= field_total_size;
6502  } while(extra_size_remaining);
6503 
6504  mz_zip_array_clear(pZip, &file_data_array);
6505  }
6506 
6507  if(!pState->m_zip64)
6508  {
6509  /* Try to detect if the new archive will most likely wind up too big and bail early (+(sizeof(mz_uint32) * 4) is for the optional descriptor which could be present, +64 is a fudge factor). */
6510  /* We also check when the archive is finalized so this doesn't need to be perfect. */
6511  mz_uint64 approx_new_archive_size = cur_dst_file_ofs + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + src_archive_bytes_remaining + (sizeof(mz_uint32) * 4) +
6512  pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_central_dir_following_data_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 64;
6513 
6514  if(approx_new_archive_size >= MZ_UINT32_MAX)
6516  }
6517 
6518  /* Write dest archive padding */
6519  if(!mz_zip_writer_write_zeros(pZip, cur_dst_file_ofs, num_alignment_padding_bytes))
6520  return MZ_FALSE;
6521 
6522  cur_dst_file_ofs += num_alignment_padding_bytes;
6523 
6524  local_dir_header_ofs = cur_dst_file_ofs;
6525  if(pZip->m_file_offset_alignment)
6526  {
6527  MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0);
6528  }
6529 
6530  /* The original zip's local header+ext block doesn't change, even with zip64, so we can just copy it over to the dest zip */
6531  if(pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
6533 
6534  cur_dst_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE;
6535 
6536  /* Copy over the source archive bytes to the dest archive, also ensure we have enough buf space to handle optional data descriptor */
6537  if(NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)MZ_MAX(32U, MZ_MIN((mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE, src_archive_bytes_remaining)))))
6538  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6539 
6540  while(src_archive_bytes_remaining)
6541  {
6542  n = (mz_uint)MZ_MIN((mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE, src_archive_bytes_remaining);
6543  if(pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, n) != n)
6544  {
6545  pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
6547  }
6548  cur_src_file_ofs += n;
6549 
6550  if(pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n)
6551  {
6552  pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
6554  }
6555  cur_dst_file_ofs += n;
6556 
6557  src_archive_bytes_remaining -= n;
6558  }
6559 
6560  /* Now deal with the optional data descriptor */
6561  bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS);
6562  if(bit_flags & 8)
6563  {
6564  /* Copy data descriptor */
6565  if((pSource_zip->m_pState->m_zip64) || (found_zip64_ext_data_in_ldir))
6566  {
6567  /* src is zip64, dest must be zip64 */
6568 
6569  /* name uint32_t's */
6570  /* id 1 (optional in zip64?) */
6571  /* crc 1 */
6572  /* comp_size 2 */
6573  /* uncomp_size 2 */
6574  if(pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, (sizeof(mz_uint32) * 6)) != (sizeof(mz_uint32) * 6))
6575  {
6576  pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
6578  }
6579 
6580  n = sizeof(mz_uint32) * ((MZ_READ_LE32(pBuf) == MZ_ZIP_DATA_DESCRIPTOR_ID) ? 6 : 5);
6581  }
6582  else
6583  {
6584  /* src is NOT zip64 */
6585  mz_bool has_id;
6586 
6587  if(pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, sizeof(mz_uint32) * 4) != sizeof(mz_uint32) * 4)
6588  {
6589  pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
6591  }
6592 
6594 
6595  if(pZip->m_pState->m_zip64)
6596  {
6597  /* dest is zip64, so upgrade the data descriptor */
6598  const mz_uint32 *pSrc_descriptor = (const mz_uint32 *)((const mz_uint8 *)pBuf + (has_id ? sizeof(mz_uint32) : 0));
6599  const mz_uint32 src_crc32 = pSrc_descriptor[0];
6600  const mz_uint64 src_comp_size = pSrc_descriptor[1];
6601  const mz_uint64 src_uncomp_size = pSrc_descriptor[2];
6602 
6604  mz_write_le32((mz_uint8 *)pBuf + sizeof(mz_uint32) * 1, src_crc32);
6605  mz_write_le64((mz_uint8 *)pBuf + sizeof(mz_uint32) * 2, src_comp_size);
6606  mz_write_le64((mz_uint8 *)pBuf + sizeof(mz_uint32) * 4, src_uncomp_size);
6607 
6608  n = sizeof(mz_uint32) * 6;
6609  }
6610  else
6611  {
6612  /* dest is NOT zip64, just copy it as-is */
6613  n = sizeof(mz_uint32) * (has_id ? 4 : 3);
6614  }
6615  }
6616 
6617  if(pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n)
6618  {
6619  pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
6621  }
6622 
6623  cur_src_file_ofs += n;
6624  cur_dst_file_ofs += n;
6625  }
6626  pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
6627 
6628  /* Finally, add the new central dir header */
6629  orig_central_dir_size = pState->m_central_dir.m_size;
6630 
6631  memcpy(new_central_header, pSrc_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE);
6632 
6633  if(pState->m_zip64)
6634  {
6635  /* This is the painful part: We need to write a new central dir header + ext block with updated zip64 fields, and ensure the old fields (if any) are not included. */
6636  const mz_uint8 *pSrc_ext = pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_filename_len;
6637  mz_zip_array new_ext_block;
6638 
6639  mz_zip_array_init(&new_ext_block, sizeof(mz_uint8));
6640 
6644 
6645  if(!mz_zip_writer_update_zip64_extension_block(&new_ext_block, pZip, pSrc_ext, src_ext_len, &src_file_stat.m_comp_size, &src_file_stat.m_uncomp_size, &local_dir_header_ofs, NULL))
6646  {
6647  mz_zip_array_clear(pZip, &new_ext_block);
6648  return MZ_FALSE;
6649  }
6650 
6651  MZ_WRITE_LE16(new_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS, new_ext_block.m_size);
6652 
6653  if(!mz_zip_array_push_back(pZip, &pState->m_central_dir, new_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE))
6654  {
6655  mz_zip_array_clear(pZip, &new_ext_block);
6656  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6657  }
6658 
6659  if(!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, src_filename_len))
6660  {
6661  mz_zip_array_clear(pZip, &new_ext_block);
6662  mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
6663  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6664  }
6665 
6666  if(!mz_zip_array_push_back(pZip, &pState->m_central_dir, new_ext_block.m_p, new_ext_block.m_size))
6667  {
6668  mz_zip_array_clear(pZip, &new_ext_block);
6669  mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
6670  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6671  }
6672 
6673  if(!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_filename_len + src_ext_len, src_comment_len))
6674  {
6675  mz_zip_array_clear(pZip, &new_ext_block);
6676  mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
6677  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6678  }
6679 
6680  mz_zip_array_clear(pZip, &new_ext_block);
6681  }
6682  else
6683  {
6684  /* sanity checks */
6685  if(cur_dst_file_ofs > MZ_UINT32_MAX)
6687 
6688  if(local_dir_header_ofs >= MZ_UINT32_MAX)
6690 
6691  MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS, local_dir_header_ofs);
6692 
6693  if(!mz_zip_array_push_back(pZip, &pState->m_central_dir, new_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE))
6694  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6695 
6696  if(!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, src_central_dir_following_data_size))
6697  {
6698  mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
6699  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6700  }
6701  }
6702 
6703  /* This shouldn't trigger unless we screwed up during the initial sanity checks */
6704  if(pState->m_central_dir.m_size >= MZ_UINT32_MAX)
6705  {
6706  /* TODO: Support central dirs >= 32-bits in size */
6707  mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
6709  }
6710 
6711  n = (mz_uint32)orig_central_dir_size;
6712  if(!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &n, 1))
6713  {
6714  mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
6715  return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6716  }
6717 
6718  pZip->m_total_files++;
6719  pZip->m_archive_size = cur_dst_file_ofs;
6720 
6721  return MZ_TRUE;
6722 }
6723 
6725 {
6726  mz_zip_internal_state *pState;
6727  mz_uint64 central_dir_ofs, central_dir_size;
6728  mz_uint8 hdr[256];
6729 
6730  if((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING))
6732 
6733  pState = pZip->m_pState;
6734 
6735  if(pState->m_zip64)
6736  {
6737  if((pZip->m_total_files > MZ_UINT32_MAX) || (pState->m_central_dir.m_size >= MZ_UINT32_MAX))
6739  }
6740  else
6741  {
6744  }
6745 
6746  central_dir_ofs = 0;
6747  central_dir_size = 0;
6748  if(pZip->m_total_files)
6749  {
6750  /* Write central directory */
6751  central_dir_ofs = pZip->m_archive_size;
6752  central_dir_size = pState->m_central_dir.m_size;
6753  pZip->m_central_directory_file_ofs = central_dir_ofs;
6754  if(pZip->m_pWrite(pZip->m_pIO_opaque, central_dir_ofs, pState->m_central_dir.m_p, (size_t)central_dir_size) != central_dir_size)
6756 
6757  pZip->m_archive_size += central_dir_size;
6758  }
6759 
6760  if(pState->m_zip64)
6761  {
6762  /* Write zip64 end of central directory header */
6763  mz_uint64 rel_ofs_to_zip64_ecdr = pZip->m_archive_size;
6764 
6765  MZ_CLEAR_OBJ(hdr);
6768  MZ_WRITE_LE16(hdr + MZ_ZIP64_ECDH_VERSION_MADE_BY_OFS, 0x031E); /* TODO: always Unix */
6772  MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_SIZE_OFS, central_dir_size);
6773  MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_OFS_OFS, central_dir_ofs);
6776 
6778 
6779  /* Write zip64 end of central directory locator */
6780  MZ_CLEAR_OBJ(hdr);
6782  MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS, rel_ofs_to_zip64_ecdr);
6786 
6788  }
6789 
6790  /* Write end of central directory record */
6791  MZ_CLEAR_OBJ(hdr);
6795  MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_SIZE_OFS, MZ_MIN(MZ_UINT32_MAX, central_dir_size));
6796  MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_OFS_OFS, MZ_MIN(MZ_UINT32_MAX, central_dir_ofs));
6797 
6800 
6801 #ifndef MINIZ_NO_STDIO
6802  if((pState->m_pFile) && (MZ_FFLUSH(pState->m_pFile) == EOF))
6804 #endif /* #ifndef MINIZ_NO_STDIO */
6805 
6807 
6809  return MZ_TRUE;
6810 }
6811 
6813 {
6814  if((!ppBuf) || (!pSize))
6816 
6817  *ppBuf = NULL;
6818  *pSize = 0;
6819 
6820  if((!pZip) || (!pZip->m_pState))
6822 
6823  if(pZip->m_pWrite != mz_zip_heap_write_func)
6825 
6827  return MZ_FALSE;
6828 
6829  *ppBuf = pZip->m_pState->m_pMem;
6830  *pSize = pZip->m_pState->m_mem_size;
6831  pZip->m_pState->m_pMem = NULL;
6832  pZip->m_pState->m_mem_size = pZip->m_pState->m_mem_capacity = 0;
6833 
6834  return MZ_TRUE;
6835 }
6836 
6838 {
6839  return mz_zip_writer_end_internal(pZip, MZ_TRUE);
6840 }
6841 
6842 #ifndef MINIZ_NO_STDIO
6843 mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags)
6844 {
6845  return mz_zip_add_mem_to_archive_file_in_place_v2(pZip_filename, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, NULL);
6846 }
6847 
6848 mz_bool mz_zip_add_mem_to_archive_file_in_place_v2(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_zip_error *pErr)
6849 {
6850  mz_bool status, created_new_archive = MZ_FALSE;
6851  mz_zip_archive zip_archive;
6852  struct MZ_FILE_STAT_STRUCT file_stat;
6853  mz_zip_error actual_err = MZ_ZIP_NO_ERROR;
6854 
6855  mz_zip_zero_struct(&zip_archive);
6856  if((int)level_and_flags < 0)
6857  level_and_flags = MZ_DEFAULT_LEVEL;
6858 
6859  if((!pZip_filename) || (!pArchive_name) || ((buf_size) && (!pBuf)) || ((comment_size) && (!pComment)) || ((level_and_flags & 0xF) > MZ_UBER_COMPRESSION))
6860  {
6861  if(pErr)
6862  *pErr = MZ_ZIP_INVALID_PARAMETER;
6863  return MZ_FALSE;
6864  }
6865 
6866  if(!mz_zip_writer_validate_archive_name(pArchive_name))
6867  {
6868  if(pErr)
6869  *pErr = MZ_ZIP_INVALID_FILENAME;
6870  return MZ_FALSE;
6871  }
6872 
6873  /* Important: The regular non-64 bit version of stat() can fail here if the file is very large, which could cause the archive to be overwritten. */
6874  /* So be sure to compile with _LARGEFILE64_SOURCE 1 */
6875  if(MZ_FILE_STAT(pZip_filename, &file_stat) != 0)
6876  {
6877  /* Create a new archive. */
6878  if(!mz_zip_writer_init_file_v2(&zip_archive, pZip_filename, 0, level_and_flags))
6879  {
6880  if(pErr)
6881  *pErr = zip_archive.m_last_error;
6882  return MZ_FALSE;
6883  }
6884 
6885  created_new_archive = MZ_TRUE;
6886  }
6887  else
6888  {
6889  /* Append to an existing archive. */
6890  if(!mz_zip_reader_init_file_v2(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY, 0, 0))
6891  {
6892  if(pErr)
6893  *pErr = zip_archive.m_last_error;
6894  return MZ_FALSE;
6895  }
6896 
6897  if(!mz_zip_writer_init_from_reader_v2(&zip_archive, pZip_filename, level_and_flags))
6898  {
6899  if(pErr)
6900  *pErr = zip_archive.m_last_error;
6901 
6902  mz_zip_reader_end_internal(&zip_archive, MZ_FALSE);
6903 
6904  return MZ_FALSE;
6905  }
6906  }
6907 
6908  status = mz_zip_writer_add_mem_ex(&zip_archive, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, 0, 0);
6909  actual_err = zip_archive.m_last_error;
6910 
6911  /* Always finalize, even if adding failed for some reason, so we have a valid central directory. (This may not always succeed, but we can try.) */
6912  if(!mz_zip_writer_finalize_archive(&zip_archive))
6913  {
6914  if(!actual_err)
6915  actual_err = zip_archive.m_last_error;
6916 
6917  status = MZ_FALSE;
6918  }
6919 
6920  if(!mz_zip_writer_end_internal(&zip_archive, status))
6921  {
6922  if(!actual_err)
6923  actual_err = zip_archive.m_last_error;
6924 
6925  status = MZ_FALSE;
6926  }
6927 
6928  if((!status) && (created_new_archive))
6929  {
6930  /* It's a new archive and something went wrong, so just delete it. */
6931  int ignoredStatus = MZ_DELETE_FILE(pZip_filename);
6932  (void)ignoredStatus;
6933  }
6934 
6935  if(pErr)
6936  *pErr = actual_err;
6937 
6938  return status;
6939 }
6940 
6941 void *mz_zip_extract_archive_file_to_heap_v2(const char *pZip_filename, const char *pArchive_name, const char *pComment, size_t *pSize, mz_uint flags, mz_zip_error *pErr)
6942 {
6943  mz_uint32 file_index;
6944  mz_zip_archive zip_archive;
6945  void *p = NULL;
6946 
6947  if(pSize)
6948  *pSize = 0;
6949 
6950  if((!pZip_filename) || (!pArchive_name))
6951  {
6952  if(pErr)
6953  *pErr = MZ_ZIP_INVALID_PARAMETER;
6954 
6955  return NULL;
6956  }
6957 
6958  mz_zip_zero_struct(&zip_archive);
6959  if(!mz_zip_reader_init_file_v2(&zip_archive, pZip_filename, flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY, 0, 0))
6960  {
6961  if(pErr)
6962  *pErr = zip_archive.m_last_error;
6963 
6964  return NULL;
6965  }
6966 
6967  if(mz_zip_reader_locate_file_v2(&zip_archive, pArchive_name, pComment, flags, &file_index))
6968  {
6969  p = mz_zip_reader_extract_to_heap(&zip_archive, file_index, pSize, flags);
6970  }
6971 
6972  mz_zip_reader_end_internal(&zip_archive, p != NULL);
6973 
6974  if(pErr)
6975  *pErr = zip_archive.m_last_error;
6976 
6977  return p;
6978 }
6979 
6980 void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags)
6981 {
6982  return mz_zip_extract_archive_file_to_heap_v2(pZip_filename, pArchive_name, NULL, pSize, flags, NULL);
6983 }
6984 
6985 #endif /* #ifndef MINIZ_NO_STDIO */
6986 
6987 #endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS */
6988 
6989 /* ------------------- Misc utils */
6990 
6992 {
6993  return pZip ? pZip->m_zip_mode : MZ_ZIP_MODE_INVALID;
6994 }
6995 
6997 {
6998  return pZip ? pZip->m_zip_type : MZ_ZIP_TYPE_INVALID;
6999 }
7000 
7002 {
7003  mz_zip_error prev_err;
7004 
7005  if(!pZip)
7006  return MZ_ZIP_INVALID_PARAMETER;
7007 
7008  prev_err = pZip->m_last_error;
7009 
7010  pZip->m_last_error = err_num;
7011  return prev_err;
7012 }
7013 
7015 {
7016  if(!pZip)
7017  return MZ_ZIP_INVALID_PARAMETER;
7018 
7019  return pZip->m_last_error;
7020 }
7021 
7023 {
7024  return mz_zip_set_last_error(pZip, MZ_ZIP_NO_ERROR);
7025 }
7026 
7028 {
7029  mz_zip_error prev_err;
7030 
7031  if(!pZip)
7032  return MZ_ZIP_INVALID_PARAMETER;
7033 
7034  prev_err = pZip->m_last_error;
7035 
7036  pZip->m_last_error = MZ_ZIP_NO_ERROR;
7037  return prev_err;
7038 }
7039 
7041 {
7042  switch(mz_err)
7043  {
7044  case MZ_ZIP_NO_ERROR:
7045  return "no error";
7047  return "undefined error";
7048  case MZ_ZIP_TOO_MANY_FILES:
7049  return "too many files";
7050  case MZ_ZIP_FILE_TOO_LARGE:
7051  return "file too large";
7053  return "unsupported method";
7055  return "unsupported encryption";
7057  return "unsupported feature";
7059  return "failed finding central directory";
7060  case MZ_ZIP_NOT_AN_ARCHIVE:
7061  return "not a ZIP archive";
7063  return "invalid header or archive is corrupted";
7065  return "unsupported multidisk archive";
7067  return "decompression failed or archive is corrupted";
7069  return "compression failed";
7071  return "unexpected decompressed size";
7073  return "CRC-32 check failed";
7075  return "unsupported central directory size";
7076  case MZ_ZIP_ALLOC_FAILED:
7077  return "allocation failed";
7079  return "file open failed";
7081  return "file create failed";
7083  return "file write failed";
7085  return "file read failed";
7087  return "file close failed";
7089  return "file seek failed";
7091  return "file stat failed";
7093  return "invalid parameter";
7095  return "invalid filename";
7096  case MZ_ZIP_BUF_TOO_SMALL:
7097  return "buffer too small";
7098  case MZ_ZIP_INTERNAL_ERROR:
7099  return "internal error";
7100  case MZ_ZIP_FILE_NOT_FOUND:
7101  return "file not found";
7103  return "archive is too large";
7105  return "validation failed";
7107  return "write calledback failed";
7108  case MZ_ZIP_TOTAL_ERRORS:
7109  // not an actual error, just the maximum index
7110  break;
7111  }
7112 
7113  return "unknown error";
7114 }
7115 
7116 /* Note: Just because the archive is not zip64 doesn't necessarily mean it doesn't have Zip64 extended information extra field, argh. */
7118 {
7119  if((!pZip) || (!pZip->m_pState))
7120  return MZ_FALSE;
7121 
7122  return pZip->m_pState->m_zip64;
7123 }
7124 
7126 {
7127  if((!pZip) || (!pZip->m_pState))
7128  return 0;
7129 
7130  return pZip->m_pState->m_central_dir.m_size;
7131 }
7132 
7134 {
7135  return pZip ? pZip->m_total_files : 0;
7136 }
7137 
7139 {
7140  if(!pZip)
7141  return 0;
7142  return pZip->m_archive_size;
7143 }
7144 
7146 {
7147  if((!pZip) || (!pZip->m_pState))
7148  return 0;
7149  return pZip->m_pState->m_file_archive_start_ofs;
7150 }
7151 
7153 {
7154  if((!pZip) || (!pZip->m_pState))
7155  return 0;
7156  return pZip->m_pState->m_pFile;
7157 }
7158 
7159 size_t mz_zip_read_archive_data(mz_zip_archive *pZip, mz_uint64 file_ofs, void *pBuf, size_t n)
7160 {
7161  if((!pZip) || (!pZip->m_pState) || (!pBuf) || (!pZip->m_pRead))
7163 
7164  return pZip->m_pRead(pZip->m_pIO_opaque, file_ofs, pBuf, n);
7165 }
7166 
7167 mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size)
7168 {
7169  mz_uint n;
7170  const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
7171  if(!p)
7172  {
7173  if(filename_buf_size)
7174  pFilename[0] = '\0';
7176  return 0;
7177  }
7179  if(filename_buf_size)
7180  {
7181  n = MZ_MIN(n, filename_buf_size - 1);
7182  memcpy(pFilename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n);
7183  pFilename[n] = '\0';
7184  }
7185  return n + 1;
7186 }
7187 
7189 {
7190  return mz_zip_file_stat_internal(pZip, file_index, mz_zip_get_cdh(pZip, file_index), pStat, NULL);
7191 }
7192 
7194 {
7195  if(!pZip)
7196  return MZ_FALSE;
7197 
7198  if(pZip->m_zip_mode == MZ_ZIP_MODE_READING)
7199  return mz_zip_reader_end(pZip);
7201  return mz_zip_writer_end(pZip);
7202 
7203  return MZ_FALSE;
7204 }
7205 
7206 #ifdef __cplusplus
7207 }
7208 #endif
static bool has_id(const jsont &json)
Return true iff the argument has a "@id" key.
int16_t s2
Definition: bytecode_info.h:60
int8_t s1
Definition: bytecode_info.h:59
void err(int eval, const char *fmt,...)
Definition: err.c:13
static int8_t r
Definition: irep_hash.h:60
literalt pos(literalt a)
Definition: literal.h:194
static tdefl_sym_freq * tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq *pSyms0, tdefl_sym_freq *pSyms1)
Definition: miniz.cpp:725
#define MZ_WRITE_LE32(p, v)
Definition: miniz.cpp:5132
#define MZ_FILE_STAT
Definition: miniz.cpp:3028
void * tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out)
Definition: miniz.cpp:2128
mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len)
Definition: miniz.cpp:57
static mz_bool mz_zip_writer_add_to_central_dir(mz_zip_archive *pZip, const char *pFilename, mz_uint16 filename_size, const void *pExtra, mz_uint16 extra_size, const void *pComment, mz_uint16 comment_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, mz_uint64 local_header_ofs, mz_uint32 ext_attributes, const char *user_extra_data, mz_uint user_extra_data_len)
Definition: miniz.cpp:5588
mz_bool mz_zip_is_zip64(mz_zip_archive *pZip)
Definition: miniz.cpp:7117
static const mz_uint8 s_tdefl_len_extra[256]
Definition: miniz.cpp:670
mz_bool mz_zip_reader_end(mz_zip_archive *pZip)
Definition: miniz.cpp:3742
mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags)
Definition: miniz.cpp:4972
mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip)
Definition: miniz.cpp:6724
mz_zip_type mz_zip_get_type(mz_zip_archive *pZip)
Definition: miniz.cpp:6996
static size_t mz_zip_file_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
Definition: miniz.cpp:3808
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)
Definition: miniz.cpp:1957
static const mz_uint16 s_tdefl_len_sym[256]
Definition: miniz.cpp:658
mz_bool mz_zip_end(mz_zip_archive *pZip)
Definition: miniz.cpp:7193
static int tdefl_flush_block(tdefl_compressor *d, int flush)
Definition: miniz.cpp:1225
#define TINFL_CR_BEGIN
Definition: miniz.cpp:2191
mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip)
Definition: miniz.cpp:7133
mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning)
Definition: miniz.cpp:5322
#define MZ_WRITE_LE16(p, v)
Definition: miniz.cpp:5131
static void mz_zip_array_init(mz_zip_array *pArray, mz_uint32 element_size)
Definition: miniz.cpp:3171
static void mz_zip_reader_sort_central_dir_offsets_by_filename(mz_zip_archive *pZip)
Definition: miniz.cpp:3370
static void tdefl_start_dynamic_block(tdefl_compressor *d)
Definition: miniz.cpp:962
mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags)
Definition: miniz.cpp:3821
int mz_deflateReset(mz_streamp pStream)
Definition: miniz.cpp:242
static void mz_write_le64(mz_uint8 *p, mz_uint64 v)
Definition: miniz.cpp:5125
#define TINFL_GET_BYTE(state_index, c)
Definition: miniz.cpp:2216
#define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size)
Definition: miniz.cpp:3158
static mz_bool mz_zip_writer_end_internal(mz_zip_archive *pZip, mz_bool set_last_error)
Definition: miniz.cpp:5173
size_t mz_zip_get_central_dir_size(mz_zip_archive *pZip)
Definition: miniz.cpp:7125
static 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)
Definition: miniz.cpp: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)
Definition: miniz.cpp:4006
void * tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
Definition: miniz.cpp:2796
#define MZ_FFLUSH
Definition: miniz.cpp:3029
int mz_inflateInit(mz_streamp pStream)
Definition: miniz.cpp:413
int mz_inflate(mz_streamp pStream, int flush)
Definition: miniz.cpp:418
int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
Definition: miniz.cpp:358
mz_uint32 tdefl_get_adler32(tdefl_compressor *d)
Definition: miniz.cpp:1952
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)
Definition: miniz.cpp:4678
static 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)
Definition: miniz.cpp:3341
#define TDEFL_RLE_ZERO_CODE_SIZE()
Definition: miniz.cpp:934
mz_ulong mz_compressBound(mz_ulong source_len)
Definition: miniz.cpp:363
static void mz_write_le32(mz_uint8 *p, mz_uint32 v)
Definition: miniz.cpp:5118
static mz_bool mz_zip_reader_locate_header_sig(mz_zip_archive *pZip, mz_uint32 record_sig, mz_uint32 record_size, mz_int64 *pOfs)
Definition: miniz.cpp:3422
mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags)
Definition: miniz.cpp:6843
int mz_deflateEnd(mz_streamp pStream)
Definition: miniz.cpp:309
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)
Definition: miniz.cpp:2019
mz_zip_mode mz_zip_get_mode(mz_zip_archive *pZip)
Definition: miniz.cpp:6991
#define MZ_FREOPEN(f, m, s)
Definition: miniz.cpp:3030
static void tdefl_calculate_minimum_redundancy(tdefl_sym_freq *A, int n)
Definition: miniz.cpp:759
static const mz_uint8 s_tdefl_small_dist_sym[512]
Definition: miniz.cpp:678
tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
Definition: miniz.cpp:1914
static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d)
Definition: miniz.cpp:1168
const char * mz_version(void)
Definition: miniz.cpp:196
size_t mz_zip_read_archive_data(mz_zip_archive *pZip, mz_uint64 file_ofs, void *pBuf, size_t n)
Definition: miniz.cpp:7159
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)
Definition: miniz.cpp:2843
mz_bool mz_zip_writer_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning, mz_uint flags)
Definition: miniz.cpp:5327
static size_t mz_zip_file_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
Definition: miniz.cpp:5306
mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index)
Definition: miniz.cpp:3974
static mz_bool tdefl_output_buffer_putter(const void *pBuf, int len, void *pUser)
Definition: miniz.cpp:1979
mz_bool mz_zip_add_mem_to_archive_file_in_place_v2(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_zip_error *pErr)
Definition: miniz.cpp:6848
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)
Definition: miniz.cpp:4265
unsigned char mz_validate_uint32[sizeof(mz_uint32)==4 ? 1 :-1]
Definition: miniz.cpp:48
mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32)
Definition: miniz.cpp:5670
#define TINFL_MEMCPY(d, s, l)
Definition: miniz.cpp:2188
static mz_bool mz_zip_string_equal(const char *pA, const char *pB, mz_uint len, mz_uint flags)
Definition: miniz.cpp:4123
#define TINFL_GET_BITS(state_index, b, n)
Definition: miniz.cpp:2246
mz_bool mz_zip_reader_locate_file_v2(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags, mz_uint32 *pIndex)
Definition: miniz.cpp:4200
mz_bool mz_zip_reader_extract_to_cfile(mz_zip_archive *pZip, mz_uint file_index, FILE *pFile, mz_uint flags)
Definition: miniz.cpp:4738
static const mz_uint8 s_tdefl_small_dist_extra[512]
Definition: miniz.cpp:694
tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d)
Definition: miniz.cpp:1947
mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size)
Definition: miniz.cpp:5300
#define MZ_FREAD
Definition: miniz.cpp:3023
static mz_bool mz_zip_reader_init_internal(mz_zip_archive *pZip, mz_uint flags)
Definition: miniz.cpp:3307
mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32, time_t *last_modified, const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len)
Definition: miniz.cpp:5676
static mz_bool mz_zip_reader_end_internal(mz_zip_archive *pZip, mz_bool set_last_error)
Definition: miniz.cpp:3695
mz_zip_error mz_zip_peek_last_error(mz_zip_archive *pZip)
Definition: miniz.cpp:7014
mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint flags)
Definition: miniz.cpp:3746
#define TINFL_HUFF_DECODE(state_index, sym, pHuff)
Definition: miniz.cpp:2294
void * miniz_def_alloc_func(void *opaque, size_t items, size_t size)
Definition: miniz.cpp:180
static time_t mz_zip_dos_to_time_t(int dos_time, int dos_date)
Definition: miniz.cpp:3239
mz_zip_error mz_zip_get_last_error(mz_zip_archive *pZip)
Definition: miniz.cpp:7027
mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags)
Definition: miniz.cpp:4729
#define MZ_FWRITE
Definition: miniz.cpp:3024
tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush)
Definition: miniz.cpp:1908
mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags)
Definition: miniz.cpp:4480
mz_bool mz_zip_validate_file_archive(const char *pFilename, mz_uint flags, mz_zip_error *pErr)
Definition: miniz.cpp:5067
#define MZ_TOLOWER(c)
Definition: miniz.cpp:3035
static const mz_uint8 s_tdefl_large_dist_extra[128]
Definition: miniz.cpp:713
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)
Definition: miniz.cpp:2065
static void mz_zip_time_t_to_dos_time(time_t time, mz_uint16 *pDOS_time, mz_uint16 *pDOS_date)
Definition: miniz.cpp:3253
tinfl_decompressor * tinfl_decompressor_alloc()
Definition: miniz.cpp:2872
static const mz_uint s_tdefl_num_probes[11]
Definition: miniz.cpp:2033
int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy)
Definition: miniz.cpp:206
mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint flags)
Definition: miniz.cpp:3774
static mz_bool tdefl_compress_normal(tdefl_compressor *d)
Definition: miniz.cpp:1674
mz_bool mz_zip_writer_init_cfile(mz_zip_archive *pZip, FILE *pFile, mz_uint flags)
Definition: miniz.cpp:5373
int mz_deflateInit(mz_streamp pStream, int level)
Definition: miniz.cpp:201
static size_t mz_zip_file_write_callback(void *pOpaque, mz_uint64 ofs, const void *pBuf, size_t n)
Definition: miniz.cpp:4688
static void tdefl_record_match(tdefl_compressor *d, mz_uint match_len, mz_uint match_dist)
Definition: miniz.cpp:1644
#define MZ_FSEEK64
Definition: miniz.cpp:3026
const char * mz_zip_get_error_string(mz_zip_error mz_err)
Definition: miniz.cpp:7040
static mz_bool mz_zip_array_reserve(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_capacity, mz_uint growing)
Definition: miniz.cpp:3203
mz_bool mz_zip_reader_init_cfile(mz_zip_archive *pZip, FILE *pFile, mz_uint64 archive_size, mz_uint flags)
Definition: miniz.cpp:3875
void * mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags)
Definition: miniz.cpp:4426
void miniz_def_free_func(void *opaque, void *address)
Definition: miniz.cpp:185
static void tdefl_huffman_enforce_max_code_size(int *pNum_codes, int code_list_len, int max_code_size)
Definition: miniz.cpp:819
static mz_bool mz_zip_array_push_back(mz_zip_archive *pZip, mz_zip_array *pArray, const void *pElements, size_t n)
Definition: miniz.cpp:3229
static void tdefl_start_static_block(tdefl_compressor *d)
Definition: miniz.cpp:1049
int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level)
Definition: miniz.cpp:328
#define MZ_FOPEN(f, m)
Definition: miniz.cpp:3021
static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flags)
Definition: miniz.cpp:3468
mz_bool mz_zip_writer_end(mz_zip_archive *pZip)
Definition: miniz.cpp:6837
static mz_bool mz_zip_writer_create_central_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, mz_uint16 extra_size, mz_uint16 comment_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, mz_uint64 local_header_ofs, mz_uint32 ext_attributes)
Definition: miniz.cpp:5563
void mz_free(void *p)
Definition: miniz.cpp:173
#define TINFL_MEMSET(p, c, l)
Definition: miniz.cpp:2189
mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags)
Definition: miniz.cpp:6253
static size_t mz_zip_heap_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
Definition: miniz.cpp:5135
int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags)
Definition: miniz.cpp:4191
tdefl_compressor * tdefl_compressor_alloc()
Definition: miniz.cpp:2137
mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index)
Definition: miniz.cpp:3924
mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size)
Definition: miniz.cpp:5268
mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
Definition: miniz.cpp:106
void mz_zip_zero_struct(mz_zip_archive *pZip)
Definition: miniz.cpp:3689
static mz_uint32 mz_zip_writer_create_zip64_extra_data(mz_uint8 *pBuf, mz_uint64 *pUncomp_size, mz_uint64 *pComp_size, mz_uint64 *pLocal_header_ofs)
Definition: miniz.cpp:5509
static 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)
Definition: miniz.cpp:1415
mz_bool mz_zip_reader_extract_file_to_cfile(mz_zip_archive *pZip, const char *pArchive_filename, FILE *pFile, mz_uint flags)
Definition: miniz.cpp:4751
mz_uint64 mz_zip_get_archive_size(mz_zip_archive *pZip)
Definition: miniz.cpp:7138
static mz_uint mz_zip_writer_compute_padding_needed_for_file_alignment(mz_zip_archive *pZip)
Definition: miniz.cpp:5645
static void mz_write_le16(mz_uint8 *p, mz_uint16 v)
Definition: miniz.cpp:5113
void * mz_zip_extract_archive_file_to_heap_v2(const char *pZip_filename, const char *pArchive_name, const char *pComment, size_t *pSize, mz_uint flags, mz_zip_error *pErr)
Definition: miniz.cpp:6941
int mz_inflateInit2(mz_streamp pStream, int window_bits)
Definition: miniz.cpp:377
static mz_bool mz_zip_writer_add_put_buf_callback(const void *pBuf, int len, void *pUser)
Definition: miniz.cpp:5496
static mz_bool mz_zip_writer_validate_archive_name(const char *pArchive_name)
Definition: miniz.cpp:5628
static size_t mz_zip_mem_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
Definition: miniz.cpp:3766
mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint src_file_index)
Definition: miniz.cpp:6364
mz_bool mz_zip_reader_is_file_supported(mz_zip_archive *pZip, mz_uint file_index)
Definition: miniz.cpp:3938
#define TINFL_CR_FINISH
Definition: miniz.cpp:2214
static void tdefl_record_literal(tdefl_compressor *d, mz_uint8 lit)
Definition: miniz.cpp:1631
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)
Definition: miniz.cpp:4416
#define TINFL_CR_RETURN(state_index, result)
Definition: miniz.cpp:2195
#define TINFL_CR_RETURN_FOREVER(state_index, result)
Definition: miniz.cpp:2205
static const mz_uint8 * mz_zip_get_cdh(mz_zip_archive *pZip, mz_uint file_index)
Definition: miniz.cpp:3917
mz_zip_error mz_zip_set_last_error(mz_zip_archive *pZip, mz_zip_error err_num)
Definition: miniz.cpp:7001
int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
Definition: miniz.cpp:542
#define MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE
Definition: miniz.cpp:5508
mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat)
Definition: miniz.cpp:7188
mz_bool mz_zip_writer_init_from_reader_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags)
Definition: miniz.cpp:5393
static mz_bool mz_zip_locate_file_binary_search(mz_zip_archive *pZip, const char *pFilename, mz_uint32 *pIndex)
Definition: miniz.cpp:4151
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)
Definition: miniz.cpp:3826
void tdefl_compressor_free(tdefl_compressor *pComp)
Definition: miniz.cpp:2142
mz_uint64 mz_zip_get_archive_file_start_offset(mz_zip_archive *pZip)
Definition: miniz.cpp:7145
@ MZ_ZIP64_ECDH_VERSION_MADE_BY_OFS
Definition: miniz.cpp:3110
@ MZ_ZIP_CDH_FILENAME_LEN_OFS
Definition: miniz.cpp:3069
@ MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR
Definition: miniz.cpp:3089
@ MZ_ZIP_LOCAL_DIR_HEADER_SIG
Definition: miniz.cpp:3043
@ MZ_ZIP_CDH_FILE_DATE_OFS
Definition: miniz.cpp:3065
@ MZ_ZIP_LDH_CRC32_OFS
Definition: miniz.cpp:3084
@ MZ_ZIP64_ECDH_SIG_OFS
Definition: miniz.cpp:3108
@ MZ_ZIP_LDH_BIT_FLAG_OFS
Definition: miniz.cpp:3080
@ MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS
Definition: miniz.cpp:3094
@ MZ_ZIP_CDH_VERSION_NEEDED_OFS
Definition: miniz.cpp:3061
@ MZ_ZIP_DATA_DESCRIPTER_SIZE64
Definition: miniz.cpp:3055
@ MZ_ZIP_CDH_LOCAL_HEADER_OFS
Definition: miniz.cpp:3075
@ MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG
Definition: miniz.cpp:3049
@ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8
Definition: miniz.cpp:3124
@ MZ_ZIP64_ECDH_NUM_DISK_CDIR_OFS
Definition: miniz.cpp:3113
@ MZ_ZIP_CDH_COMPRESSED_SIZE_OFS
Definition: miniz.cpp:3067
@ MZ_ZIP_DATA_DESCRIPTER_SIZE32
Definition: miniz.cpp:3056
@ MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS
Definition: miniz.cpp:3095
@ MZ_ZIP_CDH_SIG_OFS
Definition: miniz.cpp:3059
@ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG
Definition: miniz.cpp:3121
@ MZ_ZIP64_ECDL_NUM_DISK_CDIR_OFS
Definition: miniz.cpp:3103
@ MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS
Definition: miniz.cpp:3068
@ MZ_ZIP_ECDH_CDIR_SIZE_OFS
Definition: miniz.cpp:3097
@ MZ_ZIP64_ECDL_SIG_OFS
Definition: miniz.cpp:3102
@ MZ_ZIP_CDH_METHOD_OFS
Definition: miniz.cpp:3063
@ MZ_ZIP_LDH_FILENAME_LEN_OFS
Definition: miniz.cpp:3087
@ MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE
Definition: miniz.cpp:3052
@ MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG
Definition: miniz.cpp:3119
@ MZ_ZIP_LDH_FILE_TIME_OFS
Definition: miniz.cpp:3082
@ MZ_ZIP64_ECDH_VERSION_NEEDED_OFS
Definition: miniz.cpp:3111
@ MZ_ZIP_CDH_EXTRA_LEN_OFS
Definition: miniz.cpp:3070
@ MZ_ZIP_LDH_FILE_DATE_OFS
Definition: miniz.cpp:3083
@ MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS
Definition: miniz.cpp:3104
@ MZ_ZIP_LDH_METHOD_OFS
Definition: miniz.cpp:3081
@ MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS
Definition: miniz.cpp:3114
@ MZ_ZIP_LDH_COMPRESSED_SIZE_OFS
Definition: miniz.cpp:3085
@ MZ_ZIP_CDH_FILE_TIME_OFS
Definition: miniz.cpp:3064
@ MZ_ZIP_VERSION_MADE_BY_DOS_FILESYSTEM_ID
Definition: miniz.cpp:3118
@ MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS
Definition: miniz.cpp:3096
@ MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID
Definition: miniz.cpp:3053
@ MZ_ZIP_CENTRAL_DIR_HEADER_SIG
Definition: miniz.cpp:3042
@ MZ_ZIP_ECDH_SIG_OFS
Definition: miniz.cpp:3092
@ MZ_ZIP_ECDH_COMMENT_SIZE_OFS
Definition: miniz.cpp:3099
@ MZ_ZIP64_ECDH_CDIR_SIZE_OFS
Definition: miniz.cpp:3116
@ MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS
Definition: miniz.cpp:3105
@ MZ_ZIP_LDH_SIG_OFS
Definition: miniz.cpp:3078
@ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION
Definition: miniz.cpp:3122
@ MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG
Definition: miniz.cpp:3041
@ MZ_ZIP_CDH_CRC32_OFS
Definition: miniz.cpp:3066
@ MZ_ZIP_CDH_DISK_START_OFS
Definition: miniz.cpp:3072
@ MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS
Definition: miniz.cpp:3115
@ MZ_ZIP_CDH_INTERNAL_ATTR_OFS
Definition: miniz.cpp:3073
@ MZ_ZIP_LDH_VERSION_NEEDED_OFS
Definition: miniz.cpp:3079
@ MZ_ZIP_ECDH_CDIR_OFS_OFS
Definition: miniz.cpp:3098
@ MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG
Definition: miniz.cpp:3050
@ MZ_ZIP_LDH_EXTRA_LEN_OFS
Definition: miniz.cpp:3088
@ MZ_ZIP_CDH_EXTERNAL_ATTR_OFS
Definition: miniz.cpp:3074
@ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_LOCAL_DIR_IS_MASKED
Definition: miniz.cpp:3123
@ MZ_ZIP64_ECDH_NUM_THIS_DISK_OFS
Definition: miniz.cpp:3112
@ MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE
Definition: miniz.cpp:3046
@ MZ_ZIP_LOCAL_DIR_HEADER_SIZE
Definition: miniz.cpp:3044
@ MZ_ZIP64_ECDH_CDIR_OFS_OFS
Definition: miniz.cpp:3117
@ MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS
Definition: miniz.cpp:3086
@ MZ_ZIP_CDH_BIT_FLAG_OFS
Definition: miniz.cpp:3062
@ MZ_ZIP_CDH_COMMENT_LEN_OFS
Definition: miniz.cpp:3071
@ MZ_ZIP_CENTRAL_DIR_HEADER_SIZE
Definition: miniz.cpp:3045
@ MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE
Definition: miniz.cpp:3051
@ MZ_ZIP_DATA_DESCRIPTOR_ID
Definition: miniz.cpp:3054
@ MZ_ZIP_CDH_VERSION_MADE_BY_OFS
Definition: miniz.cpp:3060
@ MZ_ZIP_ECDH_NUM_THIS_DISK_OFS
Definition: miniz.cpp:3093
@ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED
Definition: miniz.cpp:3120
@ MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS
Definition: miniz.cpp:3109
static mz_bool mz_zip_set_error(mz_zip_archive *pZip, mz_zip_error err_num)
Definition: miniz.cpp:3300
unsigned char mz_validate_uint64[sizeof(mz_uint64)==8 ? 1 :-1]
Definition: miniz.cpp:49
int mz_inflateEnd(mz_streamp pStream)
Definition: miniz.cpp:530
mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags)
Definition: miniz.cpp:5484
static const mz_uint mz_bitmasks[17]
Definition: miniz.cpp:1071
int mz_deflate(mz_streamp pStream, int flush)
Definition: miniz.cpp:251
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)
Definition: miniz.cpp:4421
#define MZ_FILE_STAT_STRUCT
Definition: miniz.cpp:3027
static mz_uint8 s_tdefl_packed_code_size_syms_swizzle[]
Definition: miniz.cpp:960
@ TDEFL_MAX_SUPPORTED_HUFF_CODESIZE
Definition: miniz.cpp:817
static void mz_zip_array_clear(mz_zip_archive *pZip, mz_zip_array *pArray)
Definition: miniz.cpp:3177
void * mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags)
Definition: miniz.cpp:4468
static mz_bool mz_zip_array_ensure_room(mz_zip_archive *pZip, mz_zip_array *pArray, size_t n)
Definition: miniz.cpp:3224
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)
Definition: miniz.cpp:4408
static mz_bool mz_zip_writer_write_zeros(mz_zip_archive *pZip, mz_uint64 cur_file_ofs, mz_uint32 n)
Definition: miniz.cpp:5654
const char * mz_error(int err)
Definition: miniz.cpp:572
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)
Definition: miniz.cpp:2834
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)
Definition: miniz.cpp:2328
#define MZ_SWAP_UINT32(a, b)
Definition: miniz.cpp:3360
static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int table_len, int code_size_limit, int static_table)
Definition: miniz.cpp:843
static const mz_uint8 s_tdefl_large_dist_sym[128]
Definition: miniz.cpp:706
#define TDEFL_PROBE
static mz_bool mz_zip_get_file_modified_time(const char *pFilename, time_t *pTime)
Definition: miniz.cpp:3274
#define MZ_FCLOSE
Definition: miniz.cpp:3022
mz_bool mz_zip_validate_mem_archive(const void *pMem, size_t size, mz_uint flags, mz_zip_error *pErr)
Definition: miniz.cpp:5025
mz_bool mz_zip_validate_file(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags)
Definition: miniz.cpp:4769
mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len)
Definition: miniz.cpp:321
mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy)
Definition: miniz.cpp:2036
static mz_bool tdefl_compress_block(tdefl_compressor *d, mz_bool static_block)
Definition: miniz.cpp:1216
static size_t mz_zip_compute_crc32_callback(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
Definition: miniz.cpp:4761
#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index)
Definition: miniz.cpp:3168
static mz_bool mz_zip_writer_update_zip64_extension_block(mz_zip_array *pNew_ext, mz_zip_archive *pZip, const mz_uint8 *pExt, uint32_t ext_len, mz_uint64 *pComp_size, mz_uint64 *pUncomp_size, mz_uint64 *pLocal_header_ofs, mz_uint32 *pDisk_start)
Definition: miniz.cpp:6284
static mz_bool mz_zip_set_file_times(const char *pFilename, time_t access_time, time_t modified_time)
Definition: miniz.cpp:3287
static mz_bool mz_zip_writer_create_local_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, mz_uint16 extra_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date)
Definition: miniz.cpp:5545
mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **ppBuf, size_t *pSize)
Definition: miniz.cpp:6812
static mz_bool mz_zip_array_resize(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_size, mz_uint growing)
Definition: miniz.cpp:3213
unsigned char mz_validate_uint16[sizeof(mz_uint16)==2 ? 1 :-1]
Definition: miniz.cpp:47
void * miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size)
Definition: miniz.cpp:190
#define MZ_WRITE_LE64(p, v)
Definition: miniz.cpp:5133
mz_bool mz_zip_writer_init_v2(mz_zip_archive *pZip, mz_uint64 existing_size, mz_uint flags)
Definition: miniz.cpp:5219
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)
Definition: miniz.cpp:1840
mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename)
Definition: miniz.cpp:5478
static mz_bool mz_zip_array_ensure_capacity(mz_zip_archive *pZip, mz_zip_array *pArray, size_t min_new_capacity, mz_uint growing)
Definition: miniz.cpp:3183
void * mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags)
Definition: miniz.cpp:6980
mz_zip_error mz_zip_clear_last_error(mz_zip_archive *pZip)
Definition: miniz.cpp:7022
#define TINFL_SKIP_BITS(state_index, n)
Definition: miniz.cpp:2235
FILE * mz_zip_get_cfile(mz_zip_archive *pZip)
Definition: miniz.cpp:7152
#define TDEFL_RLE_PREV_CODE_SIZE()
Definition: miniz.cpp:914
mz_bool mz_zip_writer_init_heap_v2(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size, mz_uint flags)
Definition: miniz.cpp:5273
mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags)
Definition: miniz.cpp:4695
#define MZ_FTELL64
Definition: miniz.cpp:3025
mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size)
Definition: miniz.cpp:7167
static tdefl_status tdefl_flush_output_buffer(tdefl_compressor *d)
Definition: miniz.cpp:1819
void tinfl_decompressor_free(tinfl_decompressor *pDecomp)
Definition: miniz.cpp:2880
mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, FILE *pSrc_file, mz_uint64 size_to_add, const time_t *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len)
Definition: miniz.cpp:5961
#define TDEFL_PUT_BITS(b, l)
Definition: miniz.cpp:896
void * tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
Definition: miniz.cpp:2004
#define MZ_DELETE_FILE
Definition: miniz.cpp:3031
unsigned long mz_ulong
Definition: miniz.h:250
@ MZ_UBER_COMPRESSION
Definition: miniz.h:324
@ MZ_DEFAULT_LEVEL
Definition: miniz.h:325
@ MZ_DEFAULT_COMPRESSION
Definition: miniz.h:326
#define MZ_MALLOC(x)
Definition: miniz.h:577
@ MZ_ZIP_FLAG_WRITE_ZIP64
Definition: miniz.h:1049
@ MZ_ZIP_FLAG_WRITE_ALLOW_READING
Definition: miniz.h:1050
@ MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY
Definition: miniz.h:1048
@ MZ_ZIP_FLAG_UTF8_FILENAME
Definition: miniz.h:1051
@ MZ_ZIP_FLAG_VALIDATE_LOCATE_FILE_FLAG
Definition: miniz.h:1047
@ MZ_ZIP_FLAG_COMPRESSED_DATA
Definition: miniz.h:1045
@ MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY
Definition: miniz.h:1046
@ MZ_ZIP_FLAG_CASE_SENSITIVE
Definition: miniz.h:1043
@ MZ_ZIP_FLAG_IGNORE_PATH
Definition: miniz.h:1044
#define MZ_READ_LE16(p)
Definition: miniz.h:590
#define MZ_REALLOC(p, x)
Definition: miniz.h:579
@ TDEFL_MAX_PROBES_MASK
Definition: miniz.h:635
int16_t mz_int16
Definition: miniz.h:535
size_t(* mz_file_write_func)(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
Definition: miniz.h:1028
#define MZ_FALSE
Definition: miniz.h:543
#define MZ_FORCEINLINE
Definition: miniz.h:601
#define MZ_ASSERT(x)
Definition: miniz.h:570
#define tinfl_init(r)
Definition: miniz.h:900
@ MZ_FILTERED
Definition: miniz.h:267
@ MZ_FIXED
Definition: miniz.h:270
@ MZ_DEFAULT_STRATEGY
Definition: miniz.h:266
@ MZ_RLE
Definition: miniz.h:269
@ MZ_HUFFMAN_ONLY
Definition: miniz.h:268
tinfl_status
Definition: miniz.h:866
@ TINFL_STATUS_ADLER32_MISMATCH
Definition: miniz.h:876
@ TINFL_STATUS_FAILED
Definition: miniz.h:879
@ TINFL_STATUS_NEEDS_MORE_INPUT
Definition: miniz.h:890
@ TINFL_STATUS_HAS_MORE_OUTPUT
Definition: miniz.h:896
@ TINFL_STATUS_BAD_PARAM
Definition: miniz.h:873
@ TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS
Definition: miniz.h:870
@ TINFL_STATUS_DONE
Definition: miniz.h:885
#define TINFL_LZ_DICT_SIZE
Definition: miniz.h:862
#define MZ_CLEAR_OBJ(obj)
Definition: miniz.h:584
#define MZ_DEFLATED
Definition: miniz.h:274
unsigned int mz_uint
Definition: miniz.h:538
int64_t mz_int64
Definition: miniz.h:539
#define MZ_ADLER32_INIT
Definition: miniz.h:255
#define MZ_CRC32_INIT
Definition: miniz.h:259
int(* tinfl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser)
Definition: miniz.h:848
uint8_t mz_uint8
Definition: miniz.h:534
#define MZ_UINT16_MAX
Definition: miniz.h:612
#define tinfl_get_adler32(r)
Definition: miniz.h:906
#define MZ_DEFAULT_WINDOW_BITS
Definition: miniz.h:330
bool mz_bool
Definition: miniz.h:541
#define MZ_VERSION
Definition: miniz.h:285
@ TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF
Definition: miniz.h:827
@ TINFL_FLAG_HAS_MORE_INPUT
Definition: miniz.h:826
@ TINFL_FLAG_COMPUTE_ADLER32
Definition: miniz.h:828
@ TINFL_FLAG_PARSE_ZLIB_HEADER
Definition: miniz.h:825
#define MZ_FILE
Definition: miniz.h:557
@ TDEFL_MAX_HUFF_SYMBOLS
Definition: miniz.h:722
@ TDEFL_LEVEL1_HASH_SIZE_MASK
Definition: miniz.h:724
@ TDEFL_LZ_HASH_BITS
Definition: miniz.h:723
@ TDEFL_LZ_HASH_SIZE
Definition: miniz.h:726
@ TDEFL_LZ_CODE_BUF_SIZE
Definition: miniz.h:720
@ TDEFL_LZ_HASH_SHIFT
Definition: miniz.h:725
@ TDEFL_OUT_BUF_SIZE
Definition: miniz.h:721
#define MZ_TIME_T
Definition: miniz.h:567
tdefl_flush
Definition: miniz.h:741
@ TDEFL_NO_FLUSH
Definition: miniz.h:742
@ TDEFL_FULL_FLUSH
Definition: miniz.h:744
@ TDEFL_FINISH
Definition: miniz.h:745
mz_zip_type
Definition: miniz.h:1055
@ MZ_ZIP_TYPE_USER
Definition: miniz.h:1057
@ MZ_ZIP_TYPE_FILE
Definition: miniz.h:1060
@ MZ_ZIP_TYPE_HEAP
Definition: miniz.h:1059
@ MZ_ZIP_TYPE_MEMORY
Definition: miniz.h:1058
@ MZ_ZIP_TYPE_CFILE
Definition: miniz.h:1061
@ MZ_ZIP_TYPE_INVALID
Definition: miniz.h:1056
#define crc32
Definition: miniz.h:507
@ TDEFL_MAX_MATCH_LEN
Definition: miniz.h:702
@ TDEFL_MAX_HUFF_SYMBOLS_0
Definition: miniz.h:696
@ TDEFL_LZ_DICT_SIZE_MASK
Definition: miniz.h:700
@ TDEFL_LZ_DICT_SIZE
Definition: miniz.h:699
@ TDEFL_MIN_MATCH_LEN
Definition: miniz.h:701
@ TDEFL_MAX_HUFF_SYMBOLS_1
Definition: miniz.h:697
@ TDEFL_MAX_HUFF_SYMBOLS_2
Definition: miniz.h:698
@ TDEFL_FORCE_ALL_RAW_BLOCKS
Definition: miniz.h:656
@ TDEFL_GREEDY_PARSING_FLAG
Definition: miniz.h:651
@ TDEFL_FORCE_ALL_STATIC_BLOCKS
Definition: miniz.h:655
@ TDEFL_COMPUTE_ADLER32
Definition: miniz.h:650
@ TDEFL_FILTER_MATCHES
Definition: miniz.h:654
@ TDEFL_WRITE_ZLIB_HEADER
Definition: miniz.h:649
@ TDEFL_NONDETERMINISTIC_PARSING_FLAG
Definition: miniz.h:652
@ TDEFL_RLE_MATCHES
Definition: miniz.h:653
#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED
Definition: miniz.h:843
@ MZ_SYNC_FLUSH
Definition: miniz.h:297
@ MZ_FINISH
Definition: miniz.h:299
@ MZ_PARTIAL_FLUSH
Definition: miniz.h:296
#define MZ_MIN(a, b)
Definition: miniz.h:583
tdefl_status
Definition: miniz.h:732
@ TDEFL_STATUS_OKAY
Definition: miniz.h:735
@ TDEFL_STATUS_DONE
Definition: miniz.h:736
@ TDEFL_STATUS_BAD_PARAM
Definition: miniz.h:733
@ TDEFL_STATUS_PUT_BUF_FAILED
Definition: miniz.h:734
@ MZ_MEM_ERROR
Definition: miniz.h:312
@ MZ_PARAM_ERROR
Definition: miniz.h:315
@ MZ_NEED_DICT
Definition: miniz.h:308
@ MZ_VERSION_ERROR
Definition: miniz.h:314
@ MZ_STREAM_END
Definition: miniz.h:307
@ MZ_ERRNO
Definition: miniz.h:309
@ MZ_OK
Definition: miniz.h:306
@ MZ_BUF_ERROR
Definition: miniz.h:313
@ MZ_STREAM_ERROR
Definition: miniz.h:310
@ MZ_DATA_ERROR
Definition: miniz.h:311
uint32_t mz_uint32
Definition: miniz.h:537
#define MZ_FREE(x)
Definition: miniz.h:578
uint64_t mz_uint64
Definition: miniz.h:540
#define MZ_READ_LE32(p)
Definition: miniz.h:591
uint16_t mz_uint16
Definition: miniz.h:536
mz_zip_mode
Definition: miniz.h:1034
@ MZ_ZIP_MODE_WRITING
Definition: miniz.h:1037
@ MZ_ZIP_MODE_READING
Definition: miniz.h:1036
@ MZ_ZIP_MODE_INVALID
Definition: miniz.h:1035
@ MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED
Definition: miniz.h:1038
mz_bool(* tdefl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser)
Definition: miniz.h:688
@ MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE
Definition: miniz.h:968
@ MZ_ZIP_MAX_IO_BUF_SIZE
Definition: miniz.h:966
@ MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE
Definition: miniz.h:967
mz_zip_error
Definition: miniz.h:1067
@ MZ_ZIP_UNSUPPORTED_METHOD
Definition: miniz.h:1072
@ MZ_ZIP_UNSUPPORTED_FEATURE
Definition: miniz.h:1074
@ MZ_ZIP_FILE_OPEN_FAILED
Definition: miniz.h:1085
@ MZ_ZIP_FILE_TOO_LARGE
Definition: miniz.h:1071
@ MZ_ZIP_WRITE_CALLBACK_FAILED
Definition: miniz.h:1099
@ MZ_ZIP_CRC_CHECK_FAILED
Definition: miniz.h:1082
@ MZ_ZIP_INTERNAL_ERROR
Definition: miniz.h:1095
@ MZ_ZIP_FILE_CLOSE_FAILED
Definition: miniz.h:1089
@ MZ_ZIP_FILE_CREATE_FAILED
Definition: miniz.h:1086
@ MZ_ZIP_BUF_TOO_SMALL
Definition: miniz.h:1094
@ MZ_ZIP_VALIDATION_FAILED
Definition: miniz.h:1098
@ MZ_ZIP_FILE_STAT_FAILED
Definition: miniz.h:1091
@ MZ_ZIP_INVALID_FILENAME
Definition: miniz.h:1093
@ MZ_ZIP_COMPRESSION_FAILED
Definition: miniz.h:1080
@ MZ_ZIP_NO_ERROR
Definition: miniz.h:1068
@ MZ_ZIP_UNSUPPORTED_ENCRYPTION
Definition: miniz.h:1073
@ MZ_ZIP_TOO_MANY_FILES
Definition: miniz.h:1070
@ MZ_ZIP_UNDEFINED_ERROR
Definition: miniz.h:1069
@ MZ_ZIP_UNSUPPORTED_MULTIDISK
Definition: miniz.h:1078
@ MZ_ZIP_ALLOC_FAILED
Definition: miniz.h:1084
@ MZ_ZIP_ARCHIVE_TOO_LARGE
Definition: miniz.h:1097
@ MZ_ZIP_DECOMPRESSION_FAILED
Definition: miniz.h:1079
@ MZ_ZIP_FILE_WRITE_FAILED
Definition: miniz.h:1087
@ MZ_ZIP_INVALID_PARAMETER
Definition: miniz.h:1092
@ MZ_ZIP_INVALID_HEADER_OR_CORRUPTED
Definition: miniz.h:1077
@ MZ_ZIP_UNSUPPORTED_CDIR_SIZE
Definition: miniz.h:1083
@ MZ_ZIP_FILE_READ_FAILED
Definition: miniz.h:1088
@ MZ_ZIP_FILE_NOT_FOUND
Definition: miniz.h:1096
@ MZ_ZIP_FAILED_FINDING_CENTRAL_DIR
Definition: miniz.h:1075
@ MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE
Definition: miniz.h:1081
@ MZ_ZIP_NOT_AN_ARCHIVE
Definition: miniz.h:1076
@ MZ_ZIP_TOTAL_ERRORS
Definition: miniz.h:1100
@ MZ_ZIP_FILE_SEEK_FAILED
Definition: miniz.h:1090
#define MZ_READ_LE64(p)
Definition: miniz.h:594
#define MZ_MAX(a, b)
Definition: miniz.h:582
#define MZ_TRUE
Definition: miniz.h:544
mz_uint32 tinfl_bit_buf_t
Definition: miniz.h:937
@ TINFL_FAST_LOOKUP_SIZE
Definition: miniz.h:920
@ TINFL_FAST_LOOKUP_BITS
Definition: miniz.h:919
#define MZ_UINT32_MAX
Definition: miniz.h:613
void * memcpy(void *dst, const void *src, size_t n)
Definition: string.c:613
int memcmp(const void *s1, const void *s2, size_t n)
Definition: string.c:923
size_t strlen(const char *s)
Definition: string.c:561
void * memset(void *s, int c, size_t n)
Definition: string.c:713
int m_window_bits
Definition: miniz.cpp:372
mz_uint m_dict_ofs
Definition: miniz.cpp:371
mz_uint m_has_flushed
Definition: miniz.cpp:371
mz_uint8 m_dict[32768]
Definition: miniz.cpp:373
mz_uint m_dict_avail
Definition: miniz.cpp:371
mz_uint m_first_call
Definition: miniz.cpp:371
tinfl_status m_last_status
Definition: miniz.cpp:374
tinfl_decompressor m_decomp
Definition: miniz.cpp:370
mz_ulong adler
Definition: miniz.h:353
unsigned char * next_out
Definition: miniz.h:341
void * opaque
Definition: miniz.h:350
int data_type
Definition: miniz.h:352
mz_free_func zfree
Definition: miniz.h:349
mz_ulong total_out
Definition: miniz.h:343
unsigned int avail_out
Definition: miniz.h:342
struct mz_internal_state * state
Definition: miniz.h:346
const unsigned char * next_in
Definition: miniz.h:337
unsigned int avail_in
Definition: miniz.h:338
mz_alloc_func zalloc
Definition: miniz.h:348
mz_ulong total_in
Definition: miniz.h:339
char * msg
Definition: miniz.h:345
mz_ulong reserved
Definition: miniz.h:354
mz_uint32 m_external_attr
Definition: miniz.h:1000
mz_uint16 m_version_needed
Definition: miniz.h:981
mz_uint16 m_version_made_by
Definition: miniz.h:980
mz_uint64 m_central_dir_ofs
Definition: miniz.h:977
mz_uint32 m_file_index
Definition: miniz.h:974
mz_uint64 m_uncomp_size
Definition: miniz.h:996
mz_uint32 m_comment_size
Definition: miniz.h:1006
mz_uint16 m_bit_flag
Definition: miniz.h:982
mz_uint64 m_local_header_ofs
Definition: miniz.h:1003
mz_uint16 m_internal_attr
Definition: miniz.h:999
mz_uint16 m_method
Definition: miniz.h:983
mz_uint64 m_comp_size
Definition: miniz.h:993
char m_filename[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE]
Definition: miniz.h:1019
char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE]
Definition: miniz.h:1023
mz_uint64 m_central_directory_file_ofs
Definition: miniz.h:1106
mz_zip_error m_last_error
Definition: miniz.h:1112
mz_alloc_func m_pAlloc
Definition: miniz.h:1116
mz_zip_mode m_zip_mode
Definition: miniz.h:1110
mz_uint64 m_archive_size
Definition: miniz.h:1105
void * m_pIO_opaque
Definition: miniz.h:1123
void * m_pAlloc_opaque
Definition: miniz.h:1119
mz_file_write_func m_pWrite
Definition: miniz.h:1122
mz_zip_internal_state * m_pState
Definition: miniz.h:1125
mz_free_func m_pFree
Definition: miniz.h:1117
mz_realloc_func m_pRealloc
Definition: miniz.h:1118
mz_file_read_func m_pRead
Definition: miniz.h:1121
mz_uint64 m_file_offset_alignment
Definition: miniz.h:1114
mz_zip_type m_zip_type
Definition: miniz.h:1111
mz_uint32 m_total_files
Definition: miniz.h:1109
size_t m_size
Definition: miniz.cpp:3130
void * m_p
Definition: miniz.cpp:3129
size_t m_capacity
Definition: miniz.cpp:3130
mz_uint m_element_size
Definition: miniz.cpp:3131
mz_bool m_zip64_has_extended_info_fields
Definition: miniz.cpp:3147
mz_zip_array m_sorted_central_dir_offsets
Definition: miniz.cpp:3138
mz_uint64 m_file_archive_start_ofs
Definition: miniz.cpp:3151
mz_zip_array m_central_dir_offsets
Definition: miniz.cpp:3137
mz_zip_array m_central_dir
Definition: miniz.cpp:3136
mz_uint64 m_cur_archive_file_ofs
Definition: miniz.cpp:5492
mz_zip_archive * m_pZip
Definition: miniz.cpp:5491
mz_uint m_max_probes[2]
Definition: miniz.h:753
mz_uint m_block_index
Definition: miniz.h:758
mz_uint m_saved_lit
Definition: miniz.h:758
mz_uint m_saved_match_dist
Definition: miniz.h:758
size_t * m_pOut_buf_size
Definition: miniz.h:762
mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE]
Definition: miniz.h:772
const mz_uint8 * m_pSrc
Definition: miniz.h:764
mz_uint16 m_huff_codes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]
Definition: miniz.h:768
mz_uint m_output_flush_remaining
Definition: miniz.h:758
mz_uint m_num_flags_left
Definition: miniz.h:757
mz_uint m_lookahead_pos
Definition: miniz.h:755
mz_uint m_wants_to_finish
Definition: miniz.h:758
mz_uint m_finished
Definition: miniz.h:758
mz_uint m_total_lz_bytes
Definition: miniz.h:757
size_t m_src_buf_left
Definition: miniz.h:765
tdefl_status m_prev_return_status
Definition: miniz.h:759
mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE+TDEFL_MAX_MATCH_LEN - 1]
Definition: miniz.h:766
tdefl_put_buf_func_ptr m_pPut_buf_func
Definition: miniz.h:751
tdefl_flush m_flush
Definition: miniz.h:763
mz_uint m_output_flush_ofs
Definition: miniz.h:758
size_t m_out_buf_ofs
Definition: miniz.h:765
mz_uint m_bit_buffer
Definition: miniz.h:757
mz_uint m_bits_in
Definition: miniz.h:757
mz_uint16 m_next[TDEFL_LZ_DICT_SIZE]
Definition: miniz.h:771
mz_uint8 * m_pOutput_buf_end
Definition: miniz.h:756
mz_uint m_lookahead_size
Definition: miniz.h:755
mz_uint8 * m_pLZ_flags
Definition: miniz.h:756
mz_uint m_saved_match_len
Definition: miniz.h:758
mz_uint16 m_huff_count[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]
Definition: miniz.h:767
void * m_pOut_buf
Definition: miniz.h:761
mz_uint m_lz_code_buf_dict_pos
Definition: miniz.h:757
const void * m_pIn_buf
Definition: miniz.h:760
mz_uint m_flags
Definition: miniz.h:753
mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE]
Definition: miniz.h:770
int m_greedy_parsing
Definition: miniz.h:754
void * m_pPut_buf_user
Definition: miniz.h:752
mz_uint8 * m_pLZ_code_buf
Definition: miniz.h:756
mz_uint m_dict_size
Definition: miniz.h:755
mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]
Definition: miniz.h:769
size_t * m_pIn_buf_size
Definition: miniz.h:762
mz_uint m_adler32
Definition: miniz.h:755
mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE]
Definition: miniz.h:773
mz_uint8 * m_pOutput_buf
Definition: miniz.h:756
mz_bool m_expandable
Definition: miniz.cpp:1976
mz_uint8 * m_pBuf
Definition: miniz.cpp:1975
mz_uint16 m_sym_index
Definition: miniz.cpp:723
mz_uint16 m_key
Definition: miniz.cpp:723
mz_int16 m_tree[TINFL_MAX_HUFF_SYMBOLS_0 *2]
Definition: miniz.h:926
mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0]
Definition: miniz.h:925
mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE]
Definition: miniz.h:926
struct tm * localtime(const time_t *clock)
Definition: time.c:127
time_t time(time_t *tloc)
Definition: time.c:13
time_t mktime(struct tm *timeptr)
Definition: time.c:170