43 mz_uint32 i,
s1 = (mz_uint32)(adler & 0xffff),
s2 = (mz_uint32)(adler >> 16);
44 size_t block_len = buf_len % 5552;
49 for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
60 for (; i < block_len; ++i)
62 s1 %= 65521U,
s2 %= 65521U;
66 return (
s2 << 16) +
s1;
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)
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];
169 (void)opaque, (
void)items, (void)size;
170 return MZ_MALLOC(items * size);
174 (void)opaque, (
void)address;
179 (void)opaque, (
void)address, (void)items, (
void)size;
180 return MZ_REALLOC(address, items * size);
188#ifndef MINIZ_NO_ZLIB_APIS
190#ifndef MINIZ_NO_DEFLATE_APIS
192 int mz_deflateInit(mz_streamp pStream,
int level)
197 int mz_deflateInit2(mz_streamp pStream,
int level,
int method,
int window_bits,
int mem_level,
int strategy)
199 tdefl_compressor *pComp;
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;
210 pStream->reserved = 0;
211 pStream->total_in = 0;
212 pStream->total_out = 0;
213 if (!pStream->zalloc)
218 pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1,
sizeof(tdefl_compressor));
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;
233 int mz_deflateReset(mz_streamp pStream)
235 if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree))
236 return MZ_STREAM_ERROR;
237 pStream->total_in = pStream->total_out = 0;
238 tdefl_init((tdefl_compressor *)pStream->state, NULL, NULL, ((tdefl_compressor *)pStream->state)->m_flags);
242 int mz_deflate(mz_streamp pStream,
int flush)
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;
271 pStream->adler = tdefl_get_adler32((tdefl_compressor *)pStream->state);
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))
300 int mz_deflateEnd(mz_streamp pStream)
303 return MZ_STREAM_ERROR;
306 pStream->zfree(pStream->opaque, pStream->state);
307 pStream->state = NULL;
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)
356 return mz_deflateBound(NULL, source_len);
361#ifndef MINIZ_NO_INFLATE_APIS
365 tinfl_decompressor m_decomp;
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)
374 inflate_state *pDecomp;
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)
391 pDecomp = (inflate_state *)pStream->zalloc(pStream->opaque, 1,
sizeof(inflate_state));
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;
408 int mz_inflateInit(mz_streamp pStream)
410 return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS);
413 int mz_inflateReset(mz_streamp pStream)
415 inflate_state *pDecomp;
417 return MZ_STREAM_ERROR;
419 pStream->data_type = 0;
422 pStream->total_in = 0;
423 pStream->total_out = 0;
424 pStream->reserved = 0;
426 pDecomp = (inflate_state *)pStream->state;
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;
439 int mz_inflate(mz_streamp pStream,
int flush)
441 inflate_state *pState;
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;
453 pState = (inflate_state *)pStream->state;
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;
551 int mz_inflateEnd(mz_streamp pStream)
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;
747 static tdefl_sym_freq *tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq *pSyms0, tdefl_sym_freq *pSyms1)
749 mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2];
750 tdefl_sym_freq *pCur_syms = pSyms0, *pNew_syms = pSyms1;
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];
772 tdefl_sym_freq *t = pCur_syms;
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 };
984 static void tdefl_start_dynamic_block(tdefl_compressor *d)
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]);
1071 static void tdefl_start_static_block(tdefl_compressor *d)
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
1096 static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d)
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);
1191static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d)
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 };
1250 static int tdefl_flush_block(tdefl_compressor *d,
int flush)
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)
1532 static mz_bool tdefl_compress_fast(tdefl_compressor *d)
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]]++;
1747 static mz_bool tdefl_compress_normal(tdefl_compressor *d)
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;
1892 static tdefl_status tdefl_flush_output_buffer(tdefl_compressor *d)
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;
2023 tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d)
2025 return d->m_prev_return_status;
2028 mz_uint32 tdefl_get_adler32(tdefl_compressor *d)
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)
2035 tdefl_compressor *pComp;
2037 if (((buf_len) && (!pBuf)) || (!pPut_buf_func))
2039 pComp = (tdefl_compressor *)MZ_MALLOC(
sizeof(tdefl_compressor));
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;
2053 } tdefl_output_buffer;
2055 static mz_bool tdefl_output_buffer_putter(
const void *pBuf,
int len,
void *pUser)
2057 tdefl_output_buffer *p = (tdefl_output_buffer *)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)
2082 tdefl_output_buffer out_buf;
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)
2097 tdefl_output_buffer out_buf;
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;
2118 comp_flags |= TDEFL_FILTER_MATCHES;
2120 comp_flags &= ~TDEFL_MAX_PROBES_MASK;
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 };
2141 tdefl_compressor *pComp = (tdefl_compressor *)MZ_MALLOC(
sizeof(tdefl_compressor));
2142 tdefl_output_buffer out_buf;
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;
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);
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
2225 tdefl_compressor *tdefl_compressor_alloc(
void)
2227 return (tdefl_compressor *)MZ_MALLOC(
sizeof(tdefl_compressor));
2230 void tdefl_compressor_free(tdefl_compressor *pComp)
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)
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)))));
2490 r->m_type =
r->m_final >> 1;
2494 for (counter = 0; counter < 4; ++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))))
2505 while ((counter) && (num_bits))
2508 while (pOut_buf_cur >= pOut_buf_end)
2512 *pOut_buf_cur++ = (mz_uint8)dist;
2518 while (pOut_buf_cur >= pOut_buf_end)
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);
2530 counter -= (mz_uint)n;
2533 else if (
r->m_type == 3)
2541 mz_uint8 *p =
r->m_code_size_0;
2543 r->m_table_sizes[0] = 288;
2544 r->m_table_sizes[1] = 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++)
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++)
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);
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))
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]);)
2645 r->m_len_codes[counter++] = (mz_uint8)dist;
2648 if ((dist == 16) && (!counter))
2652 num_extra =
"\02\03\07"[dist - 16];
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)
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))
2676 while (pOut_buf_cur >= pOut_buf_end)
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;
2739 if (sym2 == 0 && counter == 0)
2744 pOut_buf_cur[0] = (mz_uint8)counter;
2751 pOut_buf_cur[1] = (mz_uint8)sym2;
2755 if ((counter &= 511) == 256)
2758 num_extra = s_length_extra[counter - 257];
2759 counter = s_length_base[counter - 257];
2764 counter += extra_bits;
2768 num_extra = s_dist_extra[dist];
2769 dist = s_dist_base[dist];
2777 dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
2778 if ((dist == 0 || dist > dist_from_out_buf_start || dist_from_out_buf_start == 0) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
2783 pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask);
2785 if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end)
2789 while (pOut_buf_cur >= pOut_buf_end)
2793 *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask];
2797#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
2798 else if ((counter >= 9) && (counter <= dist))
2800 const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
2803#ifdef MINIZ_UNALIGNED_USE_MEMCPY
2804 memcpy(pOut_buf_cur, pSrc,
sizeof(mz_uint32) * 2);
2806 ((mz_uint32 *)pOut_buf_cur)[0] = ((
const mz_uint32 *)pSrc)[0];
2807 ((mz_uint32 *)pOut_buf_cur)[1] = ((
const mz_uint32 *)pSrc)[1];
2810 }
while ((pSrc += 8) < pSrc_end);
2811 if ((counter &= 7) < 3)
2815 pOut_buf_cur[0] = pSrc[0];
2817 pOut_buf_cur[1] = pSrc[1];
2818 pOut_buf_cur += counter;
2826 pOut_buf_cur[0] = pSrc[0];
2827 pOut_buf_cur[1] = pSrc[1];
2828 pOut_buf_cur[2] = pSrc[2];
2835 pOut_buf_cur[0] = pSrc[0];
2837 pOut_buf_cur[1] = pSrc[1];
2838 pOut_buf_cur += counter;
2842 }
while (!(
r->m_final & 1));
2847 while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8))
2852 bit_buf &= ~(~(tinfl_bit_buf_t)0 << num_bits);
2853 MZ_ASSERT(!num_bits);
2855 if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
2857 for (counter = 0; counter < 4; ++counter)
2864 r->m_z_adler32 = (
r->m_z_adler32 << 8) | s;
2875 if ((status != TINFL_STATUS_NEEDS_MORE_INPUT) && (status != TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS))
2877 while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8))
2883 r->m_num_bits = num_bits;
2884 r->m_bit_buf = bit_buf & ~(~(tinfl_bit_buf_t)0 << num_bits);
2886 r->m_counter = counter;
2887 r->m_num_extra = num_extra;
2888 r->m_dist_from_out_buf_start = dist_from_out_buf_start;
2889 *pIn_buf_size = pIn_buf_cur - pIn_buf_next;
2890 *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
2891 if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0))
2893 const mz_uint8 *ptr = pOut_buf_next;
2894 size_t buf_len = *pOut_buf_size;
2895 mz_uint32 i,
s1 =
r->m_check_adler32 & 0xffff,
s2 =
r->m_check_adler32 >> 16;
2896 size_t block_len = buf_len % 5552;
2899 for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
2910 for (; i < block_len; ++i)
2912 s1 %= 65521U,
s2 %= 65521U;
2913 buf_len -= block_len;
2916 r->m_check_adler32 = (
s2 << 16) +
s1;
2917 if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (
r->m_check_adler32 !=
r->m_z_adler32))
2918 status = TINFL_STATUS_ADLER32_MISMATCH;
2926 tinfl_decompressor decomp;
2927 void *pBuf = NULL, *pNew_buf;
2928 size_t src_buf_ofs = 0, out_buf_capacity = 0;
2930 tinfl_init(&decomp);
2933 size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity;
2934 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,
2935 (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
2936 if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT))
2942 src_buf_ofs += src_buf_size;
2943 *pOut_len += dst_buf_size;
2944 if (status == TINFL_STATUS_DONE)
2946 new_out_buf_capacity = out_buf_capacity * 2;
2947 if (new_out_buf_capacity < 128)
2948 new_out_buf_capacity = 128;
2949 pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity);
2957 out_buf_capacity = new_out_buf_capacity;
2964 tinfl_decompressor decomp;
2965 tinfl_status status;
2966 tinfl_init(&decomp);
2967 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);
2968 return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len;
2974 tinfl_decompressor decomp;
2975 mz_uint8 *pDict = (mz_uint8 *)MZ_MALLOC(TINFL_LZ_DICT_SIZE);
2976 size_t in_buf_ofs = 0, dict_ofs = 0;
2978 return TINFL_STATUS_FAILED;
2979 memset(pDict, 0, TINFL_LZ_DICT_SIZE);
2980 tinfl_init(&decomp);
2983 size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs;
2984 tinfl_status status =
tinfl_decompress(&decomp, (
const mz_uint8 *)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size,
2985 (flags & ~(TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)));
2986 in_buf_ofs += in_buf_size;
2987 if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (
int)dst_buf_size, pPut_buf_user)))
2989 if (status != TINFL_STATUS_HAS_MORE_OUTPUT)
2991 result = (status == TINFL_STATUS_DONE);
2994 dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1);
2997 *pIn_buf_size = in_buf_ofs;
3001#ifndef MINIZ_NO_MALLOC
3004 tinfl_decompressor *pDecomp = (tinfl_decompressor *)MZ_MALLOC(
sizeof(tinfl_decompressor));
3006 tinfl_init(pDecomp);
3049#ifndef MINIZ_NO_ARCHIVE_APIS
3058#ifdef MINIZ_NO_STDIO
3059#define MZ_FILE void *
3061#include <sys/stat.h>
3063#if defined(_MSC_VER) || defined(__MINGW64__) || defined(__MINGW32__)
3065#ifndef WIN32_LEAN_AND_MEAN
3066#define WIN32_LEAN_AND_MEAN
3069#define MICROSOFT_WINDOWS_WINBASE_H_DEFINE_INTERLOCKED_CPLUSPLUS_OVERLOADS 0
3076static WCHAR *mz_utf8z_to_widechar(
const char *str)
3078 int reqChars = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
3079 WCHAR *wStr = (WCHAR *)malloc(reqChars *
sizeof(WCHAR));
3080 MultiByteToWideChar(CP_UTF8, 0, str, -1, wStr, reqChars);
3084static FILE *mz_fopen(
const char *pFilename,
const char *pMode)
3086 WCHAR *wFilename = mz_utf8z_to_widechar(pFilename);
3087 WCHAR *wMode = mz_utf8z_to_widechar(pMode);
3089 errno_t err = _wfopen_s(&pFile, wFilename, wMode);
3092 return err ? NULL : pFile;
3095static FILE *mz_freopen(
const char *pPath,
const char *pMode, FILE *pStream)
3097 WCHAR *wPath = mz_utf8z_to_widechar(pPath);
3098 WCHAR *wMode = mz_utf8z_to_widechar(pMode);
3100 errno_t err = _wfreopen_s(&pFile, wPath, wMode, pStream);
3103 return err ? NULL : pFile;
3106#if defined(__MINGW32__)
3107static int mz_stat(
const char *path,
struct _stat *buffer)
3109 WCHAR *wPath = mz_utf8z_to_widechar(path);
3110 int res = _wstat(wPath, buffer);
3115static int mz_stat64(
const char *path,
struct __stat64 *buffer)
3117 WCHAR *wPath = mz_utf8z_to_widechar(path);
3118 int res = _wstat64(wPath, buffer);
3124#ifndef MINIZ_NO_TIME
3125#include <sys/utime.h>
3127#define MZ_FOPEN mz_fopen
3128#define MZ_FCLOSE fclose
3129#define MZ_FREAD fread
3130#define MZ_FWRITE fwrite
3131#define MZ_FTELL64 _ftelli64
3132#define MZ_FSEEK64 _fseeki64
3133#if defined(__MINGW32__)
3134#define MZ_FILE_STAT_STRUCT _stat
3135#define MZ_FILE_STAT mz_stat
3137#define MZ_FILE_STAT_STRUCT _stat64
3138#define MZ_FILE_STAT mz_stat64
3140#define MZ_FFLUSH fflush
3141#define MZ_FREOPEN mz_freopen
3142#define MZ_DELETE_FILE remove
3144#elif defined(__WATCOMC__)
3145#ifndef MINIZ_NO_TIME
3146#include <sys/utime.h>
3148#define MZ_FOPEN(f, m) fopen(f, m)
3149#define MZ_FCLOSE fclose
3150#define MZ_FREAD fread
3151#define MZ_FWRITE fwrite
3152#define MZ_FTELL64 _ftelli64
3153#define MZ_FSEEK64 _fseeki64
3154#define MZ_FILE_STAT_STRUCT stat
3155#define MZ_FILE_STAT stat
3156#define MZ_FFLUSH fflush
3157#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
3158#define MZ_DELETE_FILE remove
3160#elif defined(__TINYC__)
3161#ifndef MINIZ_NO_TIME
3162#include <sys/utime.h>
3164#define MZ_FOPEN(f, m) fopen(f, m)
3165#define MZ_FCLOSE fclose
3166#define MZ_FREAD fread
3167#define MZ_FWRITE fwrite
3168#define MZ_FTELL64 ftell
3169#define MZ_FSEEK64 fseek
3170#define MZ_FILE_STAT_STRUCT stat
3171#define MZ_FILE_STAT stat
3172#define MZ_FFLUSH fflush
3173#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
3174#define MZ_DELETE_FILE remove
3176#elif defined(__USE_LARGEFILE64)
3177#ifndef MINIZ_NO_TIME
3180#define MZ_FOPEN(f, m) fopen64(f, m)
3181#define MZ_FCLOSE fclose
3182#define MZ_FREAD fread
3183#define MZ_FWRITE fwrite
3184#define MZ_FTELL64 ftello64
3185#define MZ_FSEEK64 fseeko64
3186#define MZ_FILE_STAT_STRUCT stat64
3187#define MZ_FILE_STAT stat64
3188#define MZ_FFLUSH fflush
3189#define MZ_FREOPEN(p, m, s) freopen64(p, m, s)
3190#define MZ_DELETE_FILE remove
3192#elif defined(__APPLE__) || defined(__FreeBSD__) || (defined(__linux__) && defined(__x86_64__))
3193#ifndef MINIZ_NO_TIME
3196#define MZ_FOPEN(f, m) fopen(f, m)
3197#define MZ_FCLOSE fclose
3198#define MZ_FREAD fread
3199#define MZ_FWRITE fwrite
3200#define MZ_FTELL64 ftello
3201#define MZ_FSEEK64 fseeko
3202#define MZ_FILE_STAT_STRUCT stat
3203#define MZ_FILE_STAT stat
3204#define MZ_FFLUSH fflush
3205#define MZ_FREOPEN(p, m, s) freopen(p, m, s)
3206#define MZ_DELETE_FILE remove
3209#pragma message("Using fopen, ftello, fseeko, stat() etc. path for file I/O - this path may not support large files.")
3210#ifndef MINIZ_NO_TIME
3213#define MZ_FOPEN(f, m) fopen(f, m)
3214#define MZ_FCLOSE fclose
3215#define MZ_FREAD fread
3216#define MZ_FWRITE fwrite
3217#ifdef __STRICT_ANSI__
3218#define MZ_FTELL64 ftell
3219#define MZ_FSEEK64 fseek
3221#define MZ_FTELL64 ftello
3222#define MZ_FSEEK64 fseeko
3224#define MZ_FILE_STAT_STRUCT stat
3225#define MZ_FILE_STAT stat
3226#define MZ_FFLUSH fflush
3227#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
3228#define MZ_DELETE_FILE remove
3232#define MZ_TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c))
3355#define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size) (array_ptr)->m_element_size = element_size
3357#if defined(DEBUG) || defined(_DEBUG)
3358 static MZ_FORCEINLINE mz_uint mz_zip_array_range_check(
const mz_zip_array *pArray, mz_uint index)
3360 MZ_ASSERT(index < pArray->m_size);
3363#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[mz_zip_array_range_check(array_ptr, index)]
3365#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[index]
3376 pZip->m_pFree(pZip->m_pAlloc_opaque, pArray->
m_p);
3383 size_t new_capacity = min_new_capacity;
3389 new_capacity = MZ_MAX(1, pArray->
m_capacity);
3390 while (new_capacity < min_new_capacity)
3393 if (NULL == (pNew_p = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pArray->
m_p, pArray->
m_element_size, new_capacity)))
3395 pArray->
m_p = pNew_p;
3400#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
3401 static MZ_FORCEINLINE mz_bool mz_zip_array_reserve(mz_zip_archive *pZip,
mz_zip_array *pArray,
size_t new_capacity, mz_uint growing)
3419 pArray->
m_size = new_size;
3423#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
3424 static MZ_FORCEINLINE mz_bool mz_zip_array_ensure_room(mz_zip_archive *pZip,
mz_zip_array *pArray,
size_t n)
3426 return mz_zip_array_reserve(pZip, pArray, pArray->
m_size + n, MZ_TRUE);
3429 static MZ_FORCEINLINE mz_bool mz_zip_array_push_back(mz_zip_archive *pZip,
mz_zip_array *pArray,
const void *pElements,
size_t n)
3431 size_t orig_size = pArray->
m_size;
3440#ifndef MINIZ_NO_TIME
3441 static MZ_TIME_T mz_zip_dos_to_time_t(
int dos_time,
int dos_date)
3444 memset(&tm, 0,
sizeof(tm));
3446 tm.tm_year = ((dos_date >> 9) & 127) + 1980 - 1900;
3447 tm.tm_mon = ((dos_date >> 5) & 15) - 1;
3448 tm.tm_mday = dos_date & 31;
3449 tm.tm_hour = (dos_time >> 11) & 31;
3450 tm.tm_min = (dos_time >> 5) & 63;
3451 tm.tm_sec = (dos_time << 1) & 62;
3455#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
3456 static void mz_zip_time_t_to_dos_time(MZ_TIME_T time, mz_uint16 *pDOS_time, mz_uint16 *pDOS_date)
3459 struct tm tm_struct;
3460 struct tm *tm = &tm_struct;
3461 errno_t err = localtime_s(tm, &time);
3469 struct tm *tm = localtime(&time);
3472 *pDOS_time = (mz_uint16)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) + ((tm->tm_sec) >> 1));
3473 *pDOS_date = (mz_uint16)(((tm->tm_year + 1900 - 1980) << 9) + ((tm->tm_mon + 1) << 5) + tm->tm_mday);
3477#ifndef MINIZ_NO_STDIO
3478#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
3479 static mz_bool mz_zip_get_file_modified_time(
const char *pFilename, MZ_TIME_T *pTime)
3487 *pTime = file_stat.st_mtime;
3493 static mz_bool mz_zip_set_file_times(
const char *pFilename, MZ_TIME_T access_time, MZ_TIME_T modified_time)
3497 memset(&t, 0,
sizeof(t));
3498 t.actime = access_time;
3499 t.modtime = modified_time;
3501 return !utime(pFilename, &t);
3509 pZip->m_last_error = err_num;
3516 if ((!pZip) || (pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
3519 if (!pZip->m_pAlloc)
3523 if (!pZip->m_pRealloc)
3526 pZip->m_archive_size = 0;
3527 pZip->m_central_directory_file_ofs = 0;
3528 pZip->m_total_files = 0;
3529 pZip->m_last_error = MZ_ZIP_NO_ERROR;
3531 if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1,
sizeof(mz_zip_internal_state))))
3534 memset(pZip->m_pState, 0,
sizeof(mz_zip_internal_state));
3538 pZip->m_pState->m_init_flags = flags;
3539 pZip->m_pState->m_zip64 = MZ_FALSE;
3540 pZip->m_pState->m_zip64_has_extended_info_fields = MZ_FALSE;
3542 pZip->m_zip_mode = MZ_ZIP_MODE_READING;
3552 mz_uint8 l = 0,
r = 0;
3555 pE = pL + MZ_MIN(l_len, r_len);
3563 return (pL == pE) ? (l_len < r_len) : (l <
r);
3566#define MZ_SWAP_UINT32(a, b) \
3578 mz_zip_internal_state *pState = pZip->m_pState;
3579 const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
3580 const mz_zip_array *pCentral_dir = &pState->m_central_dir;
3581 mz_uint32 *pIndices;
3582 mz_uint32 start, end;
3583 const mz_uint32 size = pZip->m_total_files;
3590 start = (size - 2U) >> 1U;
3593 mz_uint64 child, root = start;
3596 if ((child = (root << 1U) + 1U) >= size)
3598 child += (((child + 1U) < size) && (
mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1U])));
3612 mz_uint64 child, root = 0;
3616 if ((child = (root << 1U) + 1U) >= end)
3618 child += (((child + 1U) < end) &&
mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1U]));
3630 mz_int64 cur_file_ofs;
3631 mz_uint32 buf_u32[4096 /
sizeof(mz_uint32)];
3632 mz_uint8 *pBuf = (mz_uint8 *)buf_u32;
3635 if (pZip->m_archive_size < record_size)
3639 cur_file_ofs = MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)
sizeof(buf_u32), 0);
3642 int i, n = (int)MZ_MIN(
sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs);
3644 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n)
3647 for (i = n - 4; i >= 0; --i)
3649 mz_uint s = MZ_READ_LE32(pBuf + i);
3650 if (s == record_sig)
3652 if ((pZip->m_archive_size - (cur_file_ofs + i)) >= record_size)
3664 if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >= ((mz_uint64)(MZ_UINT16_MAX) + record_size)))
3667 cur_file_ofs = MZ_MAX(cur_file_ofs - (
sizeof(buf_u32) - 3), 0);
3670 *pOfs = cur_file_ofs;
3689 mz_uint cdir_size = 0, cdir_entries_on_this_disk = 0, num_this_disk = 0, cdir_disk_index = 0;
3690 mz_uint64 cdir_ofs = 0, eocd_ofs = 0, archive_ofs = 0;
3691 mz_int64 cur_file_ofs = 0;
3694 mz_uint32 buf_u32[4096 /
sizeof(mz_uint32)];
3695 mz_uint8 *pBuf = (mz_uint8 *)buf_u32;
3696 mz_bool sort_central_dir = ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0);
3698 mz_uint8 *pZip64_locator = (mz_uint8 *)zip64_end_of_central_dir_locator_u32;
3701 mz_uint8 *pZip64_end_of_central_dir = (mz_uint8 *)zip64_end_of_central_dir_header_u32;
3703 mz_uint64 zip64_end_of_central_dir_ofs = 0;
3712 eocd_ofs = cur_file_ofs;
3726 pZip->m_pState->m_zip64 = MZ_TRUE;
3731 if (pZip->m_pState->m_zip64)
3739 zip64_end_of_central_dir_ofs = cur_file_ofs -
3744 pZip64_end_of_central_dir))
3747 zip64_end_of_central_dir_ofs = MZ_READ_LE64(
3750 if (zip64_end_of_central_dir_ofs >
3755 pZip64_end_of_central_dir))
3767 if (pZip->m_pState->m_zip64)
3778 if (zip64_total_num_of_disks != 1U)
3782 if (zip64_cdir_total_entries > MZ_UINT32_MAX)
3785 pZip->m_total_files = (mz_uint32)zip64_cdir_total_entries;
3787 if (zip64_cdir_total_entries_on_this_disk > MZ_UINT32_MAX)
3790 cdir_entries_on_this_disk = (mz_uint32)zip64_cdir_total_entries_on_this_disk;
3793 if (zip64_size_of_central_directory > MZ_UINT32_MAX)
3796 cdir_size = (mz_uint32)zip64_size_of_central_directory;
3805 if (pZip->m_total_files != cdir_entries_on_this_disk)
3808 if (((num_this_disk | cdir_disk_index) != 0) && ((num_this_disk != 1) || (cdir_disk_index != 1)))
3814 if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size)
3817 if (eocd_ofs < cdir_ofs + cdir_size)
3822 archive_ofs = eocd_ofs - (cdir_ofs + cdir_size);
3823 if (pZip->m_pState->m_zip64)
3834 if ((pZip->m_zip_type == MZ_ZIP_TYPE_FILE || pZip->m_zip_type == MZ_ZIP_TYPE_CFILE ||
3835 pZip->m_zip_type == MZ_ZIP_TYPE_USER) && pZip->m_pState->m_file_archive_start_ofs == 0)
3837 pZip->m_pState->m_file_archive_start_ofs = archive_ofs;
3838 pZip->m_archive_size -= archive_ofs;
3841 pZip->m_central_directory_file_ofs = cdir_ofs;
3843 if (pZip->m_total_files)
3848 (!
mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir_offsets, pZip->m_total_files, MZ_FALSE)))
3851 if (sort_central_dir)
3853 if (!
mz_zip_array_resize(pZip, &pZip->m_pState->m_sorted_central_dir_offsets, pZip->m_total_files, MZ_FALSE))
3857 if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs, pZip->m_pState->m_central_dir.m_p, cdir_size) != cdir_size)
3861 p = (
const mz_uint8 *)pZip->m_pState->m_central_dir.m_p;
3862 for (n = cdir_size, i = 0; i < pZip->m_total_files; ++i)
3864 mz_uint total_header_size, disk_index, bit_flags, filename_size, ext_data_size;
3865 mz_uint64 comp_size, decomp_size, local_header_ofs;
3870 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);
3872 if (sort_central_dir)
3881 if ((!pZip->m_pState->m_zip64_has_extended_info_fields) &&
3883 (MZ_MAX(MZ_MAX(comp_size, decomp_size), local_header_ofs) == MZ_UINT32_MAX))
3886 mz_uint32 extra_size_remaining = ext_data_size;
3888 if (extra_size_remaining)
3890 const mz_uint8 *pExtra_data;
3895 buf = MZ_MALLOC(ext_data_size);
3905 pExtra_data = (mz_uint8 *)buf;
3915 mz_uint32 field_data_size;
3917 if (extra_size_remaining < (
sizeof(mz_uint16) * 2))
3923 field_id = MZ_READ_LE16(pExtra_data);
3924 field_data_size = MZ_READ_LE16(pExtra_data +
sizeof(mz_uint16));
3926 if ((field_data_size +
sizeof(mz_uint16) * 2) > extra_size_remaining)
3935 pZip->m_pState->m_zip64 = MZ_TRUE;
3936 pZip->m_pState->m_zip64_has_extended_info_fields = MZ_TRUE;
3940 pExtra_data +=
sizeof(mz_uint16) * 2 + field_data_size;
3941 extra_size_remaining = extra_size_remaining -
sizeof(mz_uint16) * 2 - field_data_size;
3942 }
while (extra_size_remaining);
3949 if ((comp_size != MZ_UINT32_MAX) && (decomp_size != MZ_UINT32_MAX))
3951 if (((!MZ_READ_LE32(p +
MZ_ZIP_CDH_METHOD_OFS)) && (decomp_size != comp_size)) || (decomp_size && !comp_size))
3956 if ((disk_index == MZ_UINT16_MAX) || ((disk_index != num_this_disk) && (disk_index != 1)))
3959 if (comp_size != MZ_UINT32_MAX)
3972 n -= total_header_size;
3973 p += total_header_size;
3977 if (sort_central_dir)
3991 mz_bool status = MZ_TRUE;
3996 if ((!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
3999 pZip->m_last_error = MZ_ZIP_INVALID_PARAMETER;
4006 mz_zip_internal_state *pState = pZip->m_pState;
4007 pZip->m_pState = NULL;
4013#ifndef MINIZ_NO_STDIO
4014 if (pState->m_pFile)
4016 if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE)
4021 pZip->m_last_error = MZ_ZIP_FILE_CLOSE_FAILED;
4025 pState->m_pFile = NULL;
4029 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
4031 pZip->m_zip_mode = MZ_ZIP_MODE_INVALID;
4042 if ((!pZip) || (!pZip->m_pRead))
4048 pZip->m_zip_type = MZ_ZIP_TYPE_USER;
4049 pZip->m_archive_size = size;
4062 mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
4063 size_t s = (file_ofs >= pZip->m_archive_size) ? 0 : (size_t)MZ_MIN(pZip->m_archive_size - file_ofs, n);
4064 memcpy(pBuf, (
const mz_uint8 *)pZip->m_pState->m_pMem + file_ofs, s);
4079 pZip->m_zip_type = MZ_ZIP_TYPE_MEMORY;
4080 pZip->m_archive_size = size;
4082 pZip->m_pIO_opaque = pZip;
4083 pZip->m_pNeeds_keepalive = NULL;
4086 pZip->m_pState->m_pMem =
const_cast<void *
>(pMem);
4088 pZip->m_pState->m_pMem = (
void *)pMem;
4091 pZip->m_pState->m_mem_size = size;
4102#ifndef MINIZ_NO_STDIO
4105 mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
4106 mz_int64 cur_ofs =
MZ_FTELL64(pZip->m_pState->m_pFile);
4108 file_ofs += pZip->m_pState->m_file_archive_start_ofs;
4110 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))))
4113 return MZ_FREAD(pBuf, 1, n, pZip->m_pState->m_pFile);
4123 mz_uint64 file_size;
4129 pFile =
MZ_FOPEN(pFilename, (flags & MZ_ZIP_FLAG_READ_ALLOW_WRITING ) ?
"r+b" :
"rb");
4133 file_size = archive_size;
4159 pZip->m_zip_type = MZ_ZIP_TYPE_FILE;
4161 pZip->m_pIO_opaque = pZip;
4162 pZip->m_pState->m_pFile = pFile;
4163 pZip->m_archive_size = file_size;
4164 pZip->m_pState->m_file_archive_start_ofs = file_start_ofs;
4177 mz_uint64 cur_file_ofs;
4179 if ((!pZip) || (!pFile))
4189 archive_size =
MZ_FTELL64(pFile) - cur_file_ofs;
4198 pZip->m_zip_type = MZ_ZIP_TYPE_CFILE;
4201 pZip->m_pIO_opaque = pZip;
4202 pZip->m_pState->m_pFile = pFile;
4203 pZip->m_archive_size = archive_size;
4204 pZip->m_pState->m_file_archive_start_ofs = cur_file_ofs;
4217 static MZ_FORCEINLINE
const mz_uint8 *
mz_zip_get_cdh(mz_zip_archive *pZip, mz_uint file_index)
4219 if ((!pZip) || (!pZip->m_pState) || (file_index >= pZip->m_total_files))
4276 mz_uint filename_len, attribute_mapping_id, external_attr;
4295 (void)attribute_mapping_id;
4306 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)
4309 const mz_uint8 *p = pCentral_dir_header;
4311 if (pFound_zip64_extra_data)
4312 *pFound_zip64_extra_data = MZ_FALSE;
4314 if ((!p) || (!pStat))
4318 pStat->m_file_index = file_index;
4319 pStat->m_central_dir_ofs =
MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index);
4324#ifndef MINIZ_NO_TIME
4336 n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE - 1);
4338 pStat->m_filename[n] =
'\0';
4341 n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE - 1);
4342 pStat->m_comment_size = n;
4344 pStat->m_comment[n] =
'\0';
4353 if (MZ_MAX(MZ_MAX(pStat->m_comp_size, pStat->m_uncomp_size), pStat->m_local_header_ofs) == MZ_UINT32_MAX)
4358 if (extra_size_remaining)
4365 mz_uint32 field_data_size;
4367 if (extra_size_remaining < (
sizeof(mz_uint16) * 2))
4370 field_id = MZ_READ_LE16(pExtra_data);
4371 field_data_size = MZ_READ_LE16(pExtra_data +
sizeof(mz_uint16));
4373 if ((field_data_size +
sizeof(mz_uint16) * 2) > extra_size_remaining)
4378 const mz_uint8 *pField_data = pExtra_data +
sizeof(mz_uint16) * 2;
4379 mz_uint32 field_data_remaining = field_data_size;
4381 if (pFound_zip64_extra_data)
4382 *pFound_zip64_extra_data = MZ_TRUE;
4384 if (pStat->m_uncomp_size == MZ_UINT32_MAX)
4386 if (field_data_remaining <
sizeof(mz_uint64))
4389 pStat->m_uncomp_size = MZ_READ_LE64(pField_data);
4390 pField_data +=
sizeof(mz_uint64);
4391 field_data_remaining -=
sizeof(mz_uint64);
4394 if (pStat->m_comp_size == MZ_UINT32_MAX)
4396 if (field_data_remaining <
sizeof(mz_uint64))
4399 pStat->m_comp_size = MZ_READ_LE64(pField_data);
4400 pField_data +=
sizeof(mz_uint64);
4401 field_data_remaining -=
sizeof(mz_uint64);
4404 if (pStat->m_local_header_ofs == MZ_UINT32_MAX)
4406 if (field_data_remaining <
sizeof(mz_uint64))
4409 pStat->m_local_header_ofs = MZ_READ_LE64(pField_data);
4410 pField_data +=
sizeof(mz_uint64);
4411 field_data_remaining -=
sizeof(mz_uint64);
4417 pExtra_data +=
sizeof(mz_uint16) * 2 + field_data_size;
4418 extra_size_remaining = extra_size_remaining -
sizeof(mz_uint16) * 2 - field_data_size;
4419 }
while (extra_size_remaining);
4429 if (flags & MZ_ZIP_FLAG_CASE_SENSITIVE)
4430 return 0 == memcmp(pA, pB, len);
4431 for (i = 0; i < len; ++i)
4441 mz_uint8 l = 0,
r = 0;
4443 pE = pL + MZ_MIN(l_len, r_len);
4451 return (pL == pE) ? (int)(l_len - r_len) : (l -
r);
4456 mz_zip_internal_state *pState = pZip->m_pState;
4457 const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
4458 const mz_zip_array *pCentral_dir = &pState->m_central_dir;
4459 mz_uint32 *pIndices = &
MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0);
4460 const mz_uint32 size = pZip->m_total_files;
4461 const mz_uint filename_len = (mz_uint)strlen(pFilename);
4470 mz_int64 l = 0, h = (mz_int64)size - 1;
4474 mz_int64 m = l + ((h - l) >> 1);
4475 mz_uint32 file_index = pIndices[(mz_uint32)m];
4481 *pIndex = file_index;
4506 size_t name_len, comment_len;
4511 if ((!pZip) || (!pZip->m_pState) || (!pName))
4515 if (((pZip->m_pState->m_init_flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0) &&
4516 (pZip->m_zip_mode == MZ_ZIP_MODE_READING) &&
4517 ((flags & (MZ_ZIP_FLAG_IGNORE_PATH | MZ_ZIP_FLAG_CASE_SENSITIVE)) == 0) && (!pComment) && (pZip->m_pState->m_sorted_central_dir_offsets.m_size))
4523 name_len = strlen(pName);
4524 if (name_len > MZ_UINT16_MAX)
4527 comment_len = pComment ? strlen(pComment) : 0;
4528 if (comment_len > MZ_UINT16_MAX)
4531 for (file_index = 0; file_index < pZip->m_total_files; file_index++)
4536 if (filename_len < name_len)
4541 const char *pFile_comment = pFilename + filename_len + file_extra_len;
4542 if ((file_comment_len != comment_len) || (!
mz_zip_string_equal(pComment, pFile_comment, file_comment_len, flags)))
4545 if ((flags & MZ_ZIP_FLAG_IGNORE_PATH) && (filename_len))
4547 int ofs = filename_len - 1;
4550 if ((pFilename[ofs] ==
'/') || (pFilename[ofs] ==
'\\') || (pFilename[ofs] ==
':'))
4552 }
while (--ofs >= 0);
4555 filename_len -= ofs;
4557 if ((filename_len == name_len) && (
mz_zip_string_equal(pName, pFilename, filename_len, flags)))
4560 *pIndex = file_index;
4568 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)
4570 int status = TINFL_STATUS_DONE;
4571 mz_uint64 needed_size, cur_file_ofs, comp_remaining, out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail;
4572 mz_zip_archive_file_stat file_stat;
4575 mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
4576 tinfl_decompressor inflator;
4578 if ((!pZip) || (!pZip->m_pState) || ((buf_size) && (!pBuf)) || ((user_read_buf_size) && (!pUser_read_buf)) || (!pZip->m_pRead))
4589 if ((file_stat.m_is_directory) || (!file_stat.m_comp_size))
4597 if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method !=
MZ_DEFLATED))
4601 needed_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size : file_stat.m_uncomp_size;
4602 if (buf_size < needed_size)
4606 cur_file_ofs = file_stat.m_local_header_ofs;
4614 if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
4617 if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method))
4620 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, (
size_t)needed_size) != needed_size)
4623#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4624 if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) == 0)
4626 if (
mz_crc32(
MZ_CRC32_INIT, (
const mz_uint8 *)pBuf, (
size_t)file_stat.m_uncomp_size) != file_stat.m_crc32)
4635 tinfl_init(&inflator);
4637 if (pZip->m_pState->m_pMem)
4640 pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
4641 read_buf_size = read_buf_avail = file_stat.m_comp_size;
4644 else if (pUser_read_buf)
4647 if (!user_read_buf_size)
4649 pRead_buf = (mz_uint8 *)pUser_read_buf;
4650 read_buf_size = user_read_buf_size;
4652 comp_remaining = file_stat.m_comp_size;
4657 read_buf_size = MZ_MIN(file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
4658 if (((
sizeof(
size_t) ==
sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
4661 if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (
size_t)read_buf_size)))
4665 comp_remaining = file_stat.m_comp_size;
4671 size_t in_buf_size, out_buf_size = (size_t)(file_stat.m_uncomp_size - out_buf_ofs);
4672 if ((!read_buf_avail) && (!pZip->m_pState->m_pMem))
4674 read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
4675 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (
size_t)read_buf_avail) != read_buf_avail)
4677 status = TINFL_STATUS_FAILED;
4681 cur_file_ofs += read_buf_avail;
4682 comp_remaining -= read_buf_avail;
4685 in_buf_size = (size_t)read_buf_avail;
4686 status =
tinfl_decompress(&inflator, (mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pBuf, (mz_uint8 *)pBuf + out_buf_ofs, &out_buf_size, TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF | (comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0));
4687 read_buf_avail -= in_buf_size;
4688 read_buf_ofs += in_buf_size;
4689 out_buf_ofs += out_buf_size;
4690 }
while (status == TINFL_STATUS_NEEDS_MORE_INPUT);
4692 if (status == TINFL_STATUS_DONE)
4695 if (out_buf_ofs != file_stat.m_uncomp_size)
4698 status = TINFL_STATUS_FAILED;
4700#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4701 else if (
mz_crc32(
MZ_CRC32_INIT, (
const mz_uint8 *)pBuf, (
size_t)file_stat.m_uncomp_size) != file_stat.m_crc32)
4704 status = TINFL_STATUS_FAILED;
4709 if ((!pZip->m_pState->m_pMem) && (!pUser_read_buf))
4710 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
4712 return status == TINFL_STATUS_DONE;
4722 mz_uint32 file_index;
4740 mz_zip_archive_file_stat file_stat;
4741 mz_uint64 alloc_size;
4750 alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size : file_stat.m_uncomp_size;
4751 if (((
sizeof(
size_t) ==
sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
4757 if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (
size_t)alloc_size)))
4765 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
4770 *pSize = (size_t)alloc_size;
4776 mz_uint32 file_index;
4788 int status = TINFL_STATUS_DONE;
4789#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4792 mz_uint64 read_buf_size, read_buf_ofs = 0, read_buf_avail, comp_remaining, out_buf_ofs = 0, cur_file_ofs;
4793 mz_zip_archive_file_stat file_stat;
4794 void *pRead_buf = NULL;
4795 void *pWrite_buf = NULL;
4797 mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
4799 if ((!pZip) || (!pZip->m_pState) || (!pCallback) || (!pZip->m_pRead))
4806 if ((file_stat.m_is_directory) || (!file_stat.m_comp_size))
4814 if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method !=
MZ_DEFLATED))
4818 cur_file_ofs = file_stat.m_local_header_ofs;
4826 if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
4830 if (pZip->m_pState->m_pMem)
4832 pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
4833 read_buf_size = read_buf_avail = file_stat.m_comp_size;
4838 read_buf_size = MZ_MIN(file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
4839 if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (
size_t)read_buf_size)))
4843 comp_remaining = file_stat.m_comp_size;
4846 if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method))
4849 if (pZip->m_pState->m_pMem)
4851 if (((
sizeof(
size_t) ==
sizeof(mz_uint32))) && (file_stat.m_comp_size > MZ_UINT32_MAX))
4854 if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (
size_t)file_stat.m_comp_size) != file_stat.m_comp_size)
4857 status = TINFL_STATUS_FAILED;
4859 else if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
4861#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4862 file_crc32 = (mz_uint32)
mz_crc32(file_crc32, (
const mz_uint8 *)pRead_buf, (
size_t)file_stat.m_comp_size);
4866 cur_file_ofs += file_stat.m_comp_size;
4867 out_buf_ofs += file_stat.m_comp_size;
4872 while (comp_remaining)
4874 read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
4875 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (
size_t)read_buf_avail) != read_buf_avail)
4878 status = TINFL_STATUS_FAILED;
4882#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4883 if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
4885 file_crc32 = (mz_uint32)
mz_crc32(file_crc32, (
const mz_uint8 *)pRead_buf, (
size_t)read_buf_avail);
4889 if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (
size_t)read_buf_avail) != read_buf_avail)
4892 status = TINFL_STATUS_FAILED;
4896 cur_file_ofs += read_buf_avail;
4897 out_buf_ofs += read_buf_avail;
4898 comp_remaining -= read_buf_avail;
4904 tinfl_decompressor inflator;
4905 tinfl_init(&inflator);
4907 if (NULL == (pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, TINFL_LZ_DICT_SIZE)))
4910 status = TINFL_STATUS_FAILED;
4916 mz_uint8 *pWrite_buf_cur = (mz_uint8 *)pWrite_buf + (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
4917 size_t in_buf_size, out_buf_size = TINFL_LZ_DICT_SIZE - (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
4918 if ((!read_buf_avail) && (!pZip->m_pState->m_pMem))
4920 read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
4921 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (
size_t)read_buf_avail) != read_buf_avail)
4924 status = TINFL_STATUS_FAILED;
4927 cur_file_ofs += read_buf_avail;
4928 comp_remaining -= read_buf_avail;
4932 in_buf_size = (size_t)read_buf_avail;
4933 status =
tinfl_decompress(&inflator, (
const mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pWrite_buf, pWrite_buf_cur, &out_buf_size, comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0);
4934 read_buf_avail -= in_buf_size;
4935 read_buf_ofs += in_buf_size;
4939 if (pCallback(pOpaque, out_buf_ofs, pWrite_buf_cur, out_buf_size) != out_buf_size)
4942 status = TINFL_STATUS_FAILED;
4946#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4947 file_crc32 = (mz_uint32)
mz_crc32(file_crc32, pWrite_buf_cur, out_buf_size);
4949 if ((out_buf_ofs += out_buf_size) > file_stat.m_uncomp_size)
4952 status = TINFL_STATUS_FAILED;
4956 }
while ((status == TINFL_STATUS_NEEDS_MORE_INPUT) || (status == TINFL_STATUS_HAS_MORE_OUTPUT));
4960 if ((status == TINFL_STATUS_DONE) && (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)))
4963 if (out_buf_ofs != file_stat.m_uncomp_size)
4966 status = TINFL_STATUS_FAILED;
4968#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
4969 else if (file_crc32 != file_stat.m_crc32)
4972 status = TINFL_STATUS_FAILED;
4977 if (!pZip->m_pState->m_pMem)
4978 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
4981 pZip->m_pFree(pZip->m_pAlloc_opaque, pWrite_buf);
4983 return status == TINFL_STATUS_DONE;
4988 mz_uint32 file_index;
4997 mz_zip_reader_extract_iter_state *pState;
4999 mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
5002 if ((!pZip) || (!pZip->m_pState))
5006 pState = (mz_zip_reader_extract_iter_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1,
sizeof(mz_zip_reader_extract_iter_state));
5016 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5024 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5029 if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (pState->file_stat.m_method != 0) && (pState->file_stat.m_method !=
MZ_DEFLATED))
5032 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5037 pState->pZip = pZip;
5038 pState->flags = flags;
5041 pState->status = TINFL_STATUS_DONE;
5042#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
5045 pState->read_buf_ofs = 0;
5046 pState->out_buf_ofs = 0;
5047 pState->pRead_buf = NULL;
5048 pState->pWrite_buf = NULL;
5049 pState->out_blk_remain = 0;
5052 pState->cur_file_ofs = pState->file_stat.m_local_header_ofs;
5056 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5063 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5068 if ((pState->cur_file_ofs + pState->file_stat.m_comp_size) > pZip->m_archive_size)
5071 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5076 if (pZip->m_pState->m_pMem)
5078 pState->pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + pState->cur_file_ofs;
5079 pState->read_buf_size = pState->read_buf_avail = pState->file_stat.m_comp_size;
5080 pState->comp_remaining = pState->file_stat.m_comp_size;
5084 if (!((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!pState->file_stat.m_method)))
5087 pState->read_buf_size = MZ_MIN(pState->file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
5088 if (NULL == (pState->pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (
size_t)pState->read_buf_size)))
5091 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5098 pState->read_buf_size = 0;
5100 pState->read_buf_avail = 0;
5101 pState->comp_remaining = pState->file_stat.m_comp_size;
5104 if (!((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!pState->file_stat.m_method)))
5107 tinfl_init(&pState->inflator);
5110 if (NULL == (pState->pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, TINFL_LZ_DICT_SIZE)))
5113 if (pState->pRead_buf)
5114 pZip->m_pFree(pZip->m_pAlloc_opaque, pState->pRead_buf);
5115 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5125 mz_uint32 file_index;
5137 size_t copied_to_caller = 0;
5140 if ((!pState) || (!pState->pZip) || (!pState->pZip->m_pState) || (!pvBuf))
5143 if ((pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!pState->file_stat.m_method))
5146 copied_to_caller = (size_t)MZ_MIN(buf_size, pState->comp_remaining);
5149 if (pState->pZip->m_pState->m_pMem)
5152 memcpy(pvBuf, pState->pRead_buf, copied_to_caller);
5153 pState->pRead_buf = ((mz_uint8 *)pState->pRead_buf) + copied_to_caller;
5158 if (pState->pZip->m_pRead(pState->pZip->m_pIO_opaque, pState->cur_file_ofs, pvBuf, copied_to_caller) != copied_to_caller)
5162 pState->status = TINFL_STATUS_FAILED;
5163 copied_to_caller = 0;
5167#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
5169 if (!(pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
5170 pState->file_crc32 = (mz_uint32)
mz_crc32(pState->file_crc32, (
const mz_uint8 *)pvBuf, copied_to_caller);
5174 pState->cur_file_ofs += copied_to_caller;
5175 pState->out_buf_ofs += copied_to_caller;
5176 pState->comp_remaining -= copied_to_caller;
5183 mz_uint8 *pWrite_buf_cur = (mz_uint8 *)pState->pWrite_buf + (pState->out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
5186 size_t in_buf_size, out_buf_size = TINFL_LZ_DICT_SIZE - (pState->out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
5188 if (!pState->out_blk_remain)
5191 if ((!pState->read_buf_avail) && (!pState->pZip->m_pState->m_pMem))
5194 pState->read_buf_avail = MZ_MIN(pState->read_buf_size, pState->comp_remaining);
5195 if (pState->pZip->m_pRead(pState->pZip->m_pIO_opaque, pState->cur_file_ofs, pState->pRead_buf, (
size_t)pState->read_buf_avail) != pState->read_buf_avail)
5198 pState->status = TINFL_STATUS_FAILED;
5203 pState->cur_file_ofs += pState->read_buf_avail;
5204 pState->comp_remaining -= pState->read_buf_avail;
5205 pState->read_buf_ofs = 0;
5209 in_buf_size = (size_t)pState->read_buf_avail;
5210 pState->status =
tinfl_decompress(&pState->inflator, (
const mz_uint8 *)pState->pRead_buf + pState->read_buf_ofs, &in_buf_size, (mz_uint8 *)pState->pWrite_buf, pWrite_buf_cur, &out_buf_size, pState->comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0);
5211 pState->read_buf_avail -= in_buf_size;
5212 pState->read_buf_ofs += in_buf_size;
5215 pState->out_blk_remain = out_buf_size;
5218 if (pState->out_blk_remain)
5221 size_t to_copy = MZ_MIN((buf_size - copied_to_caller), pState->out_blk_remain);
5224 memcpy((mz_uint8 *)pvBuf + copied_to_caller, pWrite_buf_cur, to_copy);
5226#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
5228 pState->file_crc32 = (mz_uint32)
mz_crc32(pState->file_crc32, pWrite_buf_cur, to_copy);
5232 pState->out_blk_remain -= to_copy;
5235 if ((pState->out_buf_ofs += to_copy) > pState->file_stat.m_uncomp_size)
5238 pState->status = TINFL_STATUS_FAILED;
5243 copied_to_caller += to_copy;
5245 }
while ((copied_to_caller < buf_size) && ((pState->status == TINFL_STATUS_NEEDS_MORE_INPUT) || (pState->status == TINFL_STATUS_HAS_MORE_OUTPUT)));
5249 return copied_to_caller;
5257 if ((!pState) || (!pState->pZip) || (!pState->pZip->m_pState))
5261 if ((pState->status == TINFL_STATUS_DONE) && (!(pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA)))
5264 if (pState->out_buf_ofs != pState->file_stat.m_uncomp_size)
5267 pState->status = TINFL_STATUS_FAILED;
5269#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
5270 else if (pState->file_crc32 != pState->file_stat.m_crc32)
5273 pState->status = TINFL_STATUS_FAILED;
5279 if (!pState->pZip->m_pState->m_pMem)
5280 pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState->pRead_buf);
5281 if (pState->pWrite_buf)
5282 pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState->pWrite_buf);
5285 status = pState->status;
5288 pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState);
5290 return status == TINFL_STATUS_DONE;
5293#ifndef MINIZ_NO_STDIO
5298 return MZ_FWRITE(pBuf, 1, n, (MZ_FILE *)pOpaque);
5304 mz_zip_archive_file_stat file_stat;
5310 if ((file_stat.m_is_directory) || (!file_stat.m_is_supported))
5313 pFile =
MZ_FOPEN(pDst_filename,
"wb");
5327#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_STDIO)
5329 mz_zip_set_file_times(pDst_filename, file_stat.m_time, file_stat.m_time);
5337 mz_uint32 file_index;
5346 mz_zip_archive_file_stat file_stat;
5351 if ((file_stat.m_is_directory) || (!file_stat.m_is_supported))
5359 mz_uint32 file_index;
5369 mz_uint32 *p = (mz_uint32 *)pOpaque;
5371 *p = (mz_uint32)
mz_crc32(*p, (
const mz_uint8 *)pBuf, n);
5377 mz_zip_archive_file_stat file_stat;
5378 mz_zip_internal_state *pState;
5379 const mz_uint8 *pCentral_dir_header;
5380 mz_bool found_zip64_ext_data_in_cdir = MZ_FALSE;
5381 mz_bool found_zip64_ext_data_in_ldir = MZ_FALSE;
5383 mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
5384 mz_uint64 local_header_ofs = 0;
5385 mz_uint32 local_header_filename_len, local_header_extra_len, local_header_crc32;
5386 mz_uint64 local_header_comp_size, local_header_uncomp_size;
5388 mz_bool has_data_descriptor;
5389 mz_uint32 local_header_bit_flags;
5394 if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (!pZip->m_pRead))
5397 if (file_index > pZip->m_total_files)
5400 pState = pZip->m_pState;
5408 if ((file_stat.m_is_directory) || (!file_stat.m_uncomp_size))
5412 if (file_stat.m_is_encrypted)
5416 if ((file_stat.m_method != 0) && (file_stat.m_method !=
MZ_DEFLATED))
5419 if (!file_stat.m_is_supported)
5423 local_header_ofs = file_stat.m_local_header_ofs;
5436 has_data_descriptor = (local_header_bit_flags & 8) != 0;
5438 if (local_header_filename_len != strlen(file_stat.m_filename))
5441 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)
5444 if (!
mz_zip_array_resize(pZip, &file_data_array, MZ_MAX(local_header_filename_len, local_header_extra_len), MZ_FALSE))
5447 goto handle_failure;
5450 if (local_header_filename_len)
5452 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)
5455 goto handle_failure;
5459 if (memcmp(file_stat.m_filename, file_data_array.
m_p, local_header_filename_len) != 0)
5462 goto handle_failure;
5466 if ((local_header_extra_len) && ((local_header_comp_size == MZ_UINT32_MAX) || (local_header_uncomp_size == MZ_UINT32_MAX)))
5468 mz_uint32 extra_size_remaining = local_header_extra_len;
5469 const mz_uint8 *pExtra_data = (
const mz_uint8 *)file_data_array.
m_p;
5471 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)
5474 goto handle_failure;
5479 mz_uint32 field_id, field_data_size, field_total_size;
5481 if (extra_size_remaining < (
sizeof(mz_uint16) * 2))
5484 goto handle_failure;
5487 field_id = MZ_READ_LE16(pExtra_data);
5488 field_data_size = MZ_READ_LE16(pExtra_data +
sizeof(mz_uint16));
5489 field_total_size = field_data_size +
sizeof(mz_uint16) * 2;
5491 if (field_total_size > extra_size_remaining)
5494 goto handle_failure;
5499 const mz_uint8 *pSrc_field_data = pExtra_data +
sizeof(mz_uint32);
5501 if (field_data_size <
sizeof(mz_uint64) * 2)
5504 goto handle_failure;
5507 local_header_uncomp_size = MZ_READ_LE64(pSrc_field_data);
5508 local_header_comp_size = MZ_READ_LE64(pSrc_field_data +
sizeof(mz_uint64));
5510 found_zip64_ext_data_in_ldir = MZ_TRUE;
5514 pExtra_data += field_total_size;
5515 extra_size_remaining -= field_total_size;
5516 }
while (extra_size_remaining);
5521 if ((has_data_descriptor) && (!local_header_comp_size) && (!local_header_crc32))
5523 mz_uint8 descriptor_buf[32];
5525 const mz_uint8 *pSrc;
5526 mz_uint32 file_crc32;
5527 mz_uint64 comp_size = 0, uncomp_size = 0;
5529 mz_uint32 num_descriptor_uint32s = ((pState->m_zip64) || (found_zip64_ext_data_in_ldir)) ? 6 : 4;
5531 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))
5534 goto handle_failure;
5538 pSrc =
has_id ? (descriptor_buf +
sizeof(mz_uint32)) : descriptor_buf;
5540 file_crc32 = MZ_READ_LE32(pSrc);
5542 if ((pState->m_zip64) || (found_zip64_ext_data_in_ldir))
5544 comp_size = MZ_READ_LE64(pSrc +
sizeof(mz_uint32));
5545 uncomp_size = MZ_READ_LE64(pSrc +
sizeof(mz_uint32) +
sizeof(mz_uint64));
5549 comp_size = MZ_READ_LE32(pSrc +
sizeof(mz_uint32));
5550 uncomp_size = MZ_READ_LE32(pSrc +
sizeof(mz_uint32) +
sizeof(mz_uint32));
5553 if ((file_crc32 != file_stat.m_crc32) || (comp_size != file_stat.m_comp_size) || (uncomp_size != file_stat.m_uncomp_size))
5556 goto handle_failure;
5561 if ((local_header_crc32 != file_stat.m_crc32) || (local_header_comp_size != file_stat.m_comp_size) || (local_header_uncomp_size != file_stat.m_uncomp_size))
5564 goto handle_failure;
5570 if ((flags & MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY) == 0)
5576 if (uncomp_crc32 != file_stat.m_crc32)
5592 mz_zip_internal_state *pState;
5595 if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (!pZip->m_pRead))
5598 pState = pZip->m_pState;
5601 if (!pState->m_zip64)
5603 if (pZip->m_total_files > MZ_UINT16_MAX)
5606 if (pZip->m_archive_size > MZ_UINT32_MAX)
5611 if (pState->m_central_dir.m_size >= MZ_UINT32_MAX)
5615 for (i = 0; i < pZip->m_total_files; i++)
5617 if (MZ_ZIP_FLAG_VALIDATE_LOCATE_FILE_FLAG & flags)
5619 mz_uint32 found_index;
5620 mz_zip_archive_file_stat stat;
5629 if (found_index != i)
5642 mz_bool success = MZ_TRUE;
5644 mz_zip_error actual_err = MZ_ZIP_NO_ERROR;
5646 if ((!pMem) || (!size))
5649 *pErr = MZ_ZIP_INVALID_PARAMETER;
5658 *pErr = zip.m_last_error;
5664 actual_err = zip.m_last_error;
5671 actual_err = zip.m_last_error;
5681#ifndef MINIZ_NO_STDIO
5684 mz_bool success = MZ_TRUE;
5686 mz_zip_error actual_err = MZ_ZIP_NO_ERROR;
5691 *pErr = MZ_ZIP_INVALID_PARAMETER;
5700 *pErr = zip.m_last_error;
5706 actual_err = zip.m_last_error;
5713 actual_err = zip.m_last_error;
5726#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
5728 static MZ_FORCEINLINE
void mz_write_le16(mz_uint8 *p, mz_uint16 v)
5731 p[1] = (mz_uint8)(v >> 8);
5733 static MZ_FORCEINLINE
void mz_write_le32(mz_uint8 *p, mz_uint32 v)
5736 p[1] = (mz_uint8)(v >> 8);
5737 p[2] = (mz_uint8)(v >> 16);
5738 p[3] = (mz_uint8)(v >> 24);
5740 static MZ_FORCEINLINE
void mz_write_le64(mz_uint8 *p, mz_uint64 v)
5742 mz_write_le32(p, (mz_uint32)v);
5743 mz_write_le32(p +
sizeof(mz_uint32), (mz_uint32)(v >> 32));
5746#define MZ_WRITE_LE16(p, v) mz_write_le16((mz_uint8 *)(p), (mz_uint16)(v))
5747#define MZ_WRITE_LE32(p, v) mz_write_le32((mz_uint8 *)(p), (mz_uint32)(v))
5748#define MZ_WRITE_LE64(p, v) mz_write_le64((mz_uint8 *)(p), (mz_uint64)(v))
5750 static size_t mz_zip_heap_write_func(
void *pOpaque, mz_uint64 file_ofs,
const void *pBuf,
size_t n)
5752 mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
5753 mz_zip_internal_state *pState = pZip->m_pState;
5754 mz_uint64 new_size = MZ_MAX(file_ofs + n, pState->m_mem_size);
5760 if ((
sizeof(
size_t) ==
sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF))
5766 if (new_size > pState->m_mem_capacity)
5769 size_t new_capacity = MZ_MAX(64, pState->m_mem_capacity);
5771 while (new_capacity < new_size)
5774 if (NULL == (pNew_block = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pState->m_pMem, 1, new_capacity)))
5780 pState->m_pMem = pNew_block;
5781 pState->m_mem_capacity = new_capacity;
5783 memcpy((mz_uint8 *)pState->m_pMem + file_ofs, pBuf, n);
5784 pState->m_mem_size = (size_t)new_size;
5788#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
5789 static mz_bool mz_zip_writer_end_internal(mz_zip_archive *pZip, mz_bool set_last_error)
5791 mz_zip_internal_state *pState;
5792 mz_bool status = MZ_TRUE;
5794 if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || ((pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) && (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED)))
5801 pState = pZip->m_pState;
5802 pZip->m_pState = NULL;
5807#ifndef MINIZ_NO_STDIO
5808 if (pState->m_pFile)
5810 if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE)
5820 pState->m_pFile = NULL;
5824 if ((pZip->m_pWrite == mz_zip_heap_write_func) && (pState->m_pMem))
5826 pZip->m_pFree(pZip->m_pAlloc_opaque, pState->m_pMem);
5827 pState->m_pMem = NULL;
5830 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5831 pZip->m_zip_mode = MZ_ZIP_MODE_INVALID;
5835 mz_bool mz_zip_writer_init_v2(mz_zip_archive *pZip, mz_uint64 existing_size, mz_uint flags)
5837 mz_bool zip64 = (flags & MZ_ZIP_FLAG_WRITE_ZIP64) != 0;
5839 if ((!pZip) || (pZip->m_pState) || (!pZip->m_pWrite) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
5842 if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING)
5848 if (pZip->m_file_offset_alignment)
5851 if (pZip->m_file_offset_alignment & (pZip->m_file_offset_alignment - 1))
5855 if (!pZip->m_pAlloc)
5859 if (!pZip->m_pRealloc)
5862 pZip->m_archive_size = existing_size;
5863 pZip->m_central_directory_file_ofs = 0;
5864 pZip->m_total_files = 0;
5866 if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1,
sizeof(mz_zip_internal_state))))
5869 memset(pZip->m_pState, 0,
sizeof(mz_zip_internal_state));
5875 pZip->m_pState->m_zip64 = zip64;
5876 pZip->m_pState->m_zip64_has_extended_info_fields = zip64;
5878 pZip->m_zip_type = MZ_ZIP_TYPE_USER;
5879 pZip->m_zip_mode = MZ_ZIP_MODE_WRITING;
5884 mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size)
5886 return mz_zip_writer_init_v2(pZip, existing_size, 0);
5889 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)
5891 pZip->m_pWrite = mz_zip_heap_write_func;
5892 pZip->m_pNeeds_keepalive = NULL;
5894 if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING)
5897 pZip->m_pIO_opaque = pZip;
5899 if (!mz_zip_writer_init_v2(pZip, size_to_reserve_at_beginning, flags))
5902 pZip->m_zip_type = MZ_ZIP_TYPE_HEAP;
5904 if (0 != (initial_allocation_size = MZ_MAX(initial_allocation_size, size_to_reserve_at_beginning)))
5906 if (NULL == (pZip->m_pState->m_pMem = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, initial_allocation_size)))
5908 mz_zip_writer_end_internal(pZip, MZ_FALSE);
5911 pZip->m_pState->m_mem_capacity = initial_allocation_size;
5917 mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip,
size_t size_to_reserve_at_beginning,
size_t initial_allocation_size)
5919 return mz_zip_writer_init_heap_v2(pZip, size_to_reserve_at_beginning, initial_allocation_size, 0);
5922#ifndef MINIZ_NO_STDIO
5923 static size_t mz_zip_file_write_func(
void *pOpaque, mz_uint64 file_ofs,
const void *pBuf,
size_t n)
5925 mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
5926 mz_int64 cur_ofs =
MZ_FTELL64(pZip->m_pState->m_pFile);
5928 file_ofs += pZip->m_pState->m_file_archive_start_ofs;
5930 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))))
5936 return MZ_FWRITE(pBuf, 1, n, pZip->m_pState->m_pFile);
5939 mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip,
const char *pFilename, mz_uint64 size_to_reserve_at_beginning)
5941 return mz_zip_writer_init_file_v2(pZip, pFilename, size_to_reserve_at_beginning, 0);
5944 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)
5948 pZip->m_pWrite = mz_zip_file_write_func;
5949 pZip->m_pNeeds_keepalive = NULL;
5951 if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING)
5954 pZip->m_pIO_opaque = pZip;
5956 if (!mz_zip_writer_init_v2(pZip, size_to_reserve_at_beginning, flags))
5959 if (NULL == (pFile =
MZ_FOPEN(pFilename, (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING) ?
"w+b" :
"wb")))
5961 mz_zip_writer_end(pZip);
5965 pZip->m_pState->m_pFile = pFile;
5966 pZip->m_zip_type = MZ_ZIP_TYPE_FILE;
5968 if (size_to_reserve_at_beginning)
5970 mz_uint64 cur_ofs = 0;
5977 size_t n = (size_t)MZ_MIN(
sizeof(buf), size_to_reserve_at_beginning);
5978 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_ofs, buf, n) != n)
5980 mz_zip_writer_end(pZip);
5984 size_to_reserve_at_beginning -= n;
5985 }
while (size_to_reserve_at_beginning);
5991 mz_bool mz_zip_writer_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint flags)
5993 pZip->m_pWrite = mz_zip_file_write_func;
5994 pZip->m_pNeeds_keepalive = NULL;
5996 if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING)
5999 pZip->m_pIO_opaque = pZip;
6001 if (!mz_zip_writer_init_v2(pZip, 0, flags))
6004 pZip->m_pState->m_pFile = pFile;
6005 pZip->m_pState->m_file_archive_start_ofs =
MZ_FTELL64(pZip->m_pState->m_pFile);
6006 pZip->m_zip_type = MZ_ZIP_TYPE_CFILE;
6012 mz_bool mz_zip_writer_init_from_reader_v2(mz_zip_archive *pZip,
const char *pFilename, mz_uint flags)
6014 mz_zip_internal_state *pState;
6016 if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
6019 if (flags & MZ_ZIP_FLAG_WRITE_ZIP64)
6022 if (!pZip->m_pState->m_zip64)
6027 if (pZip->m_pState->m_zip64)
6029 if (pZip->m_total_files == MZ_UINT32_MAX)
6034 if (pZip->m_total_files == MZ_UINT16_MAX)
6041 pState = pZip->m_pState;
6043 if (pState->m_pFile)
6045#ifdef MINIZ_NO_STDIO
6049 if (pZip->m_pIO_opaque != pZip)
6052 if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE &&
6053 !(flags & MZ_ZIP_FLAG_READ_ALLOW_WRITING) )
6059 if (NULL == (pState->m_pFile =
MZ_FREOPEN(pFilename,
"r+b", pState->m_pFile)))
6067 pZip->m_pWrite = mz_zip_file_write_func;
6068 pZip->m_pNeeds_keepalive = NULL;
6071 else if (pState->m_pMem)
6074 if (pZip->m_pIO_opaque != pZip)
6077 pState->m_mem_capacity = pState->m_mem_size;
6078 pZip->m_pWrite = mz_zip_heap_write_func;
6079 pZip->m_pNeeds_keepalive = NULL;
6082 else if (!pZip->m_pWrite)
6087 pZip->m_archive_size = pZip->m_central_directory_file_ofs;
6088 pZip->m_central_directory_file_ofs = 0;
6095 pZip->m_zip_mode = MZ_ZIP_MODE_WRITING;
6100 mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip,
const char *pFilename)
6102 return mz_zip_writer_init_from_reader_v2(pZip, pFilename, 0);
6106 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)
6108 return mz_zip_writer_add_mem_ex(pZip, pArchive_name, pBuf, buf_size, NULL, 0, level_and_flags, 0, 0);
6113 mz_zip_archive *m_pZip;
6114 mz_uint64 m_cur_archive_file_ofs;
6115 mz_uint64 m_comp_size;
6116 } mz_zip_writer_add_state;
6118 static mz_bool mz_zip_writer_add_put_buf_callback(
const void *pBuf,
int len,
void *pUser)
6120 mz_zip_writer_add_state *pState = (mz_zip_writer_add_state *)pUser;
6121 if ((
int)pState->m_pZip->m_pWrite(pState->m_pZip->m_pIO_opaque, pState->m_cur_archive_file_ofs, pBuf, len) != len)
6124 pState->m_cur_archive_file_ofs += len;
6125 pState->m_comp_size += len;
6129#define MZ_ZIP64_MAX_LOCAL_EXTRA_FIELD_SIZE (sizeof(mz_uint16) * 2 + sizeof(mz_uint64) * 2)
6130#define MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE (sizeof(mz_uint16) * 2 + sizeof(mz_uint64) * 3)
6131 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)
6133 mz_uint8 *pDst = pBuf;
6134 mz_uint32 field_size = 0;
6137 MZ_WRITE_LE16(pDst + 2, 0);
6138 pDst +=
sizeof(mz_uint16) * 2;
6142 MZ_WRITE_LE64(pDst, *pUncomp_size);
6143 pDst +=
sizeof(mz_uint64);
6144 field_size +=
sizeof(mz_uint64);
6149 MZ_WRITE_LE64(pDst, *pComp_size);
6150 pDst +=
sizeof(mz_uint64);
6151 field_size +=
sizeof(mz_uint64);
6154 if (pLocal_header_ofs)
6156 MZ_WRITE_LE64(pDst, *pLocal_header_ofs);
6157 pDst +=
sizeof(mz_uint64);
6158 field_size +=
sizeof(mz_uint64);
6161 MZ_WRITE_LE16(pBuf + 2, field_size);
6163 return (mz_uint32)(pDst - pBuf);
6166 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)
6184 static mz_bool mz_zip_writer_create_central_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst,
6185 mz_uint16 filename_size, mz_uint16 extra_size, mz_uint16 comment_size,
6186 mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32,
6187 mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date,
6188 mz_uint64 local_header_ofs, mz_uint32 ext_attributes)
6209 static mz_bool mz_zip_writer_add_to_central_dir(mz_zip_archive *pZip,
const char *pFilename, mz_uint16 filename_size,
6210 const void *pExtra, mz_uint16 extra_size,
const void *pComment, mz_uint16 comment_size,
6211 mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32,
6212 mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date,
6213 mz_uint64 local_header_ofs, mz_uint32 ext_attributes,
6214 const char *user_extra_data, mz_uint user_extra_data_len)
6216 mz_zip_internal_state *pState = pZip->m_pState;
6217 mz_uint32 central_dir_ofs = (mz_uint32)pState->m_central_dir.m_size;
6218 size_t orig_central_dir_size = pState->m_central_dir.m_size;
6221 if (!pZip->m_pState->m_zip64)
6223 if (local_header_ofs > 0xFFFFFFFF)
6228 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)
6231 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))
6235 (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pFilename, filename_size)) ||
6236 (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pExtra, extra_size)) ||
6237 (!mz_zip_array_push_back(pZip, &pState->m_central_dir, user_extra_data, user_extra_data_len)) ||
6238 (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pComment, comment_size)) ||
6239 (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, ¢ral_dir_ofs, 1)))
6249 static mz_bool mz_zip_writer_validate_archive_name(
const char *pArchive_name)
6252 if (*pArchive_name ==
'/')
6260 static mz_uint mz_zip_writer_compute_padding_needed_for_file_alignment(mz_zip_archive *pZip)
6263 if (!pZip->m_file_offset_alignment)
6265 n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1));
6266 return (mz_uint)((pZip->m_file_offset_alignment - n) & (pZip->m_file_offset_alignment - 1));
6269 static mz_bool mz_zip_writer_write_zeros(mz_zip_archive *pZip, mz_uint64 cur_file_ofs, mz_uint32 n)
6272 memset(buf, 0, MZ_MIN(
sizeof(buf), n));
6275 mz_uint32 s = MZ_MIN(
sizeof(buf), n);
6276 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_file_ofs, buf, s) != s)
6285 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,
6286 mz_uint64 uncomp_size, mz_uint32 uncomp_crc32)
6288 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);
6291 mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip,
const char *pArchive_name,
const void *pBuf,
size_t buf_size,
const void *pComment, mz_uint16 comment_size,
6292 mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32, MZ_TIME_T *last_modified,
6293 const char *user_extra_data, mz_uint user_extra_data_len,
const char *user_extra_data_central, mz_uint user_extra_data_central_len)
6295 mz_uint16 method = 0, dos_time = 0, dos_date = 0;
6296 mz_uint level, ext_attributes = 0, num_alignment_padding_bytes;
6297 mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, comp_size = 0;
6298 size_t archive_name_size;
6300 tdefl_compressor *pComp = NULL;
6301 mz_bool store_data_uncompressed;
6302 mz_zip_internal_state *pState;
6303 mz_uint8 *pExtra_data = NULL;
6304 mz_uint32 extra_size = 0;
6305 mz_uint8 extra_data[MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE];
6306 mz_uint16 bit_flags = 0;
6308 if ((
int)level_and_flags < 0)
6311 if (uncomp_size || (buf_size && !(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)))
6314 if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME))
6317 level = level_and_flags & 0xF;
6318 store_data_uncompressed = ((!level) || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA));
6320 if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || ((buf_size) && (!pBuf)) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level >
MZ_UBER_COMPRESSION))
6323 pState = pZip->m_pState;
6325 if (pState->m_zip64)
6327 if (pZip->m_total_files == MZ_UINT32_MAX)
6332 if (pZip->m_total_files == MZ_UINT16_MAX)
6334 pState->m_zip64 = MZ_TRUE;
6337 if (((mz_uint64)buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF))
6339 pState->m_zip64 = MZ_TRUE;
6344 if ((!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (uncomp_size))
6347 if (!mz_zip_writer_validate_archive_name(pArchive_name))
6350#ifndef MINIZ_NO_TIME
6351 if (last_modified != NULL)
6353 mz_zip_time_t_to_dos_time(*last_modified, &dos_time, &dos_date);
6359 mz_zip_time_t_to_dos_time(cur_time, &dos_time, &dos_date);
6362 (void)last_modified;
6365 if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
6368 uncomp_size = buf_size;
6369 if (uncomp_size <= 3)
6372 store_data_uncompressed = MZ_TRUE;
6376 archive_name_size = strlen(pArchive_name);
6377 if (archive_name_size > MZ_UINT16_MAX)
6380 num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
6383 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)
6386 if (!pState->m_zip64)
6392 pState->m_zip64 = MZ_TRUE;
6397 if ((archive_name_size) && (pArchive_name[archive_name_size - 1] ==
'/'))
6403 if ((buf_size) || (uncomp_size))
6408 if ((!mz_zip_array_ensure_room(pZip, &pState->m_central_dir,
MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + (pState->m_zip64 ? MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE : 0))) || (!mz_zip_array_ensure_room(pZip, &pState->m_central_dir_offsets, 1)))
6411 if ((!store_data_uncompressed) && (buf_size))
6413 if (NULL == (pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1,
sizeof(tdefl_compressor))))
6417 if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes))
6419 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6423 local_dir_header_ofs += num_alignment_padding_bytes;
6424 if (pZip->m_file_offset_alignment)
6426 MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0);
6428 cur_archive_file_ofs += num_alignment_padding_bytes;
6430 MZ_CLEAR_ARR(local_dir_header);
6432 if (!store_data_uncompressed || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
6437 if (pState->m_zip64)
6439 if (uncomp_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX)
6441 pExtra_data = extra_data;
6442 extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
6443 (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
6446 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))
6449 if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header,
sizeof(local_dir_header)) !=
sizeof(local_dir_header))
6452 cur_archive_file_ofs +=
sizeof(local_dir_header);
6454 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
6456 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6459 cur_archive_file_ofs += archive_name_size;
6461 if (pExtra_data != NULL)
6463 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, extra_data, extra_size) != extra_size)
6466 cur_archive_file_ofs += extra_size;
6471 if ((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX))
6473 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))
6476 if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header,
sizeof(local_dir_header)) !=
sizeof(local_dir_header))
6479 cur_archive_file_ofs +=
sizeof(local_dir_header);
6481 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
6483 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6486 cur_archive_file_ofs += archive_name_size;
6489 if (user_extra_data_len > 0)
6491 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len)
6494 cur_archive_file_ofs += user_extra_data_len;
6497 if (store_data_uncompressed)
6499 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pBuf, buf_size) != buf_size)
6501 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6505 cur_archive_file_ofs += buf_size;
6506 comp_size = buf_size;
6510 mz_zip_writer_add_state state;
6512 state.m_pZip = pZip;
6513 state.m_cur_archive_file_ofs = cur_archive_file_ofs;
6514 state.m_comp_size = 0;
6516 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) ||
6517 (tdefl_compress_buffer(pComp, pBuf, buf_size, TDEFL_FINISH) != TDEFL_STATUS_DONE))
6519 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6523 comp_size = state.m_comp_size;
6524 cur_archive_file_ofs = state.m_cur_archive_file_ofs;
6527 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6538 MZ_WRITE_LE32(local_dir_footer + 4, uncomp_crc32);
6539 if (pExtra_data == NULL)
6541 if (comp_size > MZ_UINT32_MAX)
6544 MZ_WRITE_LE32(local_dir_footer + 8, comp_size);
6545 MZ_WRITE_LE32(local_dir_footer + 12, uncomp_size);
6549 MZ_WRITE_LE64(local_dir_footer + 8, comp_size);
6550 MZ_WRITE_LE64(local_dir_footer + 16, uncomp_size);
6554 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_footer, local_dir_footer_size) != local_dir_footer_size)
6557 cur_archive_file_ofs += local_dir_footer_size;
6560 if (pExtra_data != NULL)
6562 extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
6563 (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
6566 if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, pExtra_data, (mz_uint16)extra_size, pComment,
6567 comment_size, uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, dos_date, local_dir_header_ofs, ext_attributes,
6568 user_extra_data_central, user_extra_data_central_len))
6571 pZip->m_total_files++;
6572 pZip->m_archive_size = cur_archive_file_ofs;
6577 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,
6578 const char *user_extra_data, mz_uint user_extra_data_len,
const char *user_extra_data_central, mz_uint user_extra_data_central_len)
6580 mz_uint16 gen_flags;
6581 mz_uint uncomp_crc32 =
MZ_CRC32_INIT, level, num_alignment_padding_bytes;
6582 mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0;
6583 mz_uint64 local_dir_header_ofs, cur_archive_file_ofs = pZip->m_archive_size, uncomp_size = 0, comp_size = 0;
6584 size_t archive_name_size;
6586 mz_uint8 *pExtra_data = NULL;
6587 mz_uint32 extra_size = 0;
6588 mz_uint8 extra_data[MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE];
6589 mz_zip_internal_state *pState;
6590 mz_uint64 file_ofs = 0, cur_archive_header_file_ofs;
6592 if ((
int)level_and_flags < 0)
6594 level = level_and_flags & 0xF;
6598 if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME))
6602 if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level >
MZ_UBER_COMPRESSION))
6605 pState = pZip->m_pState;
6607 if ((!pState->m_zip64) && (max_size > MZ_UINT32_MAX))
6611 pState->m_zip64 = MZ_TRUE;
6615 if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)
6618 if (!mz_zip_writer_validate_archive_name(pArchive_name))
6621 if (pState->m_zip64)
6623 if (pZip->m_total_files == MZ_UINT32_MAX)
6628 if (pZip->m_total_files == MZ_UINT16_MAX)
6630 pState->m_zip64 = MZ_TRUE;
6635 archive_name_size = strlen(pArchive_name);
6636 if (archive_name_size > MZ_UINT16_MAX)
6639 num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
6642 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)
6645 if (!pState->m_zip64)
6650 pState->m_zip64 = MZ_TRUE;
6655#ifndef MINIZ_NO_TIME
6658 mz_zip_time_t_to_dos_time(*pFile_time, &dos_time, &dos_date);
6667 if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes))
6672 cur_archive_file_ofs += num_alignment_padding_bytes;
6673 local_dir_header_ofs = cur_archive_file_ofs;
6675 if (pZip->m_file_offset_alignment)
6677 MZ_ASSERT((cur_archive_file_ofs & (pZip->m_file_offset_alignment - 1)) == 0);
6680 if (max_size && level)
6685 MZ_CLEAR_ARR(local_dir_header);
6686 if (pState->m_zip64)
6688 if (max_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX)
6690 pExtra_data = extra_data;
6691 if (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE)
6692 extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (max_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
6693 (max_size >= MZ_UINT32_MAX) ? &comp_size : NULL,
6694 (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
6696 extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, NULL,
6698 (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
6701 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))
6704 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_header,
sizeof(local_dir_header)) !=
sizeof(local_dir_header))
6707 cur_archive_file_ofs +=
sizeof(local_dir_header);
6709 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
6714 cur_archive_file_ofs += archive_name_size;
6716 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, extra_data, extra_size) != extra_size)
6719 cur_archive_file_ofs += extra_size;
6723 if ((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX))
6725 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))
6728 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_header,
sizeof(local_dir_header)) !=
sizeof(local_dir_header))
6731 cur_archive_file_ofs +=
sizeof(local_dir_header);
6733 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
6738 cur_archive_file_ofs += archive_name_size;
6741 if (user_extra_data_len > 0)
6743 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len)
6746 cur_archive_file_ofs += user_extra_data_len;
6751 void *pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, MZ_ZIP_MAX_IO_BUF_SIZE);
6761 size_t n = read_callback(callback_opaque, file_ofs, pRead_buf, MZ_ZIP_MAX_IO_BUF_SIZE);
6765 if ((n > MZ_ZIP_MAX_IO_BUF_SIZE) || (file_ofs + n > max_size))
6767 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6770 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf, n) != n)
6772 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6776 uncomp_crc32 = (mz_uint32)
mz_crc32(uncomp_crc32, (
const mz_uint8 *)pRead_buf, n);
6777 cur_archive_file_ofs += n;
6779 uncomp_size = file_ofs;
6780 comp_size = uncomp_size;
6784 mz_bool result = MZ_FALSE;
6785 mz_zip_writer_add_state state;
6786 tdefl_compressor *pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1,
sizeof(tdefl_compressor));
6789 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6793 state.m_pZip = pZip;
6794 state.m_cur_archive_file_ofs = cur_archive_file_ofs;
6795 state.m_comp_size = 0;
6797 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)
6799 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6800 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6806 tdefl_status status;
6807 tdefl_flush flush = TDEFL_NO_FLUSH;
6809 size_t n = read_callback(callback_opaque, file_ofs, pRead_buf, MZ_ZIP_MAX_IO_BUF_SIZE);
6810 if ((n > MZ_ZIP_MAX_IO_BUF_SIZE) || (file_ofs + n > max_size))
6817 uncomp_crc32 = (mz_uint32)
mz_crc32(uncomp_crc32, (
const mz_uint8 *)pRead_buf, n);
6819 if (pZip->m_pNeeds_keepalive != NULL && pZip->m_pNeeds_keepalive(pZip->m_pIO_opaque))
6820 flush = TDEFL_FULL_FLUSH;
6823 flush = TDEFL_FINISH;
6825 status = tdefl_compress_buffer(pComp, pRead_buf, n, flush);
6826 if (status == TDEFL_STATUS_DONE)
6831 else if (status != TDEFL_STATUS_OKAY)
6838 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6842 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6846 uncomp_size = file_ofs;
6847 comp_size = state.m_comp_size;
6848 cur_archive_file_ofs = state.m_cur_archive_file_ofs;
6851 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6854 if (!(level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE))
6860 MZ_WRITE_LE32(local_dir_footer + 4, uncomp_crc32);
6861 if (pExtra_data == NULL)
6863 if (comp_size > MZ_UINT32_MAX)
6866 MZ_WRITE_LE32(local_dir_footer + 8, comp_size);
6867 MZ_WRITE_LE32(local_dir_footer + 12, uncomp_size);
6871 MZ_WRITE_LE64(local_dir_footer + 8, comp_size);
6872 MZ_WRITE_LE64(local_dir_footer + 16, uncomp_size);
6876 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, local_dir_footer, local_dir_footer_size) != local_dir_footer_size)
6879 cur_archive_file_ofs += local_dir_footer_size;
6882 if (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE)
6884 if (pExtra_data != NULL)
6886 extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (max_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
6887 (max_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
6890 if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header,
6891 (mz_uint16)archive_name_size, (mz_uint16)(extra_size + user_extra_data_len),
6892 (max_size >= MZ_UINT32_MAX) ? MZ_UINT32_MAX : uncomp_size,
6893 (max_size >= MZ_UINT32_MAX) ? MZ_UINT32_MAX : comp_size,
6894 uncomp_crc32, method, gen_flags, dos_time, dos_date))
6897 cur_archive_header_file_ofs = local_dir_header_ofs;
6899 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs, local_dir_header,
sizeof(local_dir_header)) !=
sizeof(local_dir_header))
6902 if (pExtra_data != NULL)
6904 cur_archive_header_file_ofs +=
sizeof(local_dir_header);
6906 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
6911 cur_archive_header_file_ofs += archive_name_size;
6913 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs, extra_data, extra_size) != extra_size)
6916 cur_archive_header_file_ofs += extra_size;
6920 if (pExtra_data != NULL)
6922 extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
6923 (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
6926 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,
6927 uncomp_size, comp_size, uncomp_crc32, method, gen_flags, dos_time, dos_date, local_dir_header_ofs, ext_attributes,
6928 user_extra_data_central, user_extra_data_central_len))
6931 pZip->m_total_files++;
6932 pZip->m_archive_size = cur_archive_file_ofs;
6937#ifndef MINIZ_NO_STDIO
6939 static size_t mz_file_read_func_stdio(
void *pOpaque, mz_uint64 file_ofs,
void *pBuf,
size_t n)
6941 MZ_FILE *pSrc_file = (MZ_FILE *)pOpaque;
6944 if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (
MZ_FSEEK64(pSrc_file, (mz_int64)file_ofs, SEEK_SET))))
6947 return MZ_FREAD(pBuf, 1, n, pSrc_file);
6950 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,
6951 const char *user_extra_data, mz_uint user_extra_data_len,
const char *user_extra_data_central, mz_uint user_extra_data_central_len)
6953 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,
6954 user_extra_data, user_extra_data_len, user_extra_data_central, user_extra_data_central_len);
6957 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)
6959 MZ_FILE *pSrc_file = NULL;
6960 mz_uint64 uncomp_size = 0;
6961 MZ_TIME_T file_modified_time;
6962 MZ_TIME_T *pFile_time = NULL;
6965 memset(&file_modified_time, 0,
sizeof(file_modified_time));
6967#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_STDIO)
6968 pFile_time = &file_modified_time;
6969 if (!mz_zip_get_file_modified_time(pSrc_filename, &file_modified_time))
6973 pSrc_file =
MZ_FOPEN(pSrc_filename,
"rb");
6981 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);
6989 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)
6992 if (!mz_zip_array_reserve(pZip, pNew_ext, ext_len + 64, MZ_FALSE))
6997 if ((pUncomp_size) || (pComp_size) || (pLocal_header_ofs) || (pDisk_start))
6999 mz_uint8 new_ext_block[64];
7000 mz_uint8 *pDst = new_ext_block;
7002 mz_write_le16(pDst +
sizeof(mz_uint16), 0);
7003 pDst +=
sizeof(mz_uint16) * 2;
7007 mz_write_le64(pDst, *pUncomp_size);
7008 pDst +=
sizeof(mz_uint64);
7013 mz_write_le64(pDst, *pComp_size);
7014 pDst +=
sizeof(mz_uint64);
7017 if (pLocal_header_ofs)
7019 mz_write_le64(pDst, *pLocal_header_ofs);
7020 pDst +=
sizeof(mz_uint64);
7025 mz_write_le32(pDst, *pDisk_start);
7026 pDst +=
sizeof(mz_uint32);
7029 mz_write_le16(new_ext_block +
sizeof(mz_uint16), (mz_uint16)((pDst - new_ext_block) -
sizeof(mz_uint16) * 2));
7031 if (!mz_zip_array_push_back(pZip, pNew_ext, new_ext_block, pDst - new_ext_block))
7035 if ((pExt) && (ext_len))
7037 mz_uint32 extra_size_remaining = ext_len;
7038 const mz_uint8 *pExtra_data = pExt;
7042 mz_uint32 field_id, field_data_size, field_total_size;
7044 if (extra_size_remaining < (
sizeof(mz_uint16) * 2))
7047 field_id = MZ_READ_LE16(pExtra_data);
7048 field_data_size = MZ_READ_LE16(pExtra_data +
sizeof(mz_uint16));
7049 field_total_size = field_data_size +
sizeof(mz_uint16) * 2;
7051 if (field_total_size > extra_size_remaining)
7056 if (!mz_zip_array_push_back(pZip, pNew_ext, pExtra_data, field_total_size))
7060 pExtra_data += field_total_size;
7061 extra_size_remaining -= field_total_size;
7062 }
while (extra_size_remaining);
7069 mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint src_file_index)
7071 mz_uint n, bit_flags, num_alignment_padding_bytes, src_central_dir_following_data_size;
7072 mz_uint64 src_archive_bytes_remaining, local_dir_header_ofs;
7073 mz_uint64 cur_src_file_ofs, cur_dst_file_ofs;
7075 mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
7077 size_t orig_central_dir_size;
7078 mz_zip_internal_state *pState;
7080 const mz_uint8 *pSrc_central_header;
7081 mz_zip_archive_file_stat src_file_stat;
7082 mz_uint32 src_filename_len, src_comment_len, src_ext_len;
7083 mz_uint32 local_header_filename_size, local_header_extra_len;
7084 mz_uint64 local_header_comp_size, local_header_uncomp_size;
7085 mz_bool found_zip64_ext_data_in_ldir = MZ_FALSE;
7088 if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pSource_zip->m_pRead))
7091 pState = pZip->m_pState;
7094 if ((pSource_zip->m_pState->m_zip64) && (!pZip->m_pState->m_zip64))
7098 if (NULL == (pSrc_central_header =
mz_zip_get_cdh(pSource_zip, src_file_index)))
7107 src_central_dir_following_data_size = src_filename_len + src_ext_len + src_comment_len;
7113 num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
7115 if (!pState->m_zip64)
7117 if (pZip->m_total_files == MZ_UINT16_MAX)
7123 if (pZip->m_total_files == MZ_UINT32_MAX)
7130 cur_src_file_ofs = src_file_stat.m_local_header_ofs;
7131 cur_dst_file_ofs = pZip->m_archive_size;
7147 src_archive_bytes_remaining = src_file_stat.m_comp_size + local_header_filename_size + local_header_extra_len;
7150 if ((local_header_extra_len) && ((local_header_comp_size == MZ_UINT32_MAX) || (local_header_uncomp_size == MZ_UINT32_MAX)))
7153 const mz_uint8 *pExtra_data;
7154 mz_uint32 extra_size_remaining = local_header_extra_len;
7162 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)
7168 pExtra_data = (
const mz_uint8 *)file_data_array.
m_p;
7172 mz_uint32 field_id, field_data_size, field_total_size;
7174 if (extra_size_remaining < (
sizeof(mz_uint16) * 2))
7180 field_id = MZ_READ_LE16(pExtra_data);
7181 field_data_size = MZ_READ_LE16(pExtra_data +
sizeof(mz_uint16));
7182 field_total_size = field_data_size +
sizeof(mz_uint16) * 2;
7184 if (field_total_size > extra_size_remaining)
7192 const mz_uint8 *pSrc_field_data = pExtra_data +
sizeof(mz_uint32);
7194 if (field_data_size <
sizeof(mz_uint64) * 2)
7200 local_header_uncomp_size = MZ_READ_LE64(pSrc_field_data);
7201 local_header_comp_size = MZ_READ_LE64(pSrc_field_data +
sizeof(mz_uint64));
7203 found_zip64_ext_data_in_ldir = MZ_TRUE;
7207 pExtra_data += field_total_size;
7208 extra_size_remaining -= field_total_size;
7209 }
while (extra_size_remaining);
7214 if (!pState->m_zip64)
7218 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) +
7221 if (approx_new_archive_size >= MZ_UINT32_MAX)
7226 if (!mz_zip_writer_write_zeros(pZip, cur_dst_file_ofs, num_alignment_padding_bytes))
7229 cur_dst_file_ofs += num_alignment_padding_bytes;
7231 local_dir_header_ofs = cur_dst_file_ofs;
7232 if (pZip->m_file_offset_alignment)
7234 MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0);
7244 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)))))
7247 while (src_archive_bytes_remaining)
7249 n = (mz_uint)MZ_MIN((mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE, src_archive_bytes_remaining);
7250 if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, n) != n)
7252 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
7255 cur_src_file_ofs += n;
7257 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n)
7259 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
7262 cur_dst_file_ofs += n;
7264 src_archive_bytes_remaining -= n;
7272 if ((pSource_zip->m_pState->m_zip64) || (found_zip64_ext_data_in_ldir))
7281 if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, (
sizeof(mz_uint32) * 6)) != (
sizeof(mz_uint32) * 6))
7283 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
7294 if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf,
sizeof(mz_uint32) * 4) !=
sizeof(mz_uint32) * 4)
7296 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
7302 if (pZip->m_pState->m_zip64)
7305 const mz_uint8 *pSrc_descriptor = (
const mz_uint8 *)pBuf + (
has_id ?
sizeof(mz_uint32) : 0);
7306 const mz_uint32 src_crc32 = MZ_READ_LE32(pSrc_descriptor);
7307 const mz_uint64 src_comp_size = MZ_READ_LE32(pSrc_descriptor +
sizeof(mz_uint32));
7308 const mz_uint64 src_uncomp_size = MZ_READ_LE32(pSrc_descriptor + 2 *
sizeof(mz_uint32));
7311 mz_write_le32((mz_uint8 *)pBuf +
sizeof(mz_uint32) * 1, src_crc32);
7312 mz_write_le64((mz_uint8 *)pBuf +
sizeof(mz_uint32) * 2, src_comp_size);
7313 mz_write_le64((mz_uint8 *)pBuf +
sizeof(mz_uint32) * 4, src_uncomp_size);
7315 n =
sizeof(mz_uint32) * 6;
7320 n =
sizeof(mz_uint32) * (
has_id ? 4 : 3);
7324 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n)
7326 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
7330 cur_src_file_ofs += n;
7331 cur_dst_file_ofs += n;
7333 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
7336 orig_central_dir_size = pState->m_central_dir.m_size;
7340 if (pState->m_zip64)
7352 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))
7373 if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, new_ext_block.
m_p, new_ext_block.
m_size))
7380 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))
7392 if (cur_dst_file_ofs > MZ_UINT32_MAX)
7395 if (local_dir_header_ofs >= MZ_UINT32_MAX)
7403 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))
7411 if (pState->m_central_dir.m_size >= MZ_UINT32_MAX)
7418 n = (mz_uint32)orig_central_dir_size;
7419 if (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &n, 1))
7425 pZip->m_total_files++;
7426 pZip->m_archive_size = cur_dst_file_ofs;
7431 mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip)
7433 mz_zip_internal_state *pState;
7434 mz_uint64 central_dir_ofs, central_dir_size;
7437 if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING))
7440 pState = pZip->m_pState;
7442 if (pState->m_zip64)
7444 if ((mz_uint64)pState->m_central_dir.m_size >= MZ_UINT32_MAX)
7453 central_dir_ofs = 0;
7454 central_dir_size = 0;
7455 if (pZip->m_total_files)
7458 central_dir_ofs = pZip->m_archive_size;
7459 central_dir_size = pState->m_central_dir.m_size;
7460 pZip->m_central_directory_file_ofs = central_dir_ofs;
7461 if (pZip->m_pWrite(pZip->m_pIO_opaque, central_dir_ofs, pState->m_central_dir.m_p, (
size_t)central_dir_size) != central_dir_size)
7464 pZip->m_archive_size += central_dir_size;
7467 if (pState->m_zip64)
7470 mz_uint64 rel_ofs_to_zip64_ecdr = pZip->m_archive_size;
7508#ifndef MINIZ_NO_STDIO
7509 if ((pState->m_pFile) && (
MZ_FFLUSH(pState->m_pFile) == EOF))
7515 pZip->m_zip_mode = MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED;
7519 mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip,
void **ppBuf,
size_t *pSize)
7521 if ((!ppBuf) || (!pSize))
7527 if ((!pZip) || (!pZip->m_pState))
7530 if (pZip->m_pWrite != mz_zip_heap_write_func)
7533 if (!mz_zip_writer_finalize_archive(pZip))
7536 *ppBuf = pZip->m_pState->m_pMem;
7537 *pSize = pZip->m_pState->m_mem_size;
7538 pZip->m_pState->m_pMem = NULL;
7539 pZip->m_pState->m_mem_size = pZip->m_pState->m_mem_capacity = 0;
7544 mz_bool mz_zip_writer_end(mz_zip_archive *pZip)
7546 return mz_zip_writer_end_internal(pZip, MZ_TRUE);
7550#ifndef MINIZ_NO_STDIO
7551 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)
7553 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);
7556 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)
7558 mz_bool status, created_new_archive = MZ_FALSE;
7559 mz_zip_archive zip_archive;
7561 mz_zip_error actual_err = MZ_ZIP_NO_ERROR;
7564 if ((
int)level_and_flags < 0)
7567 if ((!pZip_filename) || (!pArchive_name) || ((buf_size) && (!pBuf)) || ((comment_size) && (!pComment)) || ((level_and_flags & 0xF) >
MZ_UBER_COMPRESSION))
7570 *pErr = MZ_ZIP_INVALID_PARAMETER;
7574 if (!mz_zip_writer_validate_archive_name(pArchive_name))
7577 *pErr = MZ_ZIP_INVALID_FILENAME;
7586 if (!mz_zip_writer_init_file_v2(&zip_archive, pZip_filename, 0, level_and_flags))
7589 *pErr = zip_archive.m_last_error;
7593 created_new_archive = MZ_TRUE;
7598 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))
7601 *pErr = zip_archive.m_last_error;
7605 if (!mz_zip_writer_init_from_reader_v2(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_READ_ALLOW_WRITING))
7608 *pErr = zip_archive.m_last_error;
7616 status = mz_zip_writer_add_mem_ex(&zip_archive, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, 0, 0);
7617 actual_err = zip_archive.m_last_error;
7620 if (!mz_zip_writer_finalize_archive(&zip_archive))
7623 actual_err = zip_archive.m_last_error;
7628 if (!mz_zip_writer_end_internal(&zip_archive, status))
7631 actual_err = zip_archive.m_last_error;
7636 if ((!status) && (created_new_archive))
7640 (void)ignoredStatus;
7649 void *mz_zip_extract_archive_file_to_heap_v2(
const char *pZip_filename,
const char *pArchive_name,
const char *pComment,
size_t *pSize, mz_uint flags, mz_zip_error *pErr)
7651 mz_uint32 file_index;
7652 mz_zip_archive zip_archive;
7658 if ((!pZip_filename) || (!pArchive_name))
7661 *pErr = MZ_ZIP_INVALID_PARAMETER;
7670 *pErr = zip_archive.m_last_error;
7683 *pErr = zip_archive.m_last_error;
7688 void *mz_zip_extract_archive_file_to_heap(
const char *pZip_filename,
const char *pArchive_name,
size_t *pSize, mz_uint flags)
7690 return mz_zip_extract_archive_file_to_heap_v2(pZip_filename, pArchive_name, NULL, pSize, flags, NULL);
7701 return pZip ? pZip->m_zip_mode : MZ_ZIP_MODE_INVALID;
7706 return pZip ? pZip->m_zip_type : MZ_ZIP_TYPE_INVALID;
7711 mz_zip_error prev_err;
7714 return MZ_ZIP_INVALID_PARAMETER;
7716 prev_err = pZip->m_last_error;
7718 pZip->m_last_error = err_num;
7725 return MZ_ZIP_INVALID_PARAMETER;
7727 return pZip->m_last_error;
7737 mz_zip_error prev_err;
7740 return MZ_ZIP_INVALID_PARAMETER;
7742 prev_err = pZip->m_last_error;
7744 pZip->m_last_error = MZ_ZIP_NO_ERROR;
7752 case MZ_ZIP_NO_ERROR:
7754 case MZ_ZIP_UNDEFINED_ERROR:
7755 return "undefined error";
7756 case MZ_ZIP_TOO_MANY_FILES:
7757 return "too many files";
7758 case MZ_ZIP_FILE_TOO_LARGE:
7759 return "file too large";
7760 case MZ_ZIP_UNSUPPORTED_METHOD:
7761 return "unsupported method";
7762 case MZ_ZIP_UNSUPPORTED_ENCRYPTION:
7763 return "unsupported encryption";
7764 case MZ_ZIP_UNSUPPORTED_FEATURE:
7765 return "unsupported feature";
7766 case MZ_ZIP_FAILED_FINDING_CENTRAL_DIR:
7767 return "failed finding central directory";
7768 case MZ_ZIP_NOT_AN_ARCHIVE:
7769 return "not a ZIP archive";
7770 case MZ_ZIP_INVALID_HEADER_OR_CORRUPTED:
7771 return "invalid header or archive is corrupted";
7772 case MZ_ZIP_UNSUPPORTED_MULTIDISK:
7773 return "unsupported multidisk archive";
7774 case MZ_ZIP_DECOMPRESSION_FAILED:
7775 return "decompression failed or archive is corrupted";
7776 case MZ_ZIP_COMPRESSION_FAILED:
7777 return "compression failed";
7778 case MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE:
7779 return "unexpected decompressed size";
7780 case MZ_ZIP_CRC_CHECK_FAILED:
7781 return "CRC-32 check failed";
7782 case MZ_ZIP_UNSUPPORTED_CDIR_SIZE:
7783 return "unsupported central directory size";
7784 case MZ_ZIP_ALLOC_FAILED:
7785 return "allocation failed";
7786 case MZ_ZIP_FILE_OPEN_FAILED:
7787 return "file open failed";
7788 case MZ_ZIP_FILE_CREATE_FAILED:
7789 return "file create failed";
7790 case MZ_ZIP_FILE_WRITE_FAILED:
7791 return "file write failed";
7792 case MZ_ZIP_FILE_READ_FAILED:
7793 return "file read failed";
7794 case MZ_ZIP_FILE_CLOSE_FAILED:
7795 return "file close failed";
7796 case MZ_ZIP_FILE_SEEK_FAILED:
7797 return "file seek failed";
7798 case MZ_ZIP_FILE_STAT_FAILED:
7799 return "file stat failed";
7800 case MZ_ZIP_INVALID_PARAMETER:
7801 return "invalid parameter";
7802 case MZ_ZIP_INVALID_FILENAME:
7803 return "invalid filename";
7804 case MZ_ZIP_BUF_TOO_SMALL:
7805 return "buffer too small";
7806 case MZ_ZIP_INTERNAL_ERROR:
7807 return "internal error";
7808 case MZ_ZIP_FILE_NOT_FOUND:
7809 return "file not found";
7810 case MZ_ZIP_ARCHIVE_TOO_LARGE:
7811 return "archive is too large";
7812 case MZ_ZIP_VALIDATION_FAILED:
7813 return "validation failed";
7814 case MZ_ZIP_WRITE_CALLBACK_FAILED:
7815 return "write callback failed";
7816 case MZ_ZIP_TOTAL_ERRORS:
7817 return "total errors";
7822 return "unknown error";
7828 if ((!pZip) || (!pZip->m_pState))
7831 return pZip->m_pState->m_zip64;
7836 if ((!pZip) || (!pZip->m_pState))
7839 return pZip->m_pState->m_central_dir.m_size;
7844 return pZip ? pZip->m_total_files : 0;
7851 return pZip->m_archive_size;
7856 if ((!pZip) || (!pZip->m_pState))
7858 return pZip->m_pState->m_file_archive_start_ofs;
7863 if ((!pZip) || (!pZip->m_pState))
7865 return pZip->m_pState->m_pFile;
7870 if ((!pZip) || (!pZip->m_pState) || (!pBuf) || (!pZip->m_pRead))
7873 return pZip->m_pRead(pZip->m_pIO_opaque, file_ofs, pBuf, n);
7882 if (filename_buf_size)
7883 pFilename[0] =
'\0';
7888 if (filename_buf_size)
7890 n = MZ_MIN(n, filename_buf_size - 1);
7892 pFilename[n] =
'\0';
7907 if (pZip->m_zip_mode == MZ_ZIP_MODE_READING)
7909#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
7910 else if ((pZip->m_zip_mode == MZ_ZIP_MODE_WRITING) || (pZip->m_zip_mode == MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED))
7911 return mz_zip_writer_end(pZip);
static bool has_id(const jsont &json)
Return true iff the argument has a "@id" key.
#define TINFL_HUFF_DECODE(state_index, sym, pLookUp, pTree)
mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len)
mz_bool mz_zip_is_zip64(mz_zip_archive *pZip)
mz_bool mz_zip_reader_end(mz_zip_archive *pZip)
mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags)
mz_zip_type mz_zip_get_type(mz_zip_archive *pZip)
static size_t mz_zip_file_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
mz_bool mz_zip_end(mz_zip_archive *pZip)
mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip)
static void mz_zip_reader_sort_central_dir_offsets_by_filename(mz_zip_archive *pZip)
mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags)
#define TINFL_GET_BYTE(state_index, c)
#define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size)
size_t mz_zip_get_central_dir_size(mz_zip_archive *pZip)
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)
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)
mz_zip_reader_extract_iter_state * mz_zip_reader_extract_iter_new(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags)
static mz_bool mz_zip_reader_locate_header_sig(mz_zip_archive *pZip, mz_uint32 record_sig, mz_uint32 record_size, mz_int64 *pOfs)
mz_zip_mode mz_zip_get_mode(mz_zip_archive *pZip)
#define MZ_FREOPEN(f, m, s)
MINIZ_EXPORT void * miniz_def_alloc_func(void *opaque, size_t items, size_t size)
MINIZ_EXPORT void * miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size)
size_t mz_zip_read_archive_data(mz_zip_archive *pZip, mz_uint64 file_ofs, void *pBuf, size_t n)
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)
mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index)
void * tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
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)
unsigned char mz_validate_uint32[sizeof(mz_uint32)==4 ? 1 :-1]
#define TINFL_MEMCPY(d, s, l)
#define TINFL_GET_BITS(state_index, b, n)
mz_bool mz_zip_reader_locate_file_v2(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags, mz_uint32 *pIndex)
static void tinfl_clear_tree(tinfl_decompressor *r)
static mz_bool mz_zip_reader_init_internal(mz_zip_archive *pZip, mz_uint flags)
static mz_bool mz_zip_reader_end_internal(mz_zip_archive *pZip, mz_bool set_last_error)
mz_zip_error mz_zip_peek_last_error(mz_zip_archive *pZip)
mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint flags)
mz_zip_error mz_zip_get_last_error(mz_zip_archive *pZip)
mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags)
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)
mz_bool mz_zip_validate_file_archive(const char *pFilename, mz_uint flags, mz_zip_error *pErr)
mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint flags)
const char * mz_version(void)
static size_t mz_zip_file_write_callback(void *pOpaque, mz_uint64 ofs, const void *pBuf, size_t n)
static MZ_FORCEINLINE void mz_zip_array_init(mz_zip_array *pArray, mz_uint32 element_size)
const char * mz_zip_get_error_string(mz_zip_error mz_err)
void * mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags)
static MZ_FORCEINLINE const mz_uint8 * mz_zip_get_cdh(mz_zip_archive *pZip, mz_uint file_index)
static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flags)
#define TINFL_MEMSET(p, c, l)
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)
int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags)
mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index)
mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
void mz_zip_zero_struct(mz_zip_archive *pZip)
static MZ_FORCEINLINE void mz_zip_array_clear(mz_zip_archive *pZip, mz_zip_array *pArray)
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)
mz_uint64 mz_zip_get_archive_size(mz_zip_archive *pZip)
size_t mz_zip_reader_extract_iter_read(mz_zip_reader_extract_iter_state *pState, void *pvBuf, size_t buf_size)
MZ_FILE * mz_zip_get_cfile(mz_zip_archive *pZip)
@ MZ_ZIP64_ECDH_VERSION_MADE_BY_OFS
@ MZ_ZIP_CDH_FILENAME_LEN_OFS
@ MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR
@ MZ_ZIP_LOCAL_DIR_HEADER_SIG
@ MZ_ZIP_CDH_FILE_DATE_OFS
@ MZ_ZIP_LDH_BIT_FLAG_OFS
@ MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS
@ MZ_ZIP_CDH_VERSION_NEEDED_OFS
@ MZ_ZIP_DATA_DESCRIPTER_SIZE64
@ MZ_ZIP_CDH_LOCAL_HEADER_OFS
@ MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG
@ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8
@ MZ_ZIP64_ECDH_NUM_DISK_CDIR_OFS
@ MZ_ZIP_CDH_COMPRESSED_SIZE_OFS
@ MZ_ZIP_DATA_DESCRIPTER_SIZE32
@ MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS
@ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG
@ MZ_ZIP64_ECDL_NUM_DISK_CDIR_OFS
@ MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS
@ MZ_ZIP_ECDH_CDIR_SIZE_OFS
@ MZ_ZIP_LDH_FILENAME_LEN_OFS
@ MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE
@ MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG
@ MZ_ZIP_LDH_FILE_TIME_OFS
@ MZ_ZIP64_ECDH_VERSION_NEEDED_OFS
@ MZ_ZIP_CDH_EXTRA_LEN_OFS
@ MZ_ZIP_LDH_FILE_DATE_OFS
@ MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS
@ MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS
@ MZ_ZIP_LDH_COMPRESSED_SIZE_OFS
@ MZ_ZIP_CDH_FILE_TIME_OFS
@ MZ_ZIP_VERSION_MADE_BY_DOS_FILESYSTEM_ID
@ MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS
@ MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID
@ MZ_ZIP_CENTRAL_DIR_HEADER_SIG
@ MZ_ZIP_ECDH_COMMENT_SIZE_OFS
@ MZ_ZIP64_ECDH_CDIR_SIZE_OFS
@ MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS
@ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION
@ MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG
@ MZ_ZIP_CDH_DISK_START_OFS
@ MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS
@ MZ_ZIP_CDH_INTERNAL_ATTR_OFS
@ MZ_ZIP_LDH_VERSION_NEEDED_OFS
@ MZ_ZIP_ECDH_CDIR_OFS_OFS
@ MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG
@ MZ_ZIP_LDH_EXTRA_LEN_OFS
@ MZ_ZIP_CDH_EXTERNAL_ATTR_OFS
@ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_LOCAL_DIR_IS_MASKED
@ MZ_ZIP64_ECDH_NUM_THIS_DISK_OFS
@ MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE
@ MZ_ZIP_LOCAL_DIR_HEADER_SIZE
@ MZ_ZIP64_ECDH_CDIR_OFS_OFS
@ MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS
@ MZ_ZIP_CDH_BIT_FLAG_OFS
@ MZ_ZIP_CDH_COMMENT_LEN_OFS
@ MZ_ZIP_CENTRAL_DIR_HEADER_SIZE
@ MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE
@ MZ_ZIP_DATA_DESCRIPTOR_ID
@ MZ_ZIP_CDH_VERSION_MADE_BY_OFS
@ MZ_ZIP_ECDH_NUM_THIS_DISK_OFS
@ MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED
@ MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS
static size_t mz_zip_mem_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
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)
static MZ_FORCEINLINE mz_bool mz_zip_set_error(mz_zip_archive *pZip, mz_zip_error err_num)
mz_bool mz_zip_reader_is_file_supported(mz_zip_archive *pZip, mz_uint file_index)
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)
#define TINFL_CR_RETURN(state_index, result)
#define TINFL_CR_RETURN_FOREVER(state_index, result)
mz_zip_error mz_zip_set_last_error(mz_zip_archive *pZip, mz_zip_error err_num)
MINIZ_EXPORT void miniz_def_free_func(void *opaque, void *address)
tinfl_decompressor * tinfl_decompressor_alloc(void)
mz_zip_reader_extract_iter_state * mz_zip_reader_extract_file_iter_new(mz_zip_archive *pZip, const char *pFilename, mz_uint flags)
mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat)
static mz_bool mz_zip_locate_file_binary_search(mz_zip_archive *pZip, const char *pFilename, mz_uint32 *pIndex)
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)
mz_uint64 mz_zip_get_archive_file_start_offset(mz_zip_archive *pZip)
unsigned char mz_validate_uint64[sizeof(mz_uint64)==8 ? 1 :-1]
void * mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags)
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)
#define MZ_FILE_STAT_STRUCT
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)
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)
static MZ_FORCEINLINE mz_bool mz_zip_string_equal(const char *pA, const char *pB, mz_uint len, mz_uint flags)
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)
#define MZ_SWAP_UINT32(a, b)
mz_bool mz_zip_validate_mem_archive(const void *pMem, size_t size, mz_uint flags, mz_zip_error *pErr)
mz_bool mz_zip_validate_file(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags)
static size_t mz_zip_compute_crc32_callback(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index)
mz_bool mz_zip_reader_extract_iter_free(mz_zip_reader_extract_iter_state *pState)
mz_bool mz_zip_reader_extract_to_cfile(mz_zip_archive *pZip, mz_uint file_index, MZ_FILE *pFile, mz_uint flags)
mz_bool mz_zip_reader_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint64 archive_size, mz_uint flags)
unsigned char mz_validate_uint16[sizeof(mz_uint16)==2 ? 1 :-1]
mz_bool mz_zip_reader_extract_file_to_cfile(mz_zip_archive *pZip, const char *pArchive_filename, MZ_FILE *pFile, mz_uint flags)
static mz_bool mz_zip_array_ensure_capacity(mz_zip_archive *pZip, mz_zip_array *pArray, size_t min_new_capacity, mz_uint growing)
mz_zip_error mz_zip_clear_last_error(mz_zip_archive *pZip)
#define TINFL_SKIP_BITS(state_index, n)
static MZ_FORCEINLINE mz_bool mz_zip_array_resize(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_size, mz_uint growing)
mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags)
mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size)
void tinfl_decompressor_free(tinfl_decompressor *pDecomp)
static mz_bool mz_zip_reader_eocd64_valid(mz_zip_archive *pZip, uint64_t offset, uint8_t *buf)
mz_bool m_zip64_has_extended_info_fields
mz_zip_array m_sorted_central_dir_offsets
mz_uint64 m_file_archive_start_ofs
mz_zip_array m_central_dir_offsets
mz_zip_array m_central_dir