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