30typedef unsigned char mz_validate_uint16[
sizeof(mz_uint16) == 2 ? 1 : -1];
31typedef unsigned char mz_validate_uint32[
sizeof(mz_uint32) == 4 ? 1 : -1];
32typedef unsigned char mz_validate_uint64[
sizeof(mz_uint64) == 8 ? 1 : -1];
41 mz_ulong mz_adler32(mz_ulong adler,
const unsigned char *ptr,
size_t buf_len)
43 mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16);
44 size_t block_len = buf_len % 5552;
46 return MZ_ADLER32_INIT;
49 for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
51 s1 += ptr[0], s2 += s1;
52 s1 += ptr[1], s2 += s1;
53 s1 += ptr[2], s2 += s1;
54 s1 += ptr[3], s2 += s1;
55 s1 += ptr[4], s2 += s1;
56 s1 += ptr[5], s2 += s1;
57 s1 += ptr[6], s2 += s1;
58 s1 += ptr[7], s2 += s1;
60 for (; i < block_len; ++i)
61 s1 += *ptr++, s2 += s1;
62 s1 %= 65521U, s2 %= 65521U;
66 return (s2 << 16) + s1;
71 mz_ulong mz_crc32(mz_ulong crc,
const mz_uint8 *ptr,
size_t buf_len)
73 static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
74 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c };
75 mz_uint32 crcu32 = (mz_uint32)crc;
82 crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)];
83 crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)];
87#elif defined(USE_EXTERNAL_MZCRC)
92mz_ulong mz_crc32(mz_ulong crc,
const mz_uint8 *ptr,
size_t buf_len);
96mz_ulong mz_crc32(mz_ulong crc,
const mz_uint8 *ptr,
size_t buf_len)
98 static const mz_uint32 s_crc_table[256] = {
99 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535,
100 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
101 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D,
102 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
103 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4,
104 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
105 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC,
106 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
107 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB,
108 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
109 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB,
110 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
111 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA,
112 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE,
113 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A,
114 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
115 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409,
116 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
117 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739,
118 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
119 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268,
120 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0,
121 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8,
122 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
123 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF,
124 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
125 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7,
126 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
127 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE,
128 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
129 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6,
130 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
131 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D,
132 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
133 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605,
134 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
135 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
138 mz_uint32 crc32 = (mz_uint32)crc ^ 0xFFFFFFFF;
139 const mz_uint8 *pByte_buf = (
const mz_uint8 *)ptr;
143 crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF];
144 crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[1]) & 0xFF];
145 crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[2]) & 0xFF];
146 crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[3]) & 0xFF];
153 crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF];
162 void mz_free(
void *p)
167 MINIZ_EXPORT
void *miniz_def_alloc_func(
void *opaque,
size_t items,
size_t size)
169 (void)opaque, (
void)items, (void)size;
170 return MZ_MALLOC(items * size);
172 MINIZ_EXPORT
void miniz_def_free_func(
void *opaque,
void *address)
174 (void)opaque, (
void)address;
177 MINIZ_EXPORT
void *miniz_def_realloc_func(
void *opaque,
void *address,
size_t items,
size_t size)
179 (void)opaque, (
void)address, (void)items, (
void)size;
180 return MZ_REALLOC(address, items * size);
183 const char *mz_version(
void)
188#ifndef MINIZ_NO_ZLIB_APIS
190#ifndef MINIZ_NO_DEFLATE_APIS
192 int mz_deflateInit(
mz_streamp pStream,
int level)
194 return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY);
197 int mz_deflateInit2(
mz_streamp pStream,
int level,
int method,
int window_bits,
int mem_level,
int strategy)
200 mz_uint comp_flags = TDEFL_COMPUTE_ADLER32 | tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy);
203 return MZ_STREAM_ERROR;
204 if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) || ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)))
205 return MZ_PARAM_ERROR;
207 pStream->data_type = 0;
208 pStream->adler = MZ_ADLER32_INIT;
210 pStream->reserved = 0;
211 pStream->total_in = 0;
212 pStream->total_out = 0;
213 if (!pStream->zalloc)
214 pStream->zalloc = miniz_def_alloc_func;
216 pStream->zfree = miniz_def_free_func;
222 pStream->state = (
struct mz_internal_state *)pComp;
224 if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY)
226 mz_deflateEnd(pStream);
227 return MZ_PARAM_ERROR;
235 if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree))
236 return MZ_STREAM_ERROR;
237 pStream->total_in = pStream->total_out = 0;
244 size_t in_bytes, out_bytes;
245 mz_ulong orig_total_in, orig_total_out;
246 int mz_status = MZ_OK;
248 if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || (!pStream->next_out))
249 return MZ_STREAM_ERROR;
250 if (!pStream->avail_out)
253 if (flush == MZ_PARTIAL_FLUSH)
254 flush = MZ_SYNC_FLUSH;
256 if (((
tdefl_compressor *)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE)
257 return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR;
259 orig_total_in = pStream->total_in;
260 orig_total_out = pStream->total_out;
263 tdefl_status defl_status;
264 in_bytes = pStream->avail_in;
265 out_bytes = pStream->avail_out;
267 defl_status = tdefl_compress((
tdefl_compressor *)pStream->state, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, (tdefl_flush)flush);
268 pStream->next_in += (mz_uint)in_bytes;
269 pStream->avail_in -= (mz_uint)in_bytes;
270 pStream->total_in += (mz_uint)in_bytes;
273 pStream->next_out += (mz_uint)out_bytes;
274 pStream->avail_out -= (mz_uint)out_bytes;
275 pStream->total_out += (mz_uint)out_bytes;
279 mz_status = MZ_STREAM_ERROR;
282 else if (defl_status == TDEFL_STATUS_DONE)
284 mz_status = MZ_STREAM_END;
287 else if (!pStream->avail_out)
289 else if ((!pStream->avail_in) && (
flush != MZ_FINISH))
291 if ((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out))
303 return MZ_STREAM_ERROR;
306 pStream->zfree(pStream->opaque, pStream->state);
307 pStream->state = NULL;
312 mz_ulong mz_deflateBound(
mz_streamp pStream, mz_ulong source_len)
316 return MZ_MAX(128 + (source_len * 110) / 100, 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5);
319 int mz_compress2(
unsigned char *pDest, mz_ulong *pDest_len,
const unsigned char *pSource, mz_ulong source_len,
int level)
323 memset(&stream, 0,
sizeof(stream));
326 if ((mz_uint64)(source_len | *pDest_len) > 0xFFFFFFFFU)
327 return MZ_PARAM_ERROR;
329 stream.next_in = pSource;
330 stream.avail_in = (mz_uint32)source_len;
331 stream.next_out = pDest;
332 stream.avail_out = (mz_uint32)*pDest_len;
334 status = mz_deflateInit(&stream, level);
338 status = mz_deflate(&stream, MZ_FINISH);
339 if (status != MZ_STREAM_END)
341 mz_deflateEnd(&stream);
342 return (status == MZ_OK) ? MZ_BUF_ERROR : status;
345 *pDest_len = stream.total_out;
346 return mz_deflateEnd(&stream);
349 int mz_compress(
unsigned char *pDest, mz_ulong *pDest_len,
const unsigned char *pSource, mz_ulong source_len)
351 return mz_compress2(pDest, pDest_len, pSource, source_len, MZ_DEFAULT_COMPRESSION);
354 mz_ulong mz_compressBound(mz_ulong source_len)
356 return mz_deflateBound(NULL, source_len);
361#ifndef MINIZ_NO_INFLATE_APIS
366 mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed;
368 mz_uint8 m_dict[TINFL_LZ_DICT_SIZE];
369 tinfl_status m_last_status;
372 int mz_inflateInit2(
mz_streamp pStream,
int window_bits)
376 return MZ_STREAM_ERROR;
377 if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS))
378 return MZ_PARAM_ERROR;
380 pStream->data_type = 0;
383 pStream->total_in = 0;
384 pStream->total_out = 0;
385 pStream->reserved = 0;
386 if (!pStream->zalloc)
387 pStream->zalloc = miniz_def_alloc_func;
389 pStream->zfree = miniz_def_free_func;
395 pStream->state = (
struct mz_internal_state *)pDecomp;
397 tinfl_init(&pDecomp->m_decomp);
398 pDecomp->m_dict_ofs = 0;
399 pDecomp->m_dict_avail = 0;
400 pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
401 pDecomp->m_first_call = 1;
402 pDecomp->m_has_flushed = 0;
403 pDecomp->m_window_bits = window_bits;
410 return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS);
417 return MZ_STREAM_ERROR;
419 pStream->data_type = 0;
422 pStream->total_in = 0;
423 pStream->total_out = 0;
424 pStream->reserved = 0;
428 tinfl_init(&pDecomp->m_decomp);
429 pDecomp->m_dict_ofs = 0;
430 pDecomp->m_dict_avail = 0;
431 pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
432 pDecomp->m_first_call = 1;
433 pDecomp->m_has_flushed = 0;
442 mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32;
443 size_t in_bytes, out_bytes, orig_avail_in;
446 if ((!pStream) || (!pStream->state))
447 return MZ_STREAM_ERROR;
448 if (flush == MZ_PARTIAL_FLUSH)
449 flush = MZ_SYNC_FLUSH;
450 if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH))
451 return MZ_STREAM_ERROR;
454 if (pState->m_window_bits > 0)
455 decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER;
456 orig_avail_in = pStream->avail_in;
458 first_call = pState->m_first_call;
459 pState->m_first_call = 0;
460 if (pState->m_last_status < 0)
461 return MZ_DATA_ERROR;
463 if (pState->m_has_flushed && (flush != MZ_FINISH))
464 return MZ_STREAM_ERROR;
465 pState->m_has_flushed |= (
flush == MZ_FINISH);
467 if ((flush == MZ_FINISH) && (first_call))
470 decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF;
471 in_bytes = pStream->avail_in;
472 out_bytes = pStream->avail_out;
473 status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags);
474 pState->m_last_status = status;
475 pStream->next_in += (mz_uint)in_bytes;
476 pStream->avail_in -= (mz_uint)in_bytes;
477 pStream->total_in += (mz_uint)in_bytes;
478 pStream->adler = tinfl_get_adler32(&pState->m_decomp);
479 pStream->next_out += (mz_uint)out_bytes;
480 pStream->avail_out -= (mz_uint)out_bytes;
481 pStream->total_out += (mz_uint)out_bytes;
484 return MZ_DATA_ERROR;
485 else if (status != TINFL_STATUS_DONE)
487 pState->m_last_status = TINFL_STATUS_FAILED;
490 return MZ_STREAM_END;
493 if (flush != MZ_FINISH)
494 decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT;
496 if (pState->m_dict_avail)
498 n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
499 memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
500 pStream->next_out += n;
501 pStream->avail_out -= n;
502 pStream->total_out += n;
503 pState->m_dict_avail -= n;
504 pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
505 return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
510 in_bytes = pStream->avail_in;
511 out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs;
513 status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict, pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags);
514 pState->m_last_status = status;
516 pStream->next_in += (mz_uint)in_bytes;
517 pStream->avail_in -= (mz_uint)in_bytes;
518 pStream->total_in += (mz_uint)in_bytes;
519 pStream->adler = tinfl_get_adler32(&pState->m_decomp);
521 pState->m_dict_avail = (mz_uint)out_bytes;
523 n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
524 memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
525 pStream->next_out += n;
526 pStream->avail_out -= n;
527 pStream->total_out += n;
528 pState->m_dict_avail -= n;
529 pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
532 return MZ_DATA_ERROR;
533 else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in))
535 else if (flush == MZ_FINISH)
538 if (status == TINFL_STATUS_DONE)
539 return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END;
541 else if (!pStream->avail_out)
544 else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail))
548 return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
554 return MZ_STREAM_ERROR;
557 pStream->zfree(pStream->opaque, pStream->state);
558 pStream->state = NULL;
562 int mz_uncompress2(
unsigned char *pDest, mz_ulong *pDest_len,
const unsigned char *pSource, mz_ulong *pSource_len)
566 memset(&stream, 0,
sizeof(stream));
569 if ((mz_uint64)(*pSource_len | *pDest_len) > 0xFFFFFFFFU)
570 return MZ_PARAM_ERROR;
572 stream.next_in = pSource;
573 stream.avail_in = (mz_uint32)*pSource_len;
574 stream.next_out = pDest;
575 stream.avail_out = (mz_uint32)*pDest_len;
577 status = mz_inflateInit(&stream);
581 status = mz_inflate(&stream, MZ_FINISH);
582 *pSource_len = *pSource_len - stream.avail_in;
583 if (status != MZ_STREAM_END)
585 mz_inflateEnd(&stream);
586 return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status;
588 *pDest_len = stream.total_out;
590 return mz_inflateEnd(&stream);
593 int mz_uncompress(
unsigned char *pDest, mz_ulong *pDest_len,
const unsigned char *pSource, mz_ulong source_len)
595 return mz_uncompress2(pDest, pDest_len, pSource, &source_len);
600 const char *mz_error(
int err)
606 } s_error_descs[] = {
607 { MZ_OK,
"" }, { MZ_STREAM_END,
"stream end" }, { MZ_NEED_DICT,
"need dictionary" }, { MZ_ERRNO,
"file error" }, { MZ_STREAM_ERROR,
"stream error" }, { MZ_DATA_ERROR,
"data error" }, { MZ_MEM_ERROR,
"out of memory" }, { MZ_BUF_ERROR,
"buf error" }, { MZ_VERSION_ERROR,
"version error" }, { MZ_PARAM_ERROR,
"parameter error" }
610 for (i = 0; i <
sizeof(s_error_descs) /
sizeof(s_error_descs[0]); ++i)
611 if (s_error_descs[i].m_err == err)
612 return s_error_descs[i].m_pDesc;
676#ifndef MINIZ_NO_DEFLATE_APIS
686 static const mz_uint16 s_tdefl_len_sym[256] = {
687 257, 258, 259, 260, 261, 262, 263, 264, 265, 265, 266, 266, 267, 267, 268, 268, 269, 269, 269, 269, 270, 270, 270, 270, 271, 271, 271, 271, 272, 272, 272, 272,
688 273, 273, 273, 273, 273, 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, 274, 275, 275, 275, 275, 275, 275, 275, 275, 276, 276, 276, 276, 276, 276, 276, 276,
689 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
690 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280,
691 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281,
692 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282,
693 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283,
694 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 285
697 static const mz_uint8 s_tdefl_len_extra[256] = {
698 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
699 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
700 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
701 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0
704 static const mz_uint8 s_tdefl_small_dist_sym[512] = {
705 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11,
706 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13,
707 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
708 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
709 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
710 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
711 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
712 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
713 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
714 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
715 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
716 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17
719 static const mz_uint8 s_tdefl_small_dist_extra[512] = {
720 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
721 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
722 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
723 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
724 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
725 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
726 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
727 7, 7, 7, 7, 7, 7, 7, 7
730 static const mz_uint8 s_tdefl_large_dist_sym[128] = {
731 0, 0, 18, 19, 20, 20, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
732 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
733 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
736 static const mz_uint8 s_tdefl_large_dist_extra[128] = {
737 0, 0, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
738 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
739 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13
745 mz_uint16 m_key, m_sym_index;
749 mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2];
752 for (i = 0; i < num_syms; i++)
754 mz_uint freq = pSyms0[i].m_key;
756 hist[256 + ((freq >> 8) & 0xFF)]++;
758 while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256]))
760 for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8)
762 const mz_uint32 *pHist = &hist[pass << 8];
763 mz_uint offsets[256], cur_ofs = 0;
764 for (i = 0; i < 256; i++)
766 offsets[i] = cur_ofs;
769 for (i = 0; i < num_syms; i++)
770 pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = pCur_syms[i];
773 pCur_syms = pNew_syms;
781 static void tdefl_calculate_minimum_redundancy(
tdefl_sym_freq *A,
int n)
783 int root, leaf, next, avbl, used, dpth;
791 A[0].m_key += A[1].m_key;
794 for (next = 1; next < n - 1; next++)
796 if (leaf >= n || A[root].m_key < A[leaf].m_key)
798 A[next].m_key = A[root].m_key;
799 A[root++].m_key = (mz_uint16)next;
802 A[next].m_key = A[leaf++].m_key;
803 if (leaf >= n || (root < next && A[root].m_key < A[leaf].m_key))
805 A[next].m_key = (mz_uint16)(A[next].m_key + A[root].m_key);
806 A[root++].m_key = (mz_uint16)next;
809 A[next].m_key = (mz_uint16)(A[next].m_key + A[leaf++].m_key);
812 for (next = n - 3; next >= 0; next--)
813 A[next].m_key = A[A[next].m_key].m_key + 1;
820 while (root >= 0 && (
int)A[root].m_key == dpth)
827 A[next--].m_key = (mz_uint16)(dpth);
839 TDEFL_MAX_SUPPORTED_HUFF_CODESIZE = 32
841 static void tdefl_huffman_enforce_max_code_size(
int *pNum_codes,
int code_list_len,
int max_code_size)
845 if (code_list_len <= 1)
847 for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++)
848 pNum_codes[max_code_size] += pNum_codes[i];
849 for (i = max_code_size; i > 0; i--)
850 total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i));
851 while (total != (1UL << max_code_size))
853 pNum_codes[max_code_size]--;
854 for (i = max_code_size - 1; i > 0; i--)
858 pNum_codes[i + 1] += 2;
865 static void tdefl_optimize_huffman_table(
tdefl_compressor *d,
int table_num,
int table_len,
int code_size_limit,
int static_table)
867 int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE];
868 mz_uint next_code[TDEFL_MAX_SUPPORTED_HUFF_CODESIZE + 1];
869 MZ_CLEAR_ARR(num_codes);
872 for (i = 0; i < table_len; i++)
873 num_codes[d->m_huff_code_sizes[table_num][i]]++;
877 tdefl_sym_freq syms0[TDEFL_MAX_HUFF_SYMBOLS], syms1[TDEFL_MAX_HUFF_SYMBOLS], *pSyms;
878 int num_used_syms = 0;
879 const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0];
880 for (i = 0; i < table_len; i++)
883 syms0[num_used_syms].m_key = (mz_uint16)pSym_count[i];
884 syms0[num_used_syms++].m_sym_index = (mz_uint16)i;
887 pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1);
888 tdefl_calculate_minimum_redundancy(pSyms, num_used_syms);
890 for (i = 0; i < num_used_syms; i++)
891 num_codes[pSyms[i].m_key]++;
893 tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, code_size_limit);
895 MZ_CLEAR_ARR(d->m_huff_code_sizes[table_num]);
896 MZ_CLEAR_ARR(d->m_huff_codes[table_num]);
897 for (i = 1, j = num_used_syms; i <= code_size_limit; i++)
898 for (l = num_codes[i]; l > 0; l--)
899 d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i);
903 for (j = 0, i = 2; i <= code_size_limit; i++)
904 next_code[i] = j = ((j + num_codes[i - 1]) << 1);
906 for (i = 0; i < table_len; i++)
908 mz_uint rev_code = 0, code, code_size;
909 if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0)
911 code = next_code[code_size]++;
912 for (l = code_size; l > 0; l--, code >>= 1)
913 rev_code = (rev_code << 1) | (code & 1);
914 d->m_huff_codes[table_num][i] = (mz_uint16)rev_code;
918#define TDEFL_PUT_BITS(b, l) \
923 MZ_ASSERT(bits <= ((1U << len) - 1U)); \
924 d->m_bit_buffer |= (bits << d->m_bits_in); \
925 d->m_bits_in += len; \
926 while (d->m_bits_in >= 8) \
928 if (d->m_pOutput_buf < d->m_pOutput_buf_end) \
929 *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \
930 d->m_bit_buffer >>= 8; \
936#define TDEFL_RLE_PREV_CODE_SIZE() \
938 if (rle_repeat_count) \
940 if (rle_repeat_count < 3) \
942 d->m_huff_count[2][prev_code_size] = (mz_uint16)(d->m_huff_count[2][prev_code_size] + rle_repeat_count); \
943 while (rle_repeat_count--) \
944 packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \
948 d->m_huff_count[2][16] = (mz_uint16)(d->m_huff_count[2][16] + 1); \
949 packed_code_sizes[num_packed_code_sizes++] = 16; \
950 packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_repeat_count - 3); \
952 rle_repeat_count = 0; \
956#define TDEFL_RLE_ZERO_CODE_SIZE() \
960 if (rle_z_count < 3) \
962 d->m_huff_count[2][0] = (mz_uint16)(d->m_huff_count[2][0] + rle_z_count); \
963 while (rle_z_count--) \
964 packed_code_sizes[num_packed_code_sizes++] = 0; \
966 else if (rle_z_count <= 10) \
968 d->m_huff_count[2][17] = (mz_uint16)(d->m_huff_count[2][17] + 1); \
969 packed_code_sizes[num_packed_code_sizes++] = 17; \
970 packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 3); \
974 d->m_huff_count[2][18] = (mz_uint16)(d->m_huff_count[2][18] + 1); \
975 packed_code_sizes[num_packed_code_sizes++] = 18; \
976 packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 11); \
982 static const mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
986 int num_lit_codes, num_dist_codes, num_bit_lengths;
987 mz_uint i, total_code_sizes_to_pack, num_packed_code_sizes, rle_z_count, rle_repeat_count, packed_code_sizes_index;
988 mz_uint8 code_sizes_to_pack[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], packed_code_sizes[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], prev_code_size = 0xFF;
990 d->m_huff_count[0][256] = 1;
992 tdefl_optimize_huffman_table(d, 0, TDEFL_MAX_HUFF_SYMBOLS_0, 15, MZ_FALSE);
993 tdefl_optimize_huffman_table(d, 1, TDEFL_MAX_HUFF_SYMBOLS_1, 15, MZ_FALSE);
995 for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--)
996 if (d->m_huff_code_sizes[0][num_lit_codes - 1])
998 for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--)
999 if (d->m_huff_code_sizes[1][num_dist_codes - 1])
1002 memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes);
1003 memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0], num_dist_codes);
1004 total_code_sizes_to_pack = num_lit_codes + num_dist_codes;
1005 num_packed_code_sizes = 0;
1007 rle_repeat_count = 0;
1009 memset(&d->m_huff_count[2][0], 0,
sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2);
1010 for (i = 0; i < total_code_sizes_to_pack; i++)
1012 mz_uint8 code_size = code_sizes_to_pack[i];
1015 TDEFL_RLE_PREV_CODE_SIZE();
1016 if (++rle_z_count == 138)
1018 TDEFL_RLE_ZERO_CODE_SIZE();
1023 TDEFL_RLE_ZERO_CODE_SIZE();
1024 if (code_size != prev_code_size)
1026 TDEFL_RLE_PREV_CODE_SIZE();
1027 d->m_huff_count[2][code_size] = (mz_uint16)(d->m_huff_count[2][code_size] + 1);
1028 packed_code_sizes[num_packed_code_sizes++] = code_size;
1030 else if (++rle_repeat_count == 6)
1032 TDEFL_RLE_PREV_CODE_SIZE();
1035 prev_code_size = code_size;
1037 if (rle_repeat_count)
1039 TDEFL_RLE_PREV_CODE_SIZE();
1043 TDEFL_RLE_ZERO_CODE_SIZE();
1046 tdefl_optimize_huffman_table(d, 2, TDEFL_MAX_HUFF_SYMBOLS_2, 7, MZ_FALSE);
1048 TDEFL_PUT_BITS(2, 2);
1050 TDEFL_PUT_BITS(num_lit_codes - 257, 5);
1051 TDEFL_PUT_BITS(num_dist_codes - 1, 5);
1053 for (num_bit_lengths = 18; num_bit_lengths >= 0; num_bit_lengths--)
1054 if (d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[num_bit_lengths]])
1056 num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1));
1057 TDEFL_PUT_BITS(num_bit_lengths - 4, 4);
1058 for (i = 0; (int)i < num_bit_lengths; i++)
1059 TDEFL_PUT_BITS(d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[i]], 3);
1061 for (packed_code_sizes_index = 0; packed_code_sizes_index < num_packed_code_sizes;)
1063 mz_uint code = packed_code_sizes[packed_code_sizes_index++];
1064 MZ_ASSERT(code < TDEFL_MAX_HUFF_SYMBOLS_2);
1065 TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]);
1067 TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++],
"\02\03\07"[code - 16]);
1074 mz_uint8 *p = &d->m_huff_code_sizes[0][0];
1076 for (i = 0; i <= 143; ++i)
1078 for (; i <= 255; ++i)
1080 for (; i <= 279; ++i)
1082 for (; i <= 287; ++i)
1085 memset(d->m_huff_code_sizes[1], 5, 32);
1087 tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE);
1088 tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE);
1090 TDEFL_PUT_BITS(1, 2);
1093 static const mz_uint mz_bitmasks[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
1095#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS
1099 mz_uint8 *pLZ_codes;
1100 mz_uint8 *pOutput_buf = d->m_pOutput_buf;
1101 mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf;
1102 mz_uint64 bit_buffer = d->m_bit_buffer;
1103 mz_uint bits_in = d->m_bits_in;
1105#define TDEFL_PUT_BITS_FAST(b, l) \
1107 bit_buffer |= (((mz_uint64)(b)) << bits_in); \
1112 for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end; flags >>= 1)
1115 flags = *pLZ_codes++ | 0x100;
1119 mz_uint s0, s1, n0, n1, sym, num_extra_bits;
1120 mz_uint match_len = pLZ_codes[0];
1121 mz_uint match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8));
1124 MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
1125 TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
1126 TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]);
1129 s0 = s_tdefl_small_dist_sym[match_dist & 511];
1130 n0 = s_tdefl_small_dist_extra[match_dist & 511];
1131 s1 = s_tdefl_large_dist_sym[match_dist >> 8];
1132 n1 = s_tdefl_large_dist_extra[match_dist >> 8];
1133 sym = (match_dist < 512) ? s0 : s1;
1134 num_extra_bits = (match_dist < 512) ? n0 : n1;
1136 MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
1137 TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
1138 TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
1142 mz_uint lit = *pLZ_codes++;
1143 MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
1144 TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
1146 if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
1150 MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
1151 TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
1153 if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
1157 MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
1158 TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
1163 if (pOutput_buf >= d->m_pOutput_buf_end)
1166 memcpy(pOutput_buf, &bit_buffer,
sizeof(mz_uint64));
1167 pOutput_buf += (bits_in >> 3);
1168 bit_buffer >>= (bits_in & ~7);
1172#undef TDEFL_PUT_BITS_FAST
1174 d->m_pOutput_buf = pOutput_buf;
1176 d->m_bit_buffer = 0;
1180 mz_uint32 n = MZ_MIN(bits_in, 16);
1181 TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n);
1186 TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
1188 return (d->m_pOutput_buf < d->m_pOutput_buf_end);
1194 mz_uint8 *pLZ_codes;
1197 for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf; flags >>= 1)
1200 flags = *pLZ_codes++ | 0x100;
1203 mz_uint sym, num_extra_bits;
1204 mz_uint match_len = pLZ_codes[0], match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8));
1207 MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
1208 TDEFL_PUT_BITS(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
1209 TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]);
1211 if (match_dist < 512)
1213 sym = s_tdefl_small_dist_sym[match_dist];
1214 num_extra_bits = s_tdefl_small_dist_extra[match_dist];
1218 sym = s_tdefl_large_dist_sym[match_dist >> 8];
1219 num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8];
1221 MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
1222 TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
1223 TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
1227 mz_uint lit = *pLZ_codes++;
1228 MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
1229 TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
1233 TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
1235 return (d->m_pOutput_buf < d->m_pOutput_buf_end);
1239 static mz_bool tdefl_compress_block(
tdefl_compressor *d, mz_bool static_block)
1242 tdefl_start_static_block(d);
1244 tdefl_start_dynamic_block(d);
1245 return tdefl_compress_lz_codes(d);
1248 static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
1252 mz_uint saved_bit_buf, saved_bits_in;
1253 mz_uint8 *pSaved_output_buf;
1254 mz_bool comp_block_succeeded = MZ_FALSE;
1255 int n, use_raw_block = ((d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS) != 0) && (d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size;
1256 mz_uint8 *pOutput_buf_start = ((d->m_pPut_buf_func == NULL) && ((*d->m_pOut_buf_size - d->m_out_buf_ofs) >= TDEFL_OUT_BUF_SIZE)) ? ((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs) : d->m_output_buf;
1258 d->m_pOutput_buf = pOutput_buf_start;
1259 d->m_pOutput_buf_end = d->m_pOutput_buf + TDEFL_OUT_BUF_SIZE - 16;
1261 MZ_ASSERT(!d->m_output_flush_remaining);
1262 d->m_output_flush_ofs = 0;
1263 d->m_output_flush_remaining = 0;
1265 *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left);
1266 d->m_pLZ_code_buf -= (d->m_num_flags_left == 8);
1268 if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index))
1270 const mz_uint8 cmf = 0x78;
1271 mz_uint8 flg, flevel = 3;
1272 mz_uint header, i, mz_un =
sizeof(s_tdefl_num_probes) /
sizeof(mz_uint);
1275 for (i = 0; i < mz_un; i++)
1276 if (s_tdefl_num_probes[i] == (d->m_flags & 0xFFF))
1286 header = cmf << 8 | (flevel << 6);
1287 header += 31 - (header % 31);
1288 flg = header & 0xFF;
1290 TDEFL_PUT_BITS(cmf, 8);
1291 TDEFL_PUT_BITS(flg, 8);
1294 TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1);
1296 pSaved_output_buf = d->m_pOutput_buf;
1297 saved_bit_buf = d->m_bit_buffer;
1298 saved_bits_in = d->m_bits_in;
1301 comp_block_succeeded = tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || (d->m_total_lz_bytes < 48));
1304 if (((use_raw_block) || ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >= d->m_total_lz_bytes))) &&
1305 ((d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size))
1308 d->m_pOutput_buf = pSaved_output_buf;
1309 d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
1310 TDEFL_PUT_BITS(0, 2);
1313 TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
1315 for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF)
1317 TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16);
1319 for (i = 0; i < d->m_total_lz_bytes; ++i)
1321 TDEFL_PUT_BITS(d->m_dict[(d->m_lz_code_buf_dict_pos + i) & TDEFL_LZ_DICT_SIZE_MASK], 8);
1325 else if (!comp_block_succeeded)
1327 d->m_pOutput_buf = pSaved_output_buf;
1328 d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
1329 tdefl_compress_block(d, MZ_TRUE);
1334 if (flush == TDEFL_FINISH)
1338 TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
1340 if (d->m_flags & TDEFL_WRITE_ZLIB_HEADER)
1342 mz_uint i, a = d->m_adler32;
1343 for (i = 0; i < 4; i++)
1345 TDEFL_PUT_BITS((a >> 24) & 0xFF, 8);
1353 TDEFL_PUT_BITS(0, 3);
1356 TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
1358 for (i = 2; i; --i, z ^= 0xFFFF)
1360 TDEFL_PUT_BITS(z & 0xFFFF, 16);
1365 MZ_ASSERT(d->m_pOutput_buf < d->m_pOutput_buf_end);
1367 memset(&d->m_huff_count[0][0], 0,
sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
1368 memset(&d->m_huff_count[1][0], 0,
sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
1370 d->m_pLZ_code_buf = d->m_lz_code_buf + 1;
1371 d->m_pLZ_flags = d->m_lz_code_buf;
1372 d->m_num_flags_left = 8;
1373 d->m_lz_code_buf_dict_pos += d->m_total_lz_bytes;
1374 d->m_total_lz_bytes = 0;
1377 if ((n = (
int)(d->m_pOutput_buf - pOutput_buf_start)) != 0)
1379 if (d->m_pPut_buf_func)
1381 *d->m_pIn_buf_size = d->m_pSrc - (
const mz_uint8 *)d->m_pIn_buf;
1382 if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user))
1383 return (d->m_prev_return_status = TDEFL_STATUS_PUT_BUF_FAILED);
1385 else if (pOutput_buf_start == d->m_output_buf)
1387 int bytes_to_copy = (int)MZ_MIN((
size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs));
1388 memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf, bytes_to_copy);
1389 d->m_out_buf_ofs += bytes_to_copy;
1390 if ((n -= bytes_to_copy) != 0)
1392 d->m_output_flush_ofs = bytes_to_copy;
1393 d->m_output_flush_remaining = n;
1398 d->m_out_buf_ofs += n;
1402 return d->m_output_flush_remaining;
1405#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
1406#ifdef MINIZ_UNALIGNED_USE_MEMCPY
1407 static mz_uint16 TDEFL_READ_UNALIGNED_WORD(
const mz_uint8 *p)
1410 memcpy(&ret, p,
sizeof(mz_uint16));
1413 static mz_uint16 TDEFL_READ_UNALIGNED_WORD2(
const mz_uint16 *p)
1416 memcpy(&ret, p,
sizeof(mz_uint16));
1420#define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16 *)(p)
1421#define TDEFL_READ_UNALIGNED_WORD2(p) *(const mz_uint16 *)(p)
1423 static MZ_FORCEINLINE
void tdefl_find_match(
tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len)
1425 mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len;
1426 mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
1427 const mz_uint16 *s = (
const mz_uint16 *)(d->m_dict + pos), *p, *q;
1428 mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]), s01 = TDEFL_READ_UNALIGNED_WORD2(s);
1429 MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN);
1430 if (max_match_len <= match_len)
1436 if (--num_probes_left == 0)
1438#define TDEFL_PROBE \
1439 next_probe_pos = d->m_next[probe_pos]; \
1440 if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \
1442 probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
1443 if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) \
1451 q = (
const mz_uint16 *)(d->m_dict + probe_pos);
1452 if (TDEFL_READ_UNALIGNED_WORD2(q) != s01)
1458 }
while ((TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) &&
1459 (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (--probe_len > 0));
1462 *pMatch_dist = dist;
1463 *pMatch_len = MZ_MIN(max_match_len, (mz_uint)TDEFL_MAX_MATCH_LEN);
1466 else if ((probe_len = ((mz_uint)(p - s) * 2) + (mz_uint)(*(
const mz_uint8 *)p == *(
const mz_uint8 *)q)) > match_len)
1468 *pMatch_dist = dist;
1469 if ((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) == max_match_len)
1471 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]);
1476static MZ_FORCEINLINE
void tdefl_find_match(
tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len)
1478 mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len;
1479 mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
1480 const mz_uint8 *s = d->m_dict + pos, *p, *q;
1481 mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1];
1482 MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN);
1483 if (max_match_len <= match_len)
1489 if (--num_probes_left == 0)
1491#define TDEFL_PROBE \
1492 next_probe_pos = d->m_next[probe_pos]; \
1493 if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \
1495 probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
1496 if ((d->m_dict[probe_pos + match_len] == c0) && (d->m_dict[probe_pos + match_len - 1] == c1)) \
1505 q = d->m_dict + probe_pos;
1506 for (probe_len = 0; probe_len < max_match_len; probe_len++)
1509 if (probe_len > match_len)
1511 *pMatch_dist = dist;
1512 if ((*pMatch_len = match_len = probe_len) == max_match_len)
1514 c0 = d->m_dict[pos + match_len];
1515 c1 = d->m_dict[pos + match_len - 1];
1521#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
1522#ifdef MINIZ_UNALIGNED_USE_MEMCPY
1523 static mz_uint32 TDEFL_READ_UNALIGNED_WORD32(
const mz_uint8 *p)
1526 memcpy(&ret, p,
sizeof(mz_uint32));
1530#define TDEFL_READ_UNALIGNED_WORD32(p) *(const mz_uint32 *)(p)
1535 mz_uint lookahead_pos = d->m_lookahead_pos, lookahead_size = d->m_lookahead_size, dict_size = d->m_dict_size, total_lz_bytes = d->m_total_lz_bytes, num_flags_left = d->m_num_flags_left;
1536 mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags;
1537 mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
1539 while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size)))
1541 const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096;
1542 mz_uint dst_pos = (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK;
1543 mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size);
1544 d->m_src_buf_left -= num_bytes_to_process;
1545 lookahead_size += num_bytes_to_process;
1547 while (num_bytes_to_process)
1549 mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process);
1550 memcpy(d->m_dict + dst_pos, d->m_pSrc, n);
1551 if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
1552 memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc, MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos));
1554 dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK;
1555 num_bytes_to_process -= n;
1558 dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size);
1559 if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE))
1562 while (lookahead_size >= 4)
1564 mz_uint cur_match_dist, cur_match_len = 1;
1565 mz_uint8 *pCur_dict = d->m_dict + cur_pos;
1566 mz_uint first_trigram = TDEFL_READ_UNALIGNED_WORD32(pCur_dict) & 0xFFFFFF;
1567 mz_uint hash = (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) & TDEFL_LEVEL1_HASH_SIZE_MASK;
1568 mz_uint probe_pos = d->m_hash[hash];
1569 d->m_hash[hash] = (mz_uint16)lookahead_pos;
1571 if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <= dict_size) && ((TDEFL_READ_UNALIGNED_WORD32(d->m_dict + (probe_pos &= TDEFL_LZ_DICT_SIZE_MASK)) & 0xFFFFFF) == first_trigram))
1573 const mz_uint16 *p = (
const mz_uint16 *)pCur_dict;
1574 const mz_uint16 *q = (
const mz_uint16 *)(d->m_dict + probe_pos);
1575 mz_uint32 probe_len = 32;
1578 }
while ((TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) &&
1579 (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (--probe_len > 0));
1580 cur_match_len = ((mz_uint)(p - (
const mz_uint16 *)pCur_dict) * 2) + (mz_uint)(*(
const mz_uint8 *)p == *(
const mz_uint8 *)q);
1582 cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0;
1584 if ((cur_match_len < TDEFL_MIN_MATCH_LEN) || ((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U * 1024U)))
1587 *pLZ_code_buf++ = (mz_uint8)first_trigram;
1588 *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
1589 d->m_huff_count[0][(mz_uint8)first_trigram]++;
1594 cur_match_len = MZ_MIN(cur_match_len, lookahead_size);
1596 MZ_ASSERT((cur_match_len >= TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 1) && (cur_match_dist <= TDEFL_LZ_DICT_SIZE));
1600 pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN);
1601#ifdef MINIZ_UNALIGNED_USE_MEMCPY
1602 memcpy(&pLZ_code_buf[1], &cur_match_dist,
sizeof(cur_match_dist));
1604 *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist;
1607 *pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80);
1609 s0 = s_tdefl_small_dist_sym[cur_match_dist & 511];
1610 s1 = s_tdefl_large_dist_sym[cur_match_dist >> 8];
1611 d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++;
1613 d->m_huff_count[0][s_tdefl_len_sym[cur_match_len - TDEFL_MIN_MATCH_LEN]]++;
1618 *pLZ_code_buf++ = (mz_uint8)first_trigram;
1619 *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
1620 d->m_huff_count[0][(mz_uint8)first_trigram]++;
1623 if (--num_flags_left == 0)
1626 pLZ_flags = pLZ_code_buf++;
1629 total_lz_bytes += cur_match_len;
1630 lookahead_pos += cur_match_len;
1631 dict_size = MZ_MIN(dict_size + cur_match_len, (mz_uint)TDEFL_LZ_DICT_SIZE);
1632 cur_pos = (cur_pos + cur_match_len) & TDEFL_LZ_DICT_SIZE_MASK;
1633 MZ_ASSERT(lookahead_size >= cur_match_len);
1634 lookahead_size -= cur_match_len;
1636 if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8])
1639 d->m_lookahead_pos = lookahead_pos;
1640 d->m_lookahead_size = lookahead_size;
1641 d->m_dict_size = dict_size;
1642 d->m_total_lz_bytes = total_lz_bytes;
1643 d->m_pLZ_code_buf = pLZ_code_buf;
1644 d->m_pLZ_flags = pLZ_flags;
1645 d->m_num_flags_left = num_flags_left;
1646 if ((n = tdefl_flush_block(d, 0)) != 0)
1647 return (n < 0) ? MZ_FALSE : MZ_TRUE;
1648 total_lz_bytes = d->m_total_lz_bytes;
1649 pLZ_code_buf = d->m_pLZ_code_buf;
1650 pLZ_flags = d->m_pLZ_flags;
1651 num_flags_left = d->m_num_flags_left;
1655 while (lookahead_size)
1657 mz_uint8 lit = d->m_dict[cur_pos];
1660 *pLZ_code_buf++ = lit;
1661 *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
1662 if (--num_flags_left == 0)
1665 pLZ_flags = pLZ_code_buf++;
1668 d->m_huff_count[0][lit]++;
1671 dict_size = MZ_MIN(dict_size + 1, (mz_uint)TDEFL_LZ_DICT_SIZE);
1672 cur_pos = (cur_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK;
1675 if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8])
1678 d->m_lookahead_pos = lookahead_pos;
1679 d->m_lookahead_size = lookahead_size;
1680 d->m_dict_size = dict_size;
1681 d->m_total_lz_bytes = total_lz_bytes;
1682 d->m_pLZ_code_buf = pLZ_code_buf;
1683 d->m_pLZ_flags = pLZ_flags;
1684 d->m_num_flags_left = num_flags_left;
1685 if ((n = tdefl_flush_block(d, 0)) != 0)
1686 return (n < 0) ? MZ_FALSE : MZ_TRUE;
1687 total_lz_bytes = d->m_total_lz_bytes;
1688 pLZ_code_buf = d->m_pLZ_code_buf;
1689 pLZ_flags = d->m_pLZ_flags;
1690 num_flags_left = d->m_num_flags_left;
1695 d->m_lookahead_pos = lookahead_pos;
1696 d->m_lookahead_size = lookahead_size;
1697 d->m_dict_size = dict_size;
1698 d->m_total_lz_bytes = total_lz_bytes;
1699 d->m_pLZ_code_buf = pLZ_code_buf;
1700 d->m_pLZ_flags = pLZ_flags;
1701 d->m_num_flags_left = num_flags_left;
1706 static MZ_FORCEINLINE
void tdefl_record_literal(
tdefl_compressor *d, mz_uint8 lit)
1708 d->m_total_lz_bytes++;
1709 *d->m_pLZ_code_buf++ = lit;
1710 *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1);
1711 if (--d->m_num_flags_left == 0)
1713 d->m_num_flags_left = 8;
1714 d->m_pLZ_flags = d->m_pLZ_code_buf++;
1716 d->m_huff_count[0][lit]++;
1719 static MZ_FORCEINLINE
void tdefl_record_match(
tdefl_compressor *d, mz_uint match_len, mz_uint match_dist)
1723 MZ_ASSERT((match_len >= TDEFL_MIN_MATCH_LEN) && (match_dist >= 1) && (match_dist <= TDEFL_LZ_DICT_SIZE));
1725 d->m_total_lz_bytes += match_len;
1727 d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN);
1730 d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF);
1731 d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8);
1732 d->m_pLZ_code_buf += 3;
1734 *d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80);
1735 if (--d->m_num_flags_left == 0)
1737 d->m_num_flags_left = 8;
1738 d->m_pLZ_flags = d->m_pLZ_code_buf++;
1741 s0 = s_tdefl_small_dist_sym[match_dist & 511];
1742 s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127];
1743 d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++;
1744 d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++;
1749 const mz_uint8 *pSrc = d->m_pSrc;
1750 size_t src_buf_left = d->m_src_buf_left;
1751 tdefl_flush
flush = d->m_flush;
1753 while ((src_buf_left) || ((flush) && (d->m_lookahead_size)))
1755 mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos;
1757 if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1))
1759 mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK, ins_pos = d->m_lookahead_pos + d->m_lookahead_size - 2;
1760 mz_uint hash = (d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK];
1761 mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size);
1762 const mz_uint8 *pSrc_end = pSrc ? pSrc + num_bytes_to_process : NULL;
1763 src_buf_left -= num_bytes_to_process;
1764 d->m_lookahead_size += num_bytes_to_process;
1765 while (pSrc != pSrc_end)
1767 mz_uint8 c = *pSrc++;
1768 d->m_dict[dst_pos] = c;
1769 if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
1770 d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
1771 hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1);
1772 d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash];
1773 d->m_hash[hash] = (mz_uint16)(ins_pos);
1774 dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK;
1780 while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
1782 mz_uint8 c = *pSrc++;
1783 mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK;
1785 d->m_dict[dst_pos] = c;
1786 if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
1787 d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
1788 if ((++d->m_lookahead_size + d->m_dict_size) >= TDEFL_MIN_MATCH_LEN)
1790 mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2;
1791 mz_uint hash = ((d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << (TDEFL_LZ_HASH_SHIFT * 2)) ^ (d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1);
1792 d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash];
1793 d->m_hash[hash] = (mz_uint16)(ins_pos);
1797 d->m_dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - d->m_lookahead_size, d->m_dict_size);
1798 if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
1804 cur_match_len = d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1);
1805 cur_pos = d->m_lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
1806 if (d->m_flags & (TDEFL_RLE_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS))
1808 if ((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS)))
1810 mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK];
1812 while (cur_match_len < d->m_lookahead_size)
1814 if (d->m_dict[cur_pos + cur_match_len] != c)
1818 if (cur_match_len < TDEFL_MIN_MATCH_LEN)
1826 tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size, d->m_lookahead_size, &cur_match_dist, &cur_match_len);
1828 if (((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U * 1024U)) || (cur_pos == cur_match_dist) || ((d->m_flags & TDEFL_FILTER_MATCHES) && (cur_match_len <= 5)))
1830 cur_match_dist = cur_match_len = 0;
1832 if (d->m_saved_match_len)
1834 if (cur_match_len > d->m_saved_match_len)
1836 tdefl_record_literal(d, (mz_uint8)d->m_saved_lit);
1837 if (cur_match_len >= 128)
1839 tdefl_record_match(d, cur_match_len, cur_match_dist);
1840 d->m_saved_match_len = 0;
1841 len_to_move = cur_match_len;
1845 d->m_saved_lit = d->m_dict[cur_pos];
1846 d->m_saved_match_dist = cur_match_dist;
1847 d->m_saved_match_len = cur_match_len;
1852 tdefl_record_match(d, d->m_saved_match_len, d->m_saved_match_dist);
1853 len_to_move = d->m_saved_match_len - 1;
1854 d->m_saved_match_len = 0;
1857 else if (!cur_match_dist)
1858 tdefl_record_literal(d, d->m_dict[MZ_MIN(cur_pos,
sizeof(d->m_dict) - 1)]);
1859 else if ((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) || (cur_match_len >= 128))
1861 tdefl_record_match(d, cur_match_len, cur_match_dist);
1862 len_to_move = cur_match_len;
1866 d->m_saved_lit = d->m_dict[MZ_MIN(cur_pos,
sizeof(d->m_dict) - 1)];
1867 d->m_saved_match_dist = cur_match_dist;
1868 d->m_saved_match_len = cur_match_len;
1871 d->m_lookahead_pos += len_to_move;
1872 MZ_ASSERT(d->m_lookahead_size >= len_to_move);
1873 d->m_lookahead_size -= len_to_move;
1874 d->m_dict_size = MZ_MIN(d->m_dict_size + len_to_move, (mz_uint)TDEFL_LZ_DICT_SIZE);
1876 if ((d->m_pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) ||
1877 ((d->m_total_lz_bytes > 31 * 1024) && (((((mz_uint)(d->m_pLZ_code_buf - d->m_lz_code_buf) * 115) >> 7) >= d->m_total_lz_bytes) || (d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))))
1881 d->m_src_buf_left = src_buf_left;
1882 if ((n = tdefl_flush_block(d, 0)) != 0)
1883 return (n < 0) ? MZ_FALSE : MZ_TRUE;
1888 d->m_src_buf_left = src_buf_left;
1894 if (d->m_pIn_buf_size)
1896 *d->m_pIn_buf_size = d->m_pSrc - (
const mz_uint8 *)d->m_pIn_buf;
1899 if (d->m_pOut_buf_size)
1901 size_t n = MZ_MIN(*d->m_pOut_buf_size - d->m_out_buf_ofs, d->m_output_flush_remaining);
1902 memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf + d->m_output_flush_ofs, n);
1903 d->m_output_flush_ofs += (mz_uint)n;
1904 d->m_output_flush_remaining -= (mz_uint)n;
1905 d->m_out_buf_ofs += n;
1907 *d->m_pOut_buf_size = d->m_out_buf_ofs;
1910 return (d->m_finished && !d->m_output_flush_remaining) ? TDEFL_STATUS_DONE : TDEFL_STATUS_OKAY;
1913 tdefl_status tdefl_compress(
tdefl_compressor *d,
const void *pIn_buf,
size_t *pIn_buf_size,
void *pOut_buf,
size_t *pOut_buf_size, tdefl_flush flush)
1921 return TDEFL_STATUS_BAD_PARAM;
1924 d->m_pIn_buf = pIn_buf;
1925 d->m_pIn_buf_size = pIn_buf_size;
1926 d->m_pOut_buf = pOut_buf;
1927 d->m_pOut_buf_size = pOut_buf_size;
1928 d->m_pSrc = (
const mz_uint8 *)(pIn_buf);
1929 d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0;
1930 d->m_out_buf_ofs = 0;
1933 if (((d->m_pPut_buf_func != NULL) == ((pOut_buf != NULL) || (pOut_buf_size != NULL))) || (d->m_prev_return_status != TDEFL_STATUS_OKAY) ||
1934 (d->m_wants_to_finish && (flush != TDEFL_FINISH)) || (pIn_buf_size && *pIn_buf_size && !pIn_buf) || (pOut_buf_size && *pOut_buf_size && !pOut_buf))
1940 return (d->m_prev_return_status = TDEFL_STATUS_BAD_PARAM);
1942 d->m_wants_to_finish |= (
flush == TDEFL_FINISH);
1944 if ((d->m_output_flush_remaining) || (d->m_finished))
1945 return (d->m_prev_return_status = tdefl_flush_output_buffer(d));
1947#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
1948 if (((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) &&
1949 ((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) &&
1950 ((d->m_flags & (TDEFL_FILTER_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS | TDEFL_RLE_MATCHES)) == 0))
1952 if (!tdefl_compress_fast(d))
1953 return d->m_prev_return_status;
1958 if (!tdefl_compress_normal(d))
1959 return d->m_prev_return_status;
1962 if ((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) && (pIn_buf))
1963 d->m_adler32 = (mz_uint32)mz_adler32(d->m_adler32, (
const mz_uint8 *)pIn_buf, d->m_pSrc - (
const mz_uint8 *)pIn_buf);
1965 if ((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) && (!d->m_output_flush_remaining))
1967 if (tdefl_flush_block(d, flush) < 0)
1968 return d->m_prev_return_status;
1969 d->m_finished = (
flush == TDEFL_FINISH);
1970 if (flush == TDEFL_FULL_FLUSH)
1972 MZ_CLEAR_ARR(d->m_hash);
1973 MZ_CLEAR_ARR(d->m_next);
1978 return (d->m_prev_return_status = tdefl_flush_output_buffer(d));
1981 tdefl_status tdefl_compress_buffer(
tdefl_compressor *d,
const void *pIn_buf,
size_t in_buf_size, tdefl_flush flush)
1983 MZ_ASSERT(d->m_pPut_buf_func);
1984 return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush);
1987 tdefl_status tdefl_init(
tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func,
void *pPut_buf_user,
int flags)
1989 d->m_pPut_buf_func = pPut_buf_func;
1990 d->m_pPut_buf_user = pPut_buf_user;
1991 d->m_flags = (mz_uint)(flags);
1992 d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3;
1993 d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0;
1994 d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3;
1995 if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG))
1996 MZ_CLEAR_ARR(d->m_hash);
1997 d->m_lookahead_pos = d->m_lookahead_size = d->m_dict_size = d->m_total_lz_bytes = d->m_lz_code_buf_dict_pos = d->m_bits_in = 0;
1998 d->m_output_flush_ofs = d->m_output_flush_remaining = d->m_finished = d->m_block_index = d->m_bit_buffer = d->m_wants_to_finish = 0;
1999 d->m_pLZ_code_buf = d->m_lz_code_buf + 1;
2000 d->m_pLZ_flags = d->m_lz_code_buf;
2001 *d->m_pLZ_flags = 0;
2002 d->m_num_flags_left = 8;
2003 d->m_pOutput_buf = d->m_output_buf;
2004 d->m_pOutput_buf_end = d->m_output_buf;
2005 d->m_prev_return_status = TDEFL_STATUS_OKAY;
2006 d->m_saved_match_dist = d->m_saved_match_len = d->m_saved_lit = 0;
2008 d->m_pIn_buf = NULL;
2009 d->m_pOut_buf = NULL;
2010 d->m_pIn_buf_size = NULL;
2011 d->m_pOut_buf_size = NULL;
2012 d->m_flush = TDEFL_NO_FLUSH;
2014 d->m_src_buf_left = 0;
2015 d->m_out_buf_ofs = 0;
2016 if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG))
2017 MZ_CLEAR_ARR(d->m_dict);
2018 memset(&d->m_huff_count[0][0], 0,
sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
2019 memset(&d->m_huff_count[1][0], 0,
sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
2020 return TDEFL_STATUS_OKAY;
2025 return d->m_prev_return_status;
2030 return d->m_adler32;
2033 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)
2037 if (((buf_len) && (!pBuf)) || (!pPut_buf_func))
2042 succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags) == TDEFL_STATUS_OKAY);
2043 succeeded = succeeded && (tdefl_compress_buffer(pComp, pBuf, buf_len, TDEFL_FINISH) == TDEFL_STATUS_DONE);
2050 size_t m_size, m_capacity;
2052 mz_bool m_expandable;
2055 static mz_bool tdefl_output_buffer_putter(
const void *pBuf,
int len,
void *pUser)
2058 size_t new_size = p->m_size + len;
2059 if (new_size > p->m_capacity)
2061 size_t new_capacity = p->m_capacity;
2063 if (!p->m_expandable)
2067 new_capacity = MZ_MAX(128U, new_capacity << 1U);
2068 }
while (new_size > new_capacity);
2069 pNew_buf = (mz_uint8 *)MZ_REALLOC(p->m_pBuf, new_capacity);
2072 p->m_pBuf = pNew_buf;
2073 p->m_capacity = new_capacity;
2075 memcpy((mz_uint8 *)p->m_pBuf + p->m_size, pBuf, len);
2076 p->m_size = new_size;
2080 void *tdefl_compress_mem_to_heap(
const void *pSrc_buf,
size_t src_buf_len,
size_t *pOut_len,
int flags)
2083 MZ_CLEAR_OBJ(out_buf);
2088 out_buf.m_expandable = MZ_TRUE;
2089 if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags))
2091 *pOut_len = out_buf.m_size;
2092 return out_buf.m_pBuf;
2095 size_t tdefl_compress_mem_to_mem(
void *pOut_buf,
size_t out_buf_len,
const void *pSrc_buf,
size_t src_buf_len,
int flags)
2098 MZ_CLEAR_OBJ(out_buf);
2101 out_buf.m_pBuf = (mz_uint8 *)pOut_buf;
2102 out_buf.m_capacity = out_buf_len;
2103 if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags))
2105 return out_buf.m_size;
2109 mz_uint tdefl_create_comp_flags_from_zip_params(
int level,
int window_bits,
int strategy)
2111 mz_uint comp_flags = s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0);
2112 if (window_bits > 0)
2113 comp_flags |= TDEFL_WRITE_ZLIB_HEADER;
2116 comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS;
2117 else if (strategy == MZ_FILTERED)
2118 comp_flags |= TDEFL_FILTER_MATCHES;
2119 else if (strategy == MZ_HUFFMAN_ONLY)
2120 comp_flags &= ~TDEFL_MAX_PROBES_MASK;
2121 else if (strategy == MZ_FIXED)
2122 comp_flags |= TDEFL_FORCE_ALL_STATIC_BLOCKS;
2123 else if (strategy == MZ_RLE)
2124 comp_flags |= TDEFL_RLE_MATCHES;
2130#pragma warning(push)
2131#pragma warning(disable : 4204)
2137 void *tdefl_write_image_to_png_file_in_memory_ex(
const void *pImage,
int w,
int h,
int num_chans,
size_t *pLen_out, mz_uint level, mz_bool flip)
2140 static const mz_uint s_tdefl_png_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
2143 int i, bpl = w * num_chans, y, z;
2148 MZ_CLEAR_OBJ(out_buf);
2149 out_buf.m_expandable = MZ_TRUE;
2150 out_buf.m_capacity = 57 + MZ_MAX(64, (1 + bpl) * h);
2151 if (NULL == (out_buf.m_pBuf = (mz_uint8 *)MZ_MALLOC(out_buf.m_capacity)))
2157 for (z = 41; z; --z)
2158 tdefl_output_buffer_putter(&z, 1, &out_buf);
2160 tdefl_init(pComp, tdefl_output_buffer_putter, &out_buf, s_tdefl_png_num_probes[MZ_MIN(10, level)] | TDEFL_WRITE_ZLIB_HEADER);
2161 for (y = 0; y < h; ++y)
2163 tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH);
2164 tdefl_compress_buffer(pComp, (mz_uint8 *)pImage + (flip ? (h - 1 - y) : y) * bpl, bpl, TDEFL_NO_FLUSH);
2166 if (tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) != TDEFL_STATUS_DONE)
2169 MZ_FREE(out_buf.m_pBuf);
2173 *pLen_out = out_buf.m_size - 41;
2175 static const mz_uint8 chans[] = { 0x00, 0x00, 0x04, 0x02, 0x06 };
2176 mz_uint8 pnghdr[41] = { 0x89, 0x50, 0x4e, 0x47, 0x0d,
2177 0x0a, 0x1a, 0x0a, 0x00, 0x00,
2178 0x00, 0x0d, 0x49, 0x48, 0x44,
2179 0x52, 0x00, 0x00, 0x00, 0x00,
2180 0x00, 0x00, 0x00, 0x00, 0x08,
2181 0x00, 0x00, 0x00, 0x00, 0x00,
2182 0x00, 0x00, 0x00, 0x00, 0x00,
2183 0x00, 0x00, 0x49, 0x44, 0x41,
2185 pnghdr[18] = (mz_uint8)(w >> 8);
2186 pnghdr[19] = (mz_uint8)w;
2187 pnghdr[22] = (mz_uint8)(h >> 8);
2188 pnghdr[23] = (mz_uint8)h;
2189 pnghdr[25] = chans[num_chans];
2190 pnghdr[33] = (mz_uint8)(*pLen_out >> 24);
2191 pnghdr[34] = (mz_uint8)(*pLen_out >> 16);
2192 pnghdr[35] = (mz_uint8)(*pLen_out >> 8);
2193 pnghdr[36] = (mz_uint8)*pLen_out;
2194 c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, pnghdr + 12, 17);
2195 for (i = 0; i < 4; ++i, c <<= 8)
2196 ((mz_uint8 *)(pnghdr + 29))[i] = (mz_uint8)(c >> 24);
2197 memcpy(out_buf.m_pBuf, pnghdr, 41);
2200 if (!tdefl_output_buffer_putter(
"\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf))
2204 MZ_FREE(out_buf.m_pBuf);
2207 c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, out_buf.m_pBuf + 41 - 4, *pLen_out + 4);
2208 for (i = 0; i < 4; ++i, c <<= 8)
2209 (out_buf.m_pBuf + out_buf.m_size - 16)[i] = (mz_uint8)(c >> 24);
2213 return out_buf.m_pBuf;
2215 void *tdefl_write_image_to_png_file_in_memory(
const void *pImage,
int w,
int h,
int num_chans,
size_t *pLen_out)
2218 return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans, pLen_out, 6, MZ_FALSE);
2221#ifndef MINIZ_NO_MALLOC
2273#ifndef MINIZ_NO_INFLATE_APIS
2282#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
2283#define TINFL_MEMSET(p, c, l) memset(p, c, l)
2285#define TINFL_CR_BEGIN \
2286 switch (r->m_state) \
2289#define TINFL_CR_RETURN(state_index, result) \
2293 r->m_state = state_index; \
2295 case state_index:; \
2298#define TINFL_CR_RETURN_FOREVER(state_index, result) \
2303 TINFL_CR_RETURN(state_index, result); \
2307#define TINFL_CR_FINISH }
2309#define TINFL_GET_BYTE(state_index, c) \
2312 while (pIn_buf_cur >= pIn_buf_end) \
2314 TINFL_CR_RETURN(state_index, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS); \
2316 c = *pIn_buf_cur++; \
2320#define TINFL_NEED_BITS(state_index, n) \
2324 TINFL_GET_BYTE(state_index, c); \
2325 bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
2327 } while (num_bits < (mz_uint)(n))
2328#define TINFL_SKIP_BITS(state_index, n) \
2331 if (num_bits < (mz_uint)(n)) \
2333 TINFL_NEED_BITS(state_index, n); \
2339#define TINFL_GET_BITS(state_index, b, n) \
2342 if (num_bits < (mz_uint)(n)) \
2344 TINFL_NEED_BITS(state_index, n); \
2346 b = bit_buf & ((1 << (n)) - 1); \
2356#define TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree) \
2359 temp = pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
2362 code_len = temp >> 9; \
2363 if ((code_len) && (num_bits >= code_len)) \
2366 else if (num_bits > TINFL_FAST_LOOKUP_BITS) \
2368 code_len = TINFL_FAST_LOOKUP_BITS; \
2371 temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \
2372 } while ((temp < 0) && (num_bits >= (code_len + 1))); \
2376 TINFL_GET_BYTE(state_index, c); \
2377 bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
2379 } while (num_bits < 15);
2387#define TINFL_HUFF_DECODE(state_index, sym, pLookUp, pTree) \
2391 mz_uint code_len, c; \
2392 if (num_bits < 15) \
2394 if ((pIn_buf_end - pIn_buf_cur) < 2) \
2396 TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree); \
2400 bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); \
2405 if ((temp = pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
2406 code_len = temp >> 9, temp &= 511; \
2409 code_len = TINFL_FAST_LOOKUP_BITS; \
2412 temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \
2413 } while (temp < 0); \
2416 bit_buf >>= code_len; \
2417 num_bits -= code_len; \
2424 MZ_CLEAR_ARR(r->m_tree_0);
2425 else if (r->m_type == 1)
2426 MZ_CLEAR_ARR(r->m_tree_1);
2428 MZ_CLEAR_ARR(r->m_tree_2);
2431 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)
2433 static const mz_uint16 s_length_base[31] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 };
2434 static const mz_uint8 s_length_extra[31] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0 };
2435 static const mz_uint16 s_dist_base[32] = { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0 };
2436 static const mz_uint8 s_dist_extra[32] = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 };
2437 static const mz_uint8 s_length_dezigzag[19] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
2438 static const mz_uint16 s_min_table_sizes[3] = { 257, 1, 4 };
2440 mz_int16 *pTrees[3];
2441 mz_uint8 *pCode_sizes[3];
2443 tinfl_status status = TINFL_STATUS_FAILED;
2444 mz_uint32 num_bits, dist, counter, num_extra;
2445 tinfl_bit_buf_t bit_buf;
2446 const mz_uint8 *pIn_buf_cur = pIn_buf_next, *
const pIn_buf_end = pIn_buf_next + *pIn_buf_size;
2447 mz_uint8 *pOut_buf_cur = pOut_buf_next, *
const pOut_buf_end = pOut_buf_next ? pOut_buf_next + *pOut_buf_size : NULL;
2448 size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (
size_t)-1 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, dist_from_out_buf_start;
2451 if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start))
2453 *pIn_buf_size = *pOut_buf_size = 0;
2454 return TINFL_STATUS_BAD_PARAM;
2457 pTrees[0] = r->m_tree_0;
2458 pTrees[1] = r->m_tree_1;
2459 pTrees[2] = r->m_tree_2;
2460 pCode_sizes[0] = r->m_code_size_0;
2461 pCode_sizes[1] = r->m_code_size_1;
2462 pCode_sizes[2] = r->m_code_size_2;
2464 num_bits = r->m_num_bits;
2465 bit_buf = r->m_bit_buf;
2467 counter = r->m_counter;
2468 num_extra = r->m_num_extra;
2469 dist_from_out_buf_start = r->m_dist_from_out_buf_start;
2472 bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0;
2473 r->m_z_adler32 = r->m_check_adler32 = 1;
2474 if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
2476 TINFL_GET_BYTE(1, r->m_zhdr0);
2477 TINFL_GET_BYTE(2, r->m_zhdr1);
2478 counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8));
2479 if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
2480 counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)((
size_t)1 << (8U + (r->m_zhdr0 >> 4)))));
2483 TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED);
2489 TINFL_GET_BITS(3, r->m_final, 3);
2490 r->m_type = r->m_final >> 1;
2493 TINFL_SKIP_BITS(5, num_bits & 7);
2494 for (counter = 0; counter < 4; ++counter)
2497 TINFL_GET_BITS(6, r->m_raw_header[counter], 8);
2499 TINFL_GET_BYTE(7, r->m_raw_header[counter]);
2501 if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) != (mz_uint)(0xFFFF ^ (r->m_raw_header[2] | (r->m_raw_header[3] << 8))))
2503 TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED);
2505 while ((counter) && (num_bits))
2507 TINFL_GET_BITS(51, dist, 8);
2508 while (pOut_buf_cur >= pOut_buf_end)
2510 TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT);
2512 *pOut_buf_cur++ = (mz_uint8)dist;
2518 while (pOut_buf_cur >= pOut_buf_end)
2520 TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT);
2522 while (pIn_buf_cur >= pIn_buf_end)
2524 TINFL_CR_RETURN(38, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS);
2526 n = MZ_MIN(MZ_MIN((
size_t)(pOut_buf_end - pOut_buf_cur), (
size_t)(pIn_buf_end - pIn_buf_cur)), counter);
2527 TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n);
2530 counter -= (mz_uint)n;
2533 else if (r->m_type == 3)
2535 TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED);
2541 mz_uint8 *p = r->m_code_size_0;
2543 r->m_table_sizes[0] = 288;
2544 r->m_table_sizes[1] = 32;
2545 TINFL_MEMSET(r->m_code_size_1, 5, 32);
2546 for (i = 0; i <= 143; ++i)
2548 for (; i <= 255; ++i)
2550 for (; i <= 279; ++i)
2552 for (; i <= 287; ++i)
2557 for (counter = 0; counter < 3; counter++)
2559 TINFL_GET_BITS(11, r->m_table_sizes[counter],
"\05\05\04"[counter]);
2560 r->m_table_sizes[counter] += s_min_table_sizes[counter];
2562 MZ_CLEAR_ARR(r->m_code_size_2);
2563 for (counter = 0; counter < r->m_table_sizes[2]; counter++)
2566 TINFL_GET_BITS(14, s, 3);
2567 r->m_code_size_2[s_length_dezigzag[counter]] = (mz_uint8)s;
2569 r->m_table_sizes[2] = 19;
2571 for (; (int)r->m_type >= 0; r->m_type--)
2573 int tree_next, tree_cur;
2576 mz_uint8 *pCode_size;
2577 mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16];
2578 pLookUp = r->m_look_up[r->m_type];
2579 pTree = pTrees[r->m_type];
2580 pCode_size = pCode_sizes[r->m_type];
2581 MZ_CLEAR_ARR(total_syms);
2582 TINFL_MEMSET(pLookUp, 0,
sizeof(r->m_look_up[0]));
2583 tinfl_clear_tree(r);
2584 for (i = 0; i < r->m_table_sizes[r->m_type]; ++i)
2585 total_syms[pCode_size[i]]++;
2586 used_syms = 0, total = 0;
2587 next_code[0] = next_code[1] = 0;
2588 for (i = 1; i <= 15; ++i)
2590 used_syms += total_syms[i];
2591 next_code[i + 1] = (total = ((total + total_syms[i]) << 1));
2593 if ((65536 != total) && (used_syms > 1))
2595 TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED);
2597 for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index)
2599 mz_uint rev_code = 0, l, cur_code, code_size = pCode_size[sym_index];
2602 cur_code = next_code[code_size]++;
2603 for (l = code_size; l > 0; l--, cur_code >>= 1)
2604 rev_code = (rev_code << 1) | (cur_code & 1);
2605 if (code_size <= TINFL_FAST_LOOKUP_BITS)
2607 mz_int16 k = (mz_int16)((code_size << 9) | sym_index);
2608 while (rev_code < TINFL_FAST_LOOKUP_SIZE)
2610 pLookUp[rev_code] = k;
2611 rev_code += (1 << code_size);
2615 if (0 == (tree_cur = pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)]))
2617 pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next;
2618 tree_cur = tree_next;
2621 rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1);
2622 for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--)
2624 tree_cur -= ((rev_code >>= 1) & 1);
2625 if (!pTree[-tree_cur - 1])
2627 pTree[-tree_cur - 1] = (mz_int16)tree_next;
2628 tree_cur = tree_next;
2632 tree_cur = pTree[-tree_cur - 1];
2634 tree_cur -= ((rev_code >>= 1) & 1);
2635 pTree[-tree_cur - 1] = (mz_int16)sym_index;
2639 for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]);)
2642 TINFL_HUFF_DECODE(16, dist, r->m_look_up[2], r->m_tree_2);
2645 r->m_len_codes[counter++] = (mz_uint8)dist;
2648 if ((dist == 16) && (!counter))
2650 TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED);
2652 num_extra =
"\02\03\07"[dist - 16];
2653 TINFL_GET_BITS(18, s, num_extra);
2654 s +=
"\03\03\013"[dist - 16];
2655 TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s);
2658 if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter)
2660 TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED);
2662 TINFL_MEMCPY(r->m_code_size_0, r->m_len_codes, r->m_table_sizes[0]);
2663 TINFL_MEMCPY(r->m_code_size_1, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]);
2671 if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2))
2673 TINFL_HUFF_DECODE(23, counter, r->m_look_up[0], r->m_tree_0);
2676 while (pOut_buf_cur >= pOut_buf_end)
2678 TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT);
2680 *pOut_buf_cur++ = (mz_uint8)counter;
2686#if TINFL_USE_64BIT_BITBUF
2689 bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits);
2696 bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
2701 if ((sym2 = r->m_look_up[0][bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
2702 code_len = sym2 >> 9;
2705 code_len = TINFL_FAST_LOOKUP_BITS;
2708 sym2 = r->m_tree_0[~sym2 + ((bit_buf >> code_len++) & 1)];
2712 bit_buf >>= code_len;
2713 num_bits -= code_len;
2717#if !TINFL_USE_64BIT_BITBUF
2720 bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
2725 if ((sym2 = r->m_look_up[0][bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
2726 code_len = sym2 >> 9;
2729 code_len = TINFL_FAST_LOOKUP_BITS;
2732 sym2 = r->m_tree_0[~sym2 + ((bit_buf >> code_len++) & 1)];
2735 bit_buf >>= code_len;
2736 num_bits -= code_len;
2738 pOut_buf_cur[0] = (mz_uint8)counter;
2745 pOut_buf_cur[1] = (mz_uint8)sym2;
2749 if ((counter &= 511) == 256)
2752 num_extra = s_length_extra[counter - 257];
2753 counter = s_length_base[counter - 257];
2757 TINFL_GET_BITS(25, extra_bits, num_extra);
2758 counter += extra_bits;
2761 TINFL_HUFF_DECODE(26, dist, r->m_look_up[1], r->m_tree_1);
2762 num_extra = s_dist_extra[dist];
2763 dist = s_dist_base[dist];
2767 TINFL_GET_BITS(27, extra_bits, num_extra);
2771 dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
2772 if ((dist == 0 || dist > dist_from_out_buf_start || dist_from_out_buf_start == 0) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
2774 TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED);
2777 pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask);
2779 if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end)
2783 while (pOut_buf_cur >= pOut_buf_end)
2785 TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT);
2787 *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask];
2791#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
2792 else if ((counter >= 9) && (counter <= dist))
2794 const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
2797#ifdef MINIZ_UNALIGNED_USE_MEMCPY
2798 memcpy(pOut_buf_cur, pSrc,
sizeof(mz_uint32) * 2);
2800 ((mz_uint32 *)pOut_buf_cur)[0] = ((
const mz_uint32 *)pSrc)[0];
2801 ((mz_uint32 *)pOut_buf_cur)[1] = ((
const mz_uint32 *)pSrc)[1];
2804 }
while ((pSrc += 8) < pSrc_end);
2805 if ((counter &= 7) < 3)
2809 pOut_buf_cur[0] = pSrc[0];
2811 pOut_buf_cur[1] = pSrc[1];
2812 pOut_buf_cur += counter;
2820 pOut_buf_cur[0] = pSrc[0];
2821 pOut_buf_cur[1] = pSrc[1];
2822 pOut_buf_cur[2] = pSrc[2];
2829 pOut_buf_cur[0] = pSrc[0];
2831 pOut_buf_cur[1] = pSrc[1];
2832 pOut_buf_cur += counter;
2836 }
while (!(r->m_final & 1));
2840 TINFL_SKIP_BITS(32, num_bits & 7);
2841 while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8))
2846 bit_buf &= ~(~(tinfl_bit_buf_t)0 << num_bits);
2847 MZ_ASSERT(!num_bits);
2849 if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
2851 for (counter = 0; counter < 4; ++counter)
2855 TINFL_GET_BITS(41, s, 8);
2857 TINFL_GET_BYTE(42, s);
2858 r->m_z_adler32 = (r->m_z_adler32 << 8) | s;
2861 TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE);
2869 if ((status != TINFL_STATUS_NEEDS_MORE_INPUT) && (status != TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS))
2871 while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8))
2877 r->m_num_bits = num_bits;
2878 r->m_bit_buf = bit_buf & ~(~(tinfl_bit_buf_t)0 << num_bits);
2880 r->m_counter = counter;
2881 r->m_num_extra = num_extra;
2882 r->m_dist_from_out_buf_start = dist_from_out_buf_start;
2883 *pIn_buf_size = pIn_buf_cur - pIn_buf_next;
2884 *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
2885 if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0))
2887 const mz_uint8 *ptr = pOut_buf_next;
2888 size_t buf_len = *pOut_buf_size;
2889 mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16;
2890 size_t block_len = buf_len % 5552;
2893 for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
2895 s1 += ptr[0], s2 += s1;
2896 s1 += ptr[1], s2 += s1;
2897 s1 += ptr[2], s2 += s1;
2898 s1 += ptr[3], s2 += s1;
2899 s1 += ptr[4], s2 += s1;
2900 s1 += ptr[5], s2 += s1;
2901 s1 += ptr[6], s2 += s1;
2902 s1 += ptr[7], s2 += s1;
2904 for (; i < block_len; ++i)
2905 s1 += *ptr++, s2 += s1;
2906 s1 %= 65521U, s2 %= 65521U;
2907 buf_len -= block_len;
2910 r->m_check_adler32 = (s2 << 16) + s1;
2911 if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32))
2912 status = TINFL_STATUS_ADLER32_MISMATCH;
2918 void *tinfl_decompress_mem_to_heap(
const void *pSrc_buf,
size_t src_buf_len,
size_t *pOut_len,
int flags)
2921 void *pBuf = NULL, *pNew_buf;
2922 size_t src_buf_ofs = 0, out_buf_capacity = 0;
2924 tinfl_init(&decomp);
2927 size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity;
2928 tinfl_status status = tinfl_decompress(&decomp, (
const mz_uint8 *)pSrc_buf + src_buf_ofs, &src_buf_size, (mz_uint8 *)pBuf, pBuf ? (mz_uint8 *)pBuf + *pOut_len : NULL, &dst_buf_size,
2929 (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
2930 if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT))
2936 src_buf_ofs += src_buf_size;
2937 *pOut_len += dst_buf_size;
2938 if (status == TINFL_STATUS_DONE)
2940 new_out_buf_capacity = out_buf_capacity * 2;
2941 if (new_out_buf_capacity < 128)
2942 new_out_buf_capacity = 128;
2943 pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity);
2951 out_buf_capacity = new_out_buf_capacity;
2956 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)
2959 tinfl_status status;
2960 tinfl_init(&decomp);
2961 status = tinfl_decompress(&decomp, (
const mz_uint8 *)pSrc_buf, &src_buf_len, (mz_uint8 *)pOut_buf, (mz_uint8 *)pOut_buf, &out_buf_len, (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
2962 return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len;
2965 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)
2969 mz_uint8 *pDict = (mz_uint8 *)MZ_MALLOC(TINFL_LZ_DICT_SIZE);
2970 size_t in_buf_ofs = 0, dict_ofs = 0;
2972 return TINFL_STATUS_FAILED;
2973 memset(pDict, 0, TINFL_LZ_DICT_SIZE);
2974 tinfl_init(&decomp);
2977 size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs;
2978 tinfl_status status = tinfl_decompress(&decomp, (
const mz_uint8 *)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size,
2979 (flags & ~(TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)));
2980 in_buf_ofs += in_buf_size;
2981 if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (
int)dst_buf_size, pPut_buf_user)))
2983 if (status != TINFL_STATUS_HAS_MORE_OUTPUT)
2985 result = (status == TINFL_STATUS_DONE);
2988 dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1);
2991 *pIn_buf_size = in_buf_ofs;
2995#ifndef MINIZ_NO_MALLOC
3000 tinfl_init(pDecomp);
3043#ifndef MINIZ_NO_ARCHIVE_APIS
3052#ifdef MINIZ_NO_STDIO
3053#define MZ_FILE void *
3055#include <sys/stat.h>
3057#if defined(_MSC_VER) || defined(__MINGW64__) || defined(__MINGW32__)
3059#ifndef WIN32_LEAN_AND_MEAN
3060#define WIN32_LEAN_AND_MEAN
3063#define MICROSOFT_WINDOWS_WINBASE_H_DEFINE_INTERLOCKED_CPLUSPLUS_OVERLOADS 0
3070static WCHAR *mz_utf8z_to_widechar(
const char *str)
3072 int reqChars = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
3073 WCHAR *wStr = (WCHAR *)malloc(reqChars *
sizeof(WCHAR));
3074 MultiByteToWideChar(CP_UTF8, 0, str, -1, wStr, reqChars);
3078static FILE *mz_fopen(
const char *pFilename,
const char *pMode)
3080 WCHAR *wFilename = mz_utf8z_to_widechar(pFilename);
3081 WCHAR *wMode = mz_utf8z_to_widechar(pMode);
3083 errno_t err = _wfopen_s(&pFile, wFilename, wMode);
3086 return err ? NULL : pFile;
3089static FILE *mz_freopen(
const char *pPath,
const char *pMode, FILE *pStream)
3091 WCHAR *wPath = mz_utf8z_to_widechar(pPath);
3092 WCHAR *wMode = mz_utf8z_to_widechar(pMode);
3094 errno_t err = _wfreopen_s(&pFile, wPath, wMode, pStream);
3097 return err ? NULL : pFile;
3100#if defined(__MINGW32__)
3101static int mz_stat(
const char *path,
struct _stat *buffer)
3103 WCHAR *wPath = mz_utf8z_to_widechar(path);
3104 int res = _wstat(wPath, buffer);
3109static int mz_stat64(
const char *path,
struct __stat64 *buffer)
3111 WCHAR *wPath = mz_utf8z_to_widechar(path);
3112 int res = _wstat64(wPath, buffer);
3118#ifndef MINIZ_NO_TIME
3119#include <sys/utime.h>
3121#define MZ_FOPEN mz_fopen
3122#define MZ_FCLOSE fclose
3123#define MZ_FREAD fread
3124#define MZ_FWRITE fwrite
3125#define MZ_FTELL64 _ftelli64
3126#define MZ_FSEEK64 _fseeki64
3127#if defined(__MINGW32__)
3128#define MZ_FILE_STAT_STRUCT _stat
3129#define MZ_FILE_STAT mz_stat
3131#define MZ_FILE_STAT_STRUCT _stat64
3132#define MZ_FILE_STAT mz_stat64
3134#define MZ_FFLUSH fflush
3135#define MZ_FREOPEN mz_freopen
3136#define MZ_DELETE_FILE remove
3138#elif defined(__WATCOMC__)
3139#ifndef MINIZ_NO_TIME
3140#include <sys/utime.h>
3142#define MZ_FOPEN(f, m) fopen(f, m)
3143#define MZ_FCLOSE fclose
3144#define MZ_FREAD fread
3145#define MZ_FWRITE fwrite
3146#define MZ_FTELL64 _ftelli64
3147#define MZ_FSEEK64 _fseeki64
3148#define MZ_FILE_STAT_STRUCT stat
3149#define MZ_FILE_STAT stat
3150#define MZ_FFLUSH fflush
3151#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
3152#define MZ_DELETE_FILE remove
3154#elif defined(__TINYC__)
3155#ifndef MINIZ_NO_TIME
3156#include <sys/utime.h>
3158#define MZ_FOPEN(f, m) fopen(f, m)
3159#define MZ_FCLOSE fclose
3160#define MZ_FREAD fread
3161#define MZ_FWRITE fwrite
3162#define MZ_FTELL64 ftell
3163#define MZ_FSEEK64 fseek
3164#define MZ_FILE_STAT_STRUCT stat
3165#define MZ_FILE_STAT stat
3166#define MZ_FFLUSH fflush
3167#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
3168#define MZ_DELETE_FILE remove
3170#elif defined(__USE_LARGEFILE64)
3171#ifndef MINIZ_NO_TIME
3174#define MZ_FOPEN(f, m) fopen64(f, m)
3175#define MZ_FCLOSE fclose
3176#define MZ_FREAD fread
3177#define MZ_FWRITE fwrite
3178#define MZ_FTELL64 ftello64
3179#define MZ_FSEEK64 fseeko64
3180#define MZ_FILE_STAT_STRUCT stat64
3181#define MZ_FILE_STAT stat64
3182#define MZ_FFLUSH fflush
3183#define MZ_FREOPEN(p, m, s) freopen64(p, m, s)
3184#define MZ_DELETE_FILE remove
3186#elif defined(__APPLE__) || defined(__FreeBSD__) || (defined(__linux__) && defined(__x86_64__))
3187#ifndef MINIZ_NO_TIME
3190#define MZ_FOPEN(f, m) fopen(f, m)
3191#define MZ_FCLOSE fclose
3192#define MZ_FREAD fread
3193#define MZ_FWRITE fwrite
3194#define MZ_FTELL64 ftello
3195#define MZ_FSEEK64 fseeko
3196#define MZ_FILE_STAT_STRUCT stat
3197#define MZ_FILE_STAT stat
3198#define MZ_FFLUSH fflush
3199#define MZ_FREOPEN(p, m, s) freopen(p, m, s)
3200#define MZ_DELETE_FILE remove
3203#pragma message("Using fopen, ftello, fseeko, stat() etc. path for file I/O - this path may not support large files.")
3204#ifndef MINIZ_NO_TIME
3207#define MZ_FOPEN(f, m) fopen(f, m)
3208#define MZ_FCLOSE fclose
3209#define MZ_FREAD fread
3210#define MZ_FWRITE fwrite
3211#ifdef __STRICT_ANSI__
3212#define MZ_FTELL64 ftell
3213#define MZ_FSEEK64 fseek
3215#define MZ_FTELL64 ftello
3216#define MZ_FSEEK64 fseeko
3218#define MZ_FILE_STAT_STRUCT stat
3219#define MZ_FILE_STAT stat
3220#define MZ_FFLUSH fflush
3221#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
3222#define MZ_DELETE_FILE remove
3226#define MZ_TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c))
3232 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06054b50,
3233 MZ_ZIP_CENTRAL_DIR_HEADER_SIG = 0x02014b50,
3234 MZ_ZIP_LOCAL_DIR_HEADER_SIG = 0x04034b50,
3235 MZ_ZIP_LOCAL_DIR_HEADER_SIZE = 30,
3236 MZ_ZIP_CENTRAL_DIR_HEADER_SIZE = 46,
3237 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE = 22,
3240 MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06064b50,
3241 MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG = 0x07064b50,
3242 MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE = 56,
3243 MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE = 20,
3244 MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID = 0x0001,
3245 MZ_ZIP_DATA_DESCRIPTOR_ID = 0x08074b50,
3246 MZ_ZIP_DATA_DESCRIPTER_SIZE64 = 24,
3247 MZ_ZIP_DATA_DESCRIPTER_SIZE32 = 16,
3250 MZ_ZIP_CDH_SIG_OFS = 0,
3251 MZ_ZIP_CDH_VERSION_MADE_BY_OFS = 4,
3252 MZ_ZIP_CDH_VERSION_NEEDED_OFS = 6,
3253 MZ_ZIP_CDH_BIT_FLAG_OFS = 8,
3254 MZ_ZIP_CDH_METHOD_OFS = 10,
3255 MZ_ZIP_CDH_FILE_TIME_OFS = 12,
3256 MZ_ZIP_CDH_FILE_DATE_OFS = 14,
3257 MZ_ZIP_CDH_CRC32_OFS = 16,
3258 MZ_ZIP_CDH_COMPRESSED_SIZE_OFS = 20,
3259 MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS = 24,
3260 MZ_ZIP_CDH_FILENAME_LEN_OFS = 28,
3261 MZ_ZIP_CDH_EXTRA_LEN_OFS = 30,
3262 MZ_ZIP_CDH_COMMENT_LEN_OFS = 32,
3263 MZ_ZIP_CDH_DISK_START_OFS = 34,
3264 MZ_ZIP_CDH_INTERNAL_ATTR_OFS = 36,
3265 MZ_ZIP_CDH_EXTERNAL_ATTR_OFS = 38,
3266 MZ_ZIP_CDH_LOCAL_HEADER_OFS = 42,
3269 MZ_ZIP_LDH_SIG_OFS = 0,
3270 MZ_ZIP_LDH_VERSION_NEEDED_OFS = 4,
3271 MZ_ZIP_LDH_BIT_FLAG_OFS = 6,
3272 MZ_ZIP_LDH_METHOD_OFS = 8,
3273 MZ_ZIP_LDH_FILE_TIME_OFS = 10,
3274 MZ_ZIP_LDH_FILE_DATE_OFS = 12,
3275 MZ_ZIP_LDH_CRC32_OFS = 14,
3276 MZ_ZIP_LDH_COMPRESSED_SIZE_OFS = 18,
3277 MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS = 22,
3278 MZ_ZIP_LDH_FILENAME_LEN_OFS = 26,
3279 MZ_ZIP_LDH_EXTRA_LEN_OFS = 28,
3280 MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR = 1 << 3,
3283 MZ_ZIP_ECDH_SIG_OFS = 0,
3284 MZ_ZIP_ECDH_NUM_THIS_DISK_OFS = 4,
3285 MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS = 6,
3286 MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 8,
3287 MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS = 10,
3288 MZ_ZIP_ECDH_CDIR_SIZE_OFS = 12,
3289 MZ_ZIP_ECDH_CDIR_OFS_OFS = 16,
3290 MZ_ZIP_ECDH_COMMENT_SIZE_OFS = 20,
3293 MZ_ZIP64_ECDL_SIG_OFS = 0,
3294 MZ_ZIP64_ECDL_NUM_DISK_CDIR_OFS = 4,
3295 MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS = 8,
3296 MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS = 16,
3299 MZ_ZIP64_ECDH_SIG_OFS = 0,
3300 MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS = 4,
3301 MZ_ZIP64_ECDH_VERSION_MADE_BY_OFS = 12,
3302 MZ_ZIP64_ECDH_VERSION_NEEDED_OFS = 14,
3303 MZ_ZIP64_ECDH_NUM_THIS_DISK_OFS = 16,
3304 MZ_ZIP64_ECDH_NUM_DISK_CDIR_OFS = 20,
3305 MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 24,
3306 MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS = 32,
3307 MZ_ZIP64_ECDH_CDIR_SIZE_OFS = 40,
3308 MZ_ZIP64_ECDH_CDIR_OFS_OFS = 48,
3309 MZ_ZIP_VERSION_MADE_BY_DOS_FILESYSTEM_ID = 0,
3310 MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG = 0x10,
3311 MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED = 1,
3312 MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG = 32,
3313 MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION = 64,
3314 MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_LOCAL_DIR_IS_MASKED = 8192,
3315 MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8 = 1 << 11
3321 size_t m_size, m_capacity;
3322 mz_uint m_element_size;
3332 mz_uint32 m_init_flags;
3338 mz_bool m_zip64_has_extended_info_fields;
3342 mz_uint64 m_file_archive_start_ofs;
3346 size_t m_mem_capacity;
3349#define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size) (array_ptr)->m_element_size = element_size
3351#if defined(DEBUG) || defined(_DEBUG)
3352 static MZ_FORCEINLINE mz_uint mz_zip_array_range_check(
const mz_zip_array *pArray, mz_uint index)
3354 MZ_ASSERT(index < pArray->m_size);
3357#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[mz_zip_array_range_check(array_ptr, index)]
3359#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[index]
3362 static MZ_FORCEINLINE
void mz_zip_array_init(
mz_zip_array *pArray, mz_uint32 element_size)
3365 pArray->m_element_size = element_size;
3370 pZip->m_pFree(pZip->m_pAlloc_opaque, pArray->m_p);
3374 static mz_bool mz_zip_array_ensure_capacity(
mz_zip_archive *pZip,
mz_zip_array *pArray,
size_t min_new_capacity, mz_uint growing)
3377 size_t new_capacity = min_new_capacity;
3378 MZ_ASSERT(pArray->m_element_size);
3379 if (pArray->m_capacity >= min_new_capacity)
3383 new_capacity = MZ_MAX(1, pArray->m_capacity);
3384 while (new_capacity < min_new_capacity)
3387 if (NULL == (pNew_p = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pArray->m_p, pArray->m_element_size, new_capacity)))
3389 pArray->m_p = pNew_p;
3390 pArray->m_capacity = new_capacity;
3394 static MZ_FORCEINLINE mz_bool mz_zip_array_reserve(
mz_zip_archive *pZip,
mz_zip_array *pArray,
size_t new_capacity, mz_uint growing)
3396 if (new_capacity > pArray->m_capacity)
3398 if (!mz_zip_array_ensure_capacity(pZip, pArray, new_capacity, growing))
3404 static MZ_FORCEINLINE mz_bool mz_zip_array_resize(
mz_zip_archive *pZip,
mz_zip_array *pArray,
size_t new_size, mz_uint growing)
3406 if (new_size > pArray->m_capacity)
3408 if (!mz_zip_array_ensure_capacity(pZip, pArray, new_size, growing))
3411 pArray->m_size = new_size;
3417 return mz_zip_array_reserve(pZip, pArray, pArray->m_size + n, MZ_TRUE);
3420 static MZ_FORCEINLINE mz_bool mz_zip_array_push_back(
mz_zip_archive *pZip,
mz_zip_array *pArray,
const void *pElements,
size_t n)
3422 size_t orig_size = pArray->m_size;
3423 if (!mz_zip_array_resize(pZip, pArray, orig_size + n, MZ_TRUE))
3426 memcpy((mz_uint8 *)pArray->m_p + orig_size * pArray->m_element_size, pElements, n * pArray->m_element_size);
3430#ifndef MINIZ_NO_TIME
3431 static MZ_TIME_T mz_zip_dos_to_time_t(
int dos_time,
int dos_date)
3434 memset(&tm, 0,
sizeof(tm));
3436 tm.tm_year = ((dos_date >> 9) & 127) + 1980 - 1900;
3437 tm.tm_mon = ((dos_date >> 5) & 15) - 1;
3438 tm.tm_mday = dos_date & 31;
3439 tm.tm_hour = (dos_time >> 11) & 31;
3440 tm.tm_min = (dos_time >> 5) & 63;
3441 tm.tm_sec = (dos_time << 1) & 62;
3445#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
3446 static void mz_zip_time_t_to_dos_time(MZ_TIME_T time, mz_uint16 *pDOS_time, mz_uint16 *pDOS_date)
3449 struct tm tm_struct;
3450 struct tm *tm = &tm_struct;
3451 errno_t err = localtime_s(tm, &time);
3459 struct tm *tm = localtime(&time);
3462 *pDOS_time = (mz_uint16)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) + ((tm->tm_sec) >> 1));
3463 *pDOS_date = (mz_uint16)(((tm->tm_year + 1900 - 1980) << 9) + ((tm->tm_mon + 1) << 5) + tm->tm_mday);
3467#ifndef MINIZ_NO_STDIO
3468#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
3469 static mz_bool mz_zip_get_file_modified_time(
const char *pFilename, MZ_TIME_T *pTime)
3471 struct MZ_FILE_STAT_STRUCT file_stat;
3474 if (MZ_FILE_STAT(pFilename, &file_stat) != 0)
3477 *pTime = file_stat.st_mtime;
3483 static mz_bool mz_zip_set_file_times(
const char *pFilename, MZ_TIME_T access_time, MZ_TIME_T modified_time)
3487 memset(&t, 0,
sizeof(t));
3488 t.actime = access_time;
3489 t.modtime = modified_time;
3491 return !utime(pFilename, &t);
3496 static MZ_FORCEINLINE mz_bool mz_zip_set_error(
mz_zip_archive *pZip, mz_zip_error err_num)
3499 pZip->m_last_error = err_num;
3503 static mz_bool mz_zip_reader_init_internal(
mz_zip_archive *pZip, mz_uint flags)
3506 if ((!pZip) || (pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
3507 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
3509 if (!pZip->m_pAlloc)
3510 pZip->m_pAlloc = miniz_def_alloc_func;
3512 pZip->m_pFree = miniz_def_free_func;
3513 if (!pZip->m_pRealloc)
3514 pZip->m_pRealloc = miniz_def_realloc_func;
3516 pZip->m_archive_size = 0;
3517 pZip->m_central_directory_file_ofs = 0;
3518 pZip->m_total_files = 0;
3519 pZip->m_last_error = MZ_ZIP_NO_ERROR;
3522 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
3525 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir,
sizeof(mz_uint8));
3526 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets,
sizeof(mz_uint32));
3527 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets,
sizeof(mz_uint32));
3528 pZip->m_pState->m_init_flags = flags;
3529 pZip->m_pState->m_zip64 = MZ_FALSE;
3530 pZip->m_pState->m_zip64_has_extended_info_fields = MZ_FALSE;
3532 pZip->m_zip_mode = MZ_ZIP_MODE_READING;
3537 static MZ_FORCEINLINE mz_bool mz_zip_reader_filename_less(
const mz_zip_array *pCentral_dir_array,
const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, mz_uint r_index)
3539 const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE;
3540 const mz_uint8 *pR = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, r_index));
3541 mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS), r_len = MZ_READ_LE16(pR + MZ_ZIP_CDH_FILENAME_LEN_OFS);
3542 mz_uint8 l = 0, r = 0;
3543 pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
3544 pR += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
3545 pE = pL + MZ_MIN(l_len, r_len);
3548 if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR)))
3553 return (pL == pE) ? (l_len < r_len) : (l < r);
3556#define MZ_SWAP_UINT32(a, b) \
3566 static void mz_zip_reader_sort_central_dir_offsets_by_filename(
mz_zip_archive *pZip)
3569 const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
3570 const mz_zip_array *pCentral_dir = &pState->m_central_dir;
3571 mz_uint32 *pIndices;
3572 mz_uint32 start, end;
3573 const mz_uint32 size = pZip->m_total_files;
3578 pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0);
3580 start = (size - 2U) >> 1U;
3583 mz_uint64 child, root = start;
3586 if ((child = (root << 1U) + 1U) >= size)
3588 child += (((child + 1U) < size) && (mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1U])));
3589 if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child]))
3591 MZ_SWAP_UINT32(pIndices[root], pIndices[child]);
3602 mz_uint64 child, root = 0;
3603 MZ_SWAP_UINT32(pIndices[end], pIndices[0]);
3606 if ((child = (root << 1U) + 1U) >= end)
3608 child += (((child + 1U) < end) && mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1U]));
3609 if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child]))
3611 MZ_SWAP_UINT32(pIndices[root], pIndices[child]);
3618 static mz_bool mz_zip_reader_locate_header_sig(
mz_zip_archive *pZip, mz_uint32 record_sig, mz_uint32 record_size, mz_int64 *pOfs)
3620 mz_int64 cur_file_ofs;
3621 mz_uint32 buf_u32[4096 /
sizeof(mz_uint32)];
3622 mz_uint8 *pBuf = (mz_uint8 *)buf_u32;
3625 if (pZip->m_archive_size < record_size)
3629 cur_file_ofs = MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)
sizeof(buf_u32), 0);
3632 int i, n = (int)MZ_MIN(
sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs);
3634 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n)
3637 for (i = n - 4; i >= 0; --i)
3639 mz_uint s = MZ_READ_LE32(pBuf + i);
3640 if (s == record_sig)
3642 if ((pZip->m_archive_size - (cur_file_ofs + i)) >= record_size)
3654 if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >= ((mz_uint64)(MZ_UINT16_MAX) + record_size)))
3657 cur_file_ofs = MZ_MAX(cur_file_ofs - (
sizeof(buf_u32) - 3), 0);
3660 *pOfs = cur_file_ofs;
3664 static mz_bool mz_zip_reader_eocd64_valid(
mz_zip_archive *pZip, uint64_t offset, uint8_t *buf)
3666 if (pZip->m_pRead(pZip->m_pIO_opaque, offset, buf, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) == MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)
3668 if (MZ_READ_LE32(buf + MZ_ZIP64_ECDH_SIG_OFS) == MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG)
3677 static mz_bool mz_zip_reader_read_central_dir(
mz_zip_archive *pZip, mz_uint flags)
3679 mz_uint cdir_size = 0, cdir_entries_on_this_disk = 0, num_this_disk = 0, cdir_disk_index = 0;
3680 mz_uint64 cdir_ofs = 0, eocd_ofs = 0, archive_ofs = 0;
3681 mz_int64 cur_file_ofs = 0;
3684 mz_uint32 buf_u32[4096 /
sizeof(mz_uint32)];
3685 mz_uint8 *pBuf = (mz_uint8 *)buf_u32;
3686 mz_bool sort_central_dir = ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0);
3687 mz_uint32 zip64_end_of_central_dir_locator_u32[(MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE +
sizeof(mz_uint32) - 1) /
sizeof(mz_uint32)];
3688 mz_uint8 *pZip64_locator = (mz_uint8 *)zip64_end_of_central_dir_locator_u32;
3690 mz_uint32 zip64_end_of_central_dir_header_u32[(MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE +
sizeof(mz_uint32) - 1) /
sizeof(mz_uint32)];
3691 mz_uint8 *pZip64_end_of_central_dir = (mz_uint8 *)zip64_end_of_central_dir_header_u32;
3693 mz_uint64 zip64_end_of_central_dir_ofs = 0;
3696 if (pZip->m_archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
3697 return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
3699 if (!mz_zip_reader_locate_header_sig(pZip, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE, &cur_file_ofs))
3700 return mz_zip_set_error(pZip, MZ_ZIP_FAILED_FINDING_CENTRAL_DIR);
3702 eocd_ofs = cur_file_ofs;
3704 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
3705 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
3707 if (MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG)
3708 return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
3710 if (cur_file_ofs >= (MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE + MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE))
3712 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs - MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE, pZip64_locator, MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) == MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE)
3714 if (MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_SIG_OFS) == MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG)
3716 pZip->m_pState->m_zip64 = MZ_TRUE;
3721 if (pZip->m_pState->m_zip64)
3725 if (cur_file_ofs < MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE +
3726 MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)
3727 return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
3729 zip64_end_of_central_dir_ofs = cur_file_ofs -
3730 MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE -
3731 MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE;
3733 if (!mz_zip_reader_eocd64_valid(pZip, zip64_end_of_central_dir_ofs,
3734 pZip64_end_of_central_dir))
3737 zip64_end_of_central_dir_ofs = MZ_READ_LE64(
3738 pZip64_locator + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS);
3740 if (zip64_end_of_central_dir_ofs >
3741 (pZip->m_archive_size - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE))
3742 return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
3744 if (!mz_zip_reader_eocd64_valid(pZip, zip64_end_of_central_dir_ofs,
3745 pZip64_end_of_central_dir))
3746 return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
3750 pZip->m_total_files = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS);
3751 cdir_entries_on_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS);
3752 num_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS);
3753 cdir_disk_index = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS);
3754 cdir_size = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_SIZE_OFS);
3755 cdir_ofs = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS);
3757 if (pZip->m_pState->m_zip64)
3759 mz_uint32 zip64_total_num_of_disks = MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS);
3760 mz_uint64 zip64_cdir_total_entries = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS);
3761 mz_uint64 zip64_cdir_total_entries_on_this_disk = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS);
3762 mz_uint64 zip64_size_of_end_of_central_dir_record = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS);
3763 mz_uint64 zip64_size_of_central_directory = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_SIZE_OFS);
3765 if (zip64_size_of_end_of_central_dir_record < (MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE - 12))
3766 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
3768 if (zip64_total_num_of_disks != 1U)
3769 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK);
3772 if (zip64_cdir_total_entries > MZ_UINT32_MAX)
3773 return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
3775 pZip->m_total_files = (mz_uint32)zip64_cdir_total_entries;
3777 if (zip64_cdir_total_entries_on_this_disk > MZ_UINT32_MAX)
3778 return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
3780 cdir_entries_on_this_disk = (mz_uint32)zip64_cdir_total_entries_on_this_disk;
3783 if (zip64_size_of_central_directory > MZ_UINT32_MAX)
3784 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);
3786 cdir_size = (mz_uint32)zip64_size_of_central_directory;
3788 num_this_disk = MZ_READ_LE32(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_NUM_THIS_DISK_OFS);
3790 cdir_disk_index = MZ_READ_LE32(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_NUM_DISK_CDIR_OFS);
3792 cdir_ofs = MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_OFS_OFS);
3795 if (pZip->m_total_files != cdir_entries_on_this_disk)
3796 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK);
3798 if (((num_this_disk | cdir_disk_index) != 0) && ((num_this_disk != 1) || (cdir_disk_index != 1)))
3799 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK);
3801 if (cdir_size < (mz_uint64)pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)
3802 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
3804 if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size)
3805 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
3807 if (eocd_ofs < cdir_ofs + cdir_size)
3808 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
3812 archive_ofs = eocd_ofs - (cdir_ofs + cdir_size);
3813 if (pZip->m_pState->m_zip64)
3815 if (archive_ofs < MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE +
3816 MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE)
3817 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
3819 archive_ofs -= MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE +
3820 MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE;
3824 if ((pZip->m_zip_type == MZ_ZIP_TYPE_FILE || pZip->m_zip_type == MZ_ZIP_TYPE_CFILE ||
3825 pZip->m_zip_type == MZ_ZIP_TYPE_USER) && pZip->m_pState->m_file_archive_start_ofs == 0)
3827 pZip->m_pState->m_file_archive_start_ofs = archive_ofs;
3828 pZip->m_archive_size -= archive_ofs;
3831 pZip->m_central_directory_file_ofs = cdir_ofs;
3833 if (pZip->m_total_files)
3837 if ((!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir, cdir_size, MZ_FALSE)) ||
3838 (!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir_offsets, pZip->m_total_files, MZ_FALSE)))
3839 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
3841 if (sort_central_dir)
3843 if (!mz_zip_array_resize(pZip, &pZip->m_pState->m_sorted_central_dir_offsets, pZip->m_total_files, MZ_FALSE))
3844 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
3847 if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs, pZip->m_pState->m_central_dir.m_p, cdir_size) != cdir_size)
3848 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
3851 p = (
const mz_uint8 *)pZip->m_pState->m_central_dir.m_p;
3852 for (n = cdir_size, i = 0; i < pZip->m_total_files; ++i)
3854 mz_uint total_header_size, disk_index, bit_flags, filename_size, ext_data_size;
3855 mz_uint64 comp_size, decomp_size, local_header_ofs;
3857 if ((n < MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) || (MZ_READ_LE32(p) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG))
3858 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
3860 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);
3862 if (sort_central_dir)
3863 MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_sorted_central_dir_offsets, mz_uint32, i) = i;
3865 comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
3866 decomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
3867 local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
3868 filename_size = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
3869 ext_data_size = MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS);
3871 if ((!pZip->m_pState->m_zip64_has_extended_info_fields) &&
3873 (MZ_MAX(MZ_MAX(comp_size, decomp_size), local_header_ofs) == MZ_UINT32_MAX))
3876 mz_uint32 extra_size_remaining = ext_data_size;
3878 if (extra_size_remaining)
3880 const mz_uint8 *pExtra_data;
3883 if (MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + ext_data_size > n)
3885 buf = MZ_MALLOC(ext_data_size);
3887 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
3889 if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size, buf, ext_data_size) != ext_data_size)
3892 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
3895 pExtra_data = (mz_uint8 *)buf;
3899 pExtra_data = p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size;
3905 mz_uint32 field_data_size;
3907 if (extra_size_remaining < (
sizeof(mz_uint16) * 2))
3910 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
3913 field_id = MZ_READ_LE16(pExtra_data);
3914 field_data_size = MZ_READ_LE16(pExtra_data +
sizeof(mz_uint16));
3916 if ((field_data_size +
sizeof(mz_uint16) * 2) > extra_size_remaining)
3919 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
3922 if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID)
3925 pZip->m_pState->m_zip64 = MZ_TRUE;
3926 pZip->m_pState->m_zip64_has_extended_info_fields = MZ_TRUE;
3930 pExtra_data +=
sizeof(mz_uint16) * 2 + field_data_size;
3931 extra_size_remaining = extra_size_remaining -
sizeof(mz_uint16) * 2 - field_data_size;
3932 }
while (extra_size_remaining);
3939 if ((comp_size != MZ_UINT32_MAX) && (decomp_size != MZ_UINT32_MAX))
3941 if (((!MZ_READ_LE32(p + MZ_ZIP_CDH_METHOD_OFS)) && (decomp_size != comp_size)) || (decomp_size && !comp_size))
3942 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
3945 disk_index = MZ_READ_LE16(p + MZ_ZIP_CDH_DISK_START_OFS);
3946 if ((disk_index == MZ_UINT16_MAX) || ((disk_index != num_this_disk) && (disk_index != 1)))
3947 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK);
3949 if (comp_size != MZ_UINT32_MAX)
3951 if (((mz_uint64)MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS) + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + comp_size) > pZip->m_archive_size)
3952 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
3955 bit_flags = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
3956 if (bit_flags & MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_LOCAL_DIR_IS_MASKED)
3957 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);
3959 if ((total_header_size = MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS)) > n)
3960 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
3962 n -= total_header_size;
3963 p += total_header_size;
3967 if (sort_central_dir)
3968 mz_zip_reader_sort_central_dir_offsets_by_filename(pZip);
3979 static mz_bool mz_zip_reader_end_internal(
mz_zip_archive *pZip, mz_bool set_last_error)
3981 mz_bool status = MZ_TRUE;
3986 if ((!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
3989 pZip->m_last_error = MZ_ZIP_INVALID_PARAMETER;
3997 pZip->m_pState = NULL;
3999 mz_zip_array_clear(pZip, &pState->m_central_dir);
4000 mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
4001 mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets);
4003#ifndef MINIZ_NO_STDIO
4004 if (pState->m_pFile)
4006 if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE)
4008 if (MZ_FCLOSE(pState->m_pFile) == EOF)
4011 pZip->m_last_error = MZ_ZIP_FILE_CLOSE_FAILED;
4015 pState->m_pFile = NULL;
4019 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
4021 pZip->m_zip_mode = MZ_ZIP_MODE_INVALID;
4028 return mz_zip_reader_end_internal(pZip, MZ_TRUE);
4030 mz_bool mz_zip_reader_init(
mz_zip_archive *pZip, mz_uint64 size, mz_uint flags)
4032 if ((!pZip) || (!pZip->m_pRead))
4033 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
4035 if (!mz_zip_reader_init_internal(pZip, flags))
4038 pZip->m_zip_type = MZ_ZIP_TYPE_USER;
4039 pZip->m_archive_size = size;
4041 if (!mz_zip_reader_read_central_dir(pZip, flags))
4043 mz_zip_reader_end_internal(pZip, MZ_FALSE);
4050 static size_t mz_zip_mem_read_func(
void *pOpaque, mz_uint64 file_ofs,
void *pBuf,
size_t n)
4053 size_t s = (file_ofs >= pZip->m_archive_size) ? 0 : (
size_t)MZ_MIN(pZip->m_archive_size - file_ofs, n);
4054 memcpy(pBuf, (
const mz_uint8 *)pZip->m_pState->m_pMem + file_ofs, s);
4058 mz_bool mz_zip_reader_init_mem(
mz_zip_archive *pZip,
const void *pMem,
size_t size, mz_uint flags)
4061 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
4063 if (size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
4064 return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
4066 if (!mz_zip_reader_init_internal(pZip, flags))
4069 pZip->m_zip_type = MZ_ZIP_TYPE_MEMORY;
4070 pZip->m_archive_size = size;
4071 pZip->m_pRead = mz_zip_mem_read_func;
4072 pZip->m_pIO_opaque = pZip;
4073 pZip->m_pNeeds_keepalive = NULL;
4076 pZip->m_pState->m_pMem =
const_cast<void *
>(pMem);
4078 pZip->m_pState->m_pMem = (
void *)pMem;
4081 pZip->m_pState->m_mem_size = size;
4083 if (!mz_zip_reader_read_central_dir(pZip, flags))
4085 mz_zip_reader_end_internal(pZip, MZ_FALSE);
4092#ifndef MINIZ_NO_STDIO
4093 static size_t mz_zip_file_read_func(
void *pOpaque, mz_uint64 file_ofs,
void *pBuf,
size_t n)
4096 mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
4098 file_ofs += pZip->m_pState->m_file_archive_start_ofs;
4100 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))))
4103 return MZ_FREAD(pBuf, 1, n, pZip->m_pState->m_pFile);
4106 mz_bool mz_zip_reader_init_file(
mz_zip_archive *pZip,
const char *pFilename, mz_uint32 flags)
4108 return mz_zip_reader_init_file_v2(pZip, pFilename, flags, 0, 0);
4111 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)
4113 mz_uint64 file_size;
4116 if ((!pZip) || (!pFilename) || ((archive_size) && (archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)))
4117 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
4119 pFile = MZ_FOPEN(pFilename, (flags & MZ_ZIP_FLAG_READ_ALLOW_WRITING ) ?
"r+b" :
"rb");
4121 return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);
4123 file_size = archive_size;
4126 if (MZ_FSEEK64(pFile, 0, SEEK_END))
4129 return mz_zip_set_error(pZip, MZ_ZIP_FILE_SEEK_FAILED);
4132 file_size = MZ_FTELL64(pFile);
4137 if (file_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
4140 return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
4143 if (!mz_zip_reader_init_internal(pZip, flags))
4149 pZip->m_zip_type = MZ_ZIP_TYPE_FILE;
4150 pZip->m_pRead = mz_zip_file_read_func;
4151 pZip->m_pIO_opaque = pZip;
4152 pZip->m_pState->m_pFile = pFile;
4153 pZip->m_archive_size = file_size;
4154 pZip->m_pState->m_file_archive_start_ofs = file_start_ofs;
4156 if (!mz_zip_reader_read_central_dir(pZip, flags))
4158 mz_zip_reader_end_internal(pZip, MZ_FALSE);
4165 mz_bool mz_zip_reader_init_cfile(
mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint64 archive_size, mz_uint flags)
4167 mz_uint64 cur_file_ofs;
4169 if ((!pZip) || (!pFile))
4170 return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);
4172 cur_file_ofs = MZ_FTELL64(pFile);
4176 if (MZ_FSEEK64(pFile, 0, SEEK_END))
4177 return mz_zip_set_error(pZip, MZ_ZIP_FILE_SEEK_FAILED);
4179 archive_size = MZ_FTELL64(pFile) - cur_file_ofs;
4181 if (archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
4182 return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
4185 if (!mz_zip_reader_init_internal(pZip, flags))
4188 pZip->m_zip_type = MZ_ZIP_TYPE_CFILE;
4189 pZip->m_pRead = mz_zip_file_read_func;
4191 pZip->m_pIO_opaque = pZip;
4192 pZip->m_pState->m_pFile = pFile;
4193 pZip->m_archive_size = archive_size;
4194 pZip->m_pState->m_file_archive_start_ofs = cur_file_ofs;
4196 if (!mz_zip_reader_read_central_dir(pZip, flags))
4198 mz_zip_reader_end_internal(pZip, MZ_FALSE);
4207 static MZ_FORCEINLINE
const mz_uint8 *mz_zip_get_cdh(
mz_zip_archive *pZip, mz_uint file_index)
4209 if ((!pZip) || (!pZip->m_pState) || (file_index >= pZip->m_total_files))
4211 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));
4214 mz_bool mz_zip_reader_is_file_encrypted(
mz_zip_archive *pZip, mz_uint file_index)
4217 const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
4220 mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
4224 m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
4225 return (m_bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION)) != 0;
4228 mz_bool mz_zip_reader_is_file_supported(
mz_zip_archive *pZip, mz_uint file_index)
4233 const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
4236 mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
4240 method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS);
4241 bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
4243 if ((method != 0) && (method != MZ_DEFLATED))
4245 mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD);
4249 if (bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION))
4251 mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);
4255 if (bit_flag & MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG)
4257 mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE);
4264 mz_bool mz_zip_reader_is_file_a_directory(
mz_zip_archive *pZip, mz_uint file_index)
4266 mz_uint filename_len, attribute_mapping_id, external_attr;
4267 const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
4270 mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
4274 filename_len = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
4277 if (*(p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_len - 1) ==
'/')
4284 attribute_mapping_id = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS) >> 8;
4285 (void)attribute_mapping_id;
4287 external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS);
4288 if ((external_attr & MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG) != 0)
4296 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)
4299 const mz_uint8 *p = pCentral_dir_header;
4301 if (pFound_zip64_extra_data)
4302 *pFound_zip64_extra_data = MZ_FALSE;
4304 if ((!p) || (!pStat))
4305 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
4308 pStat->m_file_index = file_index;
4309 pStat->m_central_dir_ofs = MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index);
4310 pStat->m_version_made_by = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS);
4311 pStat->m_version_needed = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_NEEDED_OFS);
4312 pStat->m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
4313 pStat->m_method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS);
4314#ifndef MINIZ_NO_TIME
4315 pStat->m_time = mz_zip_dos_to_time_t(MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_TIME_OFS), MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_DATE_OFS));
4317 pStat->m_crc32 = MZ_READ_LE32(p + MZ_ZIP_CDH_CRC32_OFS);
4318 pStat->m_comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
4319 pStat->m_uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
4320 pStat->m_internal_attr = MZ_READ_LE16(p + MZ_ZIP_CDH_INTERNAL_ATTR_OFS);
4321 pStat->m_external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS);
4322 pStat->m_local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
4325 n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
4326 n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE - 1);
4327 memcpy(pStat->m_filename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n);
4328 pStat->m_filename[n] =
'\0';
4330 n = MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS);
4331 n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE - 1);
4332 pStat->m_comment_size = n;
4333 memcpy(pStat->m_comment, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS), n);
4334 pStat->m_comment[n] =
'\0';
4337 pStat->m_is_directory = mz_zip_reader_is_file_a_directory(pZip, file_index);
4338 pStat->m_is_encrypted = mz_zip_reader_is_file_encrypted(pZip, file_index);
4339 pStat->m_is_supported = mz_zip_reader_is_file_supported(pZip, file_index);
4343 if (MZ_MAX(MZ_MAX(pStat->m_comp_size, pStat->m_uncomp_size), pStat->m_local_header_ofs) == MZ_UINT32_MAX)
4346 mz_uint32 extra_size_remaining = MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS);
4348 if (extra_size_remaining)
4350 const mz_uint8 *pExtra_data = p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
4355 mz_uint32 field_data_size;
4357 if (extra_size_remaining < (
sizeof(mz_uint16) * 2))
4358 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
4360 field_id = MZ_READ_LE16(pExtra_data);
4361 field_data_size = MZ_READ_LE16(pExtra_data +
sizeof(mz_uint16));
4363 if ((field_data_size +
sizeof(mz_uint16) * 2) > extra_size_remaining)
4364 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
4366 if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID)
4368 const mz_uint8 *pField_data = pExtra_data +
sizeof(mz_uint16) * 2;
4369 mz_uint32 field_data_remaining = field_data_size;
4371 if (pFound_zip64_extra_data)
4372 *pFound_zip64_extra_data = MZ_TRUE;
4374 if (pStat->m_uncomp_size == MZ_UINT32_MAX)
4376 if (field_data_remaining <
sizeof(mz_uint64))
4377 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
4379 pStat->m_uncomp_size = MZ_READ_LE64(pField_data);
4380 pField_data +=
sizeof(mz_uint64);
4381 field_data_remaining -=
sizeof(mz_uint64);
4384 if (pStat->m_comp_size == MZ_UINT32_MAX)
4386 if (field_data_remaining <
sizeof(mz_uint64))
4387 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
4389 pStat->m_comp_size = MZ_READ_LE64(pField_data);
4390 pField_data +=
sizeof(mz_uint64);
4391 field_data_remaining -=
sizeof(mz_uint64);
4394 if (pStat->m_local_header_ofs == MZ_UINT32_MAX)
4396 if (field_data_remaining <
sizeof(mz_uint64))
4397 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
4399 pStat->m_local_header_ofs = MZ_READ_LE64(pField_data);
4400 pField_data +=
sizeof(mz_uint64);
4401 field_data_remaining -=
sizeof(mz_uint64);
4407 pExtra_data +=
sizeof(mz_uint16) * 2 + field_data_size;
4408 extra_size_remaining = extra_size_remaining -
sizeof(mz_uint16) * 2 - field_data_size;
4409 }
while (extra_size_remaining);
4416 static MZ_FORCEINLINE mz_bool mz_zip_string_equal(
const char *pA,
const char *pB, mz_uint len, mz_uint flags)
4419 if (flags & MZ_ZIP_FLAG_CASE_SENSITIVE)
4420 return 0 == memcmp(pA, pB, len);
4421 for (i = 0; i < len; ++i)
4422 if (MZ_TOLOWER(pA[i]) != MZ_TOLOWER(pB[i]))
4427 static MZ_FORCEINLINE
int mz_zip_filename_compare(
const mz_zip_array *pCentral_dir_array,
const mz_zip_array *pCentral_dir_offsets, mz_uint l_index,
const char *pR, mz_uint r_len)
4429 const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE;
4430 mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS);
4431 mz_uint8 l = 0, r = 0;
4432 pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
4433 pE = pL + MZ_MIN(l_len, r_len);
4436 if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR)))
4441 return (pL == pE) ? (int)(l_len - r_len) : (l - r);
4444 static mz_bool mz_zip_locate_file_binary_search(
mz_zip_archive *pZip,
const char *pFilename, mz_uint32 *pIndex)
4447 const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
4448 const mz_zip_array *pCentral_dir = &pState->m_central_dir;
4449 mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0);
4450 const mz_uint32 size = pZip->m_total_files;
4451 const mz_uint filename_len = (mz_uint)strlen(pFilename);
4460 mz_int64 l = 0, h = (mz_int64)size - 1;
4464 mz_int64 m = l + ((h - l) >> 1);
4465 mz_uint32 file_index = pIndices[(mz_uint32)m];
4467 int comp = mz_zip_filename_compare(pCentral_dir, pCentral_dir_offsets, file_index, pFilename, filename_len);
4471 *pIndex = file_index;
4481 return mz_zip_set_error(pZip, MZ_ZIP_FILE_NOT_FOUND);
4484 int mz_zip_reader_locate_file(
mz_zip_archive *pZip,
const char *pName,
const char *pComment, mz_uint flags)
4487 if (!mz_zip_reader_locate_file_v2(pZip, pName, pComment, flags, &index))
4493 mz_bool mz_zip_reader_locate_file_v2(
mz_zip_archive *pZip,
const char *pName,
const char *pComment, mz_uint flags, mz_uint32 *pIndex)
4496 size_t name_len, comment_len;
4501 if ((!pZip) || (!pZip->m_pState) || (!pName))
4502 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
4505 if (((pZip->m_pState->m_init_flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0) &&
4506 (pZip->m_zip_mode == MZ_ZIP_MODE_READING) &&
4507 ((flags & (MZ_ZIP_FLAG_IGNORE_PATH | MZ_ZIP_FLAG_CASE_SENSITIVE)) == 0) && (!pComment) && (pZip->m_pState->m_sorted_central_dir_offsets.m_size))
4509 return mz_zip_locate_file_binary_search(pZip, pName, pIndex);
4513 name_len = strlen(pName);
4514 if (name_len > MZ_UINT16_MAX)
4515 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
4517 comment_len = pComment ? strlen(pComment) : 0;
4518 if (comment_len > MZ_UINT16_MAX)
4519 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
4521 for (file_index = 0; file_index < pZip->m_total_files; file_index++)
4523 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));
4524 mz_uint filename_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_FILENAME_LEN_OFS);
4525 const char *pFilename = (
const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
4526 if (filename_len < name_len)
4530 mz_uint file_extra_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_EXTRA_LEN_OFS), file_comment_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_COMMENT_LEN_OFS);
4531 const char *pFile_comment = pFilename + filename_len + file_extra_len;
4532 if ((file_comment_len != comment_len) || (!mz_zip_string_equal(pComment, pFile_comment, file_comment_len, flags)))
4535 if ((flags & MZ_ZIP_FLAG_IGNORE_PATH) && (filename_len))
4537 int ofs = filename_len - 1;
4540 if ((pFilename[ofs] ==
'/') || (pFilename[ofs] ==
'\\') || (pFilename[ofs] ==
':'))
4542 }
while (--ofs >= 0);
4545 filename_len -= ofs;
4547 if ((filename_len == name_len) && (mz_zip_string_equal(pName, pFilename, filename_len, flags)))
4550 *pIndex = file_index;
4555 return mz_zip_set_error(pZip, MZ_ZIP_FILE_NOT_FOUND);
4558 static mz_bool mz_zip_reader_extract_to_mem_no_alloc1(
mz_zip_archive *pZip, mz_uint file_index,
void *pBuf,
size_t buf_size, mz_uint flags,
void *pUser_read_buf,
size_t user_read_buf_size,
const mz_zip_archive_file_stat *st)
4560 int status = TINFL_STATUS_DONE;
4561 mz_uint64 needed_size, cur_file_ofs, comp_remaining, out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail;
4564 mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE +
sizeof(mz_uint32) - 1) /
sizeof(mz_uint32)];
4565 mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
4568 if ((!pZip) || (!pZip->m_pState) || ((buf_size) && (!pBuf)) || ((user_read_buf_size) && (!pUser_read_buf)) || (!pZip->m_pRead))
4569 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
4575 else if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
4579 if ((file_stat.m_is_directory) || (!file_stat.m_comp_size))
4583 if (file_stat.m_bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG))
4584 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);
4587 if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
4588 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD);
4591 needed_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size : file_stat.m_uncomp_size;
4592 if (buf_size < needed_size)
4593 return mz_zip_set_error(pZip, MZ_ZIP_BUF_TOO_SMALL);
4596 cur_file_ofs = file_stat.m_local_header_ofs;
4597 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
4598 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
4600 if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
4601 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
4603 cur_file_ofs += (mz_uint64)(MZ_ZIP_LOCAL_DIR_HEADER_SIZE) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
4604 if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
4605 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
4607 if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method))
4610 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, (
size_t)needed_size) != needed_size)
4611 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
4613#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4614 if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) == 0)
4616 if (mz_crc32(MZ_CRC32_INIT, (
const mz_uint8 *)pBuf, (
size_t)file_stat.m_uncomp_size) != file_stat.m_crc32)
4617 return mz_zip_set_error(pZip, MZ_ZIP_CRC_CHECK_FAILED);
4625 tinfl_init(&inflator);
4627 if (pZip->m_pState->m_pMem)
4630 pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
4631 read_buf_size = read_buf_avail = file_stat.m_comp_size;
4634 else if (pUser_read_buf)
4637 if (!user_read_buf_size)
4639 pRead_buf = (mz_uint8 *)pUser_read_buf;
4640 read_buf_size = user_read_buf_size;
4642 comp_remaining = file_stat.m_comp_size;
4647 read_buf_size = MZ_MIN(file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
4648 if (((
sizeof(
size_t) ==
sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
4649 return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
4651 if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (
size_t)read_buf_size)))
4652 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
4655 comp_remaining = file_stat.m_comp_size;
4661 size_t in_buf_size, out_buf_size = (size_t)(file_stat.m_uncomp_size - out_buf_ofs);
4662 if ((!read_buf_avail) && (!pZip->m_pState->m_pMem))
4664 read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
4665 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (
size_t)read_buf_avail) != read_buf_avail)
4667 status = TINFL_STATUS_FAILED;
4668 mz_zip_set_error(pZip, MZ_ZIP_DECOMPRESSION_FAILED);
4671 cur_file_ofs += read_buf_avail;
4672 comp_remaining -= read_buf_avail;
4675 in_buf_size = (size_t)read_buf_avail;
4676 status = tinfl_decompress(&inflator, (mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pBuf, (mz_uint8 *)pBuf + out_buf_ofs, &out_buf_size, TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF | (comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0));
4677 read_buf_avail -= in_buf_size;
4678 read_buf_ofs += in_buf_size;
4679 out_buf_ofs += out_buf_size;
4680 }
while (status == TINFL_STATUS_NEEDS_MORE_INPUT);
4682 if (status == TINFL_STATUS_DONE)
4685 if (out_buf_ofs != file_stat.m_uncomp_size)
4687 mz_zip_set_error(pZip, MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE);
4688 status = TINFL_STATUS_FAILED;
4690#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4691 else if (mz_crc32(MZ_CRC32_INIT, (
const mz_uint8 *)pBuf, (
size_t)file_stat.m_uncomp_size) != file_stat.m_crc32)
4693 mz_zip_set_error(pZip, MZ_ZIP_CRC_CHECK_FAILED);
4694 status = TINFL_STATUS_FAILED;
4699 if ((!pZip->m_pState->m_pMem) && (!pUser_read_buf))
4700 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
4702 return status == TINFL_STATUS_DONE;
4705 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)
4707 return mz_zip_reader_extract_to_mem_no_alloc1(pZip, file_index, pBuf, buf_size, flags, pUser_read_buf, user_read_buf_size, NULL);
4710 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)
4712 mz_uint32 file_index;
4713 if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index))
4715 return mz_zip_reader_extract_to_mem_no_alloc1(pZip, file_index, pBuf, buf_size, flags, pUser_read_buf, user_read_buf_size, NULL);
4718 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)
4720 return mz_zip_reader_extract_to_mem_no_alloc1(pZip, file_index, pBuf, buf_size, flags, NULL, 0, NULL);
4723 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)
4725 return mz_zip_reader_extract_file_to_mem_no_alloc(pZip, pFilename, pBuf, buf_size, flags, NULL, 0);
4728 void *mz_zip_reader_extract_to_heap(
mz_zip_archive *pZip, mz_uint file_index,
size_t *pSize, mz_uint flags)
4731 mz_uint64 alloc_size;
4737 if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
4740 alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size : file_stat.m_uncomp_size;
4741 if (((
sizeof(
size_t) ==
sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
4743 mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
4747 if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (
size_t)alloc_size)))
4749 mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
4753 if (!mz_zip_reader_extract_to_mem_no_alloc1(pZip, file_index, pBuf, (
size_t)alloc_size, flags, NULL, 0, &file_stat))
4755 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
4760 *pSize = (size_t)alloc_size;
4764 void *mz_zip_reader_extract_file_to_heap(
mz_zip_archive *pZip,
const char *pFilename,
size_t *pSize, mz_uint flags)
4766 mz_uint32 file_index;
4767 if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index))
4773 return mz_zip_reader_extract_to_heap(pZip, file_index, pSize, flags);
4776 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)
4778 int status = TINFL_STATUS_DONE;
4779#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4780 mz_uint file_crc32 = MZ_CRC32_INIT;
4782 mz_uint64 read_buf_size, read_buf_ofs = 0, read_buf_avail, comp_remaining, out_buf_ofs = 0, cur_file_ofs;
4784 void *pRead_buf = NULL;
4785 void *pWrite_buf = NULL;
4786 mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE +
sizeof(mz_uint32) - 1) /
sizeof(mz_uint32)];
4787 mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
4789 if ((!pZip) || (!pZip->m_pState) || (!pCallback) || (!pZip->m_pRead))
4790 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
4792 if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
4796 if ((file_stat.m_is_directory) || (!file_stat.m_comp_size))
4800 if (file_stat.m_bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG))
4801 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);
4804 if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
4805 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD);
4808 cur_file_ofs = file_stat.m_local_header_ofs;
4809 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
4810 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
4812 if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
4813 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
4815 cur_file_ofs += (mz_uint64)(MZ_ZIP_LOCAL_DIR_HEADER_SIZE) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
4816 if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
4817 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
4820 if (pZip->m_pState->m_pMem)
4822 pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
4823 read_buf_size = read_buf_avail = file_stat.m_comp_size;
4828 read_buf_size = MZ_MIN(file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
4829 if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (
size_t)read_buf_size)))
4830 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
4833 comp_remaining = file_stat.m_comp_size;
4836 if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method))
4839 if (pZip->m_pState->m_pMem)
4841 if (((
sizeof(
size_t) ==
sizeof(mz_uint32))) && (file_stat.m_comp_size > MZ_UINT32_MAX))
4842 return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
4844 if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (
size_t)file_stat.m_comp_size) != file_stat.m_comp_size)
4846 mz_zip_set_error(pZip, MZ_ZIP_WRITE_CALLBACK_FAILED);
4847 status = TINFL_STATUS_FAILED;
4849 else if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
4851#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4852 file_crc32 = (mz_uint32)mz_crc32(file_crc32, (
const mz_uint8 *)pRead_buf, (size_t)file_stat.m_comp_size);
4856 cur_file_ofs += file_stat.m_comp_size;
4857 out_buf_ofs += file_stat.m_comp_size;
4862 while (comp_remaining)
4864 read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
4865 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (
size_t)read_buf_avail) != read_buf_avail)
4867 mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
4868 status = TINFL_STATUS_FAILED;
4872#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4873 if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
4875 file_crc32 = (mz_uint32)mz_crc32(file_crc32, (
const mz_uint8 *)pRead_buf, (size_t)read_buf_avail);
4879 if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (
size_t)read_buf_avail) != read_buf_avail)
4881 mz_zip_set_error(pZip, MZ_ZIP_WRITE_CALLBACK_FAILED);
4882 status = TINFL_STATUS_FAILED;
4886 cur_file_ofs += read_buf_avail;
4887 out_buf_ofs += read_buf_avail;
4888 comp_remaining -= read_buf_avail;
4895 tinfl_init(&inflator);
4897 if (NULL == (pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, TINFL_LZ_DICT_SIZE)))
4899 mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
4900 status = TINFL_STATUS_FAILED;
4906 mz_uint8 *pWrite_buf_cur = (mz_uint8 *)pWrite_buf + (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
4907 size_t in_buf_size, out_buf_size = TINFL_LZ_DICT_SIZE - (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
4908 if ((!read_buf_avail) && (!pZip->m_pState->m_pMem))
4910 read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
4911 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (
size_t)read_buf_avail) != read_buf_avail)
4913 mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
4914 status = TINFL_STATUS_FAILED;
4917 cur_file_ofs += read_buf_avail;
4918 comp_remaining -= read_buf_avail;
4922 in_buf_size = (size_t)read_buf_avail;
4923 status = tinfl_decompress(&inflator, (
const mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pWrite_buf, pWrite_buf_cur, &out_buf_size, comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0);
4924 read_buf_avail -= in_buf_size;
4925 read_buf_ofs += in_buf_size;
4929 if (pCallback(pOpaque, out_buf_ofs, pWrite_buf_cur, out_buf_size) != out_buf_size)
4931 mz_zip_set_error(pZip, MZ_ZIP_WRITE_CALLBACK_FAILED);
4932 status = TINFL_STATUS_FAILED;
4936#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4937 file_crc32 = (mz_uint32)mz_crc32(file_crc32, pWrite_buf_cur, out_buf_size);
4939 if ((out_buf_ofs += out_buf_size) > file_stat.m_uncomp_size)
4941 mz_zip_set_error(pZip, MZ_ZIP_DECOMPRESSION_FAILED);
4942 status = TINFL_STATUS_FAILED;
4946 }
while ((status == TINFL_STATUS_NEEDS_MORE_INPUT) || (status == TINFL_STATUS_HAS_MORE_OUTPUT));
4950 if ((status == TINFL_STATUS_DONE) && (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)))
4953 if (out_buf_ofs != file_stat.m_uncomp_size)
4955 mz_zip_set_error(pZip, MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE);
4956 status = TINFL_STATUS_FAILED;
4958#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4959 else if (file_crc32 != file_stat.m_crc32)
4961 mz_zip_set_error(pZip, MZ_ZIP_DECOMPRESSION_FAILED);
4962 status = TINFL_STATUS_FAILED;
4967 if (!pZip->m_pState->m_pMem)
4968 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
4971 pZip->m_pFree(pZip->m_pAlloc_opaque, pWrite_buf);
4973 return status == TINFL_STATUS_DONE;
4976 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)
4978 mz_uint32 file_index;
4979 if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index))
4982 return mz_zip_reader_extract_to_callback(pZip, file_index, pCallback, pOpaque, flags);
4988 mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE +
sizeof(mz_uint32) - 1) /
sizeof(mz_uint32)];
4989 mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
4992 if ((!pZip) || (!pZip->m_pState))
4999 mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
5004 if (!mz_zip_reader_file_stat(pZip, file_index, &pState->file_stat))
5006 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5011 if (pState->file_stat.m_bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION | MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG))
5013 mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);
5014 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5019 if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (pState->file_stat.m_method != 0) && (pState->file_stat.m_method != MZ_DEFLATED))
5021 mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD);
5022 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5027 pState->pZip = pZip;
5028 pState->flags = flags;
5031 pState->status = TINFL_STATUS_DONE;
5032#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
5033 pState->file_crc32 = MZ_CRC32_INIT;
5035 pState->read_buf_ofs = 0;
5036 pState->out_buf_ofs = 0;
5037 pState->pRead_buf = NULL;
5038 pState->pWrite_buf = NULL;
5039 pState->out_blk_remain = 0;
5042 pState->cur_file_ofs = pState->file_stat.m_local_header_ofs;
5043 if (pZip->m_pRead(pZip->m_pIO_opaque, pState->cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
5045 mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
5046 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5050 if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
5052 mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
5053 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5057 pState->cur_file_ofs += (mz_uint64)(MZ_ZIP_LOCAL_DIR_HEADER_SIZE) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
5058 if ((pState->cur_file_ofs + pState->file_stat.m_comp_size) > pZip->m_archive_size)
5060 mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
5061 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5066 if (pZip->m_pState->m_pMem)
5068 pState->pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + pState->cur_file_ofs;
5069 pState->read_buf_size = pState->read_buf_avail = pState->file_stat.m_comp_size;
5070 pState->comp_remaining = pState->file_stat.m_comp_size;
5074 if (!((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!pState->file_stat.m_method)))
5077 pState->read_buf_size = MZ_MIN(pState->file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
5078 if (NULL == (pState->pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (
size_t)pState->read_buf_size)))
5080 mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
5081 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5088 pState->read_buf_size = 0;
5090 pState->read_buf_avail = 0;
5091 pState->comp_remaining = pState->file_stat.m_comp_size;
5094 if (!((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!pState->file_stat.m_method)))
5097 tinfl_init(&pState->inflator);
5100 if (NULL == (pState->pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, TINFL_LZ_DICT_SIZE)))
5102 mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
5103 if (pState->pRead_buf)
5104 pZip->m_pFree(pZip->m_pAlloc_opaque, pState->pRead_buf);
5105 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5115 mz_uint32 file_index;
5118 if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index))
5122 return mz_zip_reader_extract_iter_new(pZip, file_index, flags);
5127 size_t copied_to_caller = 0;
5130 if ((!pState) || (!pState->pZip) || (!pState->pZip->m_pState) || (!pvBuf))
5133 if ((pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!pState->file_stat.m_method))
5136 copied_to_caller = (size_t)MZ_MIN(buf_size, pState->comp_remaining);
5139 if (pState->pZip->m_pState->m_pMem)
5142 memcpy(pvBuf, pState->pRead_buf, copied_to_caller);
5143 pState->pRead_buf = ((mz_uint8 *)pState->pRead_buf) + copied_to_caller;
5148 if (pState->pZip->m_pRead(pState->pZip->m_pIO_opaque, pState->cur_file_ofs, pvBuf, copied_to_caller) != copied_to_caller)
5151 mz_zip_set_error(pState->pZip, MZ_ZIP_FILE_READ_FAILED);
5152 pState->status = TINFL_STATUS_FAILED;
5153 copied_to_caller = 0;
5157#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
5159 if (!(pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
5160 pState->file_crc32 = (mz_uint32)mz_crc32(pState->file_crc32, (
const mz_uint8 *)pvBuf, copied_to_caller);
5164 pState->cur_file_ofs += copied_to_caller;
5165 pState->out_buf_ofs += copied_to_caller;
5166 pState->comp_remaining -= copied_to_caller;
5173 mz_uint8 *pWrite_buf_cur = (mz_uint8 *)pState->pWrite_buf + (pState->out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
5176 size_t in_buf_size, out_buf_size = TINFL_LZ_DICT_SIZE - (pState->out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
5178 if (!pState->out_blk_remain)
5181 if ((!pState->read_buf_avail) && (!pState->pZip->m_pState->m_pMem))
5184 pState->read_buf_avail = MZ_MIN(pState->read_buf_size, pState->comp_remaining);
5185 if (pState->pZip->m_pRead(pState->pZip->m_pIO_opaque, pState->cur_file_ofs, pState->pRead_buf, (
size_t)pState->read_buf_avail) != pState->read_buf_avail)
5187 mz_zip_set_error(pState->pZip, MZ_ZIP_FILE_READ_FAILED);
5188 pState->status = TINFL_STATUS_FAILED;
5193 pState->cur_file_ofs += pState->read_buf_avail;
5194 pState->comp_remaining -= pState->read_buf_avail;
5195 pState->read_buf_ofs = 0;
5199 in_buf_size = (size_t)pState->read_buf_avail;
5200 pState->status = tinfl_decompress(&pState->inflator, (
const mz_uint8 *)pState->pRead_buf + pState->read_buf_ofs, &in_buf_size, (mz_uint8 *)pState->pWrite_buf, pWrite_buf_cur, &out_buf_size, pState->comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0);
5201 pState->read_buf_avail -= in_buf_size;
5202 pState->read_buf_ofs += in_buf_size;
5205 pState->out_blk_remain = out_buf_size;
5208 if (pState->out_blk_remain)
5211 size_t to_copy = MZ_MIN((buf_size - copied_to_caller), pState->out_blk_remain);
5214 memcpy((mz_uint8 *)pvBuf + copied_to_caller, pWrite_buf_cur, to_copy);
5216#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
5218 pState->file_crc32 = (mz_uint32)mz_crc32(pState->file_crc32, pWrite_buf_cur, to_copy);
5222 pState->out_blk_remain -= to_copy;
5225 if ((pState->out_buf_ofs += to_copy) > pState->file_stat.m_uncomp_size)
5227 mz_zip_set_error(pState->pZip, MZ_ZIP_DECOMPRESSION_FAILED);
5228 pState->status = TINFL_STATUS_FAILED;
5233 copied_to_caller += to_copy;
5235 }
while ((copied_to_caller < buf_size) && ((pState->status == TINFL_STATUS_NEEDS_MORE_INPUT) || (pState->status == TINFL_STATUS_HAS_MORE_OUTPUT)));
5239 return copied_to_caller;
5247 if ((!pState) || (!pState->pZip) || (!pState->pZip->m_pState))
5251 if ((pState->status == TINFL_STATUS_DONE) && (!(pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA)))
5254 if (pState->out_buf_ofs != pState->file_stat.m_uncomp_size)
5256 mz_zip_set_error(pState->pZip, MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE);
5257 pState->status = TINFL_STATUS_FAILED;
5259#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
5260 else if (pState->file_crc32 != pState->file_stat.m_crc32)
5262 mz_zip_set_error(pState->pZip, MZ_ZIP_DECOMPRESSION_FAILED);
5263 pState->status = TINFL_STATUS_FAILED;
5269 if (!pState->pZip->m_pState->m_pMem)
5270 pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState->pRead_buf);
5271 if (pState->pWrite_buf)
5272 pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState->pWrite_buf);
5275 status = pState->status;
5278 pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState);
5280 return status == TINFL_STATUS_DONE;
5283#ifndef MINIZ_NO_STDIO
5284 static size_t mz_zip_file_write_callback(
void *pOpaque, mz_uint64 ofs,
const void *pBuf,
size_t n)
5288 return MZ_FWRITE(pBuf, 1, n, (MZ_FILE *)pOpaque);
5291 mz_bool mz_zip_reader_extract_to_file(
mz_zip_archive *pZip, mz_uint file_index,
const char *pDst_filename, mz_uint flags)
5297 if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
5300 if ((file_stat.m_is_directory) || (!file_stat.m_is_supported))
5301 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE);
5303 pFile = MZ_FOPEN(pDst_filename,
"wb");
5305 return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);
5307 status = mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_file_write_callback, pFile, flags);
5309 if (MZ_FCLOSE(pFile) == EOF)
5312 mz_zip_set_error(pZip, MZ_ZIP_FILE_CLOSE_FAILED);
5317#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_STDIO)
5319 mz_zip_set_file_times(pDst_filename, file_stat.m_time, file_stat.m_time);
5325 mz_bool mz_zip_reader_extract_file_to_file(
mz_zip_archive *pZip,
const char *pArchive_filename,
const char *pDst_filename, mz_uint flags)
5327 mz_uint32 file_index;
5328 if (!mz_zip_reader_locate_file_v2(pZip, pArchive_filename, NULL, flags, &file_index))
5331 return mz_zip_reader_extract_to_file(pZip, file_index, pDst_filename, flags);
5334 mz_bool mz_zip_reader_extract_to_cfile(
mz_zip_archive *pZip, mz_uint file_index, MZ_FILE *pFile, mz_uint flags)
5338 if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
5341 if ((file_stat.m_is_directory) || (!file_stat.m_is_supported))
5342 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE);
5344 return mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_file_write_callback, pFile, flags);
5347 mz_bool mz_zip_reader_extract_file_to_cfile(
mz_zip_archive *pZip,
const char *pArchive_filename, MZ_FILE *pFile, mz_uint flags)
5349 mz_uint32 file_index;
5350 if (!mz_zip_reader_locate_file_v2(pZip, pArchive_filename, NULL, flags, &file_index))
5353 return mz_zip_reader_extract_to_cfile(pZip, file_index, pFile, flags);
5357 static size_t mz_zip_compute_crc32_callback(
void *pOpaque, mz_uint64 file_ofs,
const void *pBuf,
size_t n)
5359 mz_uint32 *p = (mz_uint32 *)pOpaque;
5361 *p = (mz_uint32)mz_crc32(*p, (
const mz_uint8 *)pBuf, n);
5365 mz_bool mz_zip_validate_file(
mz_zip_archive *pZip, mz_uint file_index, mz_uint flags)
5369 const mz_uint8 *pCentral_dir_header;
5370 mz_bool found_zip64_ext_data_in_cdir = MZ_FALSE;
5371 mz_bool found_zip64_ext_data_in_ldir = MZ_FALSE;
5372 mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE +
sizeof(mz_uint32) - 1) /
sizeof(mz_uint32)];
5373 mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
5374 mz_uint64 local_header_ofs = 0;
5375 mz_uint32 local_header_filename_len, local_header_extra_len, local_header_crc32;
5376 mz_uint64 local_header_comp_size, local_header_uncomp_size;
5377 mz_uint32 uncomp_crc32 = MZ_CRC32_INIT;
5378 mz_bool has_data_descriptor;
5379 mz_uint32 local_header_bit_flags;
5382 mz_zip_array_init(&file_data_array, 1);
5384 if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (!pZip->m_pRead))
5385 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
5387 if (file_index > pZip->m_total_files)
5388 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
5390 pState = pZip->m_pState;
5392 pCentral_dir_header = mz_zip_get_cdh(pZip, file_index);
5394 if (!mz_zip_file_stat_internal(pZip, file_index, pCentral_dir_header, &file_stat, &found_zip64_ext_data_in_cdir))
5398 if ((file_stat.m_is_directory) || (!file_stat.m_uncomp_size))
5402 if (file_stat.m_is_encrypted)
5403 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);
5406 if ((file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
5407 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD);
5409 if (!file_stat.m_is_supported)
5410 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE);
5413 local_header_ofs = file_stat.m_local_header_ofs;
5414 if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
5415 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
5417 if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
5418 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
5420 local_header_filename_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS);
5421 local_header_extra_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
5422 local_header_comp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS);
5423 local_header_uncomp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS);
5424 local_header_crc32 = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_CRC32_OFS);
5425 local_header_bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS);
5426 has_data_descriptor = (local_header_bit_flags & 8) != 0;
5428 if (local_header_filename_len != strlen(file_stat.m_filename))
5429 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
5431 if ((local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len + local_header_extra_len + file_stat.m_comp_size) > pZip->m_archive_size)
5432 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
5434 if (!mz_zip_array_resize(pZip, &file_data_array, MZ_MAX(local_header_filename_len, local_header_extra_len), MZ_FALSE))
5436 mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
5437 goto handle_failure;
5440 if (local_header_filename_len)
5442 if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE, file_data_array.m_p, local_header_filename_len) != local_header_filename_len)
5444 mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
5445 goto handle_failure;
5449 if (memcmp(file_stat.m_filename, file_data_array.m_p, local_header_filename_len) != 0)
5451 mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
5452 goto handle_failure;
5456 if ((local_header_extra_len) && ((local_header_comp_size == MZ_UINT32_MAX) || (local_header_uncomp_size == MZ_UINT32_MAX)))
5458 mz_uint32 extra_size_remaining = local_header_extra_len;
5459 const mz_uint8 *pExtra_data = (
const mz_uint8 *)file_data_array.m_p;
5461 if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len, file_data_array.m_p, local_header_extra_len) != local_header_extra_len)
5463 mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
5464 goto handle_failure;
5469 mz_uint32 field_id, field_data_size, field_total_size;
5471 if (extra_size_remaining < (
sizeof(mz_uint16) * 2))
5473 mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
5474 goto handle_failure;
5477 field_id = MZ_READ_LE16(pExtra_data);
5478 field_data_size = MZ_READ_LE16(pExtra_data +
sizeof(mz_uint16));
5479 field_total_size = field_data_size +
sizeof(mz_uint16) * 2;
5481 if (field_total_size > extra_size_remaining)
5483 mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
5484 goto handle_failure;
5487 if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID)
5489 const mz_uint8 *pSrc_field_data = pExtra_data +
sizeof(mz_uint32);
5491 if (field_data_size <
sizeof(mz_uint64) * 2)
5493 mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
5494 goto handle_failure;
5497 local_header_uncomp_size = MZ_READ_LE64(pSrc_field_data);
5498 local_header_comp_size = MZ_READ_LE64(pSrc_field_data +
sizeof(mz_uint64));
5500 found_zip64_ext_data_in_ldir = MZ_TRUE;
5504 pExtra_data += field_total_size;
5505 extra_size_remaining -= field_total_size;
5506 }
while (extra_size_remaining);
5511 if ((has_data_descriptor) && (!local_header_comp_size) && (!local_header_crc32))
5513 mz_uint8 descriptor_buf[32];
5515 const mz_uint8 *pSrc;
5516 mz_uint32 file_crc32;
5517 mz_uint64 comp_size = 0, uncomp_size = 0;
5519 mz_uint32 num_descriptor_uint32s = ((pState->m_zip64) || (found_zip64_ext_data_in_ldir)) ? 6 : 4;
5521 if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_len + local_header_extra_len + file_stat.m_comp_size, descriptor_buf,
sizeof(mz_uint32) * num_descriptor_uint32s) != (
sizeof(mz_uint32) * num_descriptor_uint32s))
5523 mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
5524 goto handle_failure;
5527 has_id = (MZ_READ_LE32(descriptor_buf) == MZ_ZIP_DATA_DESCRIPTOR_ID);
5528 pSrc = has_id ? (descriptor_buf +
sizeof(mz_uint32)) : descriptor_buf;
5530 file_crc32 = MZ_READ_LE32(pSrc);
5532 if ((pState->m_zip64) || (found_zip64_ext_data_in_ldir))
5534 comp_size = MZ_READ_LE64(pSrc +
sizeof(mz_uint32));
5535 uncomp_size = MZ_READ_LE64(pSrc +
sizeof(mz_uint32) +
sizeof(mz_uint64));
5539 comp_size = MZ_READ_LE32(pSrc +
sizeof(mz_uint32));
5540 uncomp_size = MZ_READ_LE32(pSrc +
sizeof(mz_uint32) +
sizeof(mz_uint32));
5543 if ((file_crc32 != file_stat.m_crc32) || (comp_size != file_stat.m_comp_size) || (uncomp_size != file_stat.m_uncomp_size))
5545 mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
5546 goto handle_failure;
5551 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))
5553 mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
5554 goto handle_failure;
5558 mz_zip_array_clear(pZip, &file_data_array);
5560 if ((flags & MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY) == 0)
5562 if (!mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_compute_crc32_callback, &uncomp_crc32, 0))
5566 if (uncomp_crc32 != file_stat.m_crc32)
5568 mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
5576 mz_zip_array_clear(pZip, &file_data_array);
5580 mz_bool mz_zip_validate_archive(
mz_zip_archive *pZip, mz_uint flags)
5585 if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (!pZip->m_pRead))
5586 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
5588 pState = pZip->m_pState;
5591 if (!pState->m_zip64)
5593 if (pZip->m_total_files > MZ_UINT16_MAX)
5594 return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
5596 if (pZip->m_archive_size > MZ_UINT32_MAX)
5597 return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
5601 if (pState->m_central_dir.m_size >= MZ_UINT32_MAX)
5602 return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
5605 for (i = 0; i < pZip->m_total_files; i++)
5607 if (MZ_ZIP_FLAG_VALIDATE_LOCATE_FILE_FLAG & flags)
5609 mz_uint32 found_index;
5612 if (!mz_zip_reader_file_stat(pZip, i, &stat))
5615 if (!mz_zip_reader_locate_file_v2(pZip, stat.m_filename, NULL, 0, &found_index))
5619 if (found_index != i)
5620 return mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
5623 if (!mz_zip_validate_file(pZip, i, flags))
5630 mz_bool mz_zip_validate_mem_archive(
const void *pMem,
size_t size, mz_uint flags, mz_zip_error *pErr)
5632 mz_bool success = MZ_TRUE;
5634 mz_zip_error actual_err = MZ_ZIP_NO_ERROR;
5636 if ((!pMem) || (!size))
5639 *pErr = MZ_ZIP_INVALID_PARAMETER;
5643 mz_zip_zero_struct(&zip);
5645 if (!mz_zip_reader_init_mem(&zip, pMem, size, flags))
5648 *pErr = zip.m_last_error;
5652 if (!mz_zip_validate_archive(&zip, flags))
5654 actual_err = zip.m_last_error;
5658 if (!mz_zip_reader_end_internal(&zip, success))
5661 actual_err = zip.m_last_error;
5671#ifndef MINIZ_NO_STDIO
5672 mz_bool mz_zip_validate_file_archive(
const char *pFilename, mz_uint flags, mz_zip_error *pErr)
5674 mz_bool success = MZ_TRUE;
5676 mz_zip_error actual_err = MZ_ZIP_NO_ERROR;
5681 *pErr = MZ_ZIP_INVALID_PARAMETER;
5685 mz_zip_zero_struct(&zip);
5687 if (!mz_zip_reader_init_file_v2(&zip, pFilename, flags, 0, 0))
5690 *pErr = zip.m_last_error;
5694 if (!mz_zip_validate_archive(&zip, flags))
5696 actual_err = zip.m_last_error;
5700 if (!mz_zip_reader_end_internal(&zip, success))
5703 actual_err = zip.m_last_error;
5716#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
5718 static MZ_FORCEINLINE
void mz_write_le16(mz_uint8 *p, mz_uint16 v)
5721 p[1] = (mz_uint8)(v >> 8);
5723 static MZ_FORCEINLINE
void mz_write_le32(mz_uint8 *p, mz_uint32 v)
5726 p[1] = (mz_uint8)(v >> 8);
5727 p[2] = (mz_uint8)(v >> 16);
5728 p[3] = (mz_uint8)(v >> 24);
5730 static MZ_FORCEINLINE
void mz_write_le64(mz_uint8 *p, mz_uint64 v)
5732 mz_write_le32(p, (mz_uint32)v);
5733 mz_write_le32(p +
sizeof(mz_uint32), (mz_uint32)(v >> 32));
5736#define MZ_WRITE_LE16(p, v) mz_write_le16((mz_uint8 *)(p), (mz_uint16)(v))
5737#define MZ_WRITE_LE32(p, v) mz_write_le32((mz_uint8 *)(p), (mz_uint32)(v))
5738#define MZ_WRITE_LE64(p, v) mz_write_le64((mz_uint8 *)(p), (mz_uint64)(v))
5740 static size_t mz_zip_heap_write_func(
void *pOpaque, mz_uint64 file_ofs,
const void *pBuf,
size_t n)
5744 mz_uint64 new_size = MZ_MAX(file_ofs + n, pState->m_mem_size);
5750 if ((
sizeof(
size_t) ==
sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF))
5752 mz_zip_set_error(pZip, MZ_ZIP_FILE_TOO_LARGE);
5756 if (new_size > pState->m_mem_capacity)
5759 size_t new_capacity = MZ_MAX(64, pState->m_mem_capacity);
5761 while (new_capacity < new_size)
5764 if (NULL == (pNew_block = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pState->m_pMem, 1, new_capacity)))
5766 mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
5770 pState->m_pMem = pNew_block;
5771 pState->m_mem_capacity = new_capacity;
5773 memcpy((mz_uint8 *)pState->m_pMem + file_ofs, pBuf, n);
5774 pState->m_mem_size = (size_t)new_size;
5778 static mz_bool mz_zip_writer_end_internal(
mz_zip_archive *pZip, mz_bool set_last_error)
5781 mz_bool status = MZ_TRUE;
5783 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)))
5786 mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
5790 pState = pZip->m_pState;
5791 pZip->m_pState = NULL;
5792 mz_zip_array_clear(pZip, &pState->m_central_dir);
5793 mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
5794 mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets);
5796#ifndef MINIZ_NO_STDIO
5797 if (pState->m_pFile)
5799 if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE)
5801 if (MZ_FCLOSE(pState->m_pFile) == EOF)
5804 mz_zip_set_error(pZip, MZ_ZIP_FILE_CLOSE_FAILED);
5809 pState->m_pFile = NULL;
5813 if ((pZip->m_pWrite == mz_zip_heap_write_func) && (pState->m_pMem))
5815 pZip->m_pFree(pZip->m_pAlloc_opaque, pState->m_pMem);
5816 pState->m_pMem = NULL;
5819 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5820 pZip->m_zip_mode = MZ_ZIP_MODE_INVALID;
5824 mz_bool mz_zip_writer_init_v2(
mz_zip_archive *pZip, mz_uint64 existing_size, mz_uint flags)
5826 mz_bool zip64 = (flags & MZ_ZIP_FLAG_WRITE_ZIP64) != 0;
5828 if ((!pZip) || (pZip->m_pState) || (!pZip->m_pWrite) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
5829 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
5831 if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING)
5834 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
5837 if (pZip->m_file_offset_alignment)
5840 if (pZip->m_file_offset_alignment & (pZip->m_file_offset_alignment - 1))
5841 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
5844 if (!pZip->m_pAlloc)
5845 pZip->m_pAlloc = miniz_def_alloc_func;
5847 pZip->m_pFree = miniz_def_free_func;
5848 if (!pZip->m_pRealloc)
5849 pZip->m_pRealloc = miniz_def_realloc_func;
5851 pZip->m_archive_size = existing_size;
5852 pZip->m_central_directory_file_ofs = 0;
5853 pZip->m_total_files = 0;
5856 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
5860 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir,
sizeof(mz_uint8));
5861 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets,
sizeof(mz_uint32));
5862 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets,
sizeof(mz_uint32));
5864 pZip->m_pState->m_zip64 = zip64;
5865 pZip->m_pState->m_zip64_has_extended_info_fields = zip64;
5867 pZip->m_zip_type = MZ_ZIP_TYPE_USER;
5868 pZip->m_zip_mode = MZ_ZIP_MODE_WRITING;
5873 mz_bool mz_zip_writer_init(
mz_zip_archive *pZip, mz_uint64 existing_size)
5875 return mz_zip_writer_init_v2(pZip, existing_size, 0);
5878 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)
5880 pZip->m_pWrite = mz_zip_heap_write_func;
5881 pZip->m_pNeeds_keepalive = NULL;
5883 if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING)
5884 pZip->m_pRead = mz_zip_mem_read_func;
5886 pZip->m_pIO_opaque = pZip;
5888 if (!mz_zip_writer_init_v2(pZip, size_to_reserve_at_beginning, flags))
5891 pZip->m_zip_type = MZ_ZIP_TYPE_HEAP;
5893 if (0 != (initial_allocation_size = MZ_MAX(initial_allocation_size, size_to_reserve_at_beginning)))
5895 if (NULL == (pZip->m_pState->m_pMem = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, initial_allocation_size)))
5897 mz_zip_writer_end_internal(pZip, MZ_FALSE);
5898 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
5900 pZip->m_pState->m_mem_capacity = initial_allocation_size;
5906 mz_bool mz_zip_writer_init_heap(
mz_zip_archive *pZip,
size_t size_to_reserve_at_beginning,
size_t initial_allocation_size)
5908 return mz_zip_writer_init_heap_v2(pZip, size_to_reserve_at_beginning, initial_allocation_size, 0);
5911#ifndef MINIZ_NO_STDIO
5912 static size_t mz_zip_file_write_func(
void *pOpaque, mz_uint64 file_ofs,
const void *pBuf,
size_t n)
5915 mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
5917 file_ofs += pZip->m_pState->m_file_archive_start_ofs;
5919 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))))
5921 mz_zip_set_error(pZip, MZ_ZIP_FILE_SEEK_FAILED);
5925 return MZ_FWRITE(pBuf, 1, n, pZip->m_pState->m_pFile);
5928 mz_bool mz_zip_writer_init_file(
mz_zip_archive *pZip,
const char *pFilename, mz_uint64 size_to_reserve_at_beginning)
5930 return mz_zip_writer_init_file_v2(pZip, pFilename, size_to_reserve_at_beginning, 0);
5933 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)
5937 pZip->m_pWrite = mz_zip_file_write_func;
5938 pZip->m_pNeeds_keepalive = NULL;
5940 if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING)
5941 pZip->m_pRead = mz_zip_file_read_func;
5943 pZip->m_pIO_opaque = pZip;
5945 if (!mz_zip_writer_init_v2(pZip, size_to_reserve_at_beginning, flags))
5948 if (NULL == (pFile = MZ_FOPEN(pFilename, (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING) ?
"w+b" :
"wb")))
5950 mz_zip_writer_end(pZip);
5951 return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);
5954 pZip->m_pState->m_pFile = pFile;
5955 pZip->m_zip_type = MZ_ZIP_TYPE_FILE;
5957 if (size_to_reserve_at_beginning)
5959 mz_uint64 cur_ofs = 0;
5966 size_t n = (size_t)MZ_MIN(
sizeof(buf), size_to_reserve_at_beginning);
5967 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_ofs, buf, n) != n)
5969 mz_zip_writer_end(pZip);
5970 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
5973 size_to_reserve_at_beginning -= n;
5974 }
while (size_to_reserve_at_beginning);
5980 mz_bool mz_zip_writer_init_cfile(
mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint flags)
5982 pZip->m_pWrite = mz_zip_file_write_func;
5983 pZip->m_pNeeds_keepalive = NULL;
5985 if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING)
5986 pZip->m_pRead = mz_zip_file_read_func;
5988 pZip->m_pIO_opaque = pZip;
5990 if (!mz_zip_writer_init_v2(pZip, 0, flags))
5993 pZip->m_pState->m_pFile = pFile;
5994 pZip->m_pState->m_file_archive_start_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
5995 pZip->m_zip_type = MZ_ZIP_TYPE_CFILE;
6001 mz_bool mz_zip_writer_init_from_reader_v2(
mz_zip_archive *pZip,
const char *pFilename, mz_uint flags)
6005 if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
6006 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6008 if (flags & MZ_ZIP_FLAG_WRITE_ZIP64)
6011 if (!pZip->m_pState->m_zip64)
6012 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6016 if (pZip->m_pState->m_zip64)
6018 if (pZip->m_total_files == MZ_UINT32_MAX)
6019 return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
6023 if (pZip->m_total_files == MZ_UINT16_MAX)
6024 return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
6026 if ((pZip->m_archive_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_ZIP_LOCAL_DIR_HEADER_SIZE) > MZ_UINT32_MAX)
6027 return mz_zip_set_error(pZip, MZ_ZIP_FILE_TOO_LARGE);
6030 pState = pZip->m_pState;
6032 if (pState->m_pFile)
6034#ifdef MINIZ_NO_STDIO
6036 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6038 if (pZip->m_pIO_opaque != pZip)
6039 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6041 if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE &&
6042 !(flags & MZ_ZIP_FLAG_READ_ALLOW_WRITING) )
6045 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6048 if (NULL == (pState->m_pFile = MZ_FREOPEN(pFilename,
"r+b", pState->m_pFile)))
6051 mz_zip_reader_end_internal(pZip, MZ_FALSE);
6052 return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);
6056 pZip->m_pWrite = mz_zip_file_write_func;
6057 pZip->m_pNeeds_keepalive = NULL;
6060 else if (pState->m_pMem)
6063 if (pZip->m_pIO_opaque != pZip)
6064 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6066 pState->m_mem_capacity = pState->m_mem_size;
6067 pZip->m_pWrite = mz_zip_heap_write_func;
6068 pZip->m_pNeeds_keepalive = NULL;
6071 else if (!pZip->m_pWrite)
6072 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6076 pZip->m_archive_size = pZip->m_central_directory_file_ofs;
6077 pZip->m_central_directory_file_ofs = 0;
6082 mz_zip_array_clear(pZip, &pZip->m_pState->m_sorted_central_dir_offsets);
6084 pZip->m_zip_mode = MZ_ZIP_MODE_WRITING;
6089 mz_bool mz_zip_writer_init_from_reader(
mz_zip_archive *pZip,
const char *pFilename)
6091 return mz_zip_writer_init_from_reader_v2(pZip, pFilename, 0);
6095 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)
6097 return mz_zip_writer_add_mem_ex(pZip, pArchive_name, pBuf, buf_size, NULL, 0, level_and_flags, 0, 0);
6103 mz_uint64 m_cur_archive_file_ofs;
6104 mz_uint64 m_comp_size;
6107 static mz_bool mz_zip_writer_add_put_buf_callback(
const void *pBuf,
int len,
void *pUser)
6110 if ((
int)pState->m_pZip->m_pWrite(pState->m_pZip->m_pIO_opaque, pState->m_cur_archive_file_ofs, pBuf, len) != len)
6113 pState->m_cur_archive_file_ofs += len;
6114 pState->m_comp_size += len;
6118#define MZ_ZIP64_MAX_LOCAL_EXTRA_FIELD_SIZE (sizeof(mz_uint16) * 2 + sizeof(mz_uint64) * 2)
6119#define MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE (sizeof(mz_uint16) * 2 + sizeof(mz_uint64) * 3)
6120 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)
6122 mz_uint8 *pDst = pBuf;
6123 mz_uint32 field_size = 0;
6125 MZ_WRITE_LE16(pDst + 0, MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID);
6126 MZ_WRITE_LE16(pDst + 2, 0);
6127 pDst +=
sizeof(mz_uint16) * 2;
6131 MZ_WRITE_LE64(pDst, *pUncomp_size);
6132 pDst +=
sizeof(mz_uint64);
6133 field_size +=
sizeof(mz_uint64);
6138 MZ_WRITE_LE64(pDst, *pComp_size);
6139 pDst +=
sizeof(mz_uint64);
6140 field_size +=
sizeof(mz_uint64);
6143 if (pLocal_header_ofs)
6145 MZ_WRITE_LE64(pDst, *pLocal_header_ofs);
6146 pDst +=
sizeof(mz_uint64);
6147 field_size +=
sizeof(mz_uint64);
6150 MZ_WRITE_LE16(pBuf + 2, field_size);
6152 return (mz_uint32)(pDst - pBuf);
6155 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)
6158 memset(pDst, 0, MZ_ZIP_LOCAL_DIR_HEADER_SIZE);
6159 MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_SIG_OFS, MZ_ZIP_LOCAL_DIR_HEADER_SIG);
6160 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_VERSION_NEEDED_OFS, method ? 20 : 0);
6161 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_BIT_FLAG_OFS, bit_flags);
6162 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_METHOD_OFS, method);
6163 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_TIME_OFS, dos_time);
6164 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_DATE_OFS, dos_date);
6165 MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_CRC32_OFS, uncomp_crc32);
6166 MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS, MZ_MIN(comp_size, MZ_UINT32_MAX));
6167 MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS, MZ_MIN(uncomp_size, MZ_UINT32_MAX));
6168 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILENAME_LEN_OFS, filename_size);
6169 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_EXTRA_LEN_OFS, extra_size);
6173 static mz_bool mz_zip_writer_create_central_dir_header(
mz_zip_archive *pZip, mz_uint8 *pDst,
6174 mz_uint16 filename_size, mz_uint16 extra_size, mz_uint16 comment_size,
6175 mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32,
6176 mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date,
6177 mz_uint64 local_header_ofs, mz_uint32 ext_attributes)
6180 memset(pDst, 0, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE);
6181 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_SIG_OFS, MZ_ZIP_CENTRAL_DIR_HEADER_SIG);
6182 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_VERSION_NEEDED_OFS, method ? 20 : 0);
6183 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_BIT_FLAG_OFS, bit_flags);
6184 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_METHOD_OFS, method);
6185 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_TIME_OFS, dos_time);
6186 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_DATE_OFS, dos_date);
6187 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_CRC32_OFS, uncomp_crc32);
6188 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS, MZ_MIN(comp_size, MZ_UINT32_MAX));
6189 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS, MZ_MIN(uncomp_size, MZ_UINT32_MAX));
6190 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILENAME_LEN_OFS, filename_size);
6191 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_EXTRA_LEN_OFS, extra_size);
6192 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_COMMENT_LEN_OFS, comment_size);
6193 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS, ext_attributes);
6194 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_LOCAL_HEADER_OFS, MZ_MIN(local_header_ofs, MZ_UINT32_MAX));
6198 static mz_bool mz_zip_writer_add_to_central_dir(
mz_zip_archive *pZip,
const char *pFilename, mz_uint16 filename_size,
6199 const void *pExtra, mz_uint16 extra_size,
const void *pComment, mz_uint16 comment_size,
6200 mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32,
6201 mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date,
6202 mz_uint64 local_header_ofs, mz_uint32 ext_attributes,
6203 const char *user_extra_data, mz_uint user_extra_data_len)
6206 mz_uint32 central_dir_ofs = (mz_uint32)pState->m_central_dir.m_size;
6207 size_t orig_central_dir_size = pState->m_central_dir.m_size;
6208 mz_uint8 central_dir_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE];
6210 if (!pZip->m_pState->m_zip64)
6212 if (local_header_ofs > 0xFFFFFFFF)
6213 return mz_zip_set_error(pZip, MZ_ZIP_FILE_TOO_LARGE);
6217 if (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + extra_size + user_extra_data_len + comment_size) >= MZ_UINT32_MAX)
6218 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);
6220 if (!mz_zip_writer_create_central_dir_header(pZip, central_dir_header, filename_size, (mz_uint16)(extra_size + user_extra_data_len), comment_size, uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, dos_date, local_header_ofs, ext_attributes))
6221 return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
6223 if ((!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_dir_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) ||
6224 (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pFilename, filename_size)) ||
6225 (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pExtra, extra_size)) ||
6226 (!mz_zip_array_push_back(pZip, &pState->m_central_dir, user_extra_data, user_extra_data_len)) ||
6227 (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pComment, comment_size)) ||
6228 (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, ¢ral_dir_ofs, 1)))
6231 mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
6232 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6238 static mz_bool mz_zip_writer_validate_archive_name(
const char *pArchive_name)
6241 if (*pArchive_name ==
'/')
6249 static mz_uint mz_zip_writer_compute_padding_needed_for_file_alignment(
mz_zip_archive *pZip)
6252 if (!pZip->m_file_offset_alignment)
6254 n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1));
6255 return (mz_uint)((pZip->m_file_offset_alignment - n) & (pZip->m_file_offset_alignment - 1));
6258 static mz_bool mz_zip_writer_write_zeros(
mz_zip_archive *pZip, mz_uint64 cur_file_ofs, mz_uint32 n)
6261 memset(buf, 0, MZ_MIN(
sizeof(buf), n));
6264 mz_uint32 s = MZ_MIN(
sizeof(buf), n);
6265 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_file_ofs, buf, s) != s)
6266 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
6274 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,
6275 mz_uint64 uncomp_size, mz_uint32 uncomp_crc32)
6277 return mz_zip_writer_add_mem_ex_v2(pZip, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, uncomp_size, uncomp_crc32, NULL, NULL, 0, NULL, 0);
6280 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,
6281 mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32, MZ_TIME_T *last_modified,
6282 const char *user_extra_data, mz_uint user_extra_data_len,
const char *user_extra_data_central, mz_uint user_extra_data_central_len)
6284 mz_uint16 method = 0, dos_time = 0, dos_date = 0;
6285 mz_uint level, ext_attributes = 0, num_alignment_padding_bytes;
6286 mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, comp_size = 0;
6287 size_t archive_name_size;
6288 mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
6290 mz_bool store_data_uncompressed;
6292 mz_uint8 *pExtra_data = NULL;
6293 mz_uint32 extra_size = 0;
6294 mz_uint8 extra_data[MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE];
6295 mz_uint16 bit_flags = 0;
6297 if ((
int)level_and_flags < 0)
6298 level_and_flags = MZ_DEFAULT_LEVEL;
6300 if (uncomp_size || (buf_size && !(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)))
6301 bit_flags |= MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR;
6303 if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME))
6304 bit_flags |= MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8;
6306 level = level_and_flags & 0xF;
6307 store_data_uncompressed = ((!level) || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA));
6309 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))
6310 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6312 pState = pZip->m_pState;
6314 if (pState->m_zip64)
6316 if (pZip->m_total_files == MZ_UINT32_MAX)
6317 return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
6321 if (pZip->m_total_files == MZ_UINT16_MAX)
6323 pState->m_zip64 = MZ_TRUE;
6326 if (((mz_uint64)buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF))
6328 pState->m_zip64 = MZ_TRUE;
6333 if ((!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (uncomp_size))
6334 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6336 if (!mz_zip_writer_validate_archive_name(pArchive_name))
6337 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME);
6339#ifndef MINIZ_NO_TIME
6340 if (last_modified != NULL)
6342 mz_zip_time_t_to_dos_time(*last_modified, &dos_time, &dos_date);
6348 mz_zip_time_t_to_dos_time(cur_time, &dos_time, &dos_date);
6351 (void)last_modified;
6354 if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
6356 uncomp_crc32 = (mz_uint32)mz_crc32(MZ_CRC32_INIT, (
const mz_uint8 *)pBuf, buf_size);
6357 uncomp_size = buf_size;
6358 if (uncomp_size <= 3)
6361 store_data_uncompressed = MZ_TRUE;
6365 archive_name_size = strlen(pArchive_name);
6366 if (archive_name_size > MZ_UINT16_MAX)
6367 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME);
6369 num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
6372 if (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE + comment_size) >= MZ_UINT32_MAX)
6373 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);
6375 if (!pState->m_zip64)
6378 if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + user_extra_data_len +
6379 pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + user_extra_data_central_len + MZ_ZIP_DATA_DESCRIPTER_SIZE32) > 0xFFFFFFFF)
6381 pState->m_zip64 = MZ_TRUE;
6386 if ((archive_name_size) && (pArchive_name[archive_name_size - 1] ==
'/'))
6389 ext_attributes |= MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG;
6392 if ((buf_size) || (uncomp_size))
6393 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6397 if ((!mz_zip_array_ensure_room(pZip, &pState->m_central_dir, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + (pState->m_zip64 ? MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE : 0))) || (!mz_zip_array_ensure_room(pZip, &pState->m_central_dir_offsets, 1)))
6398 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6400 if ((!store_data_uncompressed) && (buf_size))
6403 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6406 if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes))
6408 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6412 local_dir_header_ofs += num_alignment_padding_bytes;
6413 if (pZip->m_file_offset_alignment)
6415 MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0);
6417 cur_archive_file_ofs += num_alignment_padding_bytes;
6419 MZ_CLEAR_ARR(local_dir_header);
6421 if (!store_data_uncompressed || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
6423 method = MZ_DEFLATED;
6426 if (pState->m_zip64)
6428 if (uncomp_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX)
6430 pExtra_data = extra_data;
6431 extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
6432 (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
6435 if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, (mz_uint16)(extra_size + user_extra_data_len), 0, 0, 0, method, bit_flags, dos_time, dos_date))
6436 return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
6438 if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header,
sizeof(local_dir_header)) !=
sizeof(local_dir_header))
6439 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
6441 cur_archive_file_ofs +=
sizeof(local_dir_header);
6443 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
6445 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6446 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
6448 cur_archive_file_ofs += archive_name_size;
6450 if (pExtra_data != NULL)
6452 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, extra_data, extra_size) != extra_size)
6453 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
6455 cur_archive_file_ofs += extra_size;
6460 if ((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX))
6461 return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
6462 if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, (mz_uint16)user_extra_data_len, 0, 0, 0, method, bit_flags, dos_time, dos_date))
6463 return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
6465 if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header,
sizeof(local_dir_header)) !=
sizeof(local_dir_header))
6466 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
6468 cur_archive_file_ofs +=
sizeof(local_dir_header);
6470 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
6472 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6473 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
6475 cur_archive_file_ofs += archive_name_size;
6478 if (user_extra_data_len > 0)
6480 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len)
6481 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
6483 cur_archive_file_ofs += user_extra_data_len;
6486 if (store_data_uncompressed)
6488 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pBuf, buf_size) != buf_size)
6490 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6491 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
6494 cur_archive_file_ofs += buf_size;
6495 comp_size = buf_size;
6501 state.m_pZip = pZip;
6502 state.m_cur_archive_file_ofs = cur_archive_file_ofs;
6503 state.m_comp_size = 0;
6505 if ((tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY) ||
6506 (tdefl_compress_buffer(pComp, pBuf, buf_size, TDEFL_FINISH) != TDEFL_STATUS_DONE))
6508 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6509 return mz_zip_set_error(pZip, MZ_ZIP_COMPRESSION_FAILED);
6512 comp_size = state.m_comp_size;
6513 cur_archive_file_ofs = state.m_cur_archive_file_ofs;
6516 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6521 mz_uint8 local_dir_footer[MZ_ZIP_DATA_DESCRIPTER_SIZE64];
6522 mz_uint32 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE32;
6524 MZ_ASSERT(bit_flags & MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR);
6526 MZ_WRITE_LE32(local_dir_footer + 0, MZ_ZIP_DATA_DESCRIPTOR_ID);
6527 MZ_WRITE_LE32(local_dir_footer + 4, uncomp_crc32);
6528 if (pExtra_data == NULL)
6530 if (comp_size > MZ_UINT32_MAX)
6531 return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
6533 MZ_WRITE_LE32(local_dir_footer + 8, comp_size);
6534 MZ_WRITE_LE32(local_dir_footer + 12, uncomp_size);
6538 MZ_WRITE_LE64(local_dir_footer + 8, comp_size);
6539 MZ_WRITE_LE64(local_dir_footer + 16, uncomp_size);
6540 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE64;
6543 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_footer, local_dir_footer_size) != local_dir_footer_size)
6546 cur_archive_file_ofs += local_dir_footer_size;
6549 if (pExtra_data != NULL)
6551 extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
6552 (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
6555 if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, pExtra_data, (mz_uint16)extra_size, pComment,
6556 comment_size, uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, dos_date, local_dir_header_ofs, ext_attributes,
6557 user_extra_data_central, user_extra_data_central_len))
6560 pZip->m_total_files++;
6561 pZip->m_archive_size = cur_archive_file_ofs;
6566 mz_bool mz_zip_writer_add_read_buf_callback(
mz_zip_archive *pZip,
const char *pArchive_name, mz_file_read_func read_callback,
void *callback_opaque, mz_uint64 max_size,
const MZ_TIME_T *pFile_time,
const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
6567 const char *user_extra_data, mz_uint user_extra_data_len,
const char *user_extra_data_central, mz_uint user_extra_data_central_len)
6569 mz_uint16 gen_flags;
6570 mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes;
6571 mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0;
6572 mz_uint64 local_dir_header_ofs, cur_archive_file_ofs = pZip->m_archive_size, uncomp_size = 0, comp_size = 0;
6573 size_t archive_name_size;
6574 mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
6575 mz_uint8 *pExtra_data = NULL;
6576 mz_uint32 extra_size = 0;
6577 mz_uint8 extra_data[MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE];
6579 mz_uint64 file_ofs = 0, cur_archive_header_file_ofs;
6581 if ((
int)level_and_flags < 0)
6582 level_and_flags = MZ_DEFAULT_LEVEL;
6583 level = level_and_flags & 0xF;
6585 gen_flags = (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE) ? 0 : MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR;
6587 if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME))
6588 gen_flags |= MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8;
6591 if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION))
6592 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6594 pState = pZip->m_pState;
6596 if ((!pState->m_zip64) && (max_size > MZ_UINT32_MAX))
6600 pState->m_zip64 = MZ_TRUE;
6604 if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)
6605 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6607 if (!mz_zip_writer_validate_archive_name(pArchive_name))
6608 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME);
6610 if (pState->m_zip64)
6612 if (pZip->m_total_files == MZ_UINT32_MAX)
6613 return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
6617 if (pZip->m_total_files == MZ_UINT16_MAX)
6619 pState->m_zip64 = MZ_TRUE;
6624 archive_name_size = strlen(pArchive_name);
6625 if (archive_name_size > MZ_UINT16_MAX)
6626 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME);
6628 num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
6631 if (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE + comment_size) >= MZ_UINT32_MAX)
6632 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);
6634 if (!pState->m_zip64)
6637 if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + user_extra_data_len + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 1024 + MZ_ZIP_DATA_DESCRIPTER_SIZE32 + user_extra_data_central_len) > 0xFFFFFFFF)
6639 pState->m_zip64 = MZ_TRUE;
6644#ifndef MINIZ_NO_TIME
6647 mz_zip_time_t_to_dos_time(*pFile_time, &dos_time, &dos_date);
6656 if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes))
6658 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
6661 cur_archive_file_ofs += num_alignment_padding_bytes;
6662 local_dir_header_ofs = cur_archive_file_ofs;
6664 if (pZip->m_file_offset_alignment)
6666 MZ_ASSERT((cur_archive_file_ofs & (pZip->m_file_offset_alignment - 1)) == 0);
6669 if (max_size && level)
6671 method = MZ_DEFLATED;
6674 MZ_CLEAR_ARR(local_dir_header);
6675 if (pState->m_zip64)
6677 if (max_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX)
6679 pExtra_data = extra_data;
6680 if (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE)
6681 extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (max_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
6682 (max_size >= MZ_UINT32_MAX) ? &comp_size : NULL,
6683 (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
6685 extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, NULL,
6687 (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
6690 if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, (mz_uint16)(extra_size + user_extra_data_len), 0, 0, 0, method, gen_flags, dos_time, dos_date))
6691 return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
6693 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_header,
sizeof(local_dir_header)) !=
sizeof(local_dir_header))
6694 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
6696 cur_archive_file_ofs +=
sizeof(local_dir_header);
6698 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
6700 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
6703 cur_archive_file_ofs += archive_name_size;
6705 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, extra_data, extra_size) != extra_size)
6706 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
6708 cur_archive_file_ofs += extra_size;
6712 if ((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX))
6713 return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
6714 if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, (mz_uint16)user_extra_data_len, 0, 0, 0, method, gen_flags, dos_time, dos_date))
6715 return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
6717 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_header,
sizeof(local_dir_header)) !=
sizeof(local_dir_header))
6718 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
6720 cur_archive_file_ofs +=
sizeof(local_dir_header);
6722 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
6724 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
6727 cur_archive_file_ofs += archive_name_size;
6730 if (user_extra_data_len > 0)
6732 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len)
6733 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
6735 cur_archive_file_ofs += user_extra_data_len;
6740 void *pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, MZ_ZIP_MAX_IO_BUF_SIZE);
6743 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6750 size_t n = read_callback(callback_opaque, file_ofs, pRead_buf, MZ_ZIP_MAX_IO_BUF_SIZE);
6754 if ((n > MZ_ZIP_MAX_IO_BUF_SIZE) || (file_ofs + n > max_size))
6756 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6757 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
6759 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf, n) != n)
6761 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6762 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
6765 uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (
const mz_uint8 *)pRead_buf, n);
6766 cur_archive_file_ofs += n;
6768 uncomp_size = file_ofs;
6769 comp_size = uncomp_size;
6773 mz_bool result = MZ_FALSE;
6778 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6779 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6782 state.m_pZip = pZip;
6783 state.m_cur_archive_file_ofs = cur_archive_file_ofs;
6784 state.m_comp_size = 0;
6786 if (tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY)
6788 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6789 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6790 return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
6795 tdefl_status status;
6796 tdefl_flush
flush = TDEFL_NO_FLUSH;
6798 size_t n = read_callback(callback_opaque, file_ofs, pRead_buf, MZ_ZIP_MAX_IO_BUF_SIZE);
6799 if ((n > MZ_ZIP_MAX_IO_BUF_SIZE) || (file_ofs + n > max_size))
6801 mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
6806 uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (
const mz_uint8 *)pRead_buf, n);
6808 if (pZip->m_pNeeds_keepalive != NULL && pZip->m_pNeeds_keepalive(pZip->m_pIO_opaque))
6809 flush = TDEFL_FULL_FLUSH;
6812 flush = TDEFL_FINISH;
6814 status = tdefl_compress_buffer(pComp, pRead_buf, n, flush);
6815 if (status == TDEFL_STATUS_DONE)
6820 else if (status != TDEFL_STATUS_OKAY)
6822 mz_zip_set_error(pZip, MZ_ZIP_COMPRESSION_FAILED);
6827 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6831 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6835 uncomp_size = file_ofs;
6836 comp_size = state.m_comp_size;
6837 cur_archive_file_ofs = state.m_cur_archive_file_ofs;
6840 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6843 if (!(level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE))
6845 mz_uint8 local_dir_footer[MZ_ZIP_DATA_DESCRIPTER_SIZE64];
6846 mz_uint32 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE32;
6848 MZ_WRITE_LE32(local_dir_footer + 0, MZ_ZIP_DATA_DESCRIPTOR_ID);
6849 MZ_WRITE_LE32(local_dir_footer + 4, uncomp_crc32);
6850 if (pExtra_data == NULL)
6852 if (comp_size > MZ_UINT32_MAX)
6853 return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
6855 MZ_WRITE_LE32(local_dir_footer + 8, comp_size);
6856 MZ_WRITE_LE32(local_dir_footer + 12, uncomp_size);
6860 MZ_WRITE_LE64(local_dir_footer + 8, comp_size);
6861 MZ_WRITE_LE64(local_dir_footer + 16, uncomp_size);
6862 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE64;
6865 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_footer, local_dir_footer_size) != local_dir_footer_size)
6868 cur_archive_file_ofs += local_dir_footer_size;
6871 if (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE)
6873 if (pExtra_data != NULL)
6875 extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (max_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
6876 (max_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
6879 if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header,
6880 (mz_uint16)archive_name_size, (mz_uint16)(extra_size + user_extra_data_len),
6881 (max_size >= MZ_UINT32_MAX) ? MZ_UINT32_MAX : uncomp_size,
6882 (max_size >= MZ_UINT32_MAX) ? MZ_UINT32_MAX : comp_size,
6883 uncomp_crc32, method, gen_flags, dos_time, dos_date))
6884 return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
6886 cur_archive_header_file_ofs = local_dir_header_ofs;
6888 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs, local_dir_header,
sizeof(local_dir_header)) !=
sizeof(local_dir_header))
6889 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
6891 if (pExtra_data != NULL)
6893 cur_archive_header_file_ofs +=
sizeof(local_dir_header);
6895 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
6897 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
6900 cur_archive_header_file_ofs += archive_name_size;
6902 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs, extra_data, extra_size) != extra_size)
6903 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
6905 cur_archive_header_file_ofs += extra_size;
6909 if (pExtra_data != NULL)
6911 extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
6912 (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
6915 if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, pExtra_data, (mz_uint16)extra_size, pComment, comment_size,
6916 uncomp_size, comp_size, uncomp_crc32, method, gen_flags, dos_time, dos_date, local_dir_header_ofs, ext_attributes,
6917 user_extra_data_central, user_extra_data_central_len))
6920 pZip->m_total_files++;
6921 pZip->m_archive_size = cur_archive_file_ofs;
6926#ifndef MINIZ_NO_STDIO
6928 static size_t mz_file_read_func_stdio(
void *pOpaque, mz_uint64 file_ofs,
void *pBuf,
size_t n)
6930 MZ_FILE *pSrc_file = (MZ_FILE *)pOpaque;
6931 mz_int64 cur_ofs = MZ_FTELL64(pSrc_file);
6933 if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pSrc_file, (mz_int64)file_ofs, SEEK_SET))))
6936 return MZ_FREAD(pBuf, 1, n, pSrc_file);
6939 mz_bool mz_zip_writer_add_cfile(
mz_zip_archive *pZip,
const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 max_size,
const MZ_TIME_T *pFile_time,
const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
6940 const char *user_extra_data, mz_uint user_extra_data_len,
const char *user_extra_data_central, mz_uint user_extra_data_central_len)
6942 return mz_zip_writer_add_read_buf_callback(pZip, pArchive_name, mz_file_read_func_stdio, pSrc_file, max_size, pFile_time, pComment, comment_size, level_and_flags,
6943 user_extra_data, user_extra_data_len, user_extra_data_central, user_extra_data_central_len);
6946 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)
6948 MZ_FILE *pSrc_file = NULL;
6949 mz_uint64 uncomp_size = 0;
6950 MZ_TIME_T file_modified_time;
6951 MZ_TIME_T *pFile_time = NULL;
6954 memset(&file_modified_time, 0,
sizeof(file_modified_time));
6956#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_STDIO)
6957 pFile_time = &file_modified_time;
6958 if (!mz_zip_get_file_modified_time(pSrc_filename, &file_modified_time))
6959 return mz_zip_set_error(pZip, MZ_ZIP_FILE_STAT_FAILED);
6962 pSrc_file = MZ_FOPEN(pSrc_filename,
"rb");
6964 return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);
6966 MZ_FSEEK64(pSrc_file, 0, SEEK_END);
6967 uncomp_size = MZ_FTELL64(pSrc_file);
6968 MZ_FSEEK64(pSrc_file, 0, SEEK_SET);
6970 status = mz_zip_writer_add_cfile(pZip, pArchive_name, pSrc_file, uncomp_size, pFile_time, pComment, comment_size, level_and_flags, NULL, 0, NULL, 0);
6972 MZ_FCLOSE(pSrc_file);
6978 static mz_bool mz_zip_writer_update_zip64_extension_block(
mz_zip_array *pNew_ext,
mz_zip_archive *pZip,
const mz_uint8 *pExt, mz_uint32 ext_len, mz_uint64 *pComp_size, mz_uint64 *pUncomp_size, mz_uint64 *pLocal_header_ofs, mz_uint32 *pDisk_start)
6981 if (!mz_zip_array_reserve(pZip, pNew_ext, ext_len + 64, MZ_FALSE))
6982 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6984 mz_zip_array_resize(pZip, pNew_ext, 0, MZ_FALSE);
6986 if ((pUncomp_size) || (pComp_size) || (pLocal_header_ofs) || (pDisk_start))
6988 mz_uint8 new_ext_block[64];
6989 mz_uint8 *pDst = new_ext_block;
6990 mz_write_le16(pDst, MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID);
6991 mz_write_le16(pDst +
sizeof(mz_uint16), 0);
6992 pDst +=
sizeof(mz_uint16) * 2;
6996 mz_write_le64(pDst, *pUncomp_size);
6997 pDst +=
sizeof(mz_uint64);
7002 mz_write_le64(pDst, *pComp_size);
7003 pDst +=
sizeof(mz_uint64);
7006 if (pLocal_header_ofs)
7008 mz_write_le64(pDst, *pLocal_header_ofs);
7009 pDst +=
sizeof(mz_uint64);
7014 mz_write_le32(pDst, *pDisk_start);
7015 pDst +=
sizeof(mz_uint32);
7018 mz_write_le16(new_ext_block +
sizeof(mz_uint16), (mz_uint16)((pDst - new_ext_block) -
sizeof(mz_uint16) * 2));
7020 if (!mz_zip_array_push_back(pZip, pNew_ext, new_ext_block, pDst - new_ext_block))
7021 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
7024 if ((pExt) && (ext_len))
7026 mz_uint32 extra_size_remaining = ext_len;
7027 const mz_uint8 *pExtra_data = pExt;
7031 mz_uint32 field_id, field_data_size, field_total_size;
7033 if (extra_size_remaining < (
sizeof(mz_uint16) * 2))
7034 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
7036 field_id = MZ_READ_LE16(pExtra_data);
7037 field_data_size = MZ_READ_LE16(pExtra_data +
sizeof(mz_uint16));
7038 field_total_size = field_data_size +
sizeof(mz_uint16) * 2;
7040 if (field_total_size > extra_size_remaining)
7041 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
7043 if (field_id != MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID)
7045 if (!mz_zip_array_push_back(pZip, pNew_ext, pExtra_data, field_total_size))
7046 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
7049 pExtra_data += field_total_size;
7050 extra_size_remaining -= field_total_size;
7051 }
while (extra_size_remaining);
7060 mz_uint n, bit_flags, num_alignment_padding_bytes, src_central_dir_following_data_size;
7061 mz_uint64 src_archive_bytes_remaining, local_dir_header_ofs;
7062 mz_uint64 cur_src_file_ofs, cur_dst_file_ofs;
7063 mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE +
sizeof(mz_uint32) - 1) /
sizeof(mz_uint32)];
7064 mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
7065 mz_uint8 new_central_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE];
7066 size_t orig_central_dir_size;
7069 const mz_uint8 *pSrc_central_header;
7071 mz_uint32 src_filename_len, src_comment_len, src_ext_len;
7072 mz_uint32 local_header_filename_size, local_header_extra_len;
7073 mz_uint64 local_header_comp_size, local_header_uncomp_size;
7074 mz_bool found_zip64_ext_data_in_ldir = MZ_FALSE;
7077 if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pSource_zip->m_pRead))
7078 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
7080 pState = pZip->m_pState;
7083 if ((pSource_zip->m_pState->m_zip64) && (!pZip->m_pState->m_zip64))
7084 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
7087 if (NULL == (pSrc_central_header = mz_zip_get_cdh(pSource_zip, src_file_index)))
7088 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
7090 if (MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_SIG_OFS) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG)
7091 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
7093 src_filename_len = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_FILENAME_LEN_OFS);
7094 src_comment_len = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_COMMENT_LEN_OFS);
7095 src_ext_len = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS);
7096 src_central_dir_following_data_size = src_filename_len + src_ext_len + src_comment_len;
7099 if ((pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_central_dir_following_data_size + 32) >= MZ_UINT32_MAX)
7100 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);
7102 num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
7104 if (!pState->m_zip64)
7106 if (pZip->m_total_files == MZ_UINT16_MAX)
7107 return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
7112 if (pZip->m_total_files == MZ_UINT32_MAX)
7113 return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
7116 if (!mz_zip_file_stat_internal(pSource_zip, src_file_index, pSrc_central_header, &src_file_stat, NULL))
7119 cur_src_file_ofs = src_file_stat.m_local_header_ofs;
7120 cur_dst_file_ofs = pZip->m_archive_size;
7123 if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
7124 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
7126 if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
7127 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
7129 cur_src_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE;
7132 local_header_filename_size = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS);
7133 local_header_extra_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
7134 local_header_comp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS);
7135 local_header_uncomp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS);
7136 src_archive_bytes_remaining = src_file_stat.m_comp_size + local_header_filename_size + local_header_extra_len;
7139 if ((local_header_extra_len) && ((local_header_comp_size == MZ_UINT32_MAX) || (local_header_uncomp_size == MZ_UINT32_MAX)))
7142 const mz_uint8 *pExtra_data;
7143 mz_uint32 extra_size_remaining = local_header_extra_len;
7145 mz_zip_array_init(&file_data_array, 1);
7146 if (!mz_zip_array_resize(pZip, &file_data_array, local_header_extra_len, MZ_FALSE))
7148 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
7151 if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, src_file_stat.m_local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + local_header_filename_size, file_data_array.m_p, local_header_extra_len) != local_header_extra_len)
7153 mz_zip_array_clear(pZip, &file_data_array);
7154 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
7157 pExtra_data = (
const mz_uint8 *)file_data_array.m_p;
7161 mz_uint32 field_id, field_data_size, field_total_size;
7163 if (extra_size_remaining < (
sizeof(mz_uint16) * 2))
7165 mz_zip_array_clear(pZip, &file_data_array);
7166 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
7169 field_id = MZ_READ_LE16(pExtra_data);
7170 field_data_size = MZ_READ_LE16(pExtra_data +
sizeof(mz_uint16));
7171 field_total_size = field_data_size +
sizeof(mz_uint16) * 2;
7173 if (field_total_size > extra_size_remaining)
7175 mz_zip_array_clear(pZip, &file_data_array);
7176 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
7179 if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID)
7181 const mz_uint8 *pSrc_field_data = pExtra_data +
sizeof(mz_uint32);
7183 if (field_data_size <
sizeof(mz_uint64) * 2)
7185 mz_zip_array_clear(pZip, &file_data_array);
7186 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
7189 local_header_uncomp_size = MZ_READ_LE64(pSrc_field_data);
7190 local_header_comp_size = MZ_READ_LE64(pSrc_field_data +
sizeof(mz_uint64));
7192 found_zip64_ext_data_in_ldir = MZ_TRUE;
7196 pExtra_data += field_total_size;
7197 extra_size_remaining -= field_total_size;
7198 }
while (extra_size_remaining);
7200 mz_zip_array_clear(pZip, &file_data_array);
7203 if (!pState->m_zip64)
7207 mz_uint64 approx_new_archive_size = cur_dst_file_ofs + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + src_archive_bytes_remaining + (
sizeof(mz_uint32) * 4) +
7208 pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_central_dir_following_data_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 64;
7210 if (approx_new_archive_size >= MZ_UINT32_MAX)
7211 return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
7215 if (!mz_zip_writer_write_zeros(pZip, cur_dst_file_ofs, num_alignment_padding_bytes))
7218 cur_dst_file_ofs += num_alignment_padding_bytes;
7220 local_dir_header_ofs = cur_dst_file_ofs;
7221 if (pZip->m_file_offset_alignment)
7223 MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0);
7227 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
7228 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
7230 cur_dst_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE;
7233 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)))))
7234 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
7236 while (src_archive_bytes_remaining)
7238 n = (mz_uint)MZ_MIN((mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE, src_archive_bytes_remaining);
7239 if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, n) != n)
7241 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
7242 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
7244 cur_src_file_ofs += n;
7246 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n)
7248 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
7249 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
7251 cur_dst_file_ofs += n;
7253 src_archive_bytes_remaining -= n;
7257 bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS);
7261 if ((pSource_zip->m_pState->m_zip64) || (found_zip64_ext_data_in_ldir))
7270 if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, (
sizeof(mz_uint32) * 6)) != (
sizeof(mz_uint32) * 6))
7272 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
7273 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
7276 n =
sizeof(mz_uint32) * ((MZ_READ_LE32(pBuf) == MZ_ZIP_DATA_DESCRIPTOR_ID) ? 6 : 5);
7283 if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf,
sizeof(mz_uint32) * 4) !=
sizeof(mz_uint32) * 4)
7285 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
7286 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
7289 has_id = (MZ_READ_LE32(pBuf) == MZ_ZIP_DATA_DESCRIPTOR_ID);
7291 if (pZip->m_pState->m_zip64)
7294 const mz_uint8 *pSrc_descriptor = (
const mz_uint8 *)pBuf + (has_id ?
sizeof(mz_uint32) : 0);
7295 const mz_uint32 src_crc32 = MZ_READ_LE32(pSrc_descriptor);
7296 const mz_uint64 src_comp_size = MZ_READ_LE32(pSrc_descriptor +
sizeof(mz_uint32));
7297 const mz_uint64 src_uncomp_size = MZ_READ_LE32(pSrc_descriptor + 2 *
sizeof(mz_uint32));
7299 mz_write_le32((mz_uint8 *)pBuf, MZ_ZIP_DATA_DESCRIPTOR_ID);
7300 mz_write_le32((mz_uint8 *)pBuf +
sizeof(mz_uint32) * 1, src_crc32);
7301 mz_write_le64((mz_uint8 *)pBuf +
sizeof(mz_uint32) * 2, src_comp_size);
7302 mz_write_le64((mz_uint8 *)pBuf +
sizeof(mz_uint32) * 4, src_uncomp_size);
7304 n =
sizeof(mz_uint32) * 6;
7309 n =
sizeof(mz_uint32) * (has_id ? 4 : 3);
7313 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n)
7315 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
7316 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
7319 cur_src_file_ofs += n;
7320 cur_dst_file_ofs += n;
7322 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
7325 orig_central_dir_size = pState->m_central_dir.m_size;
7327 memcpy(new_central_header, pSrc_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE);
7329 if (pState->m_zip64)
7332 const mz_uint8 *pSrc_ext = pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_filename_len;
7335 mz_zip_array_init(&new_ext_block,
sizeof(mz_uint8));
7337 MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS, MZ_UINT32_MAX);
7338 MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS, MZ_UINT32_MAX);
7339 MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS, MZ_UINT32_MAX);
7341 if (!mz_zip_writer_update_zip64_extension_block(&new_ext_block, pZip, pSrc_ext, src_ext_len, &src_file_stat.m_comp_size, &src_file_stat.m_uncomp_size, &local_dir_header_ofs, NULL))
7343 mz_zip_array_clear(pZip, &new_ext_block);
7347 MZ_WRITE_LE16(new_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS, new_ext_block.m_size);
7349 if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, new_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE))
7351 mz_zip_array_clear(pZip, &new_ext_block);
7352 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
7355 if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, src_filename_len))
7357 mz_zip_array_clear(pZip, &new_ext_block);
7358 mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
7359 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
7362 if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, new_ext_block.m_p, new_ext_block.m_size))
7364 mz_zip_array_clear(pZip, &new_ext_block);
7365 mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
7366 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
7369 if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_filename_len + src_ext_len, src_comment_len))
7371 mz_zip_array_clear(pZip, &new_ext_block);
7372 mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
7373 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
7376 mz_zip_array_clear(pZip, &new_ext_block);
7381 if (cur_dst_file_ofs > MZ_UINT32_MAX)
7382 return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
7384 if (local_dir_header_ofs >= MZ_UINT32_MAX)
7385 return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
7387 MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS, local_dir_header_ofs);
7389 if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, new_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE))
7390 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
7392 if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, src_central_dir_following_data_size))
7394 mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
7395 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
7400 if (pState->m_central_dir.m_size >= MZ_UINT32_MAX)
7403 mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
7404 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);
7407 n = (mz_uint32)orig_central_dir_size;
7408 if (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &n, 1))
7410 mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
7411 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
7414 pZip->m_total_files++;
7415 pZip->m_archive_size = cur_dst_file_ofs;
7423 mz_uint64 central_dir_ofs, central_dir_size;
7426 if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING))
7427 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
7429 pState = pZip->m_pState;
7431 if (pState->m_zip64)
7433 if ((mz_uint64)pState->m_central_dir.m_size >= MZ_UINT32_MAX)
7434 return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
7438 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))
7439 return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
7442 central_dir_ofs = 0;
7443 central_dir_size = 0;
7444 if (pZip->m_total_files)
7447 central_dir_ofs = pZip->m_archive_size;
7448 central_dir_size = pState->m_central_dir.m_size;
7449 pZip->m_central_directory_file_ofs = central_dir_ofs;
7450 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)
7451 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
7453 pZip->m_archive_size += central_dir_size;
7456 if (pState->m_zip64)
7459 mz_uint64 rel_ofs_to_zip64_ecdr = pZip->m_archive_size;
7462 MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDH_SIG_OFS, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG);
7463 MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE -
sizeof(mz_uint32) -
sizeof(mz_uint64));
7464 MZ_WRITE_LE16(hdr + MZ_ZIP64_ECDH_VERSION_MADE_BY_OFS, 0x031E);
7465 MZ_WRITE_LE16(hdr + MZ_ZIP64_ECDH_VERSION_NEEDED_OFS, 0x002D);
7466 MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS, pZip->m_total_files);
7467 MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS, pZip->m_total_files);
7468 MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_SIZE_OFS, central_dir_size);
7469 MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_OFS_OFS, central_dir_ofs);
7470 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)
7471 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
7473 pZip->m_archive_size += MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE;
7477 MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDL_SIG_OFS, MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG);
7478 MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS, rel_ofs_to_zip64_ecdr);
7479 MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS, 1);
7480 if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) != MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE)
7481 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
7483 pZip->m_archive_size += MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE;
7488 MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_SIG_OFS, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG);
7489 MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS, MZ_MIN(MZ_UINT16_MAX, pZip->m_total_files));
7490 MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS, MZ_MIN(MZ_UINT16_MAX, pZip->m_total_files));
7491 MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_SIZE_OFS, MZ_MIN(MZ_UINT32_MAX, central_dir_size));
7492 MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_OFS_OFS, MZ_MIN(MZ_UINT32_MAX, central_dir_ofs));
7494 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)
7495 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
7497#ifndef MINIZ_NO_STDIO
7498 if ((pState->m_pFile) && (MZ_FFLUSH(pState->m_pFile) == EOF))
7499 return mz_zip_set_error(pZip, MZ_ZIP_FILE_CLOSE_FAILED);
7502 pZip->m_archive_size += MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE;
7504 pZip->m_zip_mode = MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED;
7508 mz_bool mz_zip_writer_finalize_heap_archive(
mz_zip_archive *pZip,
void **ppBuf,
size_t *pSize)
7510 if ((!ppBuf) || (!pSize))
7511 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
7516 if ((!pZip) || (!pZip->m_pState))
7517 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
7519 if (pZip->m_pWrite != mz_zip_heap_write_func)
7520 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
7522 if (!mz_zip_writer_finalize_archive(pZip))
7525 *ppBuf = pZip->m_pState->m_pMem;
7526 *pSize = pZip->m_pState->m_mem_size;
7527 pZip->m_pState->m_pMem = NULL;
7528 pZip->m_pState->m_mem_size = pZip->m_pState->m_mem_capacity = 0;
7535 return mz_zip_writer_end_internal(pZip, MZ_TRUE);
7538#ifndef MINIZ_NO_STDIO
7539 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)
7541 return mz_zip_add_mem_to_archive_file_in_place_v2(pZip_filename, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, NULL);
7544 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)
7546 mz_bool status, created_new_archive = MZ_FALSE;
7548 struct MZ_FILE_STAT_STRUCT file_stat;
7549 mz_zip_error actual_err = MZ_ZIP_NO_ERROR;
7551 mz_zip_zero_struct(&zip_archive);
7552 if ((
int)level_and_flags < 0)
7553 level_and_flags = MZ_DEFAULT_LEVEL;
7555 if ((!pZip_filename) || (!pArchive_name) || ((buf_size) && (!pBuf)) || ((comment_size) && (!pComment)) || ((level_and_flags & 0xF) > MZ_UBER_COMPRESSION))
7558 *pErr = MZ_ZIP_INVALID_PARAMETER;
7562 if (!mz_zip_writer_validate_archive_name(pArchive_name))
7565 *pErr = MZ_ZIP_INVALID_FILENAME;
7571 if (MZ_FILE_STAT(pZip_filename, &file_stat) != 0)
7574 if (!mz_zip_writer_init_file_v2(&zip_archive, pZip_filename, 0, level_and_flags))
7577 *pErr = zip_archive.m_last_error;
7581 created_new_archive = MZ_TRUE;
7586 if (!mz_zip_reader_init_file_v2(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY | MZ_ZIP_FLAG_READ_ALLOW_WRITING, 0, 0))
7589 *pErr = zip_archive.m_last_error;
7593 if (!mz_zip_writer_init_from_reader_v2(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_READ_ALLOW_WRITING))
7596 *pErr = zip_archive.m_last_error;
7598 mz_zip_reader_end_internal(&zip_archive, MZ_FALSE);
7604 status = mz_zip_writer_add_mem_ex(&zip_archive, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, 0, 0);
7605 actual_err = zip_archive.m_last_error;
7608 if (!mz_zip_writer_finalize_archive(&zip_archive))
7611 actual_err = zip_archive.m_last_error;
7616 if (!mz_zip_writer_end_internal(&zip_archive, status))
7619 actual_err = zip_archive.m_last_error;
7624 if ((!status) && (created_new_archive))
7627 int ignoredStatus = MZ_DELETE_FILE(pZip_filename);
7628 (void)ignoredStatus;
7637 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)
7639 mz_uint32 file_index;
7646 if ((!pZip_filename) || (!pArchive_name))
7649 *pErr = MZ_ZIP_INVALID_PARAMETER;
7654 mz_zip_zero_struct(&zip_archive);
7655 if (!mz_zip_reader_init_file_v2(&zip_archive, pZip_filename, flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY, 0, 0))
7658 *pErr = zip_archive.m_last_error;
7663 if (mz_zip_reader_locate_file_v2(&zip_archive, pArchive_name, pComment, flags, &file_index))
7665 p = mz_zip_reader_extract_to_heap(&zip_archive, file_index, pSize, flags);
7668 mz_zip_reader_end_internal(&zip_archive, p != NULL);
7671 *pErr = zip_archive.m_last_error;
7676 void *mz_zip_extract_archive_file_to_heap(
const char *pZip_filename,
const char *pArchive_name,
size_t *pSize, mz_uint flags)
7678 return mz_zip_extract_archive_file_to_heap_v2(pZip_filename, pArchive_name, NULL, pSize, flags, NULL);
7689 return pZip ? pZip->m_zip_mode : MZ_ZIP_MODE_INVALID;
7694 return pZip ? pZip->m_zip_type : MZ_ZIP_TYPE_INVALID;
7697 mz_zip_error mz_zip_set_last_error(
mz_zip_archive *pZip, mz_zip_error err_num)
7699 mz_zip_error prev_err;
7702 return MZ_ZIP_INVALID_PARAMETER;
7704 prev_err = pZip->m_last_error;
7706 pZip->m_last_error = err_num;
7713 return MZ_ZIP_INVALID_PARAMETER;
7715 return pZip->m_last_error;
7720 return mz_zip_set_last_error(pZip, MZ_ZIP_NO_ERROR);
7725 mz_zip_error prev_err;
7728 return MZ_ZIP_INVALID_PARAMETER;
7730 prev_err = pZip->m_last_error;
7732 pZip->m_last_error = MZ_ZIP_NO_ERROR;
7736 const char *mz_zip_get_error_string(mz_zip_error mz_err)
7740 case MZ_ZIP_NO_ERROR:
7742 case MZ_ZIP_UNDEFINED_ERROR:
7743 return "undefined error";
7744 case MZ_ZIP_TOO_MANY_FILES:
7745 return "too many files";
7746 case MZ_ZIP_FILE_TOO_LARGE:
7747 return "file too large";
7748 case MZ_ZIP_UNSUPPORTED_METHOD:
7749 return "unsupported method";
7750 case MZ_ZIP_UNSUPPORTED_ENCRYPTION:
7751 return "unsupported encryption";
7752 case MZ_ZIP_UNSUPPORTED_FEATURE:
7753 return "unsupported feature";
7754 case MZ_ZIP_FAILED_FINDING_CENTRAL_DIR:
7755 return "failed finding central directory";
7756 case MZ_ZIP_NOT_AN_ARCHIVE:
7757 return "not a ZIP archive";
7758 case MZ_ZIP_INVALID_HEADER_OR_CORRUPTED:
7759 return "invalid header or archive is corrupted";
7760 case MZ_ZIP_UNSUPPORTED_MULTIDISK:
7761 return "unsupported multidisk archive";
7762 case MZ_ZIP_DECOMPRESSION_FAILED:
7763 return "decompression failed or archive is corrupted";
7764 case MZ_ZIP_COMPRESSION_FAILED:
7765 return "compression failed";
7766 case MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE:
7767 return "unexpected decompressed size";
7768 case MZ_ZIP_CRC_CHECK_FAILED:
7769 return "CRC-32 check failed";
7770 case MZ_ZIP_UNSUPPORTED_CDIR_SIZE:
7771 return "unsupported central directory size";
7772 case MZ_ZIP_ALLOC_FAILED:
7773 return "allocation failed";
7774 case MZ_ZIP_FILE_OPEN_FAILED:
7775 return "file open failed";
7776 case MZ_ZIP_FILE_CREATE_FAILED:
7777 return "file create failed";
7778 case MZ_ZIP_FILE_WRITE_FAILED:
7779 return "file write failed";
7780 case MZ_ZIP_FILE_READ_FAILED:
7781 return "file read failed";
7782 case MZ_ZIP_FILE_CLOSE_FAILED:
7783 return "file close failed";
7784 case MZ_ZIP_FILE_SEEK_FAILED:
7785 return "file seek failed";
7786 case MZ_ZIP_FILE_STAT_FAILED:
7787 return "file stat failed";
7788 case MZ_ZIP_INVALID_PARAMETER:
7789 return "invalid parameter";
7790 case MZ_ZIP_INVALID_FILENAME:
7791 return "invalid filename";
7792 case MZ_ZIP_BUF_TOO_SMALL:
7793 return "buffer too small";
7794 case MZ_ZIP_INTERNAL_ERROR:
7795 return "internal error";
7796 case MZ_ZIP_FILE_NOT_FOUND:
7797 return "file not found";
7798 case MZ_ZIP_ARCHIVE_TOO_LARGE:
7799 return "archive is too large";
7800 case MZ_ZIP_VALIDATION_FAILED:
7801 return "validation failed";
7802 case MZ_ZIP_WRITE_CALLBACK_FAILED:
7803 return "write callback failed";
7804 case MZ_ZIP_TOTAL_ERRORS:
7805 return "total errors";
7810 return "unknown error";
7816 if ((!pZip) || (!pZip->m_pState))
7819 return pZip->m_pState->m_zip64;
7824 if ((!pZip) || (!pZip->m_pState))
7827 return pZip->m_pState->m_central_dir.m_size;
7832 return pZip ? pZip->m_total_files : 0;
7839 return pZip->m_archive_size;
7842 mz_uint64 mz_zip_get_archive_file_start_offset(
mz_zip_archive *pZip)
7844 if ((!pZip) || (!pZip->m_pState))
7846 return pZip->m_pState->m_file_archive_start_ofs;
7851 if ((!pZip) || (!pZip->m_pState))
7853 return pZip->m_pState->m_pFile;
7856 size_t mz_zip_read_archive_data(
mz_zip_archive *pZip, mz_uint64 file_ofs,
void *pBuf,
size_t n)
7858 if ((!pZip) || (!pZip->m_pState) || (!pBuf) || (!pZip->m_pRead))
7859 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
7861 return pZip->m_pRead(pZip->m_pIO_opaque, file_ofs, pBuf, n);
7864 mz_uint mz_zip_reader_get_filename(
mz_zip_archive *pZip, mz_uint file_index,
char *pFilename, mz_uint filename_buf_size)
7867 const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
7870 if (filename_buf_size)
7871 pFilename[0] =
'\0';
7872 mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
7875 n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
7876 if (filename_buf_size)
7878 n = MZ_MIN(n, filename_buf_size - 1);
7879 memcpy(pFilename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n);
7880 pFilename[n] =
'\0';
7887 return mz_zip_file_stat_internal(pZip, file_index, mz_zip_get_cdh(pZip, file_index), pStat, NULL);
7895 if (pZip->m_zip_mode == MZ_ZIP_MODE_READING)
7896 return mz_zip_reader_end(pZip);
7897#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
7898 else if ((pZip->m_zip_mode == MZ_ZIP_MODE_WRITING) || (pZip->m_zip_mode == MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED))
7899 return mz_zip_writer_end(pZip);
QTextStream & flush(QTextStream &stream)