CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
miniz.cpp
Go to the documentation of this file.
1#include "miniz.h"
2/**************************************************************************
3 *
4 * Copyright 2013-2014 RAD Game Tools and Valve Software
5 * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 *
26 **************************************************************************/
27
28
29
30typedef unsigned char mz_validate_uint16[sizeof(mz_uint16) == 2 ? 1 : -1];
31typedef unsigned char mz_validate_uint32[sizeof(mz_uint32) == 4 ? 1 : -1];
32typedef unsigned char mz_validate_uint64[sizeof(mz_uint64) == 8 ? 1 : -1];
33
34#ifdef __cplusplus
35extern "C"
36{
37#endif
38
39 /* ------------------- zlib-style API's */
40
41 mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len)
42 {
43 mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16);
44 size_t block_len = buf_len % 5552;
45 if (!ptr)
46 return MZ_ADLER32_INIT;
47 while (buf_len)
48 {
49 for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
50 {
51 s1 += ptr[0], s2 += s1;
52 s1 += ptr[1], s2 += s1;
53 s1 += ptr[2], s2 += s1;
54 s1 += ptr[3], s2 += s1;
55 s1 += ptr[4], s2 += s1;
56 s1 += ptr[5], s2 += s1;
57 s1 += ptr[6], s2 += s1;
58 s1 += ptr[7], s2 += s1;
59 }
60 for (; i < block_len; ++i)
61 s1 += *ptr++, s2 += s1;
62 s1 %= 65521U, s2 %= 65521U;
64 block_len = 5552;
65 }
66 return (s2 << 16) + s1;
67 }
68
69/* 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/ */
70#if 0
71 mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
72 {
73 static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
74 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c };
76 if (!ptr)
77 return MZ_CRC32_INIT;
79 while (buf_len--)
80 {
81 mz_uint8 b = *ptr++;
82 crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)];
83 crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)];
84 }
85 return ~crcu32;
86 }
87#elif defined(USE_EXTERNAL_MZCRC)
88/* If USE_EXTERNAL_CRC is defined, an external module will export the
89 * mz_crc32() symbol for us to use, e.g. an SSE-accelerated version.
90 * Depending on the impl, it may be necessary to ~ the input/output crc values.
91 */
92mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len);
93#else
94/* Faster, but larger CPU cache footprint.
95 */
97{
98 static const mz_uint32 s_crc_table[256] = {
99 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535,
100 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
101 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D,
102 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
103 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4,
104 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
105 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC,
106 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
107 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB,
108 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
109 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB,
110 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
111 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA,
112 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE,
113 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A,
114 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
115 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409,
116 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
117 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739,
118 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
119 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268,
120 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0,
121 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8,
122 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
123 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF,
124 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
125 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7,
126 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
127 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE,
128 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
129 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6,
130 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
131 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D,
132 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
133 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605,
134 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
135 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
136 };
137
138 mz_uint32 crc32 = (mz_uint32)crc ^ 0xFFFFFFFF;
139 const mz_uint8 *pByte_buf = (const mz_uint8 *)ptr;
140
141 while (buf_len >= 4)
142 {
143 crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF];
144 crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[1]) & 0xFF];
145 crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[2]) & 0xFF];
146 crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[3]) & 0xFF];
147 pByte_buf += 4;
148 buf_len -= 4;
149 }
150
151 while (buf_len)
152 {
153 crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF];
154 ++pByte_buf;
155 --buf_len;
156 }
157
158 return ~crc32;
159}
160#endif
161
162 void mz_free(void *p)
163 {
164 MZ_FREE(p);
165 }
166
167 MINIZ_EXPORT void *miniz_def_alloc_func(void *opaque, size_t items, size_t size)
168 {
169 (void)opaque, (void)items, (void)size;
170 return MZ_MALLOC(items * size);
171 }
172 MINIZ_EXPORT void miniz_def_free_func(void *opaque, void *address)
173 {
174 (void)opaque, (void)address;
175 MZ_FREE(address);
176 }
177 MINIZ_EXPORT void *miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size)
178 {
179 (void)opaque, (void)address, (void)items, (void)size;
180 return MZ_REALLOC(address, items * size);
181 }
182
183 const char *mz_version(void)
184 {
185 return MZ_VERSION;
186 }
187
188#ifndef MINIZ_NO_ZLIB_APIS
189
190#ifndef MINIZ_NO_DEFLATE_APIS
191
192 int mz_deflateInit(mz_streamp pStream, int level)
193 {
195 }
196
197 int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy)
198 {
201
202 if (!pStream)
203 return MZ_STREAM_ERROR;
204 if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) || ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)))
205 return MZ_PARAM_ERROR;
206
207 pStream->data_type = 0;
208 pStream->adler = MZ_ADLER32_INIT;
209 pStream->msg = NULL;
210 pStream->reserved = 0;
211 pStream->total_in = 0;
212 pStream->total_out = 0;
213 if (!pStream->zalloc)
215 if (!pStream->zfree)
217
218 pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, sizeof(tdefl_compressor));
219 if (!pComp)
220 return MZ_MEM_ERROR;
221
222 pStream->state = (struct mz_internal_state *)pComp;
223
225 {
227 return MZ_PARAM_ERROR;
228 }
229
230 return MZ_OK;
231 }
232
234 {
235 if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree))
236 return MZ_STREAM_ERROR;
237 pStream->total_in = pStream->total_out = 0;
238 tdefl_init((tdefl_compressor *)pStream->state, NULL, NULL, ((tdefl_compressor *)pStream->state)->m_flags);
239 return MZ_OK;
240 }
241
242 int mz_deflate(mz_streamp pStream, int flush)
243 {
244 size_t in_bytes, out_bytes;
246 int mz_status = MZ_OK;
247
248 if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || (!pStream->next_out))
249 return MZ_STREAM_ERROR;
250 if (!pStream->avail_out)
251 return MZ_BUF_ERROR;
252
253 if (flush == MZ_PARTIAL_FLUSH)
254 flush = MZ_SYNC_FLUSH;
255
256 if (((tdefl_compressor *)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE)
257 return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR;
258
259 orig_total_in = pStream->total_in;
260 orig_total_out = pStream->total_out;
261 for (;;)
262 {
264 in_bytes = pStream->avail_in;
265 out_bytes = pStream->avail_out;
266
267 defl_status = tdefl_compress((tdefl_compressor *)pStream->state, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, (tdefl_flush)flush);
268 pStream->next_in += (mz_uint)in_bytes;
269 pStream->avail_in -= (mz_uint)in_bytes;
270 pStream->total_in += (mz_uint)in_bytes;
272
273 pStream->next_out += (mz_uint)out_bytes;
274 pStream->avail_out -= (mz_uint)out_bytes;
275 pStream->total_out += (mz_uint)out_bytes;
276
277 if (defl_status < 0)
278 {
280 break;
281 }
282 else if (defl_status == TDEFL_STATUS_DONE)
283 {
285 break;
286 }
287 else if (!pStream->avail_out)
288 break;
289 else if ((!pStream->avail_in) && (flush != MZ_FINISH))
290 {
291 if ((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out))
292 break;
293 return MZ_BUF_ERROR; /* Can't make forward progress without some input.
294 */
295 }
296 }
297 return mz_status;
298 }
299
301 {
302 if (!pStream)
303 return MZ_STREAM_ERROR;
304 if (pStream->state)
305 {
306 pStream->zfree(pStream->opaque, pStream->state);
307 pStream->state = NULL;
308 }
309 return MZ_OK;
310 }
311
313 {
314 (void)pStream;
315 /* 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.) */
316 return MZ_MAX(128 + (source_len * 110) / 100, 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5);
317 }
318
319 int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level)
320 {
321 int status;
323 memset(&stream, 0, sizeof(stream));
324
325 /* In case mz_ulong is 64-bits (argh I hate longs). */
326 if ((mz_uint64)(source_len | *pDest_len) > 0xFFFFFFFFU)
327 return MZ_PARAM_ERROR;
328
329 stream.next_in = pSource;
330 stream.avail_in = (mz_uint32)source_len;
331 stream.next_out = pDest;
332 stream.avail_out = (mz_uint32)*pDest_len;
333
334 status = mz_deflateInit(&stream, level);
335 if (status != MZ_OK)
336 return status;
337
338 status = mz_deflate(&stream, MZ_FINISH);
339 if (status != MZ_STREAM_END)
340 {
342 return (status == MZ_OK) ? MZ_BUF_ERROR : status;
343 }
344
345 *pDest_len = stream.total_out;
346 return mz_deflateEnd(&stream);
347 }
348
349 int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
350 {
352 }
353
355 {
357 }
358
359#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/
360
361#ifndef MINIZ_NO_INFLATE_APIS
362
363 typedef struct
364 {
367 int m_window_bits;
371
373 {
375 if (!pStream)
376 return MZ_STREAM_ERROR;
378 return MZ_PARAM_ERROR;
379
380 pStream->data_type = 0;
381 pStream->adler = 0;
382 pStream->msg = NULL;
383 pStream->total_in = 0;
384 pStream->total_out = 0;
385 pStream->reserved = 0;
386 if (!pStream->zalloc)
388 if (!pStream->zfree)
390
391 pDecomp = (inflate_state *)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state));
392 if (!pDecomp)
393 return MZ_MEM_ERROR;
394
395 pStream->state = (struct mz_internal_state *)pDecomp;
396
397 tinfl_init(&pDecomp->m_decomp);
398 pDecomp->m_dict_ofs = 0;
399 pDecomp->m_dict_avail = 0;
400 pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
401 pDecomp->m_first_call = 1;
402 pDecomp->m_has_flushed = 0;
403 pDecomp->m_window_bits = window_bits;
404
405 return MZ_OK;
406 }
407
409 {
411 }
412
414 {
416 if (!pStream)
417 return MZ_STREAM_ERROR;
418
419 pStream->data_type = 0;
420 pStream->adler = 0;
421 pStream->msg = NULL;
422 pStream->total_in = 0;
423 pStream->total_out = 0;
424 pStream->reserved = 0;
425
426 pDecomp = (inflate_state *)pStream->state;
427
428 tinfl_init(&pDecomp->m_decomp);
429 pDecomp->m_dict_ofs = 0;
430 pDecomp->m_dict_avail = 0;
431 pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
432 pDecomp->m_first_call = 1;
433 pDecomp->m_has_flushed = 0;
434 /* pDecomp->m_window_bits = window_bits */;
435
436 return MZ_OK;
437 }
438
439 int mz_inflate(mz_streamp pStream, int flush)
440 {
444 tinfl_status status;
445
446 if ((!pStream) || (!pStream->state))
447 return MZ_STREAM_ERROR;
448 if (flush == MZ_PARTIAL_FLUSH)
449 flush = MZ_SYNC_FLUSH;
450 if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH))
451 return MZ_STREAM_ERROR;
452
453 pState = (inflate_state *)pStream->state;
454 if (pState->m_window_bits > 0)
456 orig_avail_in = pStream->avail_in;
457
458 first_call = pState->m_first_call;
459 pState->m_first_call = 0;
460 if (pState->m_last_status < 0)
461 return MZ_DATA_ERROR;
462
463 if (pState->m_has_flushed && (flush != MZ_FINISH))
464 return MZ_STREAM_ERROR;
465 pState->m_has_flushed |= (flush == MZ_FINISH);
466
467 if ((flush == MZ_FINISH) && (first_call))
468 {
469 /* MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file. */
471 in_bytes = pStream->avail_in;
472 out_bytes = pStream->avail_out;
473 status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags);
474 pState->m_last_status = status;
475 pStream->next_in += (mz_uint)in_bytes;
476 pStream->avail_in -= (mz_uint)in_bytes;
477 pStream->total_in += (mz_uint)in_bytes;
478 pStream->adler = tinfl_get_adler32(&pState->m_decomp);
479 pStream->next_out += (mz_uint)out_bytes;
480 pStream->avail_out -= (mz_uint)out_bytes;
481 pStream->total_out += (mz_uint)out_bytes;
482
483 if (status < 0)
484 return MZ_DATA_ERROR;
485 else if (status != TINFL_STATUS_DONE)
486 {
487 pState->m_last_status = TINFL_STATUS_FAILED;
488 return MZ_BUF_ERROR;
489 }
490 return MZ_STREAM_END;
491 }
492 /* flush != MZ_FINISH then we must assume there's more input. */
493 if (flush != MZ_FINISH)
495
496 if (pState->m_dict_avail)
497 {
498 n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
499 memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
500 pStream->next_out += n;
501 pStream->avail_out -= n;
502 pStream->total_out += n;
503 pState->m_dict_avail -= n;
504 pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
505 return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
506 }
507
508 for (;;)
509 {
510 in_bytes = pStream->avail_in;
511 out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs;
512
513 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);
514 pState->m_last_status = status;
515
516 pStream->next_in += (mz_uint)in_bytes;
517 pStream->avail_in -= (mz_uint)in_bytes;
518 pStream->total_in += (mz_uint)in_bytes;
519 pStream->adler = tinfl_get_adler32(&pState->m_decomp);
520
521 pState->m_dict_avail = (mz_uint)out_bytes;
522
523 n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
524 memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
525 pStream->next_out += n;
526 pStream->avail_out -= n;
527 pStream->total_out += n;
528 pState->m_dict_avail -= n;
529 pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
530
531 if (status < 0)
532 return MZ_DATA_ERROR; /* Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well). */
533 else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in))
534 return MZ_BUF_ERROR; /* Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH. */
535 else if (flush == MZ_FINISH)
536 {
537 /* The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH. */
538 if (status == TINFL_STATUS_DONE)
539 return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END;
540 /* 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. */
541 else if (!pStream->avail_out)
542 return MZ_BUF_ERROR;
543 }
544 else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail))
545 break;
546 }
547
548 return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
549 }
550
552 {
553 if (!pStream)
554 return MZ_STREAM_ERROR;
555 if (pStream->state)
556 {
557 pStream->zfree(pStream->opaque, pStream->state);
558 pStream->state = NULL;
559 }
560 return MZ_OK;
561 }
562 int mz_uncompress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong *pSource_len)
563 {
565 int status;
566 memset(&stream, 0, sizeof(stream));
567
568 /* In case mz_ulong is 64-bits (argh I hate longs). */
569 if ((mz_uint64)(*pSource_len | *pDest_len) > 0xFFFFFFFFU)
570 return MZ_PARAM_ERROR;
571
572 stream.next_in = pSource;
573 stream.avail_in = (mz_uint32)*pSource_len;
574 stream.next_out = pDest;
575 stream.avail_out = (mz_uint32)*pDest_len;
576
577 status = mz_inflateInit(&stream);
578 if (status != MZ_OK)
579 return status;
580
581 status = mz_inflate(&stream, MZ_FINISH);
582 *pSource_len = *pSource_len - stream.avail_in;
583 if (status != MZ_STREAM_END)
584 {
586 return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status;
587 }
588 *pDest_len = stream.total_out;
589
590 return mz_inflateEnd(&stream);
591 }
592
593 int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
594 {
596 }
597
598#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/
599
600 const char *mz_error(int err)
601 {
602 static struct
603 {
604 int m_err;
605 const char *m_pDesc;
606 } s_error_descs[] = {
607 { MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" }, { MZ_DATA_ERROR, "data error" }, { MZ_MEM_ERROR, "out of memory" }, { MZ_BUF_ERROR, "buf error" }, { MZ_VERSION_ERROR, "version error" }, { MZ_PARAM_ERROR, "parameter error" }
608 };
609 mz_uint i;
610 for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i)
611 if (s_error_descs[i].m_err == err)
612 return s_error_descs[i].m_pDesc;
613 return NULL;
614 }
615
616#endif /*MINIZ_NO_ZLIB_APIS */
617
618#ifdef __cplusplus
619}
620#endif
621
622/*
623 This is free and unencumbered software released into the public domain.
624
625 Anyone is free to copy, modify, publish, use, compile, sell, or
626 distribute this software, either in source code form or as a compiled
627 binary, for any purpose, commercial or non-commercial, and by any
628 means.
629
630 In jurisdictions that recognize copyright laws, the author or authors
631 of this software dedicate any and all copyright interest in the
632 software to the public domain. We make this dedication for the benefit
633 of the public at large and to the detriment of our heirs and
634 successors. We intend this dedication to be an overt act of
635 relinquishment in perpetuity of all present and future rights to this
636 software under copyright law.
637
638 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
639 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
640 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
641 IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
642 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
643 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
644 OTHER DEALINGS IN THE SOFTWARE.
645
646 For more information, please refer to <http://unlicense.org/>
647*/
648/**************************************************************************
649 *
650 * Copyright 2013-2014 RAD Game Tools and Valve Software
651 * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
652 * All Rights Reserved.
653 *
654 * Permission is hereby granted, free of charge, to any person obtaining a copy
655 * of this software and associated documentation files (the "Software"), to deal
656 * in the Software without restriction, including without limitation the rights
657 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
658 * copies of the Software, and to permit persons to whom the Software is
659 * furnished to do so, subject to the following conditions:
660 *
661 * The above copyright notice and this permission notice shall be included in
662 * all copies or substantial portions of the Software.
663 *
664 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
665 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
666 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
667 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
668 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
669 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
670 * THE SOFTWARE.
671 *
672 **************************************************************************/
673
674
675
676#ifndef MINIZ_NO_DEFLATE_APIS
677
678#ifdef __cplusplus
679extern "C"
680{
681#endif
682
683 /* ------------------- Low-level Compression (independent from all decompression API's) */
684
685 /* Purposely making these tables static for faster init and thread safety. */
686 static const mz_uint16 s_tdefl_len_sym[256] = {
687 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,
688 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,
689 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,
690 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,
691 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,
692 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,
693 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,
694 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
695 };
696
697 static const mz_uint8 s_tdefl_len_extra[256] = {
698 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,
699 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,
700 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,
701 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
702 };
703
704 static const mz_uint8 s_tdefl_small_dist_sym[512] = {
705 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,
706 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,
707 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,
708 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,
709 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,
710 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,
711 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,
712 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,
713 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,
714 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,
715 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,
716 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
717 };
718
719 static const mz_uint8 s_tdefl_small_dist_extra[512] = {
720 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,
721 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,
722 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,
723 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,
724 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
725 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
726 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
727 7, 7, 7, 7, 7, 7, 7, 7
728 };
729
730 static const mz_uint8 s_tdefl_large_dist_sym[128] = {
731 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,
732 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,
733 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
734 };
735
736 static const mz_uint8 s_tdefl_large_dist_extra[128] = {
737 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,
738 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,
739 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
740 };
741
742 /* Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted values. */
743 typedef struct
744 {
748 {
749 mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2];
752 for (i = 0; i < num_syms; i++)
753 {
754 mz_uint freq = pSyms0[i].m_key;
755 hist[freq & 0xFF]++;
756 hist[256 + ((freq >> 8) & 0xFF)]++;
757 }
758 while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256]))
759 total_passes--;
760 for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8)
761 {
762 const mz_uint32 *pHist = &hist[pass << 8];
763 mz_uint offsets[256], cur_ofs = 0;
764 for (i = 0; i < 256; i++)
765 {
766 offsets[i] = cur_ofs;
767 cur_ofs += pHist[i];
768 }
769 for (i = 0; i < num_syms; i++)
770 pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = pCur_syms[i];
771 {
774 pNew_syms = t;
775 }
776 }
777 return pCur_syms;
778 }
779
780 /* tdefl_calculate_minimum_redundancy() originally written by: Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996. */
782 {
783 int root, leaf, next, avbl, used, dpth;
784 if (n == 0)
785 return;
786 else if (n == 1)
787 {
788 A[0].m_key = 1;
789 return;
790 }
791 A[0].m_key += A[1].m_key;
792 root = 0;
793 leaf = 2;
794 for (next = 1; next < n - 1; next++)
795 {
796 if (leaf >= n || A[root].m_key < A[leaf].m_key)
797 {
798 A[next].m_key = A[root].m_key;
799 A[root++].m_key = (mz_uint16)next;
800 }
801 else
802 A[next].m_key = A[leaf++].m_key;
803 if (leaf >= n || (root < next && A[root].m_key < A[leaf].m_key))
804 {
805 A[next].m_key = (mz_uint16)(A[next].m_key + A[root].m_key);
806 A[root++].m_key = (mz_uint16)next;
807 }
808 else
809 A[next].m_key = (mz_uint16)(A[next].m_key + A[leaf++].m_key);
810 }
811 A[n - 2].m_key = 0;
812 for (next = n - 3; next >= 0; next--)
813 A[next].m_key = A[A[next].m_key].m_key + 1;
814 avbl = 1;
815 used = dpth = 0;
816 root = n - 2;
817 next = n - 1;
818 while (avbl > 0)
819 {
820 while (root >= 0 && (int)A[root].m_key == dpth)
821 {
822 used++;
823 root--;
824 }
825 while (avbl > used)
826 {
827 A[next--].m_key = (mz_uint16)(dpth);
828 avbl--;
829 }
830 avbl = 2 * used;
831 dpth++;
832 used = 0;
833 }
834 }
835
836 /* Limits canonical Huffman code table's max code size. */
837 enum
838 {
840 };
842 {
843 int i;
844 mz_uint32 total = 0;
845 if (code_list_len <= 1)
846 return;
847 for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++)
849 for (i = max_code_size; i > 0; i--)
850 total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i));
851 while (total != (1UL << max_code_size))
852 {
854 for (i = max_code_size - 1; i > 0; i--)
855 if (pNum_codes[i])
856 {
857 pNum_codes[i]--;
858 pNum_codes[i + 1] += 2;
859 break;
860 }
861 total--;
862 }
863 }
864
866 {
870 if (static_table)
871 {
872 for (i = 0; i < table_len; i++)
873 num_codes[d->m_huff_code_sizes[table_num][i]]++;
874 }
875 else
876 {
878 int num_used_syms = 0;
879 const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0];
880 for (i = 0; i < table_len; i++)
881 if (pSym_count[i])
882 {
884 syms0[num_used_syms++].m_sym_index = (mz_uint16)i;
885 }
886
889
890 for (i = 0; i < num_used_syms; i++)
891 num_codes[pSyms[i].m_key]++;
892
894
895 MZ_CLEAR_ARR(d->m_huff_code_sizes[table_num]);
896 MZ_CLEAR_ARR(d->m_huff_codes[table_num]);
897 for (i = 1, j = num_used_syms; i <= code_size_limit; i++)
898 for (l = num_codes[i]; l > 0; l--)
899 d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i);
900 }
901
902 next_code[1] = 0;
903 for (j = 0, i = 2; i <= code_size_limit; i++)
904 next_code[i] = j = ((j + num_codes[i - 1]) << 1);
905
906 for (i = 0; i < table_len; i++)
907 {
908 mz_uint rev_code = 0, code, code_size;
909 if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0)
910 continue;
911 code = next_code[code_size]++;
912 for (l = code_size; l > 0; l--, code >>= 1)
913 rev_code = (rev_code << 1) | (code & 1);
914 d->m_huff_codes[table_num][i] = (mz_uint16)rev_code;
915 }
916 }
917
918#define TDEFL_PUT_BITS(b, l) \
919 do \
920 { \
921 mz_uint bits = b; \
922 mz_uint len = l; \
923 MZ_ASSERT(bits <= ((1U << len) - 1U)); \
924 d->m_bit_buffer |= (bits << d->m_bits_in); \
925 d->m_bits_in += len; \
926 while (d->m_bits_in >= 8) \
927 { \
928 if (d->m_pOutput_buf < d->m_pOutput_buf_end) \
929 *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \
930 d->m_bit_buffer >>= 8; \
931 d->m_bits_in -= 8; \
932 } \
933 } \
934 MZ_MACRO_END
935
936#define TDEFL_RLE_PREV_CODE_SIZE() \
937 { \
938 if (rle_repeat_count) \
939 { \
940 if (rle_repeat_count < 3) \
941 { \
942 d->m_huff_count[2][prev_code_size] = (mz_uint16)(d->m_huff_count[2][prev_code_size] + rle_repeat_count); \
943 while (rle_repeat_count--) \
944 packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \
945 } \
946 else \
947 { \
948 d->m_huff_count[2][16] = (mz_uint16)(d->m_huff_count[2][16] + 1); \
949 packed_code_sizes[num_packed_code_sizes++] = 16; \
950 packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_repeat_count - 3); \
951 } \
952 rle_repeat_count = 0; \
953 } \
954 }
955
956#define TDEFL_RLE_ZERO_CODE_SIZE() \
957 { \
958 if (rle_z_count) \
959 { \
960 if (rle_z_count < 3) \
961 { \
962 d->m_huff_count[2][0] = (mz_uint16)(d->m_huff_count[2][0] + rle_z_count); \
963 while (rle_z_count--) \
964 packed_code_sizes[num_packed_code_sizes++] = 0; \
965 } \
966 else if (rle_z_count <= 10) \
967 { \
968 d->m_huff_count[2][17] = (mz_uint16)(d->m_huff_count[2][17] + 1); \
969 packed_code_sizes[num_packed_code_sizes++] = 17; \
970 packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 3); \
971 } \
972 else \
973 { \
974 d->m_huff_count[2][18] = (mz_uint16)(d->m_huff_count[2][18] + 1); \
975 packed_code_sizes[num_packed_code_sizes++] = 18; \
976 packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 11); \
977 } \
978 rle_z_count = 0; \
979 } \
980 }
981
982 static const 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 };
983
985 {
989
990 d->m_huff_count[0][256] = 1;
991
994
995 for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--)
996 if (d->m_huff_code_sizes[0][num_lit_codes - 1])
997 break;
999 if (d->m_huff_code_sizes[1][num_dist_codes - 1])
1000 break;
1001
1002 memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes);
1003 memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0], num_dist_codes);
1006 rle_z_count = 0;
1007 rle_repeat_count = 0;
1008
1009 memset(&d->m_huff_count[2][0], 0, sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2);
1010 for (i = 0; i < total_code_sizes_to_pack; i++)
1011 {
1013 if (!code_size)
1014 {
1016 if (++rle_z_count == 138)
1017 {
1019 }
1020 }
1021 else
1022 {
1025 {
1027 d->m_huff_count[2][code_size] = (mz_uint16)(d->m_huff_count[2][code_size] + 1);
1029 }
1030 else if (++rle_repeat_count == 6)
1031 {
1033 }
1034 }
1036 }
1037 if (rle_repeat_count)
1038 {
1040 }
1041 else
1042 {
1044 }
1045
1047
1048 TDEFL_PUT_BITS(2, 2);
1049
1050 TDEFL_PUT_BITS(num_lit_codes - 257, 5);
1052
1054 if (d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[num_bit_lengths]])
1055 break;
1058 for (i = 0; (int)i < num_bit_lengths; i++)
1059 TDEFL_PUT_BITS(d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[i]], 3);
1060
1062 {
1065 TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]);
1066 if (code >= 16)
1067 TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++], "\02\03\07"[code - 16]);
1068 }
1069 }
1070
1072 {
1073 mz_uint i;
1074 mz_uint8 *p = &d->m_huff_code_sizes[0][0];
1075
1076 for (i = 0; i <= 143; ++i)
1077 *p++ = 8;
1078 for (; i <= 255; ++i)
1079 *p++ = 9;
1080 for (; i <= 279; ++i)
1081 *p++ = 7;
1082 for (; i <= 287; ++i)
1083 *p++ = 8;
1084
1085 memset(d->m_huff_code_sizes[1], 5, 32);
1086
1087 tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE);
1089
1090 TDEFL_PUT_BITS(1, 2);
1091 }
1092
1093 static const mz_uint mz_bitmasks[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
1094
1095#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS
1097 {
1098 mz_uint flags;
1100 mz_uint8 *pOutput_buf = d->m_pOutput_buf;
1101 mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf;
1102 mz_uint64 bit_buffer = d->m_bit_buffer;
1103 mz_uint bits_in = d->m_bits_in;
1104
1105#define TDEFL_PUT_BITS_FAST(b, l) \
1106 { \
1107 bit_buffer |= (((mz_uint64)(b)) << bits_in); \
1108 bits_in += (l); \
1109 }
1110
1111 flags = 1;
1112 for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end; flags >>= 1)
1113 {
1114 if (flags == 1)
1115 flags = *pLZ_codes++ | 0x100;
1116
1117 if (flags & 1)
1118 {
1119 mz_uint s0, s1, n0, n1, sym, num_extra_bits;
1121 mz_uint match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8));
1122 pLZ_codes += 3;
1123
1124 MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
1125 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]]);
1127
1128 /* This sequence coaxes MSVC into using cmov's vs. jmp's. */
1133 sym = (match_dist < 512) ? s0 : s1;
1134 num_extra_bits = (match_dist < 512) ? n0 : n1;
1135
1136 MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
1137 TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
1139 }
1140 else
1141 {
1142 mz_uint lit = *pLZ_codes++;
1143 MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
1144 TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
1145
1146 if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
1147 {
1148 flags >>= 1;
1149 lit = *pLZ_codes++;
1150 MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
1151 TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
1152
1153 if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
1154 {
1155 flags >>= 1;
1156 lit = *pLZ_codes++;
1157 MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
1158 TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
1159 }
1160 }
1161 }
1162
1163 if (pOutput_buf >= d->m_pOutput_buf_end)
1164 return MZ_FALSE;
1165
1167 pOutput_buf += (bits_in >> 3);
1168 bit_buffer >>= (bits_in & ~7);
1169 bits_in &= 7;
1170 }
1171
1172#undef TDEFL_PUT_BITS_FAST
1173
1174 d->m_pOutput_buf = pOutput_buf;
1175 d->m_bits_in = 0;
1176 d->m_bit_buffer = 0;
1177
1178 while (bits_in)
1179 {
1180 mz_uint32 n = MZ_MIN(bits_in, 16);
1182 bit_buffer >>= n;
1183 bits_in -= n;
1184 }
1185
1186 TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
1187
1188 return (d->m_pOutput_buf < d->m_pOutput_buf_end);
1189 }
1190#else
1192{
1193 mz_uint flags;
1195
1196 flags = 1;
1197 for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf; flags >>= 1)
1198 {
1199 if (flags == 1)
1200 flags = *pLZ_codes++ | 0x100;
1201 if (flags & 1)
1202 {
1204 mz_uint match_len = pLZ_codes[0], match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8));
1205 pLZ_codes += 3;
1206
1207 MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
1208 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]]);
1210
1211 if (match_dist < 512)
1212 {
1215 }
1216 else
1217 {
1220 }
1221 MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
1222 TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
1224 }
1225 else
1226 {
1227 mz_uint lit = *pLZ_codes++;
1228 MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
1229 TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
1230 }
1231 }
1232
1233 TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
1234
1235 return (d->m_pOutput_buf < d->m_pOutput_buf_end);
1236}
1237#endif /* MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS */
1238
1240 {
1241 if (static_block)
1243 else
1245 return tdefl_compress_lz_codes(d);
1246 }
1247
1248 static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
1249
1250 static int tdefl_flush_block(tdefl_compressor *d, int flush)
1251 {
1255 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;
1256 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;
1257
1258 d->m_pOutput_buf = pOutput_buf_start;
1259 d->m_pOutput_buf_end = d->m_pOutput_buf + TDEFL_OUT_BUF_SIZE - 16;
1260
1261 MZ_ASSERT(!d->m_output_flush_remaining);
1262 d->m_output_flush_ofs = 0;
1263 d->m_output_flush_remaining = 0;
1264
1265 *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left);
1266 d->m_pLZ_code_buf -= (d->m_num_flags_left == 8);
1267
1268 if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index))
1269 {
1270 const mz_uint8 cmf = 0x78;
1271 mz_uint8 flg, flevel = 3;
1272 mz_uint header, i, mz_un = sizeof(s_tdefl_num_probes) / sizeof(mz_uint);
1273
1274 /* Determine compression level by reversing the process in tdefl_create_comp_flags_from_zip_params() */
1275 for (i = 0; i < mz_un; i++)
1276 if (s_tdefl_num_probes[i] == (d->m_flags & 0xFFF))
1277 break;
1278
1279 if (i < 2)
1280 flevel = 0;
1281 else if (i < 6)
1282 flevel = 1;
1283 else if (i == 6)
1284 flevel = 2;
1285
1286 header = cmf << 8 | (flevel << 6);
1287 header += 31 - (header % 31);
1288 flg = header & 0xFF;
1289
1290 TDEFL_PUT_BITS(cmf, 8);
1291 TDEFL_PUT_BITS(flg, 8);
1292 }
1293
1294 TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1);
1295
1296 pSaved_output_buf = d->m_pOutput_buf;
1297 saved_bit_buf = d->m_bit_buffer;
1298 saved_bits_in = d->m_bits_in;
1299
1300 if (!use_raw_block)
1301 comp_block_succeeded = tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || (d->m_total_lz_bytes < 48));
1302
1303 /* If the block gets expanded, forget the current contents of the output buffer and send a raw block instead. */
1304 if (((use_raw_block) || ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >= d->m_total_lz_bytes))) &&
1305 ((d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size))
1306 {
1307 mz_uint i;
1308 d->m_pOutput_buf = pSaved_output_buf;
1309 d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
1310 TDEFL_PUT_BITS(0, 2);
1311 if (d->m_bits_in)
1312 {
1313 TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
1314 }
1315 for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF)
1316 {
1317 TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16);
1318 }
1319 for (i = 0; i < d->m_total_lz_bytes; ++i)
1320 {
1321 TDEFL_PUT_BITS(d->m_dict[(d->m_lz_code_buf_dict_pos + i) & TDEFL_LZ_DICT_SIZE_MASK], 8);
1322 }
1323 }
1324 /* Check for the extremely unlikely (if not impossible) case of the compressed block not fitting into the output buffer when using dynamic codes. */
1325 else if (!comp_block_succeeded)
1326 {
1327 d->m_pOutput_buf = pSaved_output_buf;
1328 d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
1330 }
1331
1332 if (flush)
1333 {
1334 if (flush == TDEFL_FINISH)
1335 {
1336 if (d->m_bits_in)
1337 {
1338 TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
1339 }
1340 if (d->m_flags & TDEFL_WRITE_ZLIB_HEADER)
1341 {
1342 mz_uint i, a = d->m_adler32;
1343 for (i = 0; i < 4; i++)
1344 {
1345 TDEFL_PUT_BITS((a >> 24) & 0xFF, 8);
1346 a <<= 8;
1347 }
1348 }
1349 }
1350 else
1351 {
1352 mz_uint i, z = 0;
1353 TDEFL_PUT_BITS(0, 3);
1354 if (d->m_bits_in)
1355 {
1356 TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
1357 }
1358 for (i = 2; i; --i, z ^= 0xFFFF)
1359 {
1360 TDEFL_PUT_BITS(z & 0xFFFF, 16);
1361 }
1362 }
1363 }
1364
1365 MZ_ASSERT(d->m_pOutput_buf < d->m_pOutput_buf_end);
1366
1367 memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
1368 memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
1369
1370 d->m_pLZ_code_buf = d->m_lz_code_buf + 1;
1371 d->m_pLZ_flags = d->m_lz_code_buf;
1372 d->m_num_flags_left = 8;
1373 d->m_lz_code_buf_dict_pos += d->m_total_lz_bytes;
1374 d->m_total_lz_bytes = 0;
1375 d->m_block_index++;
1376
1377 if ((n = (int)(d->m_pOutput_buf - pOutput_buf_start)) != 0)
1378 {
1379 if (d->m_pPut_buf_func)
1380 {
1381 *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf;
1382 if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user))
1383 return (d->m_prev_return_status = TDEFL_STATUS_PUT_BUF_FAILED);
1384 }
1385 else if (pOutput_buf_start == d->m_output_buf)
1386 {
1387 int bytes_to_copy = (int)MZ_MIN((size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs));
1388 memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf, bytes_to_copy);
1389 d->m_out_buf_ofs += bytes_to_copy;
1390 if ((n -= bytes_to_copy) != 0)
1391 {
1392 d->m_output_flush_ofs = bytes_to_copy;
1393 d->m_output_flush_remaining = n;
1394 }
1395 }
1396 else
1397 {
1398 d->m_out_buf_ofs += n;
1399 }
1400 }
1401
1402 return d->m_output_flush_remaining;
1403 }
1404
1405#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
1406#ifdef MINIZ_UNALIGNED_USE_MEMCPY
1408 {
1409 mz_uint16 ret;
1410 memcpy(&ret, p, sizeof(mz_uint16));
1411 return ret;
1412 }
1414 {
1415 mz_uint16 ret;
1416 memcpy(&ret, p, sizeof(mz_uint16));
1417 return ret;
1418 }
1419#else
1420#define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16 *)(p)
1421#define TDEFL_READ_UNALIGNED_WORD2(p) *(const mz_uint16 *)(p)
1422#endif
1424 {
1426 mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
1427 const mz_uint16 *s = (const mz_uint16 *)(d->m_dict + pos), *p, *q;
1430 if (max_match_len <= match_len)
1431 return;
1432 for (;;)
1433 {
1434 for (;;)
1435 {
1436 if (--num_probes_left == 0)
1437 return;
1438#define TDEFL_PROBE \
1439 next_probe_pos = d->m_next[probe_pos]; \
1440 if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \
1441 return; \
1442 probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
1443 if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) \
1444 break;
1448 }
1449 if (!dist)
1450 break;
1451 q = (const mz_uint16 *)(d->m_dict + probe_pos);
1453 continue;
1454 p = s;
1455 probe_len = 32;
1456 do
1457 {
1460 if (!probe_len)
1461 {
1462 *pMatch_dist = dist;
1464 break;
1465 }
1466 else if ((probe_len = ((mz_uint)(p - s) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q)) > match_len)
1467 {
1468 *pMatch_dist = dist;
1470 break;
1471 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]);
1472 }
1473 }
1474 }
1475#else
1477{
1479 mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
1480 const mz_uint8 *s = d->m_dict + pos, *p, *q;
1481 mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1];
1483 if (max_match_len <= match_len)
1484 return;
1485 for (;;)
1486 {
1487 for (;;)
1488 {
1489 if (--num_probes_left == 0)
1490 return;
1491#define TDEFL_PROBE \
1492 next_probe_pos = d->m_next[probe_pos]; \
1493 if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \
1494 return; \
1495 probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
1496 if ((d->m_dict[probe_pos + match_len] == c0) && (d->m_dict[probe_pos + match_len - 1] == c1)) \
1497 break;
1501 }
1502 if (!dist)
1503 break;
1504 p = s;
1505 q = d->m_dict + probe_pos;
1507 if (*p++ != *q++)
1508 break;
1509 if (probe_len > match_len)
1510 {
1511 *pMatch_dist = dist;
1513 return;
1514 c0 = d->m_dict[pos + match_len];
1515 c1 = d->m_dict[pos + match_len - 1];
1516 }
1517 }
1518}
1519#endif /* #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES */
1520
1521#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
1522#ifdef MINIZ_UNALIGNED_USE_MEMCPY
1524 {
1525 mz_uint32 ret;
1526 memcpy(&ret, p, sizeof(mz_uint32));
1527 return ret;
1528 }
1529#else
1530#define TDEFL_READ_UNALIGNED_WORD32(p) *(const mz_uint32 *)(p)
1531#endif
1533 {
1534 /* Faster, minimally featured LZRW1-style match+parse loop with better register utilization. Intended for applications where raw throughput is valued more highly than ratio. */
1535 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;
1536 mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags;
1538
1539 while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size)))
1540 {
1544 d->m_src_buf_left -= num_bytes_to_process;
1546
1547 while (num_bytes_to_process)
1548 {
1550 memcpy(d->m_dict + dst_pos, d->m_pSrc, n);
1551 if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
1552 memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc, MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos));
1553 d->m_pSrc += n;
1556 }
1557
1559 if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE))
1560 break;
1561
1562 while (lookahead_size >= 4)
1563 {
1565 mz_uint8 *pCur_dict = d->m_dict + cur_pos;
1568 mz_uint probe_pos = d->m_hash[hash];
1569 d->m_hash[hash] = (mz_uint16)lookahead_pos;
1570
1572 {
1573 const mz_uint16 *p = (const mz_uint16 *)pCur_dict;
1574 const mz_uint16 *q = (const mz_uint16 *)(d->m_dict + probe_pos);
1575 mz_uint32 probe_len = 32;
1576 do
1577 {
1580 cur_match_len = ((mz_uint)(p - (const mz_uint16 *)pCur_dict) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q);
1581 if (!probe_len)
1583
1585 {
1586 cur_match_len = 1;
1588 *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
1589 d->m_huff_count[0][(mz_uint8)first_trigram]++;
1590 }
1591 else
1592 {
1593 mz_uint32 s0, s1;
1595
1597
1599
1601#ifdef MINIZ_UNALIGNED_USE_MEMCPY
1603#else
1605#endif
1606 pLZ_code_buf += 3;
1607 *pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80);
1608
1611 d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++;
1612
1613 d->m_huff_count[0][s_tdefl_len_sym[cur_match_len - TDEFL_MIN_MATCH_LEN]]++;
1614 }
1615 }
1616 else
1617 {
1619 *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
1620 d->m_huff_count[0][(mz_uint8)first_trigram]++;
1621 }
1622
1623 if (--num_flags_left == 0)
1624 {
1625 num_flags_left = 8;
1627 }
1628
1635
1636 if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8])
1637 {
1638 int n;
1639 d->m_lookahead_pos = lookahead_pos;
1640 d->m_lookahead_size = lookahead_size;
1641 d->m_dict_size = dict_size;
1642 d->m_total_lz_bytes = total_lz_bytes;
1643 d->m_pLZ_code_buf = pLZ_code_buf;
1644 d->m_pLZ_flags = pLZ_flags;
1645 d->m_num_flags_left = num_flags_left;
1646 if ((n = tdefl_flush_block(d, 0)) != 0)
1647 return (n < 0) ? MZ_FALSE : MZ_TRUE;
1648 total_lz_bytes = d->m_total_lz_bytes;
1649 pLZ_code_buf = d->m_pLZ_code_buf;
1650 pLZ_flags = d->m_pLZ_flags;
1651 num_flags_left = d->m_num_flags_left;
1652 }
1653 }
1654
1655 while (lookahead_size)
1656 {
1657 mz_uint8 lit = d->m_dict[cur_pos];
1658
1660 *pLZ_code_buf++ = lit;
1661 *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
1662 if (--num_flags_left == 0)
1663 {
1664 num_flags_left = 8;
1666 }
1667
1668 d->m_huff_count[0][lit]++;
1669
1670 lookahead_pos++;
1674
1675 if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8])
1676 {
1677 int n;
1678 d->m_lookahead_pos = lookahead_pos;
1679 d->m_lookahead_size = lookahead_size;
1680 d->m_dict_size = dict_size;
1681 d->m_total_lz_bytes = total_lz_bytes;
1682 d->m_pLZ_code_buf = pLZ_code_buf;
1683 d->m_pLZ_flags = pLZ_flags;
1684 d->m_num_flags_left = num_flags_left;
1685 if ((n = tdefl_flush_block(d, 0)) != 0)
1686 return (n < 0) ? MZ_FALSE : MZ_TRUE;
1687 total_lz_bytes = d->m_total_lz_bytes;
1688 pLZ_code_buf = d->m_pLZ_code_buf;
1689 pLZ_flags = d->m_pLZ_flags;
1690 num_flags_left = d->m_num_flags_left;
1691 }
1692 }
1693 }
1694
1695 d->m_lookahead_pos = lookahead_pos;
1696 d->m_lookahead_size = lookahead_size;
1697 d->m_dict_size = dict_size;
1698 d->m_total_lz_bytes = total_lz_bytes;
1699 d->m_pLZ_code_buf = pLZ_code_buf;
1700 d->m_pLZ_flags = pLZ_flags;
1701 d->m_num_flags_left = num_flags_left;
1702 return MZ_TRUE;
1703 }
1704#endif /* MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN */
1705
1707 {
1708 d->m_total_lz_bytes++;
1709 *d->m_pLZ_code_buf++ = lit;
1710 *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1);
1711 if (--d->m_num_flags_left == 0)
1712 {
1713 d->m_num_flags_left = 8;
1714 d->m_pLZ_flags = d->m_pLZ_code_buf++;
1715 }
1716 d->m_huff_count[0][lit]++;
1717 }
1718
1720 {
1721 mz_uint32 s0, s1;
1722
1724
1725 d->m_total_lz_bytes += match_len;
1726
1727 d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN);
1728
1729 match_dist -= 1;
1730 d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF);
1731 d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8);
1732 d->m_pLZ_code_buf += 3;
1733
1734 *d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80);
1735 if (--d->m_num_flags_left == 0)
1736 {
1737 d->m_num_flags_left = 8;
1738 d->m_pLZ_flags = d->m_pLZ_code_buf++;
1739 }
1740
1742 s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127];
1743 d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++;
1744 d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++;
1745 }
1746
1748 {
1749 const mz_uint8 *pSrc = d->m_pSrc;
1750 size_t src_buf_left = d->m_src_buf_left;
1751 tdefl_flush flush = d->m_flush;
1752
1753 while ((src_buf_left) || ((flush) && (d->m_lookahead_size)))
1754 {
1756 /* Update dictionary and hash chains. Keeps the lookahead size equal to TDEFL_MAX_MATCH_LEN. */
1757 if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1))
1758 {
1759 mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK, ins_pos = d->m_lookahead_pos + d->m_lookahead_size - 2;
1760 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];
1764 d->m_lookahead_size += num_bytes_to_process;
1765 while (pSrc != pSrc_end)
1766 {
1767 mz_uint8 c = *pSrc++;
1768 d->m_dict[dst_pos] = c;
1769 if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
1770 d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
1771 hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1);
1772 d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash];
1773 d->m_hash[hash] = (mz_uint16)(ins_pos);
1775 ins_pos++;
1776 }
1777 }
1778 else
1779 {
1780 while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
1781 {
1782 mz_uint8 c = *pSrc++;
1783 mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK;
1784 src_buf_left--;
1785 d->m_dict[dst_pos] = c;
1786 if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
1787 d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
1788 if ((++d->m_lookahead_size + d->m_dict_size) >= TDEFL_MIN_MATCH_LEN)
1789 {
1790 mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2;
1791 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);
1792 d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash];
1793 d->m_hash[hash] = (mz_uint16)(ins_pos);
1794 }
1795 }
1796 }
1797 d->m_dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - d->m_lookahead_size, d->m_dict_size);
1798 if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
1799 break;
1800
1801 /* Simple lazy/greedy parsing state machine. */
1802 len_to_move = 1;
1803 cur_match_dist = 0;
1804 cur_match_len = d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1);
1805 cur_pos = d->m_lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
1806 if (d->m_flags & (TDEFL_RLE_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS))
1807 {
1808 if ((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS)))
1809 {
1810 mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK];
1811 cur_match_len = 0;
1813 {
1814 if (d->m_dict[cur_pos + cur_match_len] != c)
1815 break;
1816 cur_match_len++;
1817 }
1819 cur_match_len = 0;
1820 else
1821 cur_match_dist = 1;
1822 }
1823 }
1824 else
1825 {
1826 tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size, d->m_lookahead_size, &cur_match_dist, &cur_match_len);
1827 }
1828 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)))
1829 {
1831 }
1832 if (d->m_saved_match_len)
1833 {
1834 if (cur_match_len > d->m_saved_match_len)
1835 {
1836 tdefl_record_literal(d, (mz_uint8)d->m_saved_lit);
1837 if (cur_match_len >= 128)
1838 {
1840 d->m_saved_match_len = 0;
1842 }
1843 else
1844 {
1845 d->m_saved_lit = d->m_dict[cur_pos];
1846 d->m_saved_match_dist = cur_match_dist;
1847 d->m_saved_match_len = cur_match_len;
1848 }
1849 }
1850 else
1851 {
1852 tdefl_record_match(d, d->m_saved_match_len, d->m_saved_match_dist);
1853 len_to_move = d->m_saved_match_len - 1;
1854 d->m_saved_match_len = 0;
1855 }
1856 }
1857 else if (!cur_match_dist)
1858 tdefl_record_literal(d, d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]);
1859 else if ((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) || (cur_match_len >= 128))
1860 {
1863 }
1864 else
1865 {
1866 d->m_saved_lit = d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)];
1867 d->m_saved_match_dist = cur_match_dist;
1868 d->m_saved_match_len = cur_match_len;
1869 }
1870 /* Move the lookahead forward by len_to_move bytes. */
1871 d->m_lookahead_pos += len_to_move;
1872 MZ_ASSERT(d->m_lookahead_size >= len_to_move);
1873 d->m_lookahead_size -= len_to_move;
1874 d->m_dict_size = MZ_MIN(d->m_dict_size + len_to_move, (mz_uint)TDEFL_LZ_DICT_SIZE);
1875 /* Check if it's time to flush the current LZ codes to the internal output buffer. */
1876 if ((d->m_pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) ||
1877 ((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))))
1878 {
1879 int n;
1880 d->m_pSrc = pSrc;
1881 d->m_src_buf_left = src_buf_left;
1882 if ((n = tdefl_flush_block(d, 0)) != 0)
1883 return (n < 0) ? MZ_FALSE : MZ_TRUE;
1884 }
1885 }
1886
1887 d->m_pSrc = pSrc;
1888 d->m_src_buf_left = src_buf_left;
1889 return MZ_TRUE;
1890 }
1891
1893 {
1894 if (d->m_pIn_buf_size)
1895 {
1896 *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf;
1897 }
1898
1899 if (d->m_pOut_buf_size)
1900 {
1901 size_t n = MZ_MIN(*d->m_pOut_buf_size - d->m_out_buf_ofs, d->m_output_flush_remaining);
1902 memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf + d->m_output_flush_ofs, n);
1903 d->m_output_flush_ofs += (mz_uint)n;
1904 d->m_output_flush_remaining -= (mz_uint)n;
1905 d->m_out_buf_ofs += n;
1906
1907 *d->m_pOut_buf_size = d->m_out_buf_ofs;
1908 }
1909
1910 return (d->m_finished && !d->m_output_flush_remaining) ? TDEFL_STATUS_DONE : TDEFL_STATUS_OKAY;
1911 }
1912
1913 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)
1914 {
1915 if (!d)
1916 {
1917 if (pIn_buf_size)
1918 *pIn_buf_size = 0;
1919 if (pOut_buf_size)
1920 *pOut_buf_size = 0;
1922 }
1923
1924 d->m_pIn_buf = pIn_buf;
1925 d->m_pIn_buf_size = pIn_buf_size;
1926 d->m_pOut_buf = pOut_buf;
1927 d->m_pOut_buf_size = pOut_buf_size;
1928 d->m_pSrc = (const mz_uint8 *)(pIn_buf);
1929 d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0;
1930 d->m_out_buf_ofs = 0;
1931 d->m_flush = flush;
1932
1933 if (((d->m_pPut_buf_func != NULL) == ((pOut_buf != NULL) || (pOut_buf_size != NULL))) || (d->m_prev_return_status != TDEFL_STATUS_OKAY) ||
1934 (d->m_wants_to_finish && (flush != TDEFL_FINISH)) || (pIn_buf_size && *pIn_buf_size && !pIn_buf) || (pOut_buf_size && *pOut_buf_size && !pOut_buf))
1935 {
1936 if (pIn_buf_size)
1937 *pIn_buf_size = 0;
1938 if (pOut_buf_size)
1939 *pOut_buf_size = 0;
1940 return (d->m_prev_return_status = TDEFL_STATUS_BAD_PARAM);
1941 }
1942 d->m_wants_to_finish |= (flush == TDEFL_FINISH);
1943
1944 if ((d->m_output_flush_remaining) || (d->m_finished))
1945 return (d->m_prev_return_status = tdefl_flush_output_buffer(d));
1946
1947#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
1948 if (((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) &&
1949 ((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) &&
1951 {
1952 if (!tdefl_compress_fast(d))
1953 return d->m_prev_return_status;
1954 }
1955 else
1956#endif /* #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN */
1957 {
1958 if (!tdefl_compress_normal(d))
1959 return d->m_prev_return_status;
1960 }
1961
1962 if ((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) && (pIn_buf))
1963 d->m_adler32 = (mz_uint32)mz_adler32(d->m_adler32, (const mz_uint8 *)pIn_buf, d->m_pSrc - (const mz_uint8 *)pIn_buf);
1964
1965 if ((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) && (!d->m_output_flush_remaining))
1966 {
1967 if (tdefl_flush_block(d, flush) < 0)
1968 return d->m_prev_return_status;
1969 d->m_finished = (flush == TDEFL_FINISH);
1970 if (flush == TDEFL_FULL_FLUSH)
1971 {
1972 MZ_CLEAR_ARR(d->m_hash);
1973 MZ_CLEAR_ARR(d->m_next);
1974 d->m_dict_size = 0;
1975 }
1976 }
1977
1978 return (d->m_prev_return_status = tdefl_flush_output_buffer(d));
1979 }
1980
1982 {
1983 MZ_ASSERT(d->m_pPut_buf_func);
1984 return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush);
1985 }
1986
1988 {
1989 d->m_pPut_buf_func = pPut_buf_func;
1990 d->m_pPut_buf_user = pPut_buf_user;
1991 d->m_flags = (mz_uint)(flags);
1992 d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3;
1993 d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0;
1994 d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3;
1996 MZ_CLEAR_ARR(d->m_hash);
1997 d->m_lookahead_pos = d->m_lookahead_size = d->m_dict_size = d->m_total_lz_bytes = d->m_lz_code_buf_dict_pos = d->m_bits_in = 0;
1998 d->m_output_flush_ofs = d->m_output_flush_remaining = d->m_finished = d->m_block_index = d->m_bit_buffer = d->m_wants_to_finish = 0;
1999 d->m_pLZ_code_buf = d->m_lz_code_buf + 1;
2000 d->m_pLZ_flags = d->m_lz_code_buf;
2001 *d->m_pLZ_flags = 0;
2002 d->m_num_flags_left = 8;
2003 d->m_pOutput_buf = d->m_output_buf;
2004 d->m_pOutput_buf_end = d->m_output_buf;
2005 d->m_prev_return_status = TDEFL_STATUS_OKAY;
2006 d->m_saved_match_dist = d->m_saved_match_len = d->m_saved_lit = 0;
2007 d->m_adler32 = 1;
2008 d->m_pIn_buf = NULL;
2009 d->m_pOut_buf = NULL;
2010 d->m_pIn_buf_size = NULL;
2011 d->m_pOut_buf_size = NULL;
2012 d->m_flush = TDEFL_NO_FLUSH;
2013 d->m_pSrc = NULL;
2014 d->m_src_buf_left = 0;
2015 d->m_out_buf_ofs = 0;
2017 MZ_CLEAR_ARR(d->m_dict);
2018 memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
2019 memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
2020 return TDEFL_STATUS_OKAY;
2021 }
2022
2024 {
2025 return d->m_prev_return_status;
2026 }
2027
2029 {
2030 return d->m_adler32;
2031 }
2032
2034 {
2037 if (((buf_len) && (!pBuf)) || (!pPut_buf_func))
2038 return MZ_FALSE;
2040 if (!pComp)
2041 return MZ_FALSE;
2044 MZ_FREE(pComp);
2045 return succeeded;
2046 }
2047
2048 typedef struct
2049 {
2050 size_t m_size, m_capacity;
2054
2055 static mz_bool tdefl_output_buffer_putter(const void *pBuf, int len, void *pUser)
2056 {
2058 size_t new_size = p->m_size + len;
2059 if (new_size > p->m_capacity)
2060 {
2061 size_t new_capacity = p->m_capacity;
2063 if (!p->m_expandable)
2064 return MZ_FALSE;
2065 do
2066 {
2067 new_capacity = MZ_MAX(128U, new_capacity << 1U);
2068 } while (new_size > new_capacity);
2069 pNew_buf = (mz_uint8 *)MZ_REALLOC(p->m_pBuf, new_capacity);
2070 if (!pNew_buf)
2071 return MZ_FALSE;
2072 p->m_pBuf = pNew_buf;
2073 p->m_capacity = new_capacity;
2074 }
2075 memcpy((mz_uint8 *)p->m_pBuf + p->m_size, pBuf, len);
2076 p->m_size = new_size;
2077 return MZ_TRUE;
2078 }
2079
2080 void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
2081 {
2084 if (!pOut_len)
2085 return MZ_FALSE;
2086 else
2087 *pOut_len = 0;
2088 out_buf.m_expandable = MZ_TRUE;
2090 return NULL;
2091 *pOut_len = out_buf.m_size;
2092 return out_buf.m_pBuf;
2093 }
2094
2095 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)
2096 {
2099 if (!pOut_buf)
2100 return 0;
2101 out_buf.m_pBuf = (mz_uint8 *)pOut_buf;
2102 out_buf.m_capacity = out_buf_len;
2104 return 0;
2105 return out_buf.m_size;
2106 }
2107
2108 /* 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). */
2110 {
2111 mz_uint comp_flags = s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0);
2112 if (window_bits > 0)
2114
2115 if (!level)
2117 else if (strategy == MZ_FILTERED)
2119 else if (strategy == MZ_HUFFMAN_ONLY)
2121 else if (strategy == MZ_FIXED)
2123 else if (strategy == MZ_RLE)
2125
2126 return comp_flags;
2127 }
2128
2129#ifdef _MSC_VER
2130#pragma warning(push)
2131#pragma warning(disable : 4204) /* nonstandard extension used : non-constant aggregate initializer (also supported by GNU C and C99, so no big deal) */
2132#endif
2133
2134 /* Simple PNG writer function by Alex Evans, 2011. Released into the public domain: https://gist.github.com/908299, more context at
2135 http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/.
2136 This is actually a modification of Alex's original code so PNG files generated by this function pass pngcheck. */
2137 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)
2138 {
2139 /* Using a local copy of this array here in case MINIZ_NO_ZLIB_APIS was defined. */
2140 static const mz_uint s_tdefl_png_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
2143 int i, bpl = w * num_chans, y, z;
2144 mz_uint32 c;
2145 *pLen_out = 0;
2146 if (!pComp)
2147 return NULL;
2149 out_buf.m_expandable = MZ_TRUE;
2150 out_buf.m_capacity = 57 + MZ_MAX(64, (1 + bpl) * h);
2151 if (NULL == (out_buf.m_pBuf = (mz_uint8 *)MZ_MALLOC(out_buf.m_capacity)))
2152 {
2153 MZ_FREE(pComp);
2154 return NULL;
2155 }
2156 /* write dummy header */
2157 for (z = 41; z; --z)
2159 /* compress image data */
2161 for (y = 0; y < h; ++y)
2162 {
2165 }
2167 {
2168 MZ_FREE(pComp);
2169 MZ_FREE(out_buf.m_pBuf);
2170 return NULL;
2171 }
2172 /* write real header */
2173 *pLen_out = out_buf.m_size - 41;
2174 {
2175 static const mz_uint8 chans[] = { 0x00, 0x00, 0x04, 0x02, 0x06 };
2176 mz_uint8 pnghdr[41] = { 0x89, 0x50, 0x4e, 0x47, 0x0d,
2177 0x0a, 0x1a, 0x0a, 0x00, 0x00,
2178 0x00, 0x0d, 0x49, 0x48, 0x44,
2179 0x52, 0x00, 0x00, 0x00, 0x00,
2180 0x00, 0x00, 0x00, 0x00, 0x08,
2181 0x00, 0x00, 0x00, 0x00, 0x00,
2182 0x00, 0x00, 0x00, 0x00, 0x00,
2183 0x00, 0x00, 0x49, 0x44, 0x41,
2184 0x54 };
2185 pnghdr[18] = (mz_uint8)(w >> 8);
2186 pnghdr[19] = (mz_uint8)w;
2187 pnghdr[22] = (mz_uint8)(h >> 8);
2188 pnghdr[23] = (mz_uint8)h;
2189 pnghdr[25] = chans[num_chans];
2190 pnghdr[33] = (mz_uint8)(*pLen_out >> 24);
2191 pnghdr[34] = (mz_uint8)(*pLen_out >> 16);
2192 pnghdr[35] = (mz_uint8)(*pLen_out >> 8);
2193 pnghdr[36] = (mz_uint8)*pLen_out;
2194 c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, pnghdr + 12, 17);
2195 for (i = 0; i < 4; ++i, c <<= 8)
2196 ((mz_uint8 *)(pnghdr + 29))[i] = (mz_uint8)(c >> 24);
2197 memcpy(out_buf.m_pBuf, pnghdr, 41);
2198 }
2199 /* write footer (IDAT CRC-32, followed by IEND chunk) */
2200 if (!tdefl_output_buffer_putter("\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf))
2201 {
2202 *pLen_out = 0;
2203 MZ_FREE(pComp);
2204 MZ_FREE(out_buf.m_pBuf);
2205 return NULL;
2206 }
2207 c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, out_buf.m_pBuf + 41 - 4, *pLen_out + 4);
2208 for (i = 0; i < 4; ++i, c <<= 8)
2209 (out_buf.m_pBuf + out_buf.m_size - 16)[i] = (mz_uint8)(c >> 24);
2210 /* compute final size of file, grab compressed data buffer and return */
2211 *pLen_out += 57;
2212 MZ_FREE(pComp);
2213 return out_buf.m_pBuf;
2214 }
2215 void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out)
2216 {
2217 /* 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) */
2219 }
2220
2221#ifndef MINIZ_NO_MALLOC
2222 /* Allocate the tdefl_compressor and tinfl_decompressor structures in C so that */
2223 /* non-C language bindings to tdefL_ and tinfl_ API don't need to worry about */
2224 /* structure size and allocation mechanism. */
2226 {
2227 return (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor));
2228 }
2229
2231 {
2232 MZ_FREE(pComp);
2233 }
2234#endif
2235
2236#ifdef _MSC_VER
2237#pragma warning(pop)
2238#endif
2239
2240#ifdef __cplusplus
2241}
2242#endif
2243
2244#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/
2245 /**************************************************************************
2246 *
2247 * Copyright 2013-2014 RAD Game Tools and Valve Software
2248 * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
2249 * All Rights Reserved.
2250 *
2251 * Permission is hereby granted, free of charge, to any person obtaining a copy
2252 * of this software and associated documentation files (the "Software"), to deal
2253 * in the Software without restriction, including without limitation the rights
2254 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2255 * copies of the Software, and to permit persons to whom the Software is
2256 * furnished to do so, subject to the following conditions:
2257 *
2258 * The above copyright notice and this permission notice shall be included in
2259 * all copies or substantial portions of the Software.
2260 *
2261 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2262 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2263 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2264 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2265 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2266 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2267 * THE SOFTWARE.
2268 *
2269 **************************************************************************/
2270
2271
2272
2273#ifndef MINIZ_NO_INFLATE_APIS
2274
2275#ifdef __cplusplus
2276extern "C"
2277{
2278#endif
2279
2280 /* ------------------- Low-level Decompression (completely independent from all compression API's) */
2281
2282#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
2283#define TINFL_MEMSET(p, c, l) memset(p, c, l)
2284
2285#define TINFL_CR_BEGIN \
2286 switch (r->m_state) \
2287 { \
2288 case 0:
2289#define TINFL_CR_RETURN(state_index, result) \
2290 do \
2291 { \
2292 status = result; \
2293 r->m_state = state_index; \
2294 goto common_exit; \
2295 case state_index:; \
2296 } \
2297 MZ_MACRO_END
2298#define TINFL_CR_RETURN_FOREVER(state_index, result) \
2299 do \
2300 { \
2301 for (;;) \
2302 { \
2303 TINFL_CR_RETURN(state_index, result); \
2304 } \
2305 } \
2306 MZ_MACRO_END
2307#define TINFL_CR_FINISH }
2308
2309#define TINFL_GET_BYTE(state_index, c) \
2310 do \
2311 { \
2312 while (pIn_buf_cur >= pIn_buf_end) \
2313 { \
2314 TINFL_CR_RETURN(state_index, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS); \
2315 } \
2316 c = *pIn_buf_cur++; \
2317 } \
2318 MZ_MACRO_END
2319
2320#define TINFL_NEED_BITS(state_index, n) \
2321 do \
2322 { \
2323 mz_uint c; \
2324 TINFL_GET_BYTE(state_index, c); \
2325 bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
2326 num_bits += 8; \
2327 } while (num_bits < (mz_uint)(n))
2328#define TINFL_SKIP_BITS(state_index, n) \
2329 do \
2330 { \
2331 if (num_bits < (mz_uint)(n)) \
2332 { \
2333 TINFL_NEED_BITS(state_index, n); \
2334 } \
2335 bit_buf >>= (n); \
2336 num_bits -= (n); \
2337 } \
2338 MZ_MACRO_END
2339#define TINFL_GET_BITS(state_index, b, n) \
2340 do \
2341 { \
2342 if (num_bits < (mz_uint)(n)) \
2343 { \
2344 TINFL_NEED_BITS(state_index, n); \
2345 } \
2346 b = bit_buf & ((1 << (n)) - 1); \
2347 bit_buf >>= (n); \
2348 num_bits -= (n); \
2349 } \
2350 MZ_MACRO_END
2351
2352/* TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2. */
2353/* 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 */
2354/* 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 */
2355/* bit buffer contains >=15 bits (deflate's max. Huffman code size). */
2356#define TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree) \
2357 do \
2358 { \
2359 temp = pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
2360 if (temp >= 0) \
2361 { \
2362 code_len = temp >> 9; \
2363 if ((code_len) && (num_bits >= code_len)) \
2364 break; \
2365 } \
2366 else if (num_bits > TINFL_FAST_LOOKUP_BITS) \
2367 { \
2368 code_len = TINFL_FAST_LOOKUP_BITS; \
2369 do \
2370 { \
2371 temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \
2372 } while ((temp < 0) && (num_bits >= (code_len + 1))); \
2373 if (temp >= 0) \
2374 break; \
2375 } \
2376 TINFL_GET_BYTE(state_index, c); \
2377 bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
2378 num_bits += 8; \
2379 } while (num_bits < 15);
2380
2381/* 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 */
2382/* 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 */
2383/* 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. */
2384/* The slow path is only executed at the very end of the input buffer. */
2385/* 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 */
2386/* following the deflate data and our non-conservative read-ahead path won't kick in here on this code. This is much trickier. */
2387#define TINFL_HUFF_DECODE(state_index, sym, pLookUp, pTree) \
2388 do \
2389 { \
2390 int temp; \
2391 mz_uint code_len, c; \
2392 if (num_bits < 15) \
2393 { \
2394 if ((pIn_buf_end - pIn_buf_cur) < 2) \
2395 { \
2396 TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree); \
2397 } \
2398 else \
2399 { \
2400 bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); \
2401 pIn_buf_cur += 2; \
2402 num_bits += 16; \
2403 } \
2404 } \
2405 if ((temp = pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
2406 code_len = temp >> 9, temp &= 511; \
2407 else \
2408 { \
2409 code_len = TINFL_FAST_LOOKUP_BITS; \
2410 do \
2411 { \
2412 temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \
2413 } while (temp < 0); \
2414 } \
2415 sym = temp; \
2416 bit_buf >>= code_len; \
2417 num_bits -= code_len; \
2418 } \
2419 MZ_MACRO_END
2420
2422 {
2423 if (r->m_type == 0)
2424 MZ_CLEAR_ARR(r->m_tree_0);
2425 else if (r->m_type == 1)
2426 MZ_CLEAR_ARR(r->m_tree_1);
2427 else
2428 MZ_CLEAR_ARR(r->m_tree_2);
2429 }
2430
2432 {
2433 static const mz_uint16 s_length_base[31] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 };
2434 static const mz_uint8 s_length_extra[31] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0 };
2435 static const mz_uint16 s_dist_base[32] = { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0 };
2436 static const mz_uint8 s_dist_extra[32] = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 };
2437 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 };
2438 static const mz_uint16 s_min_table_sizes[3] = { 257, 1, 4 };
2439
2440 mz_int16 *pTrees[3];
2442
2444 mz_uint32 num_bits, dist, counter, num_extra;
2449
2450 /* 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). */
2452 {
2455 }
2456
2457 pTrees[0] = r->m_tree_0;
2458 pTrees[1] = r->m_tree_1;
2459 pTrees[2] = r->m_tree_2;
2460 pCode_sizes[0] = r->m_code_size_0;
2461 pCode_sizes[1] = r->m_code_size_1;
2462 pCode_sizes[2] = r->m_code_size_2;
2463
2464 num_bits = r->m_num_bits;
2465 bit_buf = r->m_bit_buf;
2466 dist = r->m_dist;
2467 counter = r->m_counter;
2468 num_extra = r->m_num_extra;
2469 dist_from_out_buf_start = r->m_dist_from_out_buf_start;
2471
2472 bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0;
2473 r->m_z_adler32 = r->m_check_adler32 = 1;
2475 {
2476 TINFL_GET_BYTE(1, r->m_zhdr0);
2477 TINFL_GET_BYTE(2, r->m_zhdr1);
2478 counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8));
2480 counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)((size_t)1 << (8U + (r->m_zhdr0 >> 4)))));
2481 if (counter)
2482 {
2484 }
2485 }
2486
2487 do
2488 {
2489 TINFL_GET_BITS(3, r->m_final, 3);
2490 r->m_type = r->m_final >> 1;
2491 if (r->m_type == 0)
2492 {
2493 TINFL_SKIP_BITS(5, num_bits & 7);
2494 for (counter = 0; counter < 4; ++counter)
2495 {
2496 if (num_bits)
2497 TINFL_GET_BITS(6, r->m_raw_header[counter], 8);
2498 else
2499 TINFL_GET_BYTE(7, r->m_raw_header[counter]);
2500 }
2501 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))))
2502 {
2504 }
2505 while ((counter) && (num_bits))
2506 {
2507 TINFL_GET_BITS(51, dist, 8);
2508 while (pOut_buf_cur >= pOut_buf_end)
2509 {
2511 }
2513 counter--;
2514 }
2515 while (counter)
2516 {
2517 size_t n;
2518 while (pOut_buf_cur >= pOut_buf_end)
2519 {
2521 }
2522 while (pIn_buf_cur >= pIn_buf_end)
2523 {
2525 }
2526 n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter);
2528 pIn_buf_cur += n;
2529 pOut_buf_cur += n;
2530 counter -= (mz_uint)n;
2531 }
2532 }
2533 else if (r->m_type == 3)
2534 {
2536 }
2537 else
2538 {
2539 if (r->m_type == 1)
2540 {
2541 mz_uint8 *p = r->m_code_size_0;
2542 mz_uint i;
2543 r->m_table_sizes[0] = 288;
2544 r->m_table_sizes[1] = 32;
2545 TINFL_MEMSET(r->m_code_size_1, 5, 32);
2546 for (i = 0; i <= 143; ++i)
2547 *p++ = 8;
2548 for (; i <= 255; ++i)
2549 *p++ = 9;
2550 for (; i <= 279; ++i)
2551 *p++ = 7;
2552 for (; i <= 287; ++i)
2553 *p++ = 8;
2554 }
2555 else
2556 {
2557 for (counter = 0; counter < 3; counter++)
2558 {
2559 TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]);
2560 r->m_table_sizes[counter] += s_min_table_sizes[counter];
2561 }
2562 MZ_CLEAR_ARR(r->m_code_size_2);
2563 for (counter = 0; counter < r->m_table_sizes[2]; counter++)
2564 {
2565 mz_uint s;
2566 TINFL_GET_BITS(14, s, 3);
2567 r->m_code_size_2[s_length_dezigzag[counter]] = (mz_uint8)s;
2568 }
2569 r->m_table_sizes[2] = 19;
2570 }
2571 for (; (int)r->m_type >= 0; r->m_type--)
2572 {
2573 int tree_next, tree_cur;
2575 mz_int16 *pTree;
2577 mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16];
2578 pLookUp = r->m_look_up[r->m_type];
2579 pTree = pTrees[r->m_type];
2580 pCode_size = pCode_sizes[r->m_type];
2582 TINFL_MEMSET(pLookUp, 0, sizeof(r->m_look_up[0]));
2584 for (i = 0; i < r->m_table_sizes[r->m_type]; ++i)
2585 total_syms[pCode_size[i]]++;
2586 used_syms = 0, total = 0;
2587 next_code[0] = next_code[1] = 0;
2588 for (i = 1; i <= 15; ++i)
2589 {
2590 used_syms += total_syms[i];
2591 next_code[i + 1] = (total = ((total + total_syms[i]) << 1));
2592 }
2593 if ((65536 != total) && (used_syms > 1))
2594 {
2596 }
2597 for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index)
2598 {
2600 if (!code_size)
2601 continue;
2603 for (l = code_size; l > 0; l--, cur_code >>= 1)
2604 rev_code = (rev_code << 1) | (cur_code & 1);
2606 {
2607 mz_int16 k = (mz_int16)((code_size << 9) | sym_index);
2609 {
2610 pLookUp[rev_code] = k;
2611 rev_code += (1 << code_size);
2612 }
2613 continue;
2614 }
2615 if (0 == (tree_cur = pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)]))
2616 {
2619 tree_next -= 2;
2620 }
2622 for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--)
2623 {
2624 tree_cur -= ((rev_code >>= 1) & 1);
2625 if (!pTree[-tree_cur - 1])
2626 {
2629 tree_next -= 2;
2630 }
2631 else
2632 tree_cur = pTree[-tree_cur - 1];
2633 }
2634 tree_cur -= ((rev_code >>= 1) & 1);
2636 }
2637 if (r->m_type == 2)
2638 {
2639 for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]);)
2640 {
2641 mz_uint s;
2642 TINFL_HUFF_DECODE(16, dist, r->m_look_up[2], r->m_tree_2);
2643 if (dist < 16)
2644 {
2645 r->m_len_codes[counter++] = (mz_uint8)dist;
2646 continue;
2647 }
2648 if ((dist == 16) && (!counter))
2649 {
2651 }
2652 num_extra = "\02\03\07"[dist - 16];
2653 TINFL_GET_BITS(18, s, num_extra);
2654 s += "\03\03\013"[dist - 16];
2655 TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s);
2656 counter += s;
2657 }
2658 if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter)
2659 {
2661 }
2662 TINFL_MEMCPY(r->m_code_size_0, r->m_len_codes, r->m_table_sizes[0]);
2663 TINFL_MEMCPY(r->m_code_size_1, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]);
2664 }
2665 }
2666 for (;;)
2667 {
2668 mz_uint8 *pSrc;
2669 for (;;)
2670 {
2671 if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2))
2672 {
2673 TINFL_HUFF_DECODE(23, counter, r->m_look_up[0], r->m_tree_0);
2674 if (counter >= 256)
2675 break;
2676 while (pOut_buf_cur >= pOut_buf_end)
2677 {
2679 }
2680 *pOut_buf_cur++ = (mz_uint8)counter;
2681 }
2682 else
2683 {
2684 int sym2;
2686#if TINFL_USE_64BIT_BITBUF
2687 if (num_bits < 30)
2688 {
2689 bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits);
2690 pIn_buf_cur += 4;
2691 num_bits += 32;
2692 }
2693#else
2694 if (num_bits < 15)
2695 {
2696 bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
2697 pIn_buf_cur += 2;
2698 num_bits += 16;
2699 }
2700#endif
2701 if ((sym2 = r->m_look_up[0][bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
2702 code_len = sym2 >> 9;
2703 else
2704 {
2706 do
2707 {
2708 sym2 = r->m_tree_0[~sym2 + ((bit_buf >> code_len++) & 1)];
2709 } while (sym2 < 0);
2710 }
2711 counter = sym2;
2712 bit_buf >>= code_len;
2713 num_bits -= code_len;
2714 if (counter & 256)
2715 break;
2716
2717#if !TINFL_USE_64BIT_BITBUF
2718 if (num_bits < 15)
2719 {
2720 bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
2721 pIn_buf_cur += 2;
2722 num_bits += 16;
2723 }
2724#endif
2725 if ((sym2 = r->m_look_up[0][bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
2726 code_len = sym2 >> 9;
2727 else
2728 {
2730 do
2731 {
2732 sym2 = r->m_tree_0[~sym2 + ((bit_buf >> code_len++) & 1)];
2733 } while (sym2 < 0);
2734 }
2735 bit_buf >>= code_len;
2736 num_bits -= code_len;
2737
2738 /* assert(sym2 != 0 && counter != 0); */
2739 if (sym2 == 0 && counter == 0)
2740 {
2742 }
2743
2744 pOut_buf_cur[0] = (mz_uint8)counter;
2745 if (sym2 & 256)
2746 {
2747 pOut_buf_cur++;
2748 counter = sym2;
2749 break;
2750 }
2752 pOut_buf_cur += 2;
2753 }
2754 }
2755 if ((counter &= 511) == 256)
2756 break;
2757
2758 num_extra = s_length_extra[counter - 257];
2759 counter = s_length_base[counter - 257];
2760 if (num_extra)
2761 {
2764 counter += extra_bits;
2765 }
2766
2767 TINFL_HUFF_DECODE(26, dist, r->m_look_up[1], r->m_tree_1);
2770 if (num_extra)
2771 {
2774 dist += extra_bits;
2775 }
2776
2779 {
2781 }
2782
2784
2785 if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end)
2786 {
2787 while (counter--)
2788 {
2789 while (pOut_buf_cur >= pOut_buf_end)
2790 {
2792 }
2794 }
2795 continue;
2796 }
2797#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
2798 else if ((counter >= 9) && (counter <= dist))
2799 {
2800 const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
2801 do
2802 {
2803#ifdef MINIZ_UNALIGNED_USE_MEMCPY
2804 memcpy(pOut_buf_cur, pSrc, sizeof(mz_uint32) * 2);
2805#else
2806 ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0];
2807 ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1];
2808#endif
2809 pOut_buf_cur += 8;
2810 } while ((pSrc += 8) < pSrc_end);
2811 if ((counter &= 7) < 3)
2812 {
2813 if (counter)
2814 {
2815 pOut_buf_cur[0] = pSrc[0];
2816 if (counter > 1)
2817 pOut_buf_cur[1] = pSrc[1];
2818 pOut_buf_cur += counter;
2819 }
2820 continue;
2821 }
2822 }
2823#endif
2824 while (counter > 2)
2825 {
2826 pOut_buf_cur[0] = pSrc[0];
2827 pOut_buf_cur[1] = pSrc[1];
2828 pOut_buf_cur[2] = pSrc[2];
2829 pOut_buf_cur += 3;
2830 pSrc += 3;
2831 counter -= 3;
2832 }
2833 if (counter > 0)
2834 {
2835 pOut_buf_cur[0] = pSrc[0];
2836 if (counter > 1)
2837 pOut_buf_cur[1] = pSrc[1];
2838 pOut_buf_cur += counter;
2839 }
2840 }
2841 }
2842 } while (!(r->m_final & 1));
2843
2844 /* 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. */
2845 /* 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. */
2846 TINFL_SKIP_BITS(32, num_bits & 7);
2847 while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8))
2848 {
2849 --pIn_buf_cur;
2850 num_bits -= 8;
2851 }
2852 bit_buf &= ~(~(tinfl_bit_buf_t)0 << num_bits);
2853 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). */
2854
2856 {
2857 for (counter = 0; counter < 4; ++counter)
2858 {
2859 mz_uint s;
2860 if (num_bits)
2861 TINFL_GET_BITS(41, s, 8);
2862 else
2863 TINFL_GET_BYTE(42, s);
2864 r->m_z_adler32 = (r->m_z_adler32 << 8) | s;
2865 }
2866 }
2868
2870
2872 /* As long as we aren't telling the caller that we NEED more input to make forward progress: */
2873 /* 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. */
2874 /* 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. */
2876 {
2877 while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8))
2878 {
2879 --pIn_buf_cur;
2880 num_bits -= 8;
2881 }
2882 }
2883 r->m_num_bits = num_bits;
2884 r->m_bit_buf = bit_buf & ~(~(tinfl_bit_buf_t)0 << num_bits);
2885 r->m_dist = dist;
2886 r->m_counter = counter;
2887 r->m_num_extra = num_extra;
2888 r->m_dist_from_out_buf_start = dist_from_out_buf_start;
2892 {
2893 const mz_uint8 *ptr = pOut_buf_next;
2894 size_t buf_len = *pOut_buf_size;
2895 mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16;
2896 size_t block_len = buf_len % 5552;
2897 while (buf_len)
2898 {
2899 for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
2900 {
2901 s1 += ptr[0], s2 += s1;
2902 s1 += ptr[1], s2 += s1;
2903 s1 += ptr[2], s2 += s1;
2904 s1 += ptr[3], s2 += s1;
2905 s1 += ptr[4], s2 += s1;
2906 s1 += ptr[5], s2 += s1;
2907 s1 += ptr[6], s2 += s1;
2908 s1 += ptr[7], s2 += s1;
2909 }
2910 for (; i < block_len; ++i)
2911 s1 += *ptr++, s2 += s1;
2912 s1 %= 65521U, s2 %= 65521U;
2913 buf_len -= block_len;
2914 block_len = 5552;
2915 }
2916 r->m_check_adler32 = (s2 << 16) + s1;
2917 if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32))
2919 }
2920 return status;
2921 }
2922
2923 /* Higher level helper functions. */
2924 void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
2925 {
2927 void *pBuf = NULL, *pNew_buf;
2928 size_t src_buf_ofs = 0, out_buf_capacity = 0;
2929 *pOut_len = 0;
2931 for (;;)
2932 {
2936 if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT))
2937 {
2938 MZ_FREE(pBuf);
2939 *pOut_len = 0;
2940 return NULL;
2941 }
2944 if (status == TINFL_STATUS_DONE)
2945 break;
2947 if (new_out_buf_capacity < 128)
2950 if (!pNew_buf)
2951 {
2952 MZ_FREE(pBuf);
2953 *pOut_len = 0;
2954 return NULL;
2955 }
2956 pBuf = pNew_buf;
2958 }
2959 return pBuf;
2960 }
2961
2970
2972 {
2973 int result = 0;
2976 size_t in_buf_ofs = 0, dict_ofs = 0;
2977 if (!pDict)
2978 return TINFL_STATUS_FAILED;
2981 for (;;)
2982 {
2988 break;
2989 if (status != TINFL_STATUS_HAS_MORE_OUTPUT)
2990 {
2991 result = (status == TINFL_STATUS_DONE);
2992 break;
2993 }
2995 }
2996 MZ_FREE(pDict);
2998 return result;
2999 }
3000
3001#ifndef MINIZ_NO_MALLOC
3009
3014#endif
3015
3016#ifdef __cplusplus
3017}
3018#endif
3019
3020#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/
3021 /**************************************************************************
3022 *
3023 * Copyright 2013-2014 RAD Game Tools and Valve Software
3024 * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
3025 * Copyright 2016 Martin Raiber
3026 * All Rights Reserved.
3027 *
3028 * Permission is hereby granted, free of charge, to any person obtaining a copy
3029 * of this software and associated documentation files (the "Software"), to deal
3030 * in the Software without restriction, including without limitation the rights
3031 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
3032 * copies of the Software, and to permit persons to whom the Software is
3033 * furnished to do so, subject to the following conditions:
3034 *
3035 * The above copyright notice and this permission notice shall be included in
3036 * all copies or substantial portions of the Software.
3037 *
3038 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3039 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3040 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
3041 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3042 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3043 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
3044 * THE SOFTWARE.
3045 *
3046 **************************************************************************/
3047
3048
3049#ifndef MINIZ_NO_ARCHIVE_APIS
3050
3051#ifdef __cplusplus
3052extern "C"
3053{
3054#endif
3055
3056 /* ------------------- .ZIP archive reading */
3057
3058#ifdef MINIZ_NO_STDIO
3059#define MZ_FILE void *
3060#else
3061#include <sys/stat.h>
3062
3063#if defined(_MSC_VER) || defined(__MINGW64__) || defined(__MINGW32__)
3064
3065#ifndef WIN32_LEAN_AND_MEAN
3066#define WIN32_LEAN_AND_MEAN
3067#endif
3068#ifndef __cplusplus
3069#define MICROSOFT_WINDOWS_WINBASE_H_DEFINE_INTERLOCKED_CPLUSPLUS_OVERLOADS 0
3070#endif
3071#ifndef NOMINMAX
3072#define NOMINMAX
3073#endif
3074#include <windows.h>
3075
3076static WCHAR *mz_utf8z_to_widechar(const char *str)
3077{
3078 int reqChars = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
3079 WCHAR *wStr = (WCHAR *)malloc(reqChars * sizeof(WCHAR));
3081 return wStr;
3082}
3083
3084static FILE *mz_fopen(const char *pFilename, const char *pMode)
3085{
3088 FILE *pFile = NULL;
3090 free(wFilename);
3091 free(wMode);
3092 return err ? NULL : pFile;
3093}
3094
3095static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream)
3096{
3099 FILE *pFile = NULL;
3101 free(wPath);
3102 free(wMode);
3103 return err ? NULL : pFile;
3104}
3105
3106#if defined(__MINGW32__)
3107static int mz_stat(const char *path, struct _stat *buffer)
3108{
3110 int res = _wstat(wPath, buffer);
3111 free(wPath);
3112 return res;
3113}
3114#else
3115static int mz_stat64(const char *path, struct __stat64 *buffer)
3116{
3118 int res = _wstat64(wPath, buffer);
3119 free(wPath);
3120 return res;
3121}
3122#endif
3123
3124#ifndef MINIZ_NO_TIME
3125#include <sys/utime.h>
3126#endif
3127#define MZ_FOPEN mz_fopen
3128#define MZ_FCLOSE fclose
3129#define MZ_FREAD fread
3130#define MZ_FWRITE fwrite
3131#define MZ_FTELL64 _ftelli64
3132#define MZ_FSEEK64 _fseeki64
3133#if defined(__MINGW32__)
3134#define MZ_FILE_STAT_STRUCT _stat
3135#define MZ_FILE_STAT mz_stat
3136#else
3137#define MZ_FILE_STAT_STRUCT _stat64
3138#define MZ_FILE_STAT mz_stat64
3139#endif
3140#define MZ_FFLUSH fflush
3141#define MZ_FREOPEN mz_freopen
3142#define MZ_DELETE_FILE remove
3143
3144#elif defined(__WATCOMC__)
3145#ifndef MINIZ_NO_TIME
3146#include <sys/utime.h>
3147#endif
3148#define MZ_FOPEN(f, m) fopen(f, m)
3149#define MZ_FCLOSE fclose
3150#define MZ_FREAD fread
3151#define MZ_FWRITE fwrite
3152#define MZ_FTELL64 _ftelli64
3153#define MZ_FSEEK64 _fseeki64
3154#define MZ_FILE_STAT_STRUCT stat
3155#define MZ_FILE_STAT stat
3156#define MZ_FFLUSH fflush
3157#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
3158#define MZ_DELETE_FILE remove
3159
3160#elif defined(__TINYC__)
3161#ifndef MINIZ_NO_TIME
3162#include <sys/utime.h>
3163#endif
3164#define MZ_FOPEN(f, m) fopen(f, m)
3165#define MZ_FCLOSE fclose
3166#define MZ_FREAD fread
3167#define MZ_FWRITE fwrite
3168#define MZ_FTELL64 ftell
3169#define MZ_FSEEK64 fseek
3170#define MZ_FILE_STAT_STRUCT stat
3171#define MZ_FILE_STAT stat
3172#define MZ_FFLUSH fflush
3173#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
3174#define MZ_DELETE_FILE remove
3175
3176#elif defined(__USE_LARGEFILE64) /* gcc, clang */
3177#ifndef MINIZ_NO_TIME
3178#include <utime.h>
3179#endif
3180#define MZ_FOPEN(f, m) fopen64(f, m)
3181#define MZ_FCLOSE fclose
3182#define MZ_FREAD fread
3183#define MZ_FWRITE fwrite
3184#define MZ_FTELL64 ftello64
3185#define MZ_FSEEK64 fseeko64
3186#define MZ_FILE_STAT_STRUCT stat64
3187#define MZ_FILE_STAT stat64
3188#define MZ_FFLUSH fflush
3189#define MZ_FREOPEN(p, m, s) freopen64(p, m, s)
3190#define MZ_DELETE_FILE remove
3191
3192#elif defined(__APPLE__) || defined(__FreeBSD__) || (defined(__linux__) && defined(__x86_64__))
3193#ifndef MINIZ_NO_TIME
3194#include <utime.h>
3195#endif
3196#define MZ_FOPEN(f, m) fopen(f, m)
3197#define MZ_FCLOSE fclose
3198#define MZ_FREAD fread
3199#define MZ_FWRITE fwrite
3200#define MZ_FTELL64 ftello
3201#define MZ_FSEEK64 fseeko
3202#define MZ_FILE_STAT_STRUCT stat
3203#define MZ_FILE_STAT stat
3204#define MZ_FFLUSH fflush
3205#define MZ_FREOPEN(p, m, s) freopen(p, m, s)
3206#define MZ_DELETE_FILE remove
3207
3208#else
3209#pragma message("Using fopen, ftello, fseeko, stat() etc. path for file I/O - this path may not support large files.")
3210#ifndef MINIZ_NO_TIME
3211#include <utime.h>
3212#endif
3213#define MZ_FOPEN(f, m) fopen(f, m)
3214#define MZ_FCLOSE fclose
3215#define MZ_FREAD fread
3216#define MZ_FWRITE fwrite
3217#ifdef __STRICT_ANSI__
3218#define MZ_FTELL64 ftell
3219#define MZ_FSEEK64 fseek
3220#else
3221#define MZ_FTELL64 ftello
3222#define MZ_FSEEK64 fseeko
3223#endif
3224#define MZ_FILE_STAT_STRUCT stat
3225#define MZ_FILE_STAT stat
3226#define MZ_FFLUSH fflush
3227#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
3228#define MZ_DELETE_FILE remove
3229#endif /* #ifdef _MSC_VER */
3230#endif /* #ifdef MINIZ_NO_STDIO */
3231
3232#define MZ_TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c))
3233
3234 /* 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. */
3235 enum
3236 {
3237 /* ZIP archive identifiers and record sizes */
3244
3245 /* ZIP64 archive identifier and record sizes */
3254
3255 /* Central directory header record offsets */
3273
3274 /* Local directory header offsets */
3287
3288 /* End of central directory offsets */
3297
3298 /* ZIP64 End of central directory locator offsets */
3299 MZ_ZIP64_ECDL_SIG_OFS = 0, /* 4 bytes */
3303
3304 /* ZIP64 End of central directory header offsets */
3305 MZ_ZIP64_ECDH_SIG_OFS = 0, /* 4 bytes */
3314 MZ_ZIP64_ECDH_CDIR_OFS_OFS = 48, /* 8 bytes */
3323
3324 typedef struct
3325 {
3326 void *m_p;
3327 size_t m_size, m_capacity;
3329 } mz_zip_array;
3330
3332 {
3336
3337 /* The flags passed in when the archive is initially opened. */
3339
3340 /* MZ_TRUE if the archive has a zip64 end of central directory headers, etc. */
3342
3343 /* 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.) */
3345
3346 /* These fields are used by the file, FILE, memory, and memory/heap read/write helpers. */
3349
3350 void *m_pMem;
3353 };
3354
3355#define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size) (array_ptr)->m_element_size = element_size
3356
3357#if defined(DEBUG) || defined(_DEBUG)
3359 {
3361 return index;
3362 }
3363#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[mz_zip_array_range_check(array_ptr, index)]
3364#else
3365#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[index]
3366#endif
3367
3369 {
3370 memset(pArray, 0, sizeof(mz_zip_array));
3371 pArray->m_element_size = element_size;
3372 }
3373
3375 {
3376 pZip->m_pFree(pZip->m_pAlloc_opaque, pArray->m_p);
3377 memset(pArray, 0, sizeof(mz_zip_array));
3378 }
3379
3381 {
3382 void *pNew_p;
3384 MZ_ASSERT(pArray->m_element_size);
3385 if (pArray->m_capacity >= min_new_capacity)
3386 return MZ_TRUE;
3387 if (growing)
3388 {
3389 new_capacity = MZ_MAX(1, pArray->m_capacity);
3391 new_capacity *= 2;
3392 }
3393 if (NULL == (pNew_p = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pArray->m_p, pArray->m_element_size, new_capacity)))
3394 return MZ_FALSE;
3395 pArray->m_p = pNew_p;
3396 pArray->m_capacity = new_capacity;
3397 return MZ_TRUE;
3398 }
3399
3400#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
3402 {
3403 if (new_capacity > pArray->m_capacity)
3404 {
3406 return MZ_FALSE;
3407 }
3408 return MZ_TRUE;
3409 }
3410#endif
3411
3413 {
3414 if (new_size > pArray->m_capacity)
3415 {
3417 return MZ_FALSE;
3418 }
3419 pArray->m_size = new_size;
3420 return MZ_TRUE;
3421 }
3422
3423#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
3425 {
3426 return mz_zip_array_reserve(pZip, pArray, pArray->m_size + n, MZ_TRUE);
3427 }
3428
3430 {
3431 size_t orig_size = pArray->m_size;
3433 return MZ_FALSE;
3434 if (n > 0)
3435 memcpy((mz_uint8 *)pArray->m_p + orig_size * pArray->m_element_size, pElements, n * pArray->m_element_size);
3436 return MZ_TRUE;
3437 }
3438#endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS */
3439
3440#ifndef MINIZ_NO_TIME
3442 {
3443 struct tm tm;
3444 memset(&tm, 0, sizeof(tm));
3445 tm.tm_isdst = -1;
3446 tm.tm_year = ((dos_date >> 9) & 127) + 1980 - 1900;
3447 tm.tm_mon = ((dos_date >> 5) & 15) - 1;
3448 tm.tm_mday = dos_date & 31;
3449 tm.tm_hour = (dos_time >> 11) & 31;
3450 tm.tm_min = (dos_time >> 5) & 63;
3451 tm.tm_sec = (dos_time << 1) & 62;
3452 return mktime(&tm);
3453 }
3454
3455#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
3457 {
3458#ifdef _MSC_VER
3459 struct tm tm_struct;
3460 struct tm *tm = &tm_struct;
3462 if (err)
3463 {
3464 *pDOS_date = 0;
3465 *pDOS_time = 0;
3466 return;
3467 }
3468#else
3469 struct tm *tm = localtime(&time);
3470#endif /* #ifdef _MSC_VER */
3471
3472 *pDOS_time = (mz_uint16)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) + ((tm->tm_sec) >> 1));
3473 *pDOS_date = (mz_uint16)(((tm->tm_year + 1900 - 1980) << 9) + ((tm->tm_mon + 1) << 5) + tm->tm_mday);
3474 }
3475#endif /* MINIZ_NO_ARCHIVE_WRITING_APIS */
3476
3477#ifndef MINIZ_NO_STDIO
3478#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
3480 {
3481 struct MZ_FILE_STAT_STRUCT file_stat;
3482
3483 /* On Linux with x86 glibc, this call will fail on large files (I think >= 0x80000000 bytes) unless you compiled with _LARGEFILE64_SOURCE. Argh. */
3484 if (MZ_FILE_STAT(pFilename, &file_stat) != 0)
3485 return MZ_FALSE;
3486
3487 *pTime = file_stat.st_mtime;
3488
3489 return MZ_TRUE;
3490 }
3491#endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS*/
3492
3494 {
3495 struct utimbuf t;
3496
3497 memset(&t, 0, sizeof(t));
3498 t.actime = access_time;
3499 t.modtime = modified_time;
3500
3501 return !utime(pFilename, &t);
3502 }
3503#endif /* #ifndef MINIZ_NO_STDIO */
3504#endif /* #ifndef MINIZ_NO_TIME */
3505
3507 {
3508 if (pZip)
3509 pZip->m_last_error = err_num;
3510 return MZ_FALSE;
3511 }
3512
3514 {
3515 (void)flags;
3516 if ((!pZip) || (pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
3518
3519 if (!pZip->m_pAlloc)
3521 if (!pZip->m_pFree)
3523 if (!pZip->m_pRealloc)
3525
3526 pZip->m_archive_size = 0;
3528 pZip->m_total_files = 0;
3530
3531 if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state))))
3533
3534 memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state));
3538 pZip->m_pState->m_init_flags = flags;
3539 pZip->m_pState->m_zip64 = MZ_FALSE;
3541
3543
3544 return MZ_TRUE;
3545 }
3546
3565
3566#define MZ_SWAP_UINT32(a, b) \
3567 do \
3568 { \
3569 mz_uint32 t = a; \
3570 a = b; \
3571 b = t; \
3572 } \
3573 MZ_MACRO_END
3574
3575 /* 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.) */
3577 {
3579 const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
3580 const mz_zip_array *pCentral_dir = &pState->m_central_dir;
3582 mz_uint32 start, end;
3583 const mz_uint32 size = pZip->m_total_files;
3584
3585 if (size <= 1U)
3586 return;
3587
3588 pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0);
3589
3590 start = (size - 2U) >> 1U;
3591 for (;;)
3592 {
3593 mz_uint64 child, root = start;
3594 for (;;)
3595 {
3596 if ((child = (root << 1U) + 1U) >= size)
3597 break;
3600 break;
3602 root = child;
3603 }
3604 if (!start)
3605 break;
3606 start--;
3607 }
3608
3609 end = size - 1;
3610 while (end > 0)
3611 {
3612 mz_uint64 child, root = 0;
3614 for (;;)
3615 {
3616 if ((child = (root << 1U) + 1U) >= end)
3617 break;
3620 break;
3622 root = child;
3623 }
3624 end--;
3625 }
3626 }
3627
3629 {
3630 mz_int64 cur_file_ofs;
3631 mz_uint32 buf_u32[4096 / sizeof(mz_uint32)];
3633
3634 /* Basic sanity checks - reject files which are too small */
3635 if (pZip->m_archive_size < record_size)
3636 return MZ_FALSE;
3637
3638 /* Find the record by scanning the file from the end towards the beginning. */
3639 cur_file_ofs = MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)sizeof(buf_u32), 0);
3640 for (;;)
3641 {
3642 int i, n = (int)MZ_MIN(sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs);
3643
3644 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n)
3645 return MZ_FALSE;
3646
3647 for (i = n - 4; i >= 0; --i)
3648 {
3649 mz_uint s = MZ_READ_LE32(pBuf + i);
3650 if (s == record_sig)
3651 {
3652 if ((pZip->m_archive_size - (cur_file_ofs + i)) >= record_size)
3653 break;
3654 }
3655 }
3656
3657 if (i >= 0)
3658 {
3659 cur_file_ofs += i;
3660 break;
3661 }
3662
3663 /* Give up if we've searched the entire file, or we've gone back "too far" (~64kb) */
3664 if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >= ((mz_uint64)(MZ_UINT16_MAX) + record_size)))
3665 return MZ_FALSE;
3666
3667 cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0);
3668 }
3669
3670 *pOfs = cur_file_ofs;
3671 return MZ_TRUE;
3672 }
3673
3686
3688 {
3690 mz_uint64 cdir_ofs = 0, eocd_ofs = 0, archive_ofs = 0;
3691 mz_int64 cur_file_ofs = 0;
3692 const mz_uint8 *p;
3693
3694 mz_uint32 buf_u32[4096 / sizeof(mz_uint32)];
3699
3702
3704
3705 /* 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. */
3708
3711
3712 eocd_ofs = cur_file_ofs;
3713 /* Read and verify the end of central directory record. */
3716
3719
3721 {
3723 {
3725 {
3726 pZip->m_pState->m_zip64 = MZ_TRUE;
3727 }
3728 }
3729 }
3730
3731 if (pZip->m_pState->m_zip64)
3732 {
3733 /* Try locating the EOCD64 right before the EOCD64 locator. This works even
3734 * when the effective start of the zip header is not yet known. */
3735 if (cur_file_ofs < MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE +
3738
3739 zip64_end_of_central_dir_ofs = cur_file_ofs -
3742
3745 {
3746 /* That failed, try reading where the locator tells us to. */
3749
3753
3757 }
3758 }
3759
3766
3767 if (pZip->m_pState->m_zip64)
3768 {
3774
3777
3778 if (zip64_total_num_of_disks != 1U)
3780
3781 /* Check for miniz's practical limits */
3784
3786
3789
3791
3792 /* Check for miniz's current practical limits (sorry, this should be enough for millions of files) */
3795
3797
3799
3801
3803 }
3804
3807
3808 if (((num_this_disk | cdir_disk_index) != 0) && ((num_this_disk != 1) || (cdir_disk_index != 1)))
3810
3813
3814 if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size)
3816
3817 if (eocd_ofs < cdir_ofs + cdir_size)
3819
3820 /* The end of central dir follows the central dir, unless the zip file has
3821 * some trailing data (e.g. it is appended to an executable file). */
3823 if (pZip->m_pState->m_zip64)
3824 {
3828
3831 }
3832
3833 /* Update the archive start position, but only if not specified. */
3834 if ((pZip->m_zip_type == MZ_ZIP_TYPE_FILE || pZip->m_zip_type == MZ_ZIP_TYPE_CFILE ||
3836 {
3838 pZip->m_archive_size -= archive_ofs;
3839 }
3840
3842
3843 if (pZip->m_total_files)
3844 {
3845 mz_uint i, n;
3846 /* 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. */
3850
3851 if (sort_central_dir)
3852 {
3855 }
3856
3859
3860 /* Now create an index into the central directory file records, do some basic sanity checking on each record */
3861 p = (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p;
3862 for (n = cdir_size, i = 0; i < pZip->m_total_files; ++i)
3863 {
3866
3869
3871
3872 if (sort_central_dir)
3874
3880
3882 (ext_data_size) &&
3884 {
3885 /* Attempt to find zip64 extended information field in the entry's extra data */
3887
3889 {
3890 const mz_uint8 *pExtra_data;
3891 void *buf = NULL;
3892
3894 {
3896 if (buf == NULL)
3898
3900 {
3901 MZ_FREE(buf);
3903 }
3904
3906 }
3907 else
3908 {
3910 }
3911
3912 do
3913 {
3916
3917 if (extra_size_remaining < (sizeof(mz_uint16) * 2))
3918 {
3919 MZ_FREE(buf);
3921 }
3922
3925
3926 if ((field_data_size + sizeof(mz_uint16) * 2) > extra_size_remaining)
3927 {
3928 MZ_FREE(buf);
3930 }
3931
3933 {
3934 /* 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). */
3935 pZip->m_pState->m_zip64 = MZ_TRUE;
3937 break;
3938 }
3939
3940 pExtra_data += sizeof(mz_uint16) * 2 + field_data_size;
3942 } while (extra_size_remaining);
3943
3944 MZ_FREE(buf);
3945 }
3946 }
3947
3948 /* I've seen archives that aren't marked as zip64 that uses zip64 ext data, argh */
3950 {
3953 }
3954
3956 if ((disk_index == MZ_UINT16_MAX) || ((disk_index != num_this_disk) && (disk_index != 1)))
3958
3959 if (comp_size != MZ_UINT32_MAX)
3960 {
3963 }
3964
3968
3971
3973 p += total_header_size;
3974 }
3975 }
3976
3977 if (sort_central_dir)
3979
3980 return MZ_TRUE;
3981 }
3982
3984 {
3985 if (pZip)
3986 MZ_CLEAR_PTR(pZip);
3987 }
3988
3990 {
3991 mz_bool status = MZ_TRUE;
3992
3993 if (!pZip)
3994 return MZ_FALSE;
3995
3996 if ((!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
3997 {
3998 if (set_last_error)
4000
4001 return MZ_FALSE;
4002 }
4003
4004 if (pZip->m_pState)
4005 {
4007 pZip->m_pState = NULL;
4008
4009 mz_zip_array_clear(pZip, &pState->m_central_dir);
4010 mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
4011 mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets);
4012
4013#ifndef MINIZ_NO_STDIO
4014 if (pState->m_pFile)
4015 {
4016 if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE)
4017 {
4018 if (MZ_FCLOSE(pState->m_pFile) == EOF)
4019 {
4020 if (set_last_error)
4022 status = MZ_FALSE;
4023 }
4024 }
4025 pState->m_pFile = NULL;
4026 }
4027#endif /* #ifndef MINIZ_NO_STDIO */
4028
4029 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
4030 }
4032
4033 return status;
4034 }
4035
4041 {
4042 if ((!pZip) || (!pZip->m_pRead))
4044
4045 if (!mz_zip_reader_init_internal(pZip, flags))
4046 return MZ_FALSE;
4047
4049 pZip->m_archive_size = size;
4050
4051 if (!mz_zip_reader_read_central_dir(pZip, flags))
4052 {
4054 return MZ_FALSE;
4055 }
4056
4057 return MZ_TRUE;
4058 }
4059
4060 static size_t mz_zip_mem_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
4061 {
4063 size_t s = (file_ofs >= pZip->m_archive_size) ? 0 : (size_t)MZ_MIN(pZip->m_archive_size - file_ofs, n);
4064 memcpy(pBuf, (const mz_uint8 *)pZip->m_pState->m_pMem + file_ofs, s);
4065 return s;
4066 }
4067
4068 mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint flags)
4069 {
4070 if (!pMem)
4072
4075
4076 if (!mz_zip_reader_init_internal(pZip, flags))
4077 return MZ_FALSE;
4078
4080 pZip->m_archive_size = size;
4082 pZip->m_pIO_opaque = pZip;
4083 pZip->m_pNeeds_keepalive = NULL;
4084
4085#ifdef __cplusplus
4086 pZip->m_pState->m_pMem = const_cast<void *>(pMem);
4087#else
4088 pZip->m_pState->m_pMem = (void *)pMem;
4089#endif
4090
4091 pZip->m_pState->m_mem_size = size;
4092
4093 if (!mz_zip_reader_read_central_dir(pZip, flags))
4094 {
4096 return MZ_FALSE;
4097 }
4098
4099 return MZ_TRUE;
4100 }
4101
4102#ifndef MINIZ_NO_STDIO
4103 static size_t mz_zip_file_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
4104 {
4107
4109
4111 return 0;
4112
4113 return MZ_FREAD(pBuf, 1, n, pZip->m_pState->m_pFile);
4114 }
4115
4117 {
4118 return mz_zip_reader_init_file_v2(pZip, pFilename, flags, 0, 0);
4119 }
4120
4122 {
4124 MZ_FILE *pFile;
4125
4128
4129 pFile = MZ_FOPEN(pFilename, (flags & MZ_ZIP_FLAG_READ_ALLOW_WRITING ) ? "r+b" : "rb");
4130 if (!pFile)
4132
4134 if (!file_size)
4135 {
4136 if (MZ_FSEEK64(pFile, 0, SEEK_END))
4137 {
4140 }
4141
4143 }
4144
4145 /* TODO: Better sanity check archive_size and the # of actual remaining bytes */
4146
4148 {
4151 }
4152
4153 if (!mz_zip_reader_init_internal(pZip, flags))
4154 {
4156 return MZ_FALSE;
4157 }
4158
4161 pZip->m_pIO_opaque = pZip;
4162 pZip->m_pState->m_pFile = pFile;
4163 pZip->m_archive_size = file_size;
4165
4166 if (!mz_zip_reader_read_central_dir(pZip, flags))
4167 {
4169 return MZ_FALSE;
4170 }
4171
4172 return MZ_TRUE;
4173 }
4174
4176 {
4177 mz_uint64 cur_file_ofs;
4178
4179 if ((!pZip) || (!pFile))
4181
4182 cur_file_ofs = MZ_FTELL64(pFile);
4183
4184 if (!archive_size)
4185 {
4186 if (MZ_FSEEK64(pFile, 0, SEEK_END))
4188
4189 archive_size = MZ_FTELL64(pFile) - cur_file_ofs;
4190
4193 }
4194
4195 if (!mz_zip_reader_init_internal(pZip, flags))
4196 return MZ_FALSE;
4197
4200
4201 pZip->m_pIO_opaque = pZip;
4202 pZip->m_pState->m_pFile = pFile;
4204 pZip->m_pState->m_file_archive_start_ofs = cur_file_ofs;
4205
4206 if (!mz_zip_reader_read_central_dir(pZip, flags))
4207 {
4209 return MZ_FALSE;
4210 }
4211
4212 return MZ_TRUE;
4213 }
4214
4215#endif /* #ifndef MINIZ_NO_STDIO */
4216
4223
4225 {
4226 mz_uint m_bit_flag;
4227 const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
4228 if (!p)
4229 {
4231 return MZ_FALSE;
4232 }
4233
4234 m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
4236 }
4237
4239 {
4241 mz_uint method;
4242
4243 const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
4244 if (!p)
4245 {
4247 return MZ_FALSE;
4248 }
4249
4250 method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS);
4252
4253 if ((method != 0) && (method != MZ_DEFLATED))
4254 {
4256 return MZ_FALSE;
4257 }
4258
4260 {
4262 return MZ_FALSE;
4263 }
4264
4266 {
4268 return MZ_FALSE;
4269 }
4270
4271 return MZ_TRUE;
4272 }
4273
4275 {
4277 const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
4278 if (!p)
4279 {
4281 return MZ_FALSE;
4282 }
4283
4285 if (filename_len)
4286 {
4287 if (*(p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_len - 1) == '/')
4288 return MZ_TRUE;
4289 }
4290
4291 /* Bugfix: This code was also checking if the internal attribute was non-zero, which wasn't correct. */
4292 /* 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. */
4293 /* FIXME: Remove this check? Is it necessary - we already check the filename. */
4296
4299 {
4300 return MZ_TRUE;
4301 }
4302
4303 return MZ_FALSE;
4304 }
4305
4307 {
4308 mz_uint n;
4309 const mz_uint8 *p = pCentral_dir_header;
4310
4313
4314 if ((!p) || (!pStat))
4316
4317 /* Extract fields from the central directory record. */
4318 pStat->m_file_index = file_index;
4320 pStat->m_version_made_by = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS);
4321 pStat->m_version_needed = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_NEEDED_OFS);
4322 pStat->m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
4323 pStat->m_method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS);
4324#ifndef MINIZ_NO_TIME
4326#endif
4327 pStat->m_crc32 = MZ_READ_LE32(p + MZ_ZIP_CDH_CRC32_OFS);
4330 pStat->m_internal_attr = MZ_READ_LE16(p + MZ_ZIP_CDH_INTERNAL_ATTR_OFS);
4331 pStat->m_external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS);
4332 pStat->m_local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
4333
4334 /* Copy as much of the filename and comment as possible. */
4337 memcpy(pStat->m_filename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n);
4338 pStat->m_filename[n] = '\0';
4339
4342 pStat->m_comment_size = n;
4344 pStat->m_comment[n] = '\0';
4345
4346 /* Set some flags for convienance */
4347 pStat->m_is_directory = mz_zip_reader_is_file_a_directory(pZip, file_index);
4348 pStat->m_is_encrypted = mz_zip_reader_is_file_encrypted(pZip, file_index);
4349 pStat->m_is_supported = mz_zip_reader_is_file_supported(pZip, file_index);
4350
4351 /* See if we need to read any zip64 extended information fields. */
4352 /* 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). */
4353 if (MZ_MAX(MZ_MAX(pStat->m_comp_size, pStat->m_uncomp_size), pStat->m_local_header_ofs) == MZ_UINT32_MAX)
4354 {
4355 /* Attempt to find zip64 extended information field in the entry's extra data */
4357
4359 {
4361
4362 do
4363 {
4366
4367 if (extra_size_remaining < (sizeof(mz_uint16) * 2))
4369
4372
4373 if ((field_data_size + sizeof(mz_uint16) * 2) > extra_size_remaining)
4375
4377 {
4378 const mz_uint8 *pField_data = pExtra_data + sizeof(mz_uint16) * 2;
4380
4383
4384 if (pStat->m_uncomp_size == MZ_UINT32_MAX)
4385 {
4386 if (field_data_remaining < sizeof(mz_uint64))
4388
4389 pStat->m_uncomp_size = MZ_READ_LE64(pField_data);
4390 pField_data += sizeof(mz_uint64);
4392 }
4393
4394 if (pStat->m_comp_size == MZ_UINT32_MAX)
4395 {
4396 if (field_data_remaining < sizeof(mz_uint64))
4398
4399 pStat->m_comp_size = MZ_READ_LE64(pField_data);
4400 pField_data += sizeof(mz_uint64);
4402 }
4403
4404 if (pStat->m_local_header_ofs == MZ_UINT32_MAX)
4405 {
4406 if (field_data_remaining < sizeof(mz_uint64))
4408
4409 pStat->m_local_header_ofs = MZ_READ_LE64(pField_data);
4410 pField_data += sizeof(mz_uint64);
4412 }
4413
4414 break;
4415 }
4416
4417 pExtra_data += sizeof(mz_uint16) * 2 + field_data_size;
4419 } while (extra_size_remaining);
4420 }
4421 }
4422
4423 return MZ_TRUE;
4424 }
4425
4426 static MZ_FORCEINLINE mz_bool mz_zip_string_equal(const char *pA, const char *pB, mz_uint len, mz_uint flags)
4427 {
4428 mz_uint i;
4429 if (flags & MZ_ZIP_FLAG_CASE_SENSITIVE)
4430 return 0 == memcmp(pA, pB, len);
4431 for (i = 0; i < len; ++i)
4432 if (MZ_TOLOWER(pA[i]) != MZ_TOLOWER(pB[i]))
4433 return MZ_FALSE;
4434 return MZ_TRUE;
4435 }
4436
4438 {
4441 mz_uint8 l = 0, r = 0;
4443 pE = pL + MZ_MIN(l_len, r_len);
4444 while (pL < pE)
4445 {
4446 if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR)))
4447 break;
4448 pL++;
4449 pR++;
4450 }
4451 return (pL == pE) ? (int)(l_len - r_len) : (l - r);
4452 }
4453
4455 {
4457 const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
4458 const mz_zip_array *pCentral_dir = &pState->m_central_dir;
4459 mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0);
4460 const mz_uint32 size = pZip->m_total_files;
4462
4463 if (pIndex)
4464 *pIndex = 0;
4465
4466 if (size)
4467 {
4468 /* yes I could use uint32_t's, but then we would have to add some special case checks in the loop, argh, and */
4469 /* honestly the major expense here on 32-bit CPU's will still be the filename compare */
4470 mz_int64 l = 0, h = (mz_int64)size - 1;
4471
4472 while (l <= h)
4473 {
4474 mz_int64 m = l + ((h - l) >> 1);
4476
4478 if (!comp)
4479 {
4480 if (pIndex)
4481 *pIndex = file_index;
4482 return MZ_TRUE;
4483 }
4484 else if (comp < 0)
4485 l = m + 1;
4486 else
4487 h = m - 1;
4488 }
4489 }
4490
4492 }
4493
4494 int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags)
4495 {
4496 mz_uint32 index;
4497 if (!mz_zip_reader_locate_file_v2(pZip, pName, pComment, flags, &index))
4498 return -1;
4499 else
4500 return (int)index;
4501 }
4502
4504 {
4506 size_t name_len, comment_len;
4507
4508 if (pIndex)
4509 *pIndex = 0;
4510
4511 if ((!pZip) || (!pZip->m_pState) || (!pName))
4513
4514 /* See if we can use a binary search */
4516 (pZip->m_zip_mode == MZ_ZIP_MODE_READING) &&
4518 {
4520 }
4521
4522 /* Locate the entry by scanning the entire central directory */
4524 if (name_len > MZ_UINT16_MAX)
4526
4530
4531 for (file_index = 0; file_index < pZip->m_total_files; file_index++)
4532 {
4535 const char *pFilename = (const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
4536 if (filename_len < name_len)
4537 continue;
4538 if (comment_len)
4539 {
4543 continue;
4544 }
4545 if ((flags & MZ_ZIP_FLAG_IGNORE_PATH) && (filename_len))
4546 {
4547 int ofs = filename_len - 1;
4548 do
4549 {
4550 if ((pFilename[ofs] == '/') || (pFilename[ofs] == '\\') || (pFilename[ofs] == ':'))
4551 break;
4552 } while (--ofs >= 0);
4553 ofs++;
4554 pFilename += ofs;
4555 filename_len -= ofs;
4556 }
4558 {
4559 if (pIndex)
4560 *pIndex = file_index;
4561 return MZ_TRUE;
4562 }
4563 }
4564
4566 }
4567
4569 {
4570 int status = TINFL_STATUS_DONE;
4571 mz_uint64 needed_size, cur_file_ofs, comp_remaining, out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail;
4572 mz_zip_archive_file_stat file_stat;
4573 void *pRead_buf;
4576 tinfl_decompressor inflator;
4577
4578 if ((!pZip) || (!pZip->m_pState) || ((buf_size) && (!pBuf)) || ((user_read_buf_size) && (!pUser_read_buf)) || (!pZip->m_pRead))
4580
4581 if (st)
4582 {
4583 file_stat = *st;
4584 }
4585 else if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
4586 return MZ_FALSE;
4587
4588 /* A directory or zero length file */
4589 if ((file_stat.m_is_directory) || (!file_stat.m_comp_size))
4590 return MZ_TRUE;
4591
4592 /* Encryption and patch files are not supported. */
4595
4596 /* This function only supports decompressing stored and deflate. */
4597 if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
4599
4600 /* Ensure supplied output buffer is large enough. */
4601 needed_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size : file_stat.m_uncomp_size;
4602 if (buf_size < needed_size)
4604
4605 /* Read and parse the local directory entry. */
4606 cur_file_ofs = file_stat.m_local_header_ofs;
4609
4612
4614 if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
4616
4617 if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method))
4618 {
4619 /* The file is stored or the caller has requested the compressed data. */
4620 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, (size_t)needed_size) != needed_size)
4622
4623#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4624 if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) == 0)
4625 {
4626 if (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32)
4628 }
4629#endif
4630
4631 return MZ_TRUE;
4632 }
4633
4634 /* Decompress the file either directly from memory or from a file input buffer. */
4635 tinfl_init(&inflator);
4636
4637 if (pZip->m_pState->m_pMem)
4638 {
4639 /* Read directly from the archive in memory. */
4640 pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
4641 read_buf_size = read_buf_avail = file_stat.m_comp_size;
4642 comp_remaining = 0;
4643 }
4644 else if (pUser_read_buf)
4645 {
4646 /* Use a user provided read buffer. */
4647 if (!user_read_buf_size)
4648 return MZ_FALSE;
4649 pRead_buf = (mz_uint8 *)pUser_read_buf;
4650 read_buf_size = user_read_buf_size;
4651 read_buf_avail = 0;
4652 comp_remaining = file_stat.m_comp_size;
4653 }
4654 else
4655 {
4656 /* Temporarily allocate a read buffer. */
4657 read_buf_size = MZ_MIN(file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
4658 if (((sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
4660
4661 if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size)))
4663
4664 read_buf_avail = 0;
4665 comp_remaining = file_stat.m_comp_size;
4666 }
4667
4668 do
4669 {
4670 /* The size_t cast here should be OK because we've verified that the output buffer is >= file_stat.m_uncomp_size above */
4671 size_t in_buf_size, out_buf_size = (size_t)(file_stat.m_uncomp_size - out_buf_ofs);
4672 if ((!read_buf_avail) && (!pZip->m_pState->m_pMem))
4673 {
4674 read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
4675 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
4676 {
4677 status = TINFL_STATUS_FAILED;
4679 break;
4680 }
4681 cur_file_ofs += read_buf_avail;
4682 comp_remaining -= read_buf_avail;
4683 read_buf_ofs = 0;
4684 }
4685 in_buf_size = (size_t)read_buf_avail;
4686 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));
4687 read_buf_avail -= in_buf_size;
4688 read_buf_ofs += in_buf_size;
4689 out_buf_ofs += out_buf_size;
4690 } while (status == TINFL_STATUS_NEEDS_MORE_INPUT);
4691
4692 if (status == TINFL_STATUS_DONE)
4693 {
4694 /* Make sure the entire file was decompressed, and check its CRC. */
4695 if (out_buf_ofs != file_stat.m_uncomp_size)
4696 {
4698 status = TINFL_STATUS_FAILED;
4699 }
4700#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4701 else if (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32)
4702 {
4704 status = TINFL_STATUS_FAILED;
4705 }
4706#endif
4707 }
4708
4709 if ((!pZip->m_pState->m_pMem) && (!pUser_read_buf))
4710 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
4711
4712 return status == TINFL_STATUS_DONE;
4713 }
4714
4719
4727
4732
4737
4739 {
4740 mz_zip_archive_file_stat file_stat;
4742 void *pBuf;
4743
4744 if (pSize)
4745 *pSize = 0;
4746
4747 if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
4748 return NULL;
4749
4750 alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size : file_stat.m_uncomp_size;
4751 if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
4752 {
4754 return NULL;
4755 }
4756
4757 if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size)))
4758 {
4760 return NULL;
4761 }
4762
4763 if (!mz_zip_reader_extract_to_mem_no_alloc1(pZip, file_index, pBuf, (size_t)alloc_size, flags, NULL, 0, &file_stat))
4764 {
4765 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
4766 return NULL;
4767 }
4768
4769 if (pSize)
4771 return pBuf;
4772 }
4773
4775 {
4778 {
4779 if (pSize)
4780 *pSize = 0;
4781 return MZ_FALSE;
4782 }
4783 return mz_zip_reader_extract_to_heap(pZip, file_index, pSize, flags);
4784 }
4785
4787 {
4788 int status = TINFL_STATUS_DONE;
4789#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4790 mz_uint file_crc32 = MZ_CRC32_INIT;
4791#endif
4792 mz_uint64 read_buf_size, read_buf_ofs = 0, read_buf_avail, comp_remaining, out_buf_ofs = 0, cur_file_ofs;
4793 mz_zip_archive_file_stat file_stat;
4794 void *pRead_buf = NULL;
4795 void *pWrite_buf = NULL;
4798
4799 if ((!pZip) || (!pZip->m_pState) || (!pCallback) || (!pZip->m_pRead))
4801
4802 if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
4803 return MZ_FALSE;
4804
4805 /* A directory or zero length file */
4806 if ((file_stat.m_is_directory) || (!file_stat.m_comp_size))
4807 return MZ_TRUE;
4808
4809 /* Encryption and patch files are not supported. */
4812
4813 /* This function only supports decompressing stored and deflate. */
4814 if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
4816
4817 /* 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) */
4818 cur_file_ofs = file_stat.m_local_header_ofs;
4821
4824
4826 if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
4828
4829 /* Decompress the file either directly from memory or from a file input buffer. */
4830 if (pZip->m_pState->m_pMem)
4831 {
4832 pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
4833 read_buf_size = read_buf_avail = file_stat.m_comp_size;
4834 comp_remaining = 0;
4835 }
4836 else
4837 {
4838 read_buf_size = MZ_MIN(file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
4839 if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size)))
4841
4842 read_buf_avail = 0;
4843 comp_remaining = file_stat.m_comp_size;
4844 }
4845
4846 if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method))
4847 {
4848 /* The file is stored or the caller has requested the compressed data. */
4849 if (pZip->m_pState->m_pMem)
4850 {
4851 if (((sizeof(size_t) == sizeof(mz_uint32))) && (file_stat.m_comp_size > MZ_UINT32_MAX))
4853
4854 if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)file_stat.m_comp_size) != file_stat.m_comp_size)
4855 {
4857 status = TINFL_STATUS_FAILED;
4858 }
4859 else if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
4860 {
4861#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4862 file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)file_stat.m_comp_size);
4863#endif
4864 }
4865
4866 cur_file_ofs += file_stat.m_comp_size;
4867 out_buf_ofs += file_stat.m_comp_size;
4868 comp_remaining = 0;
4869 }
4870 else
4871 {
4872 while (comp_remaining)
4873 {
4874 read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
4875 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
4876 {
4878 status = TINFL_STATUS_FAILED;
4879 break;
4880 }
4881
4882#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4883 if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
4884 {
4885 file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)read_buf_avail);
4886 }
4887#endif
4888
4889 if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
4890 {
4892 status = TINFL_STATUS_FAILED;
4893 break;
4894 }
4895
4896 cur_file_ofs += read_buf_avail;
4897 out_buf_ofs += read_buf_avail;
4898 comp_remaining -= read_buf_avail;
4899 }
4900 }
4901 }
4902 else
4903 {
4904 tinfl_decompressor inflator;
4905 tinfl_init(&inflator);
4906
4907 if (NULL == (pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, TINFL_LZ_DICT_SIZE)))
4908 {
4910 status = TINFL_STATUS_FAILED;
4911 }
4912 else
4913 {
4914 do
4915 {
4916 mz_uint8 *pWrite_buf_cur = (mz_uint8 *)pWrite_buf + (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
4917 size_t in_buf_size, out_buf_size = TINFL_LZ_DICT_SIZE - (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
4918 if ((!read_buf_avail) && (!pZip->m_pState->m_pMem))
4919 {
4920 read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
4921 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
4922 {
4924 status = TINFL_STATUS_FAILED;
4925 break;
4926 }
4927 cur_file_ofs += read_buf_avail;
4928 comp_remaining -= read_buf_avail;
4929 read_buf_ofs = 0;
4930 }
4931
4932 in_buf_size = (size_t)read_buf_avail;
4933 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);
4934 read_buf_avail -= in_buf_size;
4935 read_buf_ofs += in_buf_size;
4936
4937 if (out_buf_size)
4938 {
4940 {
4942 status = TINFL_STATUS_FAILED;
4943 break;
4944 }
4945
4946#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4947 file_crc32 = (mz_uint32)mz_crc32(file_crc32, pWrite_buf_cur, out_buf_size);
4948#endif
4949 if ((out_buf_ofs += out_buf_size) > file_stat.m_uncomp_size)
4950 {
4952 status = TINFL_STATUS_FAILED;
4953 break;
4954 }
4955 }
4956 } while ((status == TINFL_STATUS_NEEDS_MORE_INPUT) || (status == TINFL_STATUS_HAS_MORE_OUTPUT));
4957 }
4958 }
4959
4960 if ((status == TINFL_STATUS_DONE) && (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)))
4961 {
4962 /* Make sure the entire file was decompressed, and check its CRC. */
4963 if (out_buf_ofs != file_stat.m_uncomp_size)
4964 {
4966 status = TINFL_STATUS_FAILED;
4967 }
4968#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4969 else if (file_crc32 != file_stat.m_crc32)
4970 {
4972 status = TINFL_STATUS_FAILED;
4973 }
4974#endif
4975 }
4976
4977 if (!pZip->m_pState->m_pMem)
4978 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
4979
4980 if (pWrite_buf)
4981 pZip->m_pFree(pZip->m_pAlloc_opaque, pWrite_buf);
4982
4983 return status == TINFL_STATUS_DONE;
4984 }
4985
4994
4996 {
5000
5001 /* Argument sanity check */
5002 if ((!pZip) || (!pZip->m_pState))
5003 return NULL;
5004
5005 /* Allocate an iterator status structure */
5007 if (!pState)
5008 {
5010 return NULL;
5011 }
5012
5013 /* Fetch file details */
5014 if (!mz_zip_reader_file_stat(pZip, file_index, &pState->file_stat))
5015 {
5016 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5017 return NULL;
5018 }
5019
5020 /* Encryption and patch files are not supported. */
5022 {
5024 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5025 return NULL;
5026 }
5027
5028 /* This function only supports decompressing stored and deflate. */
5029 if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (pState->file_stat.m_method != 0) && (pState->file_stat.m_method != MZ_DEFLATED))
5030 {
5032 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5033 return NULL;
5034 }
5035
5036 /* Init state - save args */
5037 pState->pZip = pZip;
5038 pState->flags = flags;
5039
5040 /* Init state - reset variables to defaults */
5041 pState->status = TINFL_STATUS_DONE;
5042#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
5043 pState->file_crc32 = MZ_CRC32_INIT;
5044#endif
5045 pState->read_buf_ofs = 0;
5046 pState->out_buf_ofs = 0;
5047 pState->pRead_buf = NULL;
5048 pState->pWrite_buf = NULL;
5049 pState->out_blk_remain = 0;
5050
5051 /* Read and parse the local directory entry. */
5052 pState->cur_file_ofs = pState->file_stat.m_local_header_ofs;
5054 {
5056 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5057 return NULL;
5058 }
5059
5061 {
5063 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5064 return NULL;
5065 }
5066
5068 if ((pState->cur_file_ofs + pState->file_stat.m_comp_size) > pZip->m_archive_size)
5069 {
5071 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5072 return NULL;
5073 }
5074
5075 /* Decompress the file either directly from memory or from a file input buffer. */
5076 if (pZip->m_pState->m_pMem)
5077 {
5078 pState->pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + pState->cur_file_ofs;
5079 pState->read_buf_size = pState->read_buf_avail = pState->file_stat.m_comp_size;
5080 pState->comp_remaining = pState->file_stat.m_comp_size;
5081 }
5082 else
5083 {
5084 if (!((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!pState->file_stat.m_method)))
5085 {
5086 /* Decompression required, therefore intermediate read buffer required */
5087 pState->read_buf_size = MZ_MIN(pState->file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
5088 if (NULL == (pState->pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)pState->read_buf_size)))
5089 {
5091 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5092 return NULL;
5093 }
5094 }
5095 else
5096 {
5097 /* Decompression not required - we will be reading directly into user buffer, no temp buf required */
5098 pState->read_buf_size = 0;
5099 }
5100 pState->read_buf_avail = 0;
5101 pState->comp_remaining = pState->file_stat.m_comp_size;
5102 }
5103
5104 if (!((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!pState->file_stat.m_method)))
5105 {
5106 /* Decompression required, init decompressor */
5107 tinfl_init(&pState->inflator);
5108
5109 /* Allocate write buffer */
5110 if (NULL == (pState->pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, TINFL_LZ_DICT_SIZE)))
5111 {
5113 if (pState->pRead_buf)
5114 pZip->m_pFree(pZip->m_pAlloc_opaque, pState->pRead_buf);
5115 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5116 return NULL;
5117 }
5118 }
5119
5120 return pState;
5121 }
5122
5124 {
5126
5127 /* Locate file index by name */
5129 return NULL;
5130
5131 /* Construct iterator */
5132 return mz_zip_reader_extract_iter_new(pZip, file_index, flags);
5133 }
5134
5136 {
5137 size_t copied_to_caller = 0;
5138
5139 /* Argument sanity check */
5140 if ((!pState) || (!pState->pZip) || (!pState->pZip->m_pState) || (!pvBuf))
5141 return 0;
5142
5143 if ((pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!pState->file_stat.m_method))
5144 {
5145 /* The file is stored or the caller has requested the compressed data, calc amount to return. */
5146 copied_to_caller = (size_t)MZ_MIN(buf_size, pState->comp_remaining);
5147
5148 /* Zip is in memory....or requires reading from a file? */
5149 if (pState->pZip->m_pState->m_pMem)
5150 {
5151 /* Copy data to caller's buffer */
5152 memcpy(pvBuf, pState->pRead_buf, copied_to_caller);
5153 pState->pRead_buf = ((mz_uint8 *)pState->pRead_buf) + copied_to_caller;
5154 }
5155 else
5156 {
5157 /* Read directly into caller's buffer */
5158 if (pState->pZip->m_pRead(pState->pZip->m_pIO_opaque, pState->cur_file_ofs, pvBuf, copied_to_caller) != copied_to_caller)
5159 {
5160 /* Failed to read all that was asked for, flag failure and alert user */
5162 pState->status = TINFL_STATUS_FAILED;
5163 copied_to_caller = 0;
5164 }
5165 }
5166
5167#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
5168 /* Compute CRC if not returning compressed data only */
5169 if (!(pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
5170 pState->file_crc32 = (mz_uint32)mz_crc32(pState->file_crc32, (const mz_uint8 *)pvBuf, copied_to_caller);
5171#endif
5172
5173 /* Advance offsets, dec counters */
5174 pState->cur_file_ofs += copied_to_caller;
5175 pState->out_buf_ofs += copied_to_caller;
5176 pState->comp_remaining -= copied_to_caller;
5177 }
5178 else
5179 {
5180 do
5181 {
5182 /* Calc ptr to write buffer - given current output pos and block size */
5183 mz_uint8 *pWrite_buf_cur = (mz_uint8 *)pState->pWrite_buf + (pState->out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
5184
5185 /* Calc max output size - given current output pos and block size */
5186 size_t in_buf_size, out_buf_size = TINFL_LZ_DICT_SIZE - (pState->out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
5187
5188 if (!pState->out_blk_remain)
5189 {
5190 /* Read more data from file if none available (and reading from file) */
5191 if ((!pState->read_buf_avail) && (!pState->pZip->m_pState->m_pMem))
5192 {
5193 /* Calc read size */
5194 pState->read_buf_avail = MZ_MIN(pState->read_buf_size, pState->comp_remaining);
5195 if (pState->pZip->m_pRead(pState->pZip->m_pIO_opaque, pState->cur_file_ofs, pState->pRead_buf, (size_t)pState->read_buf_avail) != pState->read_buf_avail)
5196 {
5198 pState->status = TINFL_STATUS_FAILED;
5199 break;
5200 }
5201
5202 /* Advance offsets, dec counters */
5203 pState->cur_file_ofs += pState->read_buf_avail;
5204 pState->comp_remaining -= pState->read_buf_avail;
5205 pState->read_buf_ofs = 0;
5206 }
5207
5208 /* Perform decompression */
5209 in_buf_size = (size_t)pState->read_buf_avail;
5210 pState->status = tinfl_decompress(&pState->inflator, (const mz_uint8 *)pState->pRead_buf + pState->read_buf_ofs, &in_buf_size, (mz_uint8 *)pState->pWrite_buf, pWrite_buf_cur, &out_buf_size, pState->comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0);
5211 pState->read_buf_avail -= in_buf_size;
5212 pState->read_buf_ofs += in_buf_size;
5213
5214 /* Update current output block size remaining */
5215 pState->out_blk_remain = out_buf_size;
5216 }
5217
5218 if (pState->out_blk_remain)
5219 {
5220 /* Calc amount to return. */
5221 size_t to_copy = MZ_MIN((buf_size - copied_to_caller), pState->out_blk_remain);
5222
5223 /* Copy data to caller's buffer */
5225
5226#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
5227 /* Perform CRC */
5228 pState->file_crc32 = (mz_uint32)mz_crc32(pState->file_crc32, pWrite_buf_cur, to_copy);
5229#endif
5230
5231 /* Decrement data consumed from block */
5232 pState->out_blk_remain -= to_copy;
5233
5234 /* Inc output offset, while performing sanity check */
5235 if ((pState->out_buf_ofs += to_copy) > pState->file_stat.m_uncomp_size)
5236 {
5238 pState->status = TINFL_STATUS_FAILED;
5239 break;
5240 }
5241
5242 /* Increment counter of data copied to caller */
5244 }
5246 }
5247
5248 /* Return how many bytes were copied into user buffer */
5249 return copied_to_caller;
5250 }
5251
5253 {
5254 int status;
5255
5256 /* Argument sanity check */
5257 if ((!pState) || (!pState->pZip) || (!pState->pZip->m_pState))
5258 return MZ_FALSE;
5259
5260 /* Was decompression completed and requested? */
5261 if ((pState->status == TINFL_STATUS_DONE) && (!(pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA)))
5262 {
5263 /* Make sure the entire file was decompressed, and check its CRC. */
5264 if (pState->out_buf_ofs != pState->file_stat.m_uncomp_size)
5265 {
5267 pState->status = TINFL_STATUS_FAILED;
5268 }
5269#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
5270 else if (pState->file_crc32 != pState->file_stat.m_crc32)
5271 {
5273 pState->status = TINFL_STATUS_FAILED;
5274 }
5275#endif
5276 }
5277
5278 /* Free buffers */
5279 if (!pState->pZip->m_pState->m_pMem)
5280 pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState->pRead_buf);
5281 if (pState->pWrite_buf)
5282 pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState->pWrite_buf);
5283
5284 /* Save status */
5285 status = pState->status;
5286
5287 /* Free context */
5288 pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState);
5289
5290 return status == TINFL_STATUS_DONE;
5291 }
5292
5293#ifndef MINIZ_NO_STDIO
5294 static size_t mz_zip_file_write_callback(void *pOpaque, mz_uint64 ofs, const void *pBuf, size_t n)
5295 {
5296 (void)ofs;
5297
5298 return MZ_FWRITE(pBuf, 1, n, (MZ_FILE *)pOpaque);
5299 }
5300
5302 {
5303 mz_bool status;
5304 mz_zip_archive_file_stat file_stat;
5305 MZ_FILE *pFile;
5306
5307 if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
5308 return MZ_FALSE;
5309
5310 if ((file_stat.m_is_directory) || (!file_stat.m_is_supported))
5312
5313 pFile = MZ_FOPEN(pDst_filename, "wb");
5314 if (!pFile)
5316
5318
5319 if (MZ_FCLOSE(pFile) == EOF)
5320 {
5321 if (status)
5323
5324 status = MZ_FALSE;
5325 }
5326
5327#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_STDIO)
5328 if (status)
5329 mz_zip_set_file_times(pDst_filename, file_stat.m_time, file_stat.m_time);
5330#endif
5331
5332 return status;
5333 }
5334
5343
5345 {
5346 mz_zip_archive_file_stat file_stat;
5347
5348 if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
5349 return MZ_FALSE;
5350
5351 if ((file_stat.m_is_directory) || (!file_stat.m_is_supported))
5353
5355 }
5356
5365#endif /* #ifndef MINIZ_NO_STDIO */
5366
5367 static size_t mz_zip_compute_crc32_callback(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
5368 {
5369 mz_uint32 *p = (mz_uint32 *)pOpaque;
5370 (void)file_ofs;
5371 *p = (mz_uint32)mz_crc32(*p, (const mz_uint8 *)pBuf, n);
5372 return n;
5373 }
5374
5376 {
5377 mz_zip_archive_file_stat file_stat;
5390
5393
5394 if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (!pZip->m_pRead))
5396
5397 if (file_index > pZip->m_total_files)
5399
5400 pState = pZip->m_pState;
5401
5403
5405 return MZ_FALSE;
5406
5407 /* A directory or zero length file */
5408 if ((file_stat.m_is_directory) || (!file_stat.m_uncomp_size))
5409 return MZ_TRUE;
5410
5411 /* Encryption and patch files are not supported. */
5412 if (file_stat.m_is_encrypted)
5414
5415 /* This function only supports stored and deflate. */
5416 if ((file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
5418
5419 if (!file_stat.m_is_supported)
5421
5422 /* Read and parse the local directory entry. */
5426
5429
5437
5440
5443
5445 {
5447 goto handle_failure;
5448 }
5449
5451 {
5453 {
5455 goto handle_failure;
5456 }
5457
5458 /* 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. */
5460 {
5462 goto handle_failure;
5463 }
5464 }
5465
5467 {
5469 const mz_uint8 *pExtra_data = (const mz_uint8 *)file_data_array.m_p;
5470
5472 {
5474 goto handle_failure;
5475 }
5476
5477 do
5478 {
5480
5481 if (extra_size_remaining < (sizeof(mz_uint16) * 2))
5482 {
5484 goto handle_failure;
5485 }
5486
5490
5492 {
5494 goto handle_failure;
5495 }
5496
5498 {
5499 const mz_uint8 *pSrc_field_data = pExtra_data + sizeof(mz_uint32);
5500
5501 if (field_data_size < sizeof(mz_uint64) * 2)
5502 {
5504 goto handle_failure;
5505 }
5506
5509
5511 break;
5512 }
5513
5516 } while (extra_size_remaining);
5517 }
5518
5519 /* TODO: parse local header extra data when local_header_comp_size is 0xFFFFFFFF! (big_descriptor.zip) */
5520 /* I've seen zips in the wild with the data descriptor bit set, but proper local header values and bogus data descriptors */
5522 {
5525 const mz_uint8 *pSrc;
5526 mz_uint32 file_crc32;
5528
5530
5532 {
5534 goto handle_failure;
5535 }
5536
5539
5540 file_crc32 = MZ_READ_LE32(pSrc);
5541
5542 if ((pState->m_zip64) || (found_zip64_ext_data_in_ldir))
5543 {
5544 comp_size = MZ_READ_LE64(pSrc + sizeof(mz_uint32));
5545 uncomp_size = MZ_READ_LE64(pSrc + sizeof(mz_uint32) + sizeof(mz_uint64));
5546 }
5547 else
5548 {
5549 comp_size = MZ_READ_LE32(pSrc + sizeof(mz_uint32));
5550 uncomp_size = MZ_READ_LE32(pSrc + sizeof(mz_uint32) + sizeof(mz_uint32));
5551 }
5552
5553 if ((file_crc32 != file_stat.m_crc32) || (comp_size != file_stat.m_comp_size) || (uncomp_size != file_stat.m_uncomp_size))
5554 {
5556 goto handle_failure;
5557 }
5558 }
5559 else
5560 {
5561 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))
5562 {
5564 goto handle_failure;
5565 }
5566 }
5567
5569
5570 if ((flags & MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY) == 0)
5571 {
5573 return MZ_FALSE;
5574
5575 /* 1 more check to be sure, although the extract checks too. */
5576 if (uncomp_crc32 != file_stat.m_crc32)
5577 {
5579 return MZ_FALSE;
5580 }
5581 }
5582
5583 return MZ_TRUE;
5584
5587 return MZ_FALSE;
5588 }
5589
5591 {
5593 mz_uint32 i;
5594
5595 if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (!pZip->m_pRead))
5597
5598 pState = pZip->m_pState;
5599
5600 /* Basic sanity checks */
5601 if (!pState->m_zip64)
5602 {
5603 if (pZip->m_total_files > MZ_UINT16_MAX)
5605
5606 if (pZip->m_archive_size > MZ_UINT32_MAX)
5608 }
5609 else
5610 {
5611 if (pState->m_central_dir.m_size >= MZ_UINT32_MAX)
5613 }
5614
5615 for (i = 0; i < pZip->m_total_files; i++)
5616 {
5618 {
5621
5622 if (!mz_zip_reader_file_stat(pZip, i, &stat))
5623 return MZ_FALSE;
5624
5625 if (!mz_zip_reader_locate_file_v2(pZip, stat.m_filename, NULL, 0, &found_index))
5626 return MZ_FALSE;
5627
5628 /* 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) */
5629 if (found_index != i)
5631 }
5632
5633 if (!mz_zip_validate_file(pZip, i, flags))
5634 return MZ_FALSE;
5635 }
5636
5637 return MZ_TRUE;
5638 }
5639
5641 {
5643 mz_zip_archive zip;
5645
5646 if ((!pMem) || (!size))
5647 {
5648 if (pErr)
5650 return MZ_FALSE;
5651 }
5652
5653 mz_zip_zero_struct(&zip);
5654
5655 if (!mz_zip_reader_init_mem(&zip, pMem, size, flags))
5656 {
5657 if (pErr)
5658 *pErr = zip.m_last_error;
5659 return MZ_FALSE;
5660 }
5661
5662 if (!mz_zip_validate_archive(&zip, flags))
5663 {
5665 success = MZ_FALSE;
5666 }
5667
5669 {
5670 if (!actual_err)
5672 success = MZ_FALSE;
5673 }
5674
5675 if (pErr)
5676 *pErr = actual_err;
5677
5678 return success;
5679 }
5680
5681#ifndef MINIZ_NO_STDIO
5683 {
5685 mz_zip_archive zip;
5687
5688 if (!pFilename)
5689 {
5690 if (pErr)
5692 return MZ_FALSE;
5693 }
5694
5695 mz_zip_zero_struct(&zip);
5696
5697 if (!mz_zip_reader_init_file_v2(&zip, pFilename, flags, 0, 0))
5698 {
5699 if (pErr)
5700 *pErr = zip.m_last_error;
5701 return MZ_FALSE;
5702 }
5703
5704 if (!mz_zip_validate_archive(&zip, flags))
5705 {
5707 success = MZ_FALSE;
5708 }
5709
5711 {
5712 if (!actual_err)
5714 success = MZ_FALSE;
5715 }
5716
5717 if (pErr)
5718 *pErr = actual_err;
5719
5720 return success;
5721 }
5722#endif /* #ifndef MINIZ_NO_STDIO */
5723
5724 /* ------------------- .ZIP archive writing */
5725
5726#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
5727
5729 {
5730 p[0] = (mz_uint8)v;
5731 p[1] = (mz_uint8)(v >> 8);
5732 }
5734 {
5735 p[0] = (mz_uint8)v;
5736 p[1] = (mz_uint8)(v >> 8);
5737 p[2] = (mz_uint8)(v >> 16);
5738 p[3] = (mz_uint8)(v >> 24);
5739 }
5741 {
5742 mz_write_le32(p, (mz_uint32)v);
5743 mz_write_le32(p + sizeof(mz_uint32), (mz_uint32)(v >> 32));
5744 }
5745
5746#define MZ_WRITE_LE16(p, v) mz_write_le16((mz_uint8 *)(p), (mz_uint16)(v))
5747#define MZ_WRITE_LE32(p, v) mz_write_le32((mz_uint8 *)(p), (mz_uint32)(v))
5748#define MZ_WRITE_LE64(p, v) mz_write_le64((mz_uint8 *)(p), (mz_uint64)(v))
5749
5750 static size_t mz_zip_heap_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
5751 {
5754 mz_uint64 new_size = MZ_MAX(file_ofs + n, pState->m_mem_size);
5755
5756 if (!n)
5757 return 0;
5758
5759 /* An allocation this big is likely to just fail on 32-bit systems, so don't even go there. */
5760 if ((sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF))
5761 {
5763 return 0;
5764 }
5765
5766 if (new_size > pState->m_mem_capacity)
5767 {
5768 void *pNew_block;
5769 size_t new_capacity = MZ_MAX(64, pState->m_mem_capacity);
5770
5771 while (new_capacity < new_size)
5772 new_capacity *= 2;
5773
5774 if (NULL == (pNew_block = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pState->m_pMem, 1, new_capacity)))
5775 {
5777 return 0;
5778 }
5779
5780 pState->m_pMem = pNew_block;
5781 pState->m_mem_capacity = new_capacity;
5782 }
5783 memcpy((mz_uint8 *)pState->m_pMem + file_ofs, pBuf, n);
5784 pState->m_mem_size = (size_t)new_size;
5785 return n;
5786 }
5787
5788#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
5790 {
5792 mz_bool status = MZ_TRUE;
5793
5794 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)))
5795 {
5796 if (set_last_error)
5798 return MZ_FALSE;
5799 }
5800
5801 pState = pZip->m_pState;
5802 pZip->m_pState = NULL;
5803 mz_zip_array_clear(pZip, &pState->m_central_dir);
5804 mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
5805 mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets);
5806
5807#ifndef MINIZ_NO_STDIO
5808 if (pState->m_pFile)
5809 {
5810 if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE)
5811 {
5812 if (MZ_FCLOSE(pState->m_pFile) == EOF)
5813 {
5814 if (set_last_error)
5816 status = MZ_FALSE;
5817 }
5818 }
5819
5820 pState->m_pFile = NULL;
5821 }
5822#endif /* #ifndef MINIZ_NO_STDIO */
5823
5824 if ((pZip->m_pWrite == mz_zip_heap_write_func) && (pState->m_pMem))
5825 {
5826 pZip->m_pFree(pZip->m_pAlloc_opaque, pState->m_pMem);
5827 pState->m_pMem = NULL;
5828 }
5829
5830 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5832 return status;
5833 }
5834
5836 {
5837 mz_bool zip64 = (flags & MZ_ZIP_FLAG_WRITE_ZIP64) != 0;
5838
5839 if ((!pZip) || (pZip->m_pState) || (!pZip->m_pWrite) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
5841
5843 {
5844 if (!pZip->m_pRead)
5846 }
5847
5848 if (pZip->m_file_offset_alignment)
5849 {
5850 /* Ensure user specified file offset alignment is a power of 2. */
5851 if (pZip->m_file_offset_alignment & (pZip->m_file_offset_alignment - 1))
5853 }
5854
5855 if (!pZip->m_pAlloc)
5857 if (!pZip->m_pFree)
5859 if (!pZip->m_pRealloc)
5861
5864 pZip->m_total_files = 0;
5865
5866 if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state))))
5868
5869 memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state));
5870
5874
5875 pZip->m_pState->m_zip64 = zip64;
5877
5880
5881 return MZ_TRUE;
5882 }
5883
5885 {
5886 return mz_zip_writer_init_v2(pZip, existing_size, 0);
5887 }
5888
5890 {
5892 pZip->m_pNeeds_keepalive = NULL;
5893
5896
5897 pZip->m_pIO_opaque = pZip;
5898
5900 return MZ_FALSE;
5901
5903
5905 {
5906 if (NULL == (pZip->m_pState->m_pMem = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, initial_allocation_size)))
5907 {
5910 }
5912 }
5913
5914 return MZ_TRUE;
5915 }
5916
5918 {
5920 }
5921
5922#ifndef MINIZ_NO_STDIO
5923 static size_t mz_zip_file_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
5924 {
5927
5929
5931 {
5933 return 0;
5934 }
5935
5936 return MZ_FWRITE(pBuf, 1, n, pZip->m_pState->m_pFile);
5937 }
5938
5940 {
5942 }
5943
5945 {
5946 MZ_FILE *pFile;
5947
5949 pZip->m_pNeeds_keepalive = NULL;
5950
5953
5954 pZip->m_pIO_opaque = pZip;
5955
5957 return MZ_FALSE;
5958
5959 if (NULL == (pFile = MZ_FOPEN(pFilename, (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING) ? "w+b" : "wb")))
5960 {
5961 mz_zip_writer_end(pZip);
5963 }
5964
5965 pZip->m_pState->m_pFile = pFile;
5967
5969 {
5970 mz_uint64 cur_ofs = 0;
5971 char buf[4096];
5972
5974
5975 do
5976 {
5977 size_t n = (size_t)MZ_MIN(sizeof(buf), size_to_reserve_at_beginning);
5978 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_ofs, buf, n) != n)
5979 {
5980 mz_zip_writer_end(pZip);
5982 }
5983 cur_ofs += n;
5986 }
5987
5988 return MZ_TRUE;
5989 }
5990
5992 {
5994 pZip->m_pNeeds_keepalive = NULL;
5995
5998
5999 pZip->m_pIO_opaque = pZip;
6000
6001 if (!mz_zip_writer_init_v2(pZip, 0, flags))
6002 return MZ_FALSE;
6003
6004 pZip->m_pState->m_pFile = pFile;
6007
6008 return MZ_TRUE;
6009 }
6010#endif /* #ifndef MINIZ_NO_STDIO */
6011
6013 {
6015
6016 if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
6018
6019 if (flags & MZ_ZIP_FLAG_WRITE_ZIP64)
6020 {
6021 /* 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?) */
6022 if (!pZip->m_pState->m_zip64)
6024 }
6025
6026 /* No sense in trying to write to an archive that's already at the support max size */
6027 if (pZip->m_pState->m_zip64)
6028 {
6029 if (pZip->m_total_files == MZ_UINT32_MAX)
6031 }
6032 else
6033 {
6034 if (pZip->m_total_files == MZ_UINT16_MAX)
6036
6039 }
6040
6041 pState = pZip->m_pState;
6042
6043 if (pState->m_pFile)
6044 {
6045#ifdef MINIZ_NO_STDIO
6046 (void)pFilename;
6048#else
6049 if (pZip->m_pIO_opaque != pZip)
6051
6052 if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE &&
6054 {
6055 if (!pFilename)
6057
6058 /* Archive is being read from stdio and was originally opened only for reading. Try to reopen as writable. */
6059 if (NULL == (pState->m_pFile = MZ_FREOPEN(pFilename, "r+b", pState->m_pFile)))
6060 {
6061 /* The mz_zip_archive is now in a bogus state because pState->m_pFile is NULL, so just close it. */
6064 }
6065 }
6066
6068 pZip->m_pNeeds_keepalive = NULL;
6069#endif /* #ifdef MINIZ_NO_STDIO */
6070 }
6071 else if (pState->m_pMem)
6072 {
6073 /* Archive lives in a memory block. Assume it's from the heap that we can resize using the realloc callback. */
6074 if (pZip->m_pIO_opaque != pZip)
6076
6077 pState->m_mem_capacity = pState->m_mem_size;
6079 pZip->m_pNeeds_keepalive = NULL;
6080 }
6081 /* Archive is being read via a user provided read function - make sure the user has specified a write function too. */
6082 else if (!pZip->m_pWrite)
6084
6085 /* Start writing new files at the archive's current central directory location. */
6086 /* TODO: We could add a flag that lets the user start writing immediately AFTER the existing central dir - this would be safer. */
6089
6090 /* Clear the sorted central dir offsets, they aren't useful or maintained now. */
6091 /* Even though we're now in write mode, files can still be extracted and verified, but file locates will be slow. */
6092 /* TODO: We could easily maintain the sorted central directory offsets. */
6094
6096
6097 return MZ_TRUE;
6098 }
6099
6101 {
6103 }
6104
6105 /* TODO: pArchive_name is a terrible name here! */
6107 {
6109 }
6110
6111 typedef struct
6112 {
6115 mz_uint64 m_comp_size;
6117
6118 static mz_bool mz_zip_writer_add_put_buf_callback(const void *pBuf, int len, void *pUser)
6119 {
6121 if ((int)pState->m_pZip->m_pWrite(pState->m_pZip->m_pIO_opaque, pState->m_cur_archive_file_ofs, pBuf, len) != len)
6122 return MZ_FALSE;
6123
6124 pState->m_cur_archive_file_ofs += len;
6125 pState->m_comp_size += len;
6126 return MZ_TRUE;
6127 }
6128
6129#define MZ_ZIP64_MAX_LOCAL_EXTRA_FIELD_SIZE (sizeof(mz_uint16) * 2 + sizeof(mz_uint64) * 2)
6130#define MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE (sizeof(mz_uint16) * 2 + sizeof(mz_uint64) * 3)
6132 {
6133 mz_uint8 *pDst = pBuf;
6135
6137 MZ_WRITE_LE16(pDst + 2, 0);
6138 pDst += sizeof(mz_uint16) * 2;
6139
6140 if (pUncomp_size)
6141 {
6143 pDst += sizeof(mz_uint64);
6144 field_size += sizeof(mz_uint64);
6145 }
6146
6147 if (pComp_size)
6148 {
6150 pDst += sizeof(mz_uint64);
6151 field_size += sizeof(mz_uint64);
6152 }
6153
6155 {
6157 pDst += sizeof(mz_uint64);
6158 field_size += sizeof(mz_uint64);
6159 }
6160
6162
6163 return (mz_uint32)(pDst - pBuf);
6164 }
6165
6167 {
6168 (void)pZip;
6181 return MZ_TRUE;
6182 }
6183
6189 {
6190 (void)pZip;
6206 return MZ_TRUE;
6207 }
6208
6210 const void *pExtra, mz_uint16 extra_size, const void *pComment, mz_uint16 comment_size,
6215 {
6217 mz_uint32 central_dir_ofs = (mz_uint32)pState->m_central_dir.m_size;
6218 size_t orig_central_dir_size = pState->m_central_dir.m_size;
6220
6221 if (!pZip->m_pState->m_zip64)
6222 {
6223 if (local_header_ofs > 0xFFFFFFFF)
6225 }
6226
6227 /* miniz doesn't support central dirs >= MZ_UINT32_MAX bytes yet */
6230
6233
6235 (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pFilename, filename_size)) ||
6236 (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pExtra, extra_size)) ||
6238 (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pComment, comment_size)) ||
6239 (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &central_dir_ofs, 1)))
6240 {
6241 /* Try to resize the central directory array back into its original state. */
6244 }
6245
6246 return MZ_TRUE;
6247 }
6248
6250 {
6251 /* 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. */
6252 if (*pArchive_name == '/')
6253 return MZ_FALSE;
6254
6255 /* Making sure the name does not contain drive letters or DOS style backward slashes is the responsibility of the program using miniz*/
6256
6257 return MZ_TRUE;
6258 }
6259
6261 {
6262 mz_uint32 n;
6263 if (!pZip->m_file_offset_alignment)
6264 return 0;
6265 n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1));
6266 return (mz_uint)((pZip->m_file_offset_alignment - n) & (pZip->m_file_offset_alignment - 1));
6267 }
6268
6270 {
6271 char buf[4096];
6272 memset(buf, 0, MZ_MIN(sizeof(buf), n));
6273 while (n)
6274 {
6275 mz_uint32 s = MZ_MIN(sizeof(buf), n);
6276 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_file_ofs, buf, s) != s)
6278
6279 cur_file_ofs += s;
6280 n -= s;
6281 }
6282 return MZ_TRUE;
6283 }
6284
6287 {
6289 }
6290
6291 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,
6294 {
6295 mz_uint16 method = 0, dos_time = 0, dos_date = 0;
6298 size_t archive_name_size;
6306 mz_uint16 bit_flags = 0;
6307
6308 if ((int)level_and_flags < 0)
6310
6313
6316
6317 level = level_and_flags & 0xF;
6319
6320 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))
6322
6323 pState = pZip->m_pState;
6324
6325 if (pState->m_zip64)
6326 {
6327 if (pZip->m_total_files == MZ_UINT32_MAX)
6329 }
6330 else
6331 {
6332 if (pZip->m_total_files == MZ_UINT16_MAX)
6333 {
6334 pState->m_zip64 = MZ_TRUE;
6335 /*return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); */
6336 }
6337 if (((mz_uint64)buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF))
6338 {
6339 pState->m_zip64 = MZ_TRUE;
6340 /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
6341 }
6342 }
6343
6346
6349
6350#ifndef MINIZ_NO_TIME
6351 if (last_modified != NULL)
6352 {
6354 }
6355 else
6356 {
6358 time(&cur_time);
6360 }
6361#else
6363#endif /* #ifndef MINIZ_NO_TIME */
6364
6366 {
6369 if (uncomp_size <= 3)
6370 {
6371 level = 0;
6373 }
6374 }
6375
6379
6381
6382 /* miniz doesn't support central dirs >= MZ_UINT32_MAX bytes yet */
6385
6386 if (!pState->m_zip64)
6387 {
6388 /* Bail early if the archive would obviously become too large */
6391 {
6392 pState->m_zip64 = MZ_TRUE;
6393 /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
6394 }
6395 }
6396
6397 if ((archive_name_size) && (pArchive_name[archive_name_size - 1] == '/'))
6398 {
6399 /* Set DOS Subdirectory attribute bit. */
6401
6402 /* Subdirectories cannot contain data. */
6403 if ((buf_size) || (uncomp_size))
6405 }
6406
6407 /* 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.) */
6408 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)))
6410
6412 {
6413 if (NULL == (pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor))))
6415 }
6416
6418 {
6419 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6420 return MZ_FALSE;
6421 }
6422
6424 if (pZip->m_file_offset_alignment)
6425 {
6427 }
6429
6431
6433 {
6434 method = MZ_DEFLATED;
6435 }
6436
6437 if (pState->m_zip64)
6438 {
6440 {
6444 }
6445
6448
6451
6453
6455 {
6456 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6458 }
6460
6461 if (pExtra_data != NULL)
6462 {
6465
6467 }
6468 }
6469 else
6470 {
6475
6478
6480
6482 {
6483 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6485 }
6487 }
6488
6489 if (user_extra_data_len > 0)
6490 {
6493
6495 }
6496
6498 {
6500 {
6501 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6503 }
6504
6507 }
6508 else if (buf_size)
6509 {
6511
6512 state.m_pZip = pZip;
6513 state.m_cur_archive_file_ofs = cur_archive_file_ofs;
6514 state.m_comp_size = 0;
6515
6518 {
6519 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6521 }
6522
6523 comp_size = state.m_comp_size;
6524 cur_archive_file_ofs = state.m_cur_archive_file_ofs;
6525 }
6526
6527 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6528 pComp = NULL;
6529
6530 if (uncomp_size)
6531 {
6534
6536
6539 if (pExtra_data == NULL)
6540 {
6543
6546 }
6547 else
6548 {
6552 }
6553
6555 return MZ_FALSE;
6556
6558 }
6559
6560 if (pExtra_data != NULL)
6561 {
6564 }
6565
6569 return MZ_FALSE;
6570
6571 pZip->m_total_files++;
6573
6574 return MZ_TRUE;
6575 }
6576
6579 {
6582 mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0;
6584 size_t archive_name_size;
6591
6592 if ((int)level_and_flags < 0)
6594 level = level_and_flags & 0xF;
6595
6597
6600
6601 /* Sanity checks */
6602 if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION))
6604
6605 pState = pZip->m_pState;
6606
6607 if ((!pState->m_zip64) && (max_size > MZ_UINT32_MAX))
6608 {
6609 /* Source file is too large for non-zip64 */
6610 /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
6611 pState->m_zip64 = MZ_TRUE;
6612 }
6613
6614 /* We could support this, but why? */
6617
6620
6621 if (pState->m_zip64)
6622 {
6623 if (pZip->m_total_files == MZ_UINT32_MAX)
6625 }
6626 else
6627 {
6628 if (pZip->m_total_files == MZ_UINT16_MAX)
6629 {
6630 pState->m_zip64 = MZ_TRUE;
6631 /*return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); */
6632 }
6633 }
6634
6638
6640
6641 /* miniz doesn't support central dirs >= MZ_UINT32_MAX bytes yet */
6644
6645 if (!pState->m_zip64)
6646 {
6647 /* Bail early if the archive would obviously become too large */
6649 {
6650 pState->m_zip64 = MZ_TRUE;
6651 /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
6652 }
6653 }
6654
6655#ifndef MINIZ_NO_TIME
6656 if (pFile_time)
6657 {
6659 }
6660#else
6662#endif
6663
6664 if (max_size <= 3)
6665 level = 0;
6666
6668 {
6670 }
6671
6674
6675 if (pZip->m_file_offset_alignment)
6676 {
6678 }
6679
6680 if (max_size && level)
6681 {
6682 method = MZ_DEFLATED;
6683 }
6684
6686 if (pState->m_zip64)
6687 {
6689 {
6695 else
6697 NULL,
6699 }
6700
6703
6706
6708
6710 {
6712 }
6713
6715
6718
6720 }
6721 else
6722 {
6727
6730
6732
6734 {
6736 }
6737
6739 }
6740
6741 if (user_extra_data_len > 0)
6742 {
6745
6747 }
6748
6749 if (max_size)
6750 {
6751 void *pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, MZ_ZIP_MAX_IO_BUF_SIZE);
6752 if (!pRead_buf)
6753 {
6755 }
6756
6757 if (!level)
6758 {
6759 while (1)
6760 {
6762 if (n == 0)
6763 break;
6764
6765 if ((n > MZ_ZIP_MAX_IO_BUF_SIZE) || (file_ofs + n > max_size))
6766 {
6767 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6769 }
6770 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf, n) != n)
6771 {
6772 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6774 }
6775 file_ofs += n;
6776 uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n);
6778 }
6781 }
6782 else
6783 {
6784 mz_bool result = MZ_FALSE;
6787 if (!pComp)
6788 {
6789 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6791 }
6792
6793 state.m_pZip = pZip;
6794 state.m_cur_archive_file_ofs = cur_archive_file_ofs;
6795 state.m_comp_size = 0;
6796
6798 {
6799 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6800 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6802 }
6803
6804 for (;;)
6805 {
6806 tdefl_status status;
6808
6810 if ((n > MZ_ZIP_MAX_IO_BUF_SIZE) || (file_ofs + n > max_size))
6811 {
6813 break;
6814 }
6815
6816 file_ofs += n;
6817 uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n);
6818
6819 if (pZip->m_pNeeds_keepalive != NULL && pZip->m_pNeeds_keepalive(pZip->m_pIO_opaque))
6820 flush = TDEFL_FULL_FLUSH;
6821
6822 if (n == 0)
6823 flush = TDEFL_FINISH;
6824
6825 status = tdefl_compress_buffer(pComp, pRead_buf, n, flush);
6826 if (status == TDEFL_STATUS_DONE)
6827 {
6828 result = MZ_TRUE;
6829 break;
6830 }
6831 else if (status != TDEFL_STATUS_OKAY)
6832 {
6834 break;
6835 }
6836 }
6837
6838 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6839
6840 if (!result)
6841 {
6842 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6843 return MZ_FALSE;
6844 }
6845
6847 comp_size = state.m_comp_size;
6848 cur_archive_file_ofs = state.m_cur_archive_file_ofs;
6849 }
6850
6851 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6852 }
6853
6855 {
6858
6861 if (pExtra_data == NULL)
6862 {
6865
6868 }
6869 else
6870 {
6874 }
6875
6877 return MZ_FALSE;
6878
6880 }
6881
6883 {
6884 if (pExtra_data != NULL)
6885 {
6888 }
6889
6896
6898
6901
6902 if (pExtra_data != NULL)
6903 {
6905
6907 {
6909 }
6910
6912
6915
6917 }
6918 }
6919
6920 if (pExtra_data != NULL)
6921 {
6924 }
6925
6929 return MZ_FALSE;
6930
6931 pZip->m_total_files++;
6933
6934 return MZ_TRUE;
6935 }
6936
6937#ifndef MINIZ_NO_STDIO
6938
6939 static size_t mz_file_read_func_stdio(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
6940 {
6943
6945 return 0;
6946
6947 return MZ_FREAD(pBuf, 1, n, pSrc_file);
6948 }
6949
6952 {
6955 }
6956
6958 {
6963 mz_bool status;
6964
6966
6967#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_STDIO)
6971#endif
6972
6974 if (!pSrc_file)
6976
6980
6982
6984
6985 return status;
6986 }
6987#endif /* #ifndef MINIZ_NO_STDIO */
6988
6990 {
6991 /* + 64 should be enough for any new zip64 data */
6992 if (!mz_zip_array_reserve(pZip, pNew_ext, ext_len + 64, MZ_FALSE))
6994
6996
6998 {
7002 mz_write_le16(pDst + sizeof(mz_uint16), 0);
7003 pDst += sizeof(mz_uint16) * 2;
7004
7005 if (pUncomp_size)
7006 {
7008 pDst += sizeof(mz_uint64);
7009 }
7010
7011 if (pComp_size)
7012 {
7014 pDst += sizeof(mz_uint64);
7015 }
7016
7018 {
7020 pDst += sizeof(mz_uint64);
7021 }
7022
7023 if (pDisk_start)
7024 {
7026 pDst += sizeof(mz_uint32);
7027 }
7028
7030
7033 }
7034
7035 if ((pExt) && (ext_len))
7036 {
7038 const mz_uint8 *pExtra_data = pExt;
7039
7040 do
7041 {
7043
7044 if (extra_size_remaining < (sizeof(mz_uint16) * 2))
7046
7050
7053
7055 {
7058 }
7059
7062 } while (extra_size_remaining);
7063 }
7064
7065 return MZ_TRUE;
7066 }
7067
7068 /* TODO: This func is now pretty freakin complex due to zip64, split it up? */
7070 {
7077 size_t orig_central_dir_size;
7079 void *pBuf;
7086
7087 /* Sanity checks */
7088 if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pSource_zip->m_pRead))
7090
7091 pState = pZip->m_pState;
7092
7093 /* Don't support copying files from zip64 archives to non-zip64, even though in some cases this is possible */
7094 if ((pSource_zip->m_pState->m_zip64) && (!pZip->m_pState->m_zip64))
7096
7097 /* Get pointer to the source central dir header and crack it */
7100
7103
7108
7109 /* 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) */
7112
7114
7115 if (!pState->m_zip64)
7116 {
7117 if (pZip->m_total_files == MZ_UINT16_MAX)
7119 }
7120 else
7121 {
7122 /* TODO: Our zip64 support still has some 32-bit limits that may not be worth fixing. */
7123 if (pZip->m_total_files == MZ_UINT32_MAX)
7125 }
7126
7128 return MZ_FALSE;
7129
7130 cur_src_file_ofs = src_file_stat.m_local_header_ofs;
7132
7133 /* Read the source archive's local dir header */
7136
7139
7141
7142 /* Compute the total size we need to copy (filename+extra data+compressed data) */
7148
7149 /* Try to find a zip64 extended information field */
7151 {
7153 const mz_uint8 *pExtra_data;
7155
7158 {
7160 }
7161
7163 {
7166 }
7167
7168 pExtra_data = (const mz_uint8 *)file_data_array.m_p;
7169
7170 do
7171 {
7173
7174 if (extra_size_remaining < (sizeof(mz_uint16) * 2))
7175 {
7178 }
7179
7183
7185 {
7188 }
7189
7191 {
7192 const mz_uint8 *pSrc_field_data = pExtra_data + sizeof(mz_uint32);
7193
7194 if (field_data_size < sizeof(mz_uint64) * 2)
7195 {
7198 }
7199
7201 local_header_comp_size = MZ_READ_LE64(pSrc_field_data + sizeof(mz_uint64)); /* may be 0 if there's a descriptor */
7202
7204 break;
7205 }
7206
7209 } while (extra_size_remaining);
7210
7212 }
7213
7214 if (!pState->m_zip64)
7215 {
7216 /* 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). */
7217 /* We also check when the archive is finalized so this doesn't need to be perfect. */
7220
7223 }
7224
7225 /* Write dest archive padding */
7227 return MZ_FALSE;
7228
7230
7232 if (pZip->m_file_offset_alignment)
7233 {
7235 }
7236
7237 /* 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 */
7240
7242
7243 /* Copy over the source archive bytes to the dest archive, also ensure we have enough buf space to handle optional data descriptor */
7246
7248 {
7250 if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, n) != n)
7251 {
7252 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
7254 }
7256
7257 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n)
7258 {
7259 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
7261 }
7263
7265 }
7266
7267 /* Now deal with the optional data descriptor */
7269 if (bit_flags & 8)
7270 {
7271 /* Copy data descriptor */
7272 if ((pSource_zip->m_pState->m_zip64) || (found_zip64_ext_data_in_ldir))
7273 {
7274 /* src is zip64, dest must be zip64 */
7275
7276 /* name uint32_t's */
7277 /* id 1 (optional in zip64?) */
7278 /* crc 1 */
7279 /* comp_size 2 */
7280 /* uncomp_size 2 */
7281 if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, (sizeof(mz_uint32) * 6)) != (sizeof(mz_uint32) * 6))
7282 {
7283 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
7285 }
7286
7287 n = sizeof(mz_uint32) * ((MZ_READ_LE32(pBuf) == MZ_ZIP_DATA_DESCRIPTOR_ID) ? 6 : 5);
7288 }
7289 else
7290 {
7291 /* src is NOT zip64 */
7293
7294 if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, sizeof(mz_uint32) * 4) != sizeof(mz_uint32) * 4)
7295 {
7296 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
7298 }
7299
7301
7302 if (pZip->m_pState->m_zip64)
7303 {
7304 /* dest is zip64, so upgrade the data descriptor */
7305 const mz_uint8 *pSrc_descriptor = (const mz_uint8 *)pBuf + (has_id ? sizeof(mz_uint32) : 0);
7309
7311 mz_write_le32((mz_uint8 *)pBuf + sizeof(mz_uint32) * 1, src_crc32);
7314
7315 n = sizeof(mz_uint32) * 6;
7316 }
7317 else
7318 {
7319 /* dest is NOT zip64, just copy it as-is */
7320 n = sizeof(mz_uint32) * (has_id ? 4 : 3);
7321 }
7322 }
7323
7324 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n)
7325 {
7326 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
7328 }
7329
7332 }
7333 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
7334
7335 /* Finally, add the new central dir header */
7336 orig_central_dir_size = pState->m_central_dir.m_size;
7337
7339
7340 if (pState->m_zip64)
7341 {
7342 /* 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. */
7345
7347
7351
7353 {
7355 return MZ_FALSE;
7356 }
7357
7359
7361 {
7364 }
7365
7367 {
7371 }
7372
7373 if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, new_ext_block.m_p, new_ext_block.m_size))
7374 {
7378 }
7379
7381 {
7385 }
7386
7388 }
7389 else
7390 {
7391 /* sanity checks */
7394
7397
7399
7402
7404 {
7407 }
7408 }
7409
7410 /* This shouldn't trigger unless we screwed up during the initial sanity checks */
7411 if (pState->m_central_dir.m_size >= MZ_UINT32_MAX)
7412 {
7413 /* TODO: Support central dirs >= 32-bits in size */
7416 }
7417
7419 if (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &n, 1))
7420 {
7423 }
7424
7425 pZip->m_total_files++;
7427
7428 return MZ_TRUE;
7429 }
7430
7432 {
7435 mz_uint8 hdr[256];
7436
7437 if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING))
7439
7440 pState = pZip->m_pState;
7441
7442 if (pState->m_zip64)
7443 {
7444 if ((mz_uint64)pState->m_central_dir.m_size >= MZ_UINT32_MAX)
7446 }
7447 else
7448 {
7449 if ((pZip->m_total_files > MZ_UINT16_MAX) || ((pZip->m_archive_size + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) > MZ_UINT32_MAX))
7451 }
7452
7453 central_dir_ofs = 0;
7454 central_dir_size = 0;
7455 if (pZip->m_total_files)
7456 {
7457 /* Write central directory */
7459 central_dir_size = pState->m_central_dir.m_size;
7461 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)
7463
7465 }
7466
7467 if (pState->m_zip64)
7468 {
7469 /* Write zip64 end of central directory header */
7471
7475 MZ_WRITE_LE16(hdr + MZ_ZIP64_ECDH_VERSION_MADE_BY_OFS, 0x031E); /* TODO: always Unix */
7483
7485
7486 /* Write zip64 end of central directory locator */
7493
7495 }
7496
7497 /* Write end of central directory record */
7504
7507
7508#ifndef MINIZ_NO_STDIO
7509 if ((pState->m_pFile) && (MZ_FFLUSH(pState->m_pFile) == EOF))
7511#endif /* #ifndef MINIZ_NO_STDIO */
7512
7514
7516 return MZ_TRUE;
7517 }
7518
7520 {
7521 if ((!ppBuf) || (!pSize))
7523
7524 *ppBuf = NULL;
7525 *pSize = 0;
7526
7527 if ((!pZip) || (!pZip->m_pState))
7529
7530 if (pZip->m_pWrite != mz_zip_heap_write_func)
7532
7534 return MZ_FALSE;
7535
7536 *ppBuf = pZip->m_pState->m_pMem;
7537 *pSize = pZip->m_pState->m_mem_size;
7538 pZip->m_pState->m_pMem = NULL;
7539 pZip->m_pState->m_mem_size = pZip->m_pState->m_mem_capacity = 0;
7540
7541 return MZ_TRUE;
7542 }
7543
7545 {
7546 return mz_zip_writer_end_internal(pZip, MZ_TRUE);
7547 }
7548#endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS */
7549
7550#ifndef MINIZ_NO_STDIO
7552 {
7554 }
7555
7557 {
7560 struct MZ_FILE_STAT_STRUCT file_stat;
7562
7564 if ((int)level_and_flags < 0)
7566
7567 if ((!pZip_filename) || (!pArchive_name) || ((buf_size) && (!pBuf)) || ((comment_size) && (!pComment)) || ((level_and_flags & 0xF) > MZ_UBER_COMPRESSION))
7568 {
7569 if (pErr)
7571 return MZ_FALSE;
7572 }
7573
7575 {
7576 if (pErr)
7578 return MZ_FALSE;
7579 }
7580
7581 /* 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. */
7582 /* So be sure to compile with _LARGEFILE64_SOURCE 1 */
7583 if (MZ_FILE_STAT(pZip_filename, &file_stat) != 0)
7584 {
7585 /* Create a new archive. */
7587 {
7588 if (pErr)
7589 *pErr = zip_archive.m_last_error;
7590 return MZ_FALSE;
7591 }
7592
7594 }
7595 else
7596 {
7597 /* Append to an existing archive. */
7599 {
7600 if (pErr)
7601 *pErr = zip_archive.m_last_error;
7602 return MZ_FALSE;
7603 }
7604
7606 {
7607 if (pErr)
7608 *pErr = zip_archive.m_last_error;
7609
7611
7612 return MZ_FALSE;
7613 }
7614 }
7615
7617 actual_err = zip_archive.m_last_error;
7618
7619 /* 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.) */
7621 {
7622 if (!actual_err)
7623 actual_err = zip_archive.m_last_error;
7624
7625 status = MZ_FALSE;
7626 }
7627
7629 {
7630 if (!actual_err)
7631 actual_err = zip_archive.m_last_error;
7632
7633 status = MZ_FALSE;
7634 }
7635
7636 if ((!status) && (created_new_archive))
7637 {
7638 /* It's a new archive and something went wrong, so just delete it. */
7641 }
7642
7643 if (pErr)
7644 *pErr = actual_err;
7645
7646 return status;
7647 }
7648
7649 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)
7650 {
7653 void *p = NULL;
7654
7655 if (pSize)
7656 *pSize = 0;
7657
7658 if ((!pZip_filename) || (!pArchive_name))
7659 {
7660 if (pErr)
7662
7663 return NULL;
7664 }
7665
7668 {
7669 if (pErr)
7670 *pErr = zip_archive.m_last_error;
7671
7672 return NULL;
7673 }
7674
7676 {
7678 }
7679
7681
7682 if (pErr)
7683 *pErr = zip_archive.m_last_error;
7684
7685 return p;
7686 }
7687
7688 void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags)
7689 {
7691 }
7692
7693#endif /* #ifndef MINIZ_NO_STDIO */
7694
7695#endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS */
7696
7697 /* ------------------- Misc utils */
7698
7700 {
7701 return pZip ? pZip->m_zip_mode : MZ_ZIP_MODE_INVALID;
7702 }
7703
7705 {
7706 return pZip ? pZip->m_zip_type : MZ_ZIP_TYPE_INVALID;
7707 }
7708
7710 {
7712
7713 if (!pZip)
7715
7716 prev_err = pZip->m_last_error;
7717
7718 pZip->m_last_error = err_num;
7719 return prev_err;
7720 }
7721
7723 {
7724 if (!pZip)
7726
7727 return pZip->m_last_error;
7728 }
7729
7734
7736 {
7738
7739 if (!pZip)
7741
7742 prev_err = pZip->m_last_error;
7743
7745 return prev_err;
7746 }
7747
7749 {
7750 switch (mz_err)
7751 {
7752 case MZ_ZIP_NO_ERROR:
7753 return "no error";
7755 return "undefined error";
7757 return "too many files";
7759 return "file too large";
7761 return "unsupported method";
7763 return "unsupported encryption";
7765 return "unsupported feature";
7767 return "failed finding central directory";
7769 return "not a ZIP archive";
7771 return "invalid header or archive is corrupted";
7773 return "unsupported multidisk archive";
7775 return "decompression failed or archive is corrupted";
7777 return "compression failed";
7779 return "unexpected decompressed size";
7781 return "CRC-32 check failed";
7783 return "unsupported central directory size";
7785 return "allocation failed";
7787 return "file open failed";
7789 return "file create failed";
7791 return "file write failed";
7793 return "file read failed";
7795 return "file close failed";
7797 return "file seek failed";
7799 return "file stat failed";
7801 return "invalid parameter";
7803 return "invalid filename";
7805 return "buffer too small";
7807 return "internal error";
7809 return "file not found";
7811 return "archive is too large";
7813 return "validation failed";
7815 return "write callback failed";
7817 return "total errors";
7818 default:
7819 break;
7820 }
7821
7822 return "unknown error";
7823 }
7824
7825 /* Note: Just because the archive is not zip64 doesn't necessarily mean it doesn't have Zip64 extended information extra field, argh. */
7827 {
7828 if ((!pZip) || (!pZip->m_pState))
7829 return MZ_FALSE;
7830
7831 return pZip->m_pState->m_zip64;
7832 }
7833
7835 {
7836 if ((!pZip) || (!pZip->m_pState))
7837 return 0;
7838
7839 return pZip->m_pState->m_central_dir.m_size;
7840 }
7841
7843 {
7844 return pZip ? pZip->m_total_files : 0;
7845 }
7846
7848 {
7849 if (!pZip)
7850 return 0;
7851 return pZip->m_archive_size;
7852 }
7853
7855 {
7856 if ((!pZip) || (!pZip->m_pState))
7857 return 0;
7858 return pZip->m_pState->m_file_archive_start_ofs;
7859 }
7860
7862 {
7863 if ((!pZip) || (!pZip->m_pState))
7864 return 0;
7865 return pZip->m_pState->m_pFile;
7866 }
7867
7869 {
7870 if ((!pZip) || (!pZip->m_pState) || (!pBuf) || (!pZip->m_pRead))
7872
7873 return pZip->m_pRead(pZip->m_pIO_opaque, file_ofs, pBuf, n);
7874 }
7875
7877 {
7878 mz_uint n;
7879 const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
7880 if (!p)
7881 {
7883 pFilename[0] = '\0';
7885 return 0;
7886 }
7889 {
7890 n = MZ_MIN(n, filename_buf_size - 1);
7892 pFilename[n] = '\0';
7893 }
7894 return n + 1;
7895 }
7896
7901
7903 {
7904 if (!pZip)
7905 return MZ_FALSE;
7906
7907 if (pZip->m_zip_mode == MZ_ZIP_MODE_READING)
7908 return mz_zip_reader_end(pZip);
7909#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
7911 return mz_zip_writer_end(pZip);
7912#endif
7913
7914 return MZ_FALSE;
7915 }
7916
7917#ifdef __cplusplus
7918}
7919#endif
7920
7921#endif /*#ifndef MINIZ_NO_ARCHIVE_APIS*/
static bool has_id(const jsont &json)
Return true iff the argument has a "@id" key.
int8_t s1
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
ait()
Definition ai.h:565
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
#define MZ_FILE_STAT
Definition miniz.cpp:3225
#define TINFL_HUFF_DECODE(state_index, sym, pLookUp, pTree)
Definition miniz.cpp:2387
mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len)
Definition miniz.cpp:41
mz_bool mz_zip_is_zip64(mz_zip_archive *pZip)
Definition miniz.cpp:7826
mz_bool mz_zip_reader_end(mz_zip_archive *pZip)
Definition miniz.cpp:4036
mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags)
Definition miniz.cpp:5590
mz_zip_type mz_zip_get_type(mz_zip_archive *pZip)
Definition miniz.cpp:7704
static size_t mz_zip_file_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
Definition miniz.cpp:4103
mz_bool mz_zip_end(mz_zip_archive *pZip)
Definition miniz.cpp:7902
#define TINFL_CR_BEGIN
Definition miniz.cpp:2285
mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip)
Definition miniz.cpp:7842
static void mz_zip_array_init(mz_zip_array *pArray, mz_uint32 element_size)
Definition miniz.cpp:3368
static void mz_zip_reader_sort_central_dir_offsets_by_filename(mz_zip_archive *pZip)
Definition miniz.cpp:3576
mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags)
Definition miniz.cpp:4116
#define TINFL_GET_BYTE(state_index, c)
Definition miniz.cpp:2309
#define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size)
Definition miniz.cpp:3355
size_t mz_zip_get_central_dir_size(mz_zip_archive *pZip)
Definition miniz.cpp:7834
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:4437
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:4306
#define MZ_FFLUSH
Definition miniz.cpp:3226
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:4986
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:3547
static const mz_uint8 * mz_zip_get_cdh(mz_zip_archive *pZip, mz_uint file_index)
Definition miniz.cpp:4217
mz_zip_reader_extract_iter_state * mz_zip_reader_extract_iter_new(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags)
Definition miniz.cpp:4995
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:3628
mz_zip_mode mz_zip_get_mode(mz_zip_archive *pZip)
Definition miniz.cpp:7699
#define MZ_FREOPEN(f, m, s)
Definition miniz.cpp:3227
MINIZ_EXPORT void * miniz_def_alloc_func(void *opaque, size_t items, size_t size)
Definition miniz.cpp:167
MINIZ_EXPORT void * miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size)
Definition miniz.cpp:177
size_t mz_zip_read_archive_data(mz_zip_archive *pZip, mz_uint64 file_ofs, void *pBuf, size_t n)
Definition miniz.cpp:7868
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:2971
mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index)
Definition miniz.cpp:4274
void * tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
Definition miniz.cpp:2924
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:4715
unsigned char mz_validate_uint32[sizeof(mz_uint32)==4 ? 1 :-1]
Definition miniz.cpp:31
#define TINFL_MEMCPY(d, s, l)
Definition miniz.cpp:2282
static mz_bool mz_zip_string_equal(const char *pA, const char *pB, mz_uint len, mz_uint flags)
Definition miniz.cpp:4426
#define TINFL_GET_BITS(state_index, b, n)
Definition miniz.cpp:2339
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:4503
mz_bool mz_zip_reader_extract_to_cfile(mz_zip_archive *pZip, mz_uint file_index, FILE *pFile, mz_uint flags)
Definition miniz.cpp:5344
static void tinfl_clear_tree(tinfl_decompressor *r)
Definition miniz.cpp:2421
#define MZ_FREAD
Definition miniz.cpp:3215
static mz_bool mz_zip_reader_init_internal(mz_zip_archive *pZip, mz_uint flags)
Definition miniz.cpp:3513
static mz_bool mz_zip_reader_end_internal(mz_zip_archive *pZip, mz_bool set_last_error)
Definition miniz.cpp:3989
mz_zip_error mz_zip_peek_last_error(mz_zip_archive *pZip)
Definition miniz.cpp:7722
mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint flags)
Definition miniz.cpp:4040
mz_zip_error mz_zip_get_last_error(mz_zip_archive *pZip)
Definition miniz.cpp:7735
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:5335
#define MZ_FWRITE
Definition miniz.cpp:3216
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:4786
mz_bool mz_zip_validate_file_archive(const char *pFilename, mz_uint flags, mz_zip_error *pErr)
Definition miniz.cpp:5682
#define MZ_TOLOWER(c)
Definition miniz.cpp:3232
mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint flags)
Definition miniz.cpp:4068
const char * mz_version(void)
Definition miniz.cpp:183
static size_t mz_zip_file_write_callback(void *pOpaque, mz_uint64 ofs, const void *pBuf, size_t n)
Definition miniz.cpp:5294
#define MZ_FSEEK64
Definition miniz.cpp:3222
const char * mz_zip_get_error_string(mz_zip_error mz_err)
Definition miniz.cpp:7748
mz_bool mz_zip_reader_init_cfile(mz_zip_archive *pZip, FILE *pFile, mz_uint64 archive_size, mz_uint flags)
Definition miniz.cpp:4175
void * mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags)
Definition miniz.cpp:4738
FILE * mz_zip_get_cfile(mz_zip_archive *pZip)
Definition miniz.cpp:7861
#define MZ_FOPEN(f, m)
Definition miniz.cpp:3213
static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flags)
Definition miniz.cpp:3687
void mz_free(void *p)
Definition miniz.cpp:162
#define TINFL_MEMSET(p, c, l)
Definition miniz.cpp:2283
static mz_bool mz_zip_reader_extract_to_mem_no_alloc1(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, const mz_zip_archive_file_stat *st)
Definition miniz.cpp:4568
int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags)
Definition miniz.cpp:4494
mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index)
Definition miniz.cpp:4224
mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
Definition miniz.cpp:96
void mz_zip_zero_struct(mz_zip_archive *pZip)
Definition miniz.cpp:3983
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:5357
mz_uint64 mz_zip_get_archive_size(mz_zip_archive *pZip)
Definition miniz.cpp:7847
size_t mz_zip_reader_extract_iter_read(mz_zip_reader_extract_iter_state *pState, void *pvBuf, size_t buf_size)
Definition miniz.cpp:5135
static size_t mz_zip_mem_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
Definition miniz.cpp:4060
mz_bool mz_zip_reader_is_file_supported(mz_zip_archive *pZip, mz_uint file_index)
Definition miniz.cpp:4238
#define TINFL_CR_FINISH
Definition miniz.cpp:2307
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:4728
#define TINFL_CR_RETURN(state_index, result)
Definition miniz.cpp:2289
#define TINFL_CR_RETURN_FOREVER(state_index, result)
Definition miniz.cpp:2298
mz_zip_error mz_zip_set_last_error(mz_zip_archive *pZip, mz_zip_error err_num)
Definition miniz.cpp:7709
MINIZ_EXPORT void miniz_def_free_func(void *opaque, void *address)
Definition miniz.cpp:172
tinfl_decompressor * tinfl_decompressor_alloc(void)
Definition miniz.cpp:3002
mz_zip_reader_extract_iter_state * mz_zip_reader_extract_file_iter_new(mz_zip_archive *pZip, const char *pFilename, mz_uint flags)
Definition miniz.cpp:5123
mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat)
Definition miniz.cpp:7897
static mz_bool mz_zip_locate_file_binary_search(mz_zip_archive *pZip, const char *pFilename, mz_uint32 *pIndex)
Definition miniz.cpp:4454
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:4121
mz_uint64 mz_zip_get_archive_file_start_offset(mz_zip_archive *pZip)
Definition miniz.cpp:7854
static mz_bool mz_zip_set_error(mz_zip_archive *pZip, mz_zip_error err_num)
Definition miniz.cpp:3506
unsigned char mz_validate_uint64[sizeof(mz_uint64)==8 ? 1 :-1]
Definition miniz.cpp:32
void * mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags)
Definition miniz.cpp:4774
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:4733
#define MZ_FILE_STAT_STRUCT
Definition miniz.cpp:3224
@ MZ_ZIP64_ECDH_VERSION_MADE_BY_OFS
Definition miniz.cpp:3307
@ MZ_ZIP_CDH_FILENAME_LEN_OFS
Definition miniz.cpp:3266
@ MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR
Definition miniz.cpp:3286
@ MZ_ZIP_LOCAL_DIR_HEADER_SIG
Definition miniz.cpp:3240
@ MZ_ZIP_CDH_FILE_DATE_OFS
Definition miniz.cpp:3262
@ MZ_ZIP_LDH_CRC32_OFS
Definition miniz.cpp:3281
@ MZ_ZIP64_ECDH_SIG_OFS
Definition miniz.cpp:3305
@ MZ_ZIP_LDH_BIT_FLAG_OFS
Definition miniz.cpp:3277
@ MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS
Definition miniz.cpp:3291
@ MZ_ZIP_CDH_VERSION_NEEDED_OFS
Definition miniz.cpp:3258
@ MZ_ZIP_DATA_DESCRIPTER_SIZE64
Definition miniz.cpp:3252
@ MZ_ZIP_CDH_LOCAL_HEADER_OFS
Definition miniz.cpp:3272
@ MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG
Definition miniz.cpp:3246
@ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8
Definition miniz.cpp:3321
@ MZ_ZIP64_ECDH_NUM_DISK_CDIR_OFS
Definition miniz.cpp:3310
@ MZ_ZIP_CDH_COMPRESSED_SIZE_OFS
Definition miniz.cpp:3264
@ MZ_ZIP_DATA_DESCRIPTER_SIZE32
Definition miniz.cpp:3253
@ MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS
Definition miniz.cpp:3292
@ MZ_ZIP_CDH_SIG_OFS
Definition miniz.cpp:3256
@ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG
Definition miniz.cpp:3318
@ MZ_ZIP64_ECDL_NUM_DISK_CDIR_OFS
Definition miniz.cpp:3300
@ MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS
Definition miniz.cpp:3265
@ MZ_ZIP_ECDH_CDIR_SIZE_OFS
Definition miniz.cpp:3294
@ MZ_ZIP64_ECDL_SIG_OFS
Definition miniz.cpp:3299
@ MZ_ZIP_CDH_METHOD_OFS
Definition miniz.cpp:3260
@ MZ_ZIP_LDH_FILENAME_LEN_OFS
Definition miniz.cpp:3284
@ MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE
Definition miniz.cpp:3249
@ MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG
Definition miniz.cpp:3316
@ MZ_ZIP_LDH_FILE_TIME_OFS
Definition miniz.cpp:3279
@ MZ_ZIP64_ECDH_VERSION_NEEDED_OFS
Definition miniz.cpp:3308
@ MZ_ZIP_CDH_EXTRA_LEN_OFS
Definition miniz.cpp:3267
@ MZ_ZIP_LDH_FILE_DATE_OFS
Definition miniz.cpp:3280
@ MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS
Definition miniz.cpp:3301
@ MZ_ZIP_LDH_METHOD_OFS
Definition miniz.cpp:3278
@ MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS
Definition miniz.cpp:3311
@ MZ_ZIP_LDH_COMPRESSED_SIZE_OFS
Definition miniz.cpp:3282
@ MZ_ZIP_CDH_FILE_TIME_OFS
Definition miniz.cpp:3261
@ MZ_ZIP_VERSION_MADE_BY_DOS_FILESYSTEM_ID
Definition miniz.cpp:3315
@ MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS
Definition miniz.cpp:3293
@ MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID
Definition miniz.cpp:3250
@ MZ_ZIP_CENTRAL_DIR_HEADER_SIG
Definition miniz.cpp:3239
@ MZ_ZIP_ECDH_SIG_OFS
Definition miniz.cpp:3289
@ MZ_ZIP_ECDH_COMMENT_SIZE_OFS
Definition miniz.cpp:3296
@ MZ_ZIP64_ECDH_CDIR_SIZE_OFS
Definition miniz.cpp:3313
@ MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS
Definition miniz.cpp:3302
@ MZ_ZIP_LDH_SIG_OFS
Definition miniz.cpp:3275
@ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION
Definition miniz.cpp:3319
@ MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG
Definition miniz.cpp:3238
@ MZ_ZIP_CDH_CRC32_OFS
Definition miniz.cpp:3263
@ MZ_ZIP_CDH_DISK_START_OFS
Definition miniz.cpp:3269
@ MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS
Definition miniz.cpp:3312
@ MZ_ZIP_CDH_INTERNAL_ATTR_OFS
Definition miniz.cpp:3270
@ MZ_ZIP_LDH_VERSION_NEEDED_OFS
Definition miniz.cpp:3276
@ MZ_ZIP_ECDH_CDIR_OFS_OFS
Definition miniz.cpp:3295
@ MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG
Definition miniz.cpp:3247
@ MZ_ZIP_LDH_EXTRA_LEN_OFS
Definition miniz.cpp:3285
@ MZ_ZIP_CDH_EXTERNAL_ATTR_OFS
Definition miniz.cpp:3271
@ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_LOCAL_DIR_IS_MASKED
Definition miniz.cpp:3320
@ MZ_ZIP64_ECDH_NUM_THIS_DISK_OFS
Definition miniz.cpp:3309
@ MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE
Definition miniz.cpp:3243
@ MZ_ZIP_LOCAL_DIR_HEADER_SIZE
Definition miniz.cpp:3241
@ MZ_ZIP64_ECDH_CDIR_OFS_OFS
Definition miniz.cpp:3314
@ MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS
Definition miniz.cpp:3283
@ MZ_ZIP_CDH_BIT_FLAG_OFS
Definition miniz.cpp:3259
@ MZ_ZIP_CDH_COMMENT_LEN_OFS
Definition miniz.cpp:3268
@ MZ_ZIP_CENTRAL_DIR_HEADER_SIZE
Definition miniz.cpp:3242
@ MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE
Definition miniz.cpp:3248
@ MZ_ZIP_DATA_DESCRIPTOR_ID
Definition miniz.cpp:3251
@ MZ_ZIP_CDH_VERSION_MADE_BY_OFS
Definition miniz.cpp:3257
@ MZ_ZIP_ECDH_NUM_THIS_DISK_OFS
Definition miniz.cpp:3290
@ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED
Definition miniz.cpp:3317
@ MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS
Definition miniz.cpp:3306
static void mz_zip_array_clear(mz_zip_archive *pZip, mz_zip_array *pArray)
Definition miniz.cpp:3374
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:4720
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:2962
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:2431
#define MZ_SWAP_UINT32(a, b)
Definition miniz.cpp:3566
#define MZ_FCLOSE
Definition miniz.cpp:3214
mz_bool mz_zip_validate_mem_archive(const void *pMem, size_t size, mz_uint flags, mz_zip_error *pErr)
Definition miniz.cpp:5640
mz_bool mz_zip_validate_file(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags)
Definition miniz.cpp:5375
static size_t mz_zip_compute_crc32_callback(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
Definition miniz.cpp:5367
#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index)
Definition miniz.cpp:3365
mz_bool mz_zip_reader_extract_iter_free(mz_zip_reader_extract_iter_state *pState)
Definition miniz.cpp:5252
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:3412
unsigned char mz_validate_uint16[sizeof(mz_uint16)==2 ? 1 :-1]
Definition miniz.cpp:30
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:3380
mz_zip_error mz_zip_clear_last_error(mz_zip_archive *pZip)
Definition miniz.cpp:7730
#define TINFL_SKIP_BITS(state_index, n)
Definition miniz.cpp:2328
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:5301
#define MZ_FTELL64
Definition miniz.cpp:3221
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:7876
void tinfl_decompressor_free(tinfl_decompressor *pDecomp)
Definition miniz.cpp:3010
static mz_bool mz_zip_reader_eocd64_valid(mz_zip_archive *pZip, uint64_t offset, uint8_t *buf)
Definition miniz.cpp:3674
#define MZ_DELETE_FILE
Definition miniz.cpp:3228
unsigned long mz_ulong
Definition miniz.h:236
@ MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE
Definition miniz.h:1072
@ MZ_ZIP_MAX_IO_BUF_SIZE
Definition miniz.h:1070
@ MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE
Definition miniz.h:1071
#define MZ_MALLOC(x)
Definition miniz.h:661
@ MZ_ZIP_FLAG_ASCII_FILENAME
Definition miniz.h:1157
@ MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE
Definition miniz.h:1160
@ MZ_ZIP_FLAG_WRITE_ZIP64
Definition miniz.h:1155
@ MZ_ZIP_FLAG_WRITE_ALLOW_READING
Definition miniz.h:1156
@ MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY
Definition miniz.h:1154
@ MZ_ZIP_FLAG_VALIDATE_LOCATE_FILE_FLAG
Definition miniz.h:1153
@ MZ_ZIP_FLAG_COMPRESSED_DATA
Definition miniz.h:1151
@ MZ_ZIP_FLAG_READ_ALLOW_WRITING
Definition miniz.h:1161
@ MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY
Definition miniz.h:1152
@ MZ_ZIP_FLAG_CASE_SENSITIVE
Definition miniz.h:1149
@ MZ_ZIP_FLAG_IGNORE_PATH
Definition miniz.h:1150
#define MZ_READ_LE16(p)
Definition miniz.h:676
#define MZ_REALLOC(p, x)
Definition miniz.h:663
int16_t mz_int16
Definition miniz.h:618
size_t(* mz_file_write_func)(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
Definition miniz.h:1133
#define MZ_FALSE
Definition miniz.h:626
#define MZ_FORCEINLINE
Definition miniz.h:687
#define MZ_ASSERT(x)
Definition miniz.h:654
#define tinfl_init(r)
Definition miniz.h:997
@ MZ_UBER_COMPRESSION
Definition miniz.h:274
@ MZ_DEFAULT_LEVEL
Definition miniz.h:275
@ MZ_DEFAULT_COMPRESSION
Definition miniz.h:276
tinfl_status
Definition miniz.h:963
@ TINFL_STATUS_ADLER32_MISMATCH
Definition miniz.h:973
@ TINFL_STATUS_FAILED
Definition miniz.h:976
@ TINFL_STATUS_NEEDS_MORE_INPUT
Definition miniz.h:987
@ TINFL_STATUS_HAS_MORE_OUTPUT
Definition miniz.h:993
@ TINFL_STATUS_BAD_PARAM
Definition miniz.h:970
@ TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS
Definition miniz.h:967
@ TINFL_STATUS_DONE
Definition miniz.h:982
#define TINFL_LZ_DICT_SIZE
Definition miniz.h:959
#define MZ_CLEAR_OBJ(obj)
Definition miniz.h:668
#define MZ_DEFLATED
Definition miniz.h:260
int64_t mz_int64
Definition miniz.h:622
#define MZ_ADLER32_INIT
Definition miniz.h:241
#define MZ_CRC32_INIT
Definition miniz.h:245
int(* tinfl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser)
Definition miniz.h:944
#define MZ_UINT16_MAX
Definition miniz.h:699
#define tinfl_get_adler32(r)
Definition miniz.h:1003
#define MZ_VERSION
Definition miniz.h:279
#define MZ_FILE
Definition miniz.h:640
size_t(* mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
Definition miniz.h:1132
#define MZ_TIME_T
Definition miniz.h:649
int mz_bool
Definition miniz.h:624
unsigned char mz_uint8
Definition miniz.h:617
mz_zip_type
Definition miniz.h:1165
@ MZ_ZIP_TYPE_USER
Definition miniz.h:1167
@ MZ_ZIP_TYPE_FILE
Definition miniz.h:1170
@ MZ_ZIP_TYPE_HEAP
Definition miniz.h:1169
@ MZ_ZIP_TYPE_MEMORY
Definition miniz.h:1168
@ MZ_ZIP_TYPE_CFILE
Definition miniz.h:1171
@ MZ_ZIP_TYPE_INVALID
Definition miniz.h:1166
#define MZ_CLEAR_ARR(obj)
Definition miniz.h:669
@ MZ_FILTERED
Definition miniz.h:253
@ MZ_FIXED
Definition miniz.h:256
@ MZ_DEFAULT_STRATEGY
Definition miniz.h:252
@ MZ_RLE
Definition miniz.h:255
@ MZ_HUFFMAN_ONLY
Definition miniz.h:254
uint32_t mz_uint
Definition miniz.h:621
#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED
Definition miniz.h:939
@ TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF
Definition miniz.h:923
@ TINFL_FLAG_HAS_MORE_INPUT
Definition miniz.h:922
@ TINFL_FLAG_COMPUTE_ADLER32
Definition miniz.h:924
@ TINFL_FLAG_PARSE_ZLIB_HEADER
Definition miniz.h:921
#define MZ_MIN(a, b)
Definition miniz.h:667
@ TINFL_FAST_LOOKUP_SIZE
Definition miniz.h:1017
@ TINFL_FAST_LOOKUP_BITS
Definition miniz.h:1016
uint32_t mz_uint32
Definition miniz.h:620
#define MZ_FREE(x)
Definition miniz.h:662
uint64_t mz_uint64
Definition miniz.h:623
#define MZ_READ_LE32(p)
Definition miniz.h:677
uint16_t mz_uint16
Definition miniz.h:619
mz_zip_mode
Definition miniz.h:1140
@ MZ_ZIP_MODE_WRITING
Definition miniz.h:1143
@ MZ_ZIP_MODE_READING
Definition miniz.h:1142
@ MZ_ZIP_MODE_INVALID
Definition miniz.h:1141
@ MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED
Definition miniz.h:1144
#define MZ_CLEAR_PTR(obj)
Definition miniz.h:670
mz_zip_error
Definition miniz.h:1177
@ MZ_ZIP_UNSUPPORTED_METHOD
Definition miniz.h:1182
@ MZ_ZIP_UNSUPPORTED_FEATURE
Definition miniz.h:1184
@ MZ_ZIP_FILE_OPEN_FAILED
Definition miniz.h:1195
@ MZ_ZIP_FILE_TOO_LARGE
Definition miniz.h:1181
@ MZ_ZIP_WRITE_CALLBACK_FAILED
Definition miniz.h:1209
@ MZ_ZIP_CRC_CHECK_FAILED
Definition miniz.h:1192
@ MZ_ZIP_INTERNAL_ERROR
Definition miniz.h:1205
@ MZ_ZIP_FILE_CLOSE_FAILED
Definition miniz.h:1199
@ MZ_ZIP_FILE_CREATE_FAILED
Definition miniz.h:1196
@ MZ_ZIP_BUF_TOO_SMALL
Definition miniz.h:1204
@ MZ_ZIP_VALIDATION_FAILED
Definition miniz.h:1208
@ MZ_ZIP_FILE_STAT_FAILED
Definition miniz.h:1201
@ MZ_ZIP_INVALID_FILENAME
Definition miniz.h:1203
@ MZ_ZIP_COMPRESSION_FAILED
Definition miniz.h:1190
@ MZ_ZIP_NO_ERROR
Definition miniz.h:1178
@ MZ_ZIP_UNSUPPORTED_ENCRYPTION
Definition miniz.h:1183
@ MZ_ZIP_TOO_MANY_FILES
Definition miniz.h:1180
@ MZ_ZIP_UNDEFINED_ERROR
Definition miniz.h:1179
@ MZ_ZIP_UNSUPPORTED_MULTIDISK
Definition miniz.h:1188
@ MZ_ZIP_ALLOC_FAILED
Definition miniz.h:1194
@ MZ_ZIP_ARCHIVE_TOO_LARGE
Definition miniz.h:1207
@ MZ_ZIP_DECOMPRESSION_FAILED
Definition miniz.h:1189
@ MZ_ZIP_FILE_WRITE_FAILED
Definition miniz.h:1197
@ MZ_ZIP_INVALID_PARAMETER
Definition miniz.h:1202
@ MZ_ZIP_INVALID_HEADER_OR_CORRUPTED
Definition miniz.h:1187
@ MZ_ZIP_UNSUPPORTED_CDIR_SIZE
Definition miniz.h:1193
@ MZ_ZIP_FILE_READ_FAILED
Definition miniz.h:1198
@ MZ_ZIP_FILE_NOT_FOUND
Definition miniz.h:1206
@ MZ_ZIP_FAILED_FINDING_CENTRAL_DIR
Definition miniz.h:1185
@ MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE
Definition miniz.h:1191
@ MZ_ZIP_NOT_AN_ARCHIVE
Definition miniz.h:1186
@ MZ_ZIP_TOTAL_ERRORS
Definition miniz.h:1210
@ MZ_ZIP_FILE_SEEK_FAILED
Definition miniz.h:1200
#define MZ_READ_LE64(p)
Definition miniz.h:680
#define MZ_MAX(a, b)
Definition miniz.h:666
#define MZ_TRUE
Definition miniz.h:627
mz_uint32 tinfl_bit_buf_t
Definition miniz.h:1030
#define MZ_UINT32_MAX
Definition miniz.h:700
void * malloc(__CPROVER_size_t malloc_size)
Definition stdlib.c:212
void free(void *ptr)
Definition stdlib.c:317
void * memset(void *s, int c, size_t n)
Definition string.c:713
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 * memcpy(void *dst, const void *src, size_t n)
Definition string.c:613
mz_uint64 m_uncomp_size
Definition miniz.h:1096
mz_uint64 m_local_header_ofs
Definition miniz.h:1103
char m_filename[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE]
Definition miniz.h:1119
mz_uint64 m_central_directory_file_ofs
Definition miniz.h:1216
mz_zip_error m_last_error
Definition miniz.h:1222
mz_alloc_func m_pAlloc
Definition miniz.h:1226
mz_zip_mode m_zip_mode
Definition miniz.h:1220
mz_uint64 m_archive_size
Definition miniz.h:1215
void * m_pIO_opaque
Definition miniz.h:1234
void * m_pAlloc_opaque
Definition miniz.h:1229
mz_file_needs_keepalive m_pNeeds_keepalive
Definition miniz.h:1233
mz_file_write_func m_pWrite
Definition miniz.h:1232
mz_zip_internal_state * m_pState
Definition miniz.h:1236
mz_free_func m_pFree
Definition miniz.h:1227
mz_realloc_func m_pRealloc
Definition miniz.h:1228
mz_file_read_func m_pRead
Definition miniz.h:1231
mz_uint64 m_file_offset_alignment
Definition miniz.h:1224
mz_zip_type m_zip_type
Definition miniz.h:1221
mz_uint32 m_total_files
Definition miniz.h:1219
size_t m_size
Definition miniz.cpp:3327
void * m_p
Definition miniz.cpp:3326
size_t m_capacity
Definition miniz.cpp:3327
mz_uint m_element_size
Definition miniz.cpp:3328
mz_bool m_zip64_has_extended_info_fields
Definition miniz.cpp:3344
mz_zip_array m_sorted_central_dir_offsets
Definition miniz.cpp:3335
mz_uint64 m_file_archive_start_ofs
Definition miniz.cpp:3348
mz_zip_array m_central_dir_offsets
Definition miniz.cpp:3334
mz_zip_array m_central_dir
Definition miniz.cpp:3333
time_t time(time_t *tloc)
Definition time.c:13
struct tm * localtime(const time_t *clock)
Definition time.c:127
time_t mktime(struct tm *timeptr)
Definition time.c:170