PolyVox  0.3.0-dev
Open source voxel management library
miniz.c
Go to the documentation of this file.
1 /*
2  * CHANGES FOR POLYVOX
3  * -------------------
4  * This file gave compiler warnings on certain versions of GCC (at least version 4.3.5 used by out build machine)
5  * and I did not want to risk tampering with the code to fix them.Therefore the only difference between this file
6  * and the official 'miniz.c' is the pragma below which disables warnings for this file in GCC.
7  */
8 #ifdef __GNUC__
9 #pragma GCC system_header
10 #endif
11 
12 /* miniz.c v1.14 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
13  See "unlicense" statement at the end of this file.
14  Rich Geldreich <richgel99@gmail.com>, last updated May 20, 2012
15  Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
16 
17  Most API's defined in miniz.c are optional. For example, to disable the archive related functions just define
18  MINIZ_NO_ARCHIVE_APIS, or to get rid of all stdio usage define MINIZ_NO_STDIO (see the list below for more macros).
19 
20  * Change History
21  5/20/12 v1.14 - MinGW32/64 GCC 4.6.1 compiler fixes: added MZ_FORCEINLINE, #include <time.h> (thanks fermtect).
22  5/19/12 v1.13 - From jason@cornsyrup.org and kelwert@mtu.edu - Fix mz_crc32() so it doesn't compute the wrong CRC-32's when mz_ulong is 64-bit.
23  Temporarily/locally slammed in "typedef unsigned long mz_ulong" and re-ran a randomized regression test on ~500k files.
24  Eliminated a bunch of warnings when compiling with GCC 32-bit/64.
25  Ran all examples, miniz.c, and tinfl.c through MSVC 2008's /analyze (static analysis) option and fixed all warnings (except for the silly
26  "Use of the comma-operator in a tested expression.." analysis warning, which I purposely use to work around a MSVC compiler warning).
27  Created 32-bit and 64-bit Codeblocks projects/workspace. Built and tested Linux executables. The codeblocks workspace is compatible with Linux+Win32/x64.
28  Added miniz_tester solution/project, which is a useful little app derived from LZHAM's tester app that I use as part of the regression test.
29  Ran miniz.c and tinfl.c through another series of regression testing on ~500,000 files and archives.
30  Modified example5.c so it purposely disables a bunch of high-level functionality (MINIZ_NO_STDIO, etc.). (Thanks to corysama for the MINIZ_NO_STDIO bug report.)
31  Fix ftell() usage in examples so they exit with an error on files which are too large (a limitation of the examples, not miniz itself).
32  4/12/12 v1.12 - More comments, added low-level example5.c, fixed a couple minor level_and_flags issues in the archive API's.
33  level_and_flags can now be set to MZ_DEFAULT_COMPRESSION. Thanks to Bruce Dawson <bruced@valvesoftware.com> for the feedback/bug report.
34  5/28/11 v1.11 - Added statement from unlicense.org
35  5/27/11 v1.10 - Substantial compressor optimizations:
36  Level 1 is now ~4x faster than before. The L1 compressor's throughput now varies between 70-110MB/sec. on a
37  Core i7 (actual throughput varies depending on the type of data, and x64 vs. x86).
38  Improved baseline L2-L9 compression perf. Also, greatly improved compression perf. issues on some file types.
39  Refactored the compression code for better readability and maintainability.
40  Added level 10 compression level (L10 has slightly better ratio than level 9, but could have a potentially large
41  drop in throughput on some files).
42  5/15/11 v1.09 - Initial stable release.
43 
44  * Low-level Deflate/Inflate implementation notes:
45 
46  Compression: Use the "tdefl" API's. The compressor supports raw, static, and dynamic blocks, lazy or
47  greedy parsing, match length filtering, RLE-only, and Huffman-only streams. It performs and compresses
48  approximately as well as zlib.
49 
50  Decompression: Use the "tinfl" API's. The entire decompressor is implemented as a single function
51  coroutine: see tinfl_decompress(). It supports decompression into a 32KB (or larger power of 2) wrapping buffer, or into a memory
52  block large enough to hold the entire file.
53 
54  The low-level tdefl/tinfl API's do not make any use of dynamic memory allocation.
55 
56  * zlib-style API notes:
57 
58  miniz.c implements a fairly large subset of zlib. There's enough functionality present for it to be a drop-in
59  zlib replacement in many apps:
60  The z_stream struct, optional memory allocation callbacks
61  deflateInit/deflateInit2/deflate/deflateReset/deflateEnd/deflateBound
62  inflateInit/inflateInit2/inflate/inflateEnd
63  compress, compress2, compressBound, uncompress
64  CRC-32, Adler-32 - Using modern, minimal code size, CPU cache friendly routines.
65  Supports raw deflate streams or standard zlib streams with adler-32 checking.
66 
67  Limitations:
68  The callback API's are not implemented yet. No support for gzip headers or zlib static dictionaries.
69  I've tried to closely emulate zlib's various flavors of stream flushing and return status codes, but
70  there are no guarantees that miniz.c pulls this off perfectly.
71 
72  * PNG writing: See the tdefl_write_image_to_png_file_in_memory() function, originally written by
73  Alex Evans. Supports 1-4 bytes/pixel images.
74 
75  * ZIP archive API notes:
76 
77  The ZIP archive API's where designed with simplicity and efficiency in mind, with just enough abstraction to
78  get the job done with minimal fuss. There are simple API's to retrieve file information, read files from
79  existing archives, create new archives, append new files to existing archives, or clone archive data from
80  one archive to another. It supports archives located in memory or the heap, on disk (using stdio.h),
81  or you can specify custom file read/write callbacks.
82 
83  - Archive reading: Just call this function to read a single file from a disk archive:
84 
85  void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name,
86  size_t *pSize, mz_uint zip_flags);
87 
88  For more complex cases, use the "mz_zip_reader" functions. Upon opening an archive, the entire central
89  directory is located and read as-is into memory, and subsequent file access only occurs when reading individual files.
90 
91  - Archives file scanning: The simple way is to use this function to scan a loaded archive for a specific file:
92 
93  int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);
94 
95  The locate operation can optionally check file comments too, which (as one example) can be used to identify
96  multiple versions of the same file in an archive. This function uses a simple linear search through the central
97  directory, so it's not very fast.
98 
99  Alternately, you can iterate through all the files in an archive (using mz_zip_reader_get_num_files()) and
100  retrieve detailed info on each file by calling mz_zip_reader_file_stat().
101 
102  - Archive creation: Use the "mz_zip_writer" functions. The ZIP writer immediately writes compressed file data
103  to disk and builds an exact image of the central directory in memory. The central directory image is written
104  all at once at the end of the archive file when the archive is finalized.
105 
106  The archive writer can optionally align each file's local header and file data to any power of 2 alignment,
107  which can be useful when the archive will be read from optical media. Also, the writer supports placing
108  arbitrary data blobs at the very beginning of ZIP archives. Archives written using either feature are still
109  readable by any ZIP tool.
110 
111  - Archive appending: The simple way to add a single file to an archive is to call this function:
112 
113  mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name,
114  const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
115 
116  The archive will be created if it doesn't already exist, otherwise it'll be appended to.
117  Note the appending is done in-place and is not an atomic operation, so if something goes wrong
118  during the operation it's possible the archive could be left without a central directory (although the local
119  file headers and file data will be fine, so the archive will be recoverable).
120 
121  For more complex archive modification scenarios:
122  1. The safest way is to use a mz_zip_reader to read the existing archive, cloning only those bits you want to
123  preserve into a new archive using using the mz_zip_writer_add_from_zip_reader() function (which compiles the
124  compressed file data as-is). When you're done, delete the old archive and rename the newly written archive, and
125  you're done. This is safe but requires a bunch of temporary disk space or heap memory.
126 
127  2. Or, you can convert an mz_zip_reader in-place to an mz_zip_writer using mz_zip_writer_init_from_reader(),
128  append new files as needed, then finalize the archive which will write an updated central directory to the
129  original archive. (This is basically what mz_zip_add_mem_to_archive_file_in_place() does.) There's a
130  possibility that the archive's central directory could be lost with this method if anything goes wrong, though.
131 
132  - ZIP archive support limitations:
133  No zip64 or spanning support. Extraction functions can only handle unencrypted, stored or deflated files.
134  Requires streams capable of seeking.
135 
136  * This is a header file library, like stb_image.c. To get only a header file, either cut and paste the
137  below header, or create miniz.h, #define MINIZ_HEADER_FILE_ONLY, and then include miniz.c from it.
138 
139  * Important: For best perf. be sure to customize the below macros for your target platform:
140  #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
141  #define MINIZ_LITTLE_ENDIAN 1
142  #define MINIZ_HAS_64BIT_REGISTERS 1
143 */
144 
145 #ifndef MINIZ_HEADER_INCLUDED
146 #define MINIZ_HEADER_INCLUDED
147 
148 #include <stdlib.h>
149 
150 #if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_ARCHIVE_APIS)
151 #include <time.h>
152 #endif
153 
154 // Defines to completely disable specific portions of miniz.c:
155 // If all macros here are defined the only functionality remaining will be CRC-32, adler-32, tinfl, and tdefl.
156 
157 // Define MINIZ_NO_STDIO to disable all usage and any functions which rely on stdio for file I/O.
158 //#define MINIZ_NO_STDIO
159 
160 // If MINIZ_NO_TIME is specified then the ZIP archive functions will not be able to get the current time, or
161 // get/set file times.
162 //#define MINIZ_NO_TIME
163 
164 // Define MINIZ_NO_ARCHIVE_APIS to disable all ZIP archive API's.
165 //#define MINIZ_NO_ARCHIVE_APIS
166 
167 // Define MINIZ_NO_ARCHIVE_APIS to disable all writing related ZIP archive API's.
168 //#define MINIZ_NO_ARCHIVE_WRITING_APIS
169 
170 // Define MINIZ_NO_ZLIB_APIS to remove all ZLIB-style compression/decompression API's.
171 //#define MINIZ_NO_ZLIB_APIS
172 
173 // Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent conflicts against stock zlib.
174 //#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES
175 
176 // Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc.
177 // Note if MINIZ_NO_MALLOC is defined then the user must always provide custom user alloc/free/realloc
178 // callbacks to the zlib and archive API's, and a few stand-alone helper API's which don't provide custom user
179 // functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work.
180 //#define MINIZ_NO_MALLOC
181 
182 #if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__)
183 // MINIZ_X86_OR_X64_CPU is only used to help set the below macros.
184 #define MINIZ_X86_OR_X64_CPU 1
185 #endif
186 
187 #if (__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU
188 // Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian.
189 #define MINIZ_LITTLE_ENDIAN 1
190 #endif
191 
192 #if MINIZ_X86_OR_X64_CPU
193 // Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient integer loads and stores from unaligned addresses.
194 #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
195 #endif
196 
197 #if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) || defined(__ia64__) || defined(__x86_64__)
198 // Set MINIZ_HAS_64BIT_REGISTERS to 1 if operations on 64-bit integers are reasonably fast (and don't involve compiler generated calls to helper functions).
199 #define MINIZ_HAS_64BIT_REGISTERS 1
200 #endif
201 
202 #ifdef __cplusplus
203 extern "C" {
204 #endif
205 
206 // ------------------- zlib-style API Definitions.
207 
208 // For more compatibility with zlib, miniz.c uses unsigned long for some parameters/struct members. Beware: mz_ulong can be either 32 or 64-bits!
209 typedef unsigned long mz_ulong;
210 
211 // Heap allocation callbacks.
212 // Note that mz_alloc_func parameter types purpsosely differ from zlib's: items/size is size_t, not unsigned long.
213 typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size);
214 typedef void (*mz_free_func)(void *opaque, void *address);
215 typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size);
216 
217 #define MZ_ADLER32_INIT (1)
218 // mz_adler32() returns the initial adler-32 value to use when called with ptr==NULL.
219 mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len);
220 
221 #define MZ_CRC32_INIT (0)
222 // mz_crc32() returns the initial CRC-32 value to use when called with ptr==NULL.
223 mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len);
224 
225 // Compression strategies.
227 
228 // Method
229 #define MZ_DEFLATED 8
230 
231 #ifndef MINIZ_NO_ZLIB_APIS
232 
233 #define MZ_VERSION "9.1.14"
234 #define MZ_VERNUM 0x91E0
235 #define MZ_VER_MAJOR 9
236 #define MZ_VER_MINOR 1
237 #define MZ_VER_REVISION 14
238 #define MZ_VER_SUBREVISION 0
239 
240 // Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The other values are for advanced use (refer to the zlib docs).
242 
243 // Return status codes. MZ_PARAM_ERROR is non-standard.
245 
246 // Compression levels: 0-9 are the standard zlib-style levels, 10 is best possible compression (not zlib compatible, and may be very slow), MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL.
248 
249 // Window bits
250 #define MZ_DEFAULT_WINDOW_BITS 15
251 
252 struct mz_internal_state;
253 
254 // Compression/decompression stream struct.
255 typedef struct mz_stream_s
256 {
257  const unsigned char *next_in; // pointer to next byte to read
258  unsigned int avail_in; // number of bytes available at next_in
259  mz_ulong total_in; // total number of bytes consumed so far
260 
261  unsigned char *next_out; // pointer to next byte to write
262  unsigned int avail_out; // number of bytes that can be written to next_out
263  mz_ulong total_out; // total number of bytes produced so far
264 
265  char *msg; // error msg (unused)
266  struct mz_internal_state *state; // internal state, allocated by zalloc/zfree
267 
268  mz_alloc_func zalloc; // optional heap allocation function (defaults to malloc)
269  mz_free_func zfree; // optional heap free function (defaults to free)
270  void *opaque; // heap alloc function user pointer
271 
272  int data_type; // data_type (unused)
273  mz_ulong adler; // adler32 of the source or uncompressed data
274  mz_ulong reserved; // not used
275 } mz_stream;
276 
278 
279 // Returns the version string of miniz.c.
280 const char *mz_version(void);
281 
282 // mz_deflateInit() initializes a compressor with default options:
283 // Parameters:
284 // pStream must point to an initialized mz_stream struct.
285 // level must be between [MZ_NO_COMPRESSION, MZ_BEST_COMPRESSION].
286 // level 1 enables a specially optimized compression function that's been optimized purely for performance, not ratio.
287 // (This special func. is currently only enabled when MINIZ_USE_UNALIGNED_LOADS_AND_STORES and MINIZ_LITTLE_ENDIAN are defined.)
288 // Return values:
289 // MZ_OK on success.
290 // MZ_STREAM_ERROR if the stream is bogus.
291 // MZ_PARAM_ERROR if the input parameters are bogus.
292 // MZ_MEM_ERROR on out of memory.
293 int mz_deflateInit(mz_streamp pStream, int level);
294 
295 // mz_deflateInit2() is like mz_deflate(), except with more control:
296 // Additional parameters:
297 // method must be MZ_DEFLATED
298 // window_bits must be MZ_DEFAULT_WINDOW_BITS (to wrap the deflate stream with zlib header/adler-32 footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate/no header or footer)
299 // mem_level must be between [1, 9] (it's checked but ignored by miniz.c)
300 int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy);
301 
302 // Quickly resets a compressor without having to reallocate anything. Same as calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2().
303 int mz_deflateReset(mz_streamp pStream);
304 
305 // mz_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible.
306 // Parameters:
307 // pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members.
308 // flush may be MZ_NO_FLUSH, MZ_PARTIAL_FLUSH/MZ_SYNC_FLUSH, MZ_FULL_FLUSH, or MZ_FINISH.
309 // Return values:
310 // MZ_OK on success (when flushing, or if more input is needed but not available, and/or there's more output to be written but the output buffer is full).
311 // MZ_STREAM_END if all input has been consumed and all output bytes have been written. Don't call mz_deflate() on the stream anymore.
312 // MZ_STREAM_ERROR if the stream is bogus.
313 // MZ_PARAM_ERROR if one of the parameters is invalid.
314 // MZ_BUF_ERROR if no forward progress is possible because the input and/or output buffers are empty. (Fill up the input buffer or free up some output space and try again.)
315 int mz_deflate(mz_streamp pStream, int flush);
316 
317 // mz_deflateEnd() deinitializes a compressor:
318 // Return values:
319 // MZ_OK on success.
320 // MZ_STREAM_ERROR if the stream is bogus.
321 int mz_deflateEnd(mz_streamp pStream);
322 
323 // mz_deflateBound() returns a (very) conservative upper bound on the amount of data that could be generated by deflate(), assuming flush is set to only MZ_NO_FLUSH or MZ_FINISH.
324 mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len);
325 
326 // Single-call compression functions mz_compress() and mz_compress2():
327 // Returns MZ_OK on success, or one of the error codes from mz_deflate() on failure.
328 int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
329 int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level);
330 
331 // mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress().
332 mz_ulong mz_compressBound(mz_ulong source_len);
333 
334 // Initializes a decompressor.
335 int mz_inflateInit(mz_streamp pStream);
336 
337 // mz_inflateInit2() is like mz_inflateInit() with an additional option that controls the window size and whether or not the stream has been wrapped with a zlib header/footer:
338 // window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate).
339 int mz_inflateInit2(mz_streamp pStream, int window_bits);
340 
341 // Decompresses the input stream to the output, consuming only as much of the input as needed, and writing as much to the output as possible.
342 // Parameters:
343 // pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members.
344 // flush may be MZ_NO_FLUSH, MZ_SYNC_FLUSH, or MZ_FINISH.
345 // On the first call, if flush is MZ_FINISH it's assumed the input and output buffers are both sized large enough to decompress the entire stream in a single call (this is slightly faster).
346 // MZ_FINISH implies that there are no more source bytes available beside what's already in the input buffer, and that the output buffer is large enough to hold the rest of the decompressed data.
347 // Return values:
348 // MZ_OK on success. Either more input is needed but not available, and/or there's more output to be written but the output buffer is full.
349 // MZ_STREAM_END if all needed input has been consumed and all output bytes have been written. For zlib streams, the adler-32 of the decompressed data has also been verified.
350 // MZ_STREAM_ERROR if the stream is bogus.
351 // MZ_DATA_ERROR if the deflate stream is invalid.
352 // MZ_PARAM_ERROR if one of the parameters is invalid.
353 // MZ_BUF_ERROR if no forward progress is possible because the input buffer is empty but the inflater needs more input to continue, or if the output buffer is not large enough. Call mz_inflate() again
354 // with more input data, or with more room in the output buffer (except when using single call decompression, described above).
355 int mz_inflate(mz_streamp pStream, int flush);
356 
357 // Deinitializes a decompressor.
358 int mz_inflateEnd(mz_streamp pStream);
359 
360 // Single-call decompression.
361 // Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure.
362 int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
363 
364 // Returns a string description of the specified error code, or NULL if the error code is invalid.
365 const char *mz_error(int err);
366 
367 // Redefine zlib-compatible names to miniz equivalents, so miniz.c can be used as a drop-in replacement for the subset of zlib that miniz.c supports.
368 // Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project.
369 #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
370  typedef unsigned char Byte;
371  typedef unsigned int uInt;
372  typedef mz_ulong uLong;
373  typedef Byte Bytef;
374  typedef uInt uIntf;
375  typedef char charf;
376  typedef int intf;
377  typedef void *voidpf;
378  typedef uLong uLongf;
379  typedef void *voidp;
380  typedef void *const voidpc;
381  #define Z_NULL 0
382  #define Z_NO_FLUSH MZ_NO_FLUSH
383  #define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH
384  #define Z_SYNC_FLUSH MZ_SYNC_FLUSH
385  #define Z_FULL_FLUSH MZ_FULL_FLUSH
386  #define Z_FINISH MZ_FINISH
387  #define Z_BLOCK MZ_BLOCK
388  #define Z_OK MZ_OK
389  #define Z_STREAM_END MZ_STREAM_END
390  #define Z_NEED_DICT MZ_NEED_DICT
391  #define Z_ERRNO MZ_ERRNO
392  #define Z_STREAM_ERROR MZ_STREAM_ERROR
393  #define Z_DATA_ERROR MZ_DATA_ERROR
394  #define Z_MEM_ERROR MZ_MEM_ERROR
395  #define Z_BUF_ERROR MZ_BUF_ERROR
396  #define Z_VERSION_ERROR MZ_VERSION_ERROR
397  #define Z_PARAM_ERROR MZ_PARAM_ERROR
398  #define Z_NO_COMPRESSION MZ_NO_COMPRESSION
399  #define Z_BEST_SPEED MZ_BEST_SPEED
400  #define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION
401  #define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION
402  #define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY
403  #define Z_FILTERED MZ_FILTERED
404  #define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY
405  #define Z_RLE MZ_RLE
406  #define Z_FIXED MZ_FIXED
407  #define Z_DEFLATED MZ_DEFLATED
408  #define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS
409  #define alloc_func mz_alloc_func
410  #define free_func mz_free_func
411  #define internal_state mz_internal_state
412  #define z_stream mz_stream
413  #define deflateInit mz_deflateInit
414  #define deflateInit2 mz_deflateInit2
415  #define deflateReset mz_deflateReset
416  #define deflate mz_deflate
417  #define deflateEnd mz_deflateEnd
418  #define deflateBound mz_deflateBound
419  #define compress mz_compress
420  #define compress2 mz_compress2
421  #define compressBound mz_compressBound
422  #define inflateInit mz_inflateInit
423  #define inflateInit2 mz_inflateInit2
424  #define inflate mz_inflate
425  #define inflateEnd mz_inflateEnd
426  #define uncompress mz_uncompress
427  #define crc32 mz_crc32
428  #define adler32 mz_adler32
429  #define MAX_WBITS 15
430  #define MAX_MEM_LEVEL 9
431  #define zError mz_error
432  #define ZLIB_VERSION MZ_VERSION
433  #define ZLIB_VERNUM MZ_VERNUM
434  #define ZLIB_VER_MAJOR MZ_VER_MAJOR
435  #define ZLIB_VER_MINOR MZ_VER_MINOR
436  #define ZLIB_VER_REVISION MZ_VER_REVISION
437  #define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION
438  #define zlibVersion mz_version
439  #define zlib_version mz_version()
440 #endif // #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
441 
442 #endif // MINIZ_NO_ZLIB_APIS
443 
444 // ------------------- Types and macros
445 
446 typedef unsigned char mz_uint8;
447 typedef signed short mz_int16;
448 typedef unsigned short mz_uint16;
449 typedef unsigned int mz_uint32;
450 typedef unsigned int mz_uint;
451 typedef long long mz_int64;
452 typedef unsigned long long mz_uint64;
453 typedef int mz_bool;
454 
455 #define MZ_FALSE (0)
456 #define MZ_TRUE (1)
457 
458 // Works around MSVC's spammy "warning C4127: conditional expression is constant" message.
459 #ifdef _MSC_VER
460  #define MZ_MACRO_END while (0, 0)
461 #else
462  #define MZ_MACRO_END while (0)
463 #endif
464 
465 // ------------------- ZIP archive reading/writing
466 
467 #ifndef MINIZ_NO_ARCHIVE_APIS
468 
469 enum
470 {
474 };
475 
476 typedef struct
477 {
478  mz_uint32 m_file_index;
479  mz_uint32 m_central_dir_ofs;
480  mz_uint16 m_version_made_by;
481  mz_uint16 m_version_needed;
482  mz_uint16 m_bit_flag;
483  mz_uint16 m_method;
484 #ifndef MINIZ_NO_TIME
485  time_t m_time;
486 #endif
487  mz_uint32 m_crc32;
488  mz_uint64 m_comp_size;
489  mz_uint64 m_uncomp_size;
490  mz_uint16 m_internal_attr;
491  mz_uint32 m_external_attr;
493  mz_uint32 m_comment_size;
497 
498 typedef size_t (*mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n);
499 typedef size_t (*mz_file_write_func)(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n);
500 
503 
504 typedef enum
505 {
510 } mz_zip_mode;
511 
512 typedef struct
513 {
514  mz_uint64 m_archive_size;
516  mz_uint m_total_files;
518 
520 
525 
529 
531 
533 
534 typedef enum
535 {
540 } mz_zip_flags;
541 
542 // ZIP archive reading
543 
544 // Inits a ZIP archive reader.
545 // These functions read and validate the archive's central directory.
546 mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint32 flags);
547 mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint32 flags);
548 
549 #ifndef MINIZ_NO_STDIO
550 mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags);
551 #endif
552 
553 // Returns the total number of files in the archive.
555 
556 // Returns detailed information about an archive file entry.
557 mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat);
558 
559 // Determines if an archive file entry is a directory entry.
560 mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index);
561 mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index);
562 
563 // Retrieves the filename of an archive file entry.
564 // Returns the number of bytes written to pFilename, or if filename_buf_size is 0 this function returns the number of bytes needed to fully store the filename.
565 mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size);
566 
567 // Attempts to locates a file in the archive's central directory.
568 // Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH
569 // Returns -1 if the file cannot be found.
570 int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);
571 
572 // Extracts a archive file to a memory buffer using no memory allocation.
573 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);
574 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);
575 
576 // Extracts a archive file to a memory buffer.
577 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);
578 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);
579 
580 // Extracts a archive file to a dynamically allocated heap buffer.
581 void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags);
582 void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags);
583 
584 // Extracts a archive file using a callback function to output the file's data.
585 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);
586 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);
587 
588 #ifndef MINIZ_NO_STDIO
589 // Extracts a archive file to a disk file and sets its last accessed and modified times.
590 // This function only extracts files, not archive directory records.
591 mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags);
592 mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags);
593 #endif
594 
595 // Ends archive reading, freeing all allocations, and closing the input archive file if mz_zip_reader_init_file() was used.
596 mz_bool mz_zip_reader_end(mz_zip_archive *pZip);
597 
598 // ZIP archive writing
599 
600 #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
601 
602 // Inits a ZIP archive writer.
603 mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size);
604 mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size);
605 
606 #ifndef MINIZ_NO_STDIO
607 mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning);
608 #endif
609 
610 // Converts a ZIP archive reader object into a writer object, to allow efficient in-place file appends to occur on an existing archive.
611 // For archives opened using mz_zip_reader_init_file, pFilename must be the archive's filename so it can be reopened for writing. If the file can't be reopened, mz_zip_reader_end() will be called.
612 // For archives opened using mz_zip_reader_init_mem, the memory block must be growable using the realloc callback (which defaults to realloc unless you've overridden it).
613 // Finally, for archives opened using mz_zip_reader_init, the mz_zip_archive's user provided m_pWrite function cannot be NULL.
614 // Note: In-place archive modification is not recommended unless you know what you're doing, because if execution stops or something goes wrong before
615 // the archive is finalized the file's central directory will be hosed.
616 mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename);
617 
618 // Adds the contents of a memory buffer to an archive. These functions record the current local time into the archive.
619 // To add a directory entry, call this method with an archive name ending in a forwardslash with empty buffer.
620 // level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
621 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);
622 mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32);
623 
624 #ifndef MINIZ_NO_STDIO
625 // Adds the contents of a disk file to an archive. This function also records the disk file's modified time into the archive.
626 // level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
627 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);
628 #endif
629 
630 // Adds a file to an archive by fully cloning the data from another archive.
631 // This function fully clones the source file's compressed data (no recompression), along with its full filename, extra data, and comment fields.
632 mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint file_index);
633 
634 // Finalizes the archive by writing the central directory records followed by the end of central directory record.
635 // After an archive is finalized, the only valid call on the mz_zip_archive struct is mz_zip_writer_end().
636 // An archive must be manually finalized by calling this function for it to be valid.
638 mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **pBuf, size_t *pSize);
639 
640 // Ends archive writing, freeing all allocations, and closing the output file if mz_zip_writer_init_file() was used.
641 // Note for the archive to be valid, it must have been finalized before ending.
642 mz_bool mz_zip_writer_end(mz_zip_archive *pZip);
643 
644 // Misc. high-level helper functions:
645 
646 // mz_zip_add_mem_to_archive_file_in_place() efficiently (but not atomically) appends a memory blob to a ZIP archive.
647 // level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
648 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);
649 
650 // Reads a single file from an archive into a heap block.
651 // Returns NULL on failure.
652 void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint zip_flags);
653 
654 #endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
655 
656 #endif // #ifndef MINIZ_NO_ARCHIVE_APIS
657 
658 // ------------------- Low-level Decompression API Definitions
659 
660 // Decompression flags used by tinfl_decompress().
661 // TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream.
662 // TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available beyond the end of the supplied input buffer. If clear, the input buffer contains all remaining input.
663 // TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large enough to hold the entire decompressed stream. If clear, the output buffer is at least the size of the dictionary (typically 32KB).
664 // TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the decompressed bytes.
665 enum
666 {
671 };
672 
673 // High level decompression functions:
674 // tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block allocated via malloc().
675 // On entry:
676 // pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data to decompress.
677 // On return:
678 // Function returns a pointer to the decompressed data, or NULL on failure.
679 // *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data.
680 // The caller must free() the returned block when it's no longer needed.
681 void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
682 
683 // tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory.
684 // Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success.
685 #define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1))
686 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);
687 
688 // tinfl_decompress_mem_to_callback() decompresses a block in memory to an internal 32KB buffer, and a user provided callback function will be called to flush the buffer.
689 // Returns 1 on success or 0 on failure.
690 typedef int (*tinfl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser);
691 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);
692 
694 
695 // Max size of LZ dictionary.
696 #define TINFL_LZ_DICT_SIZE 32768
697 
698 // Return status.
699 typedef enum
700 {
707 } tinfl_status;
708 
709 // Initializes the decompressor to its initial state.
710 #define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END
711 #define tinfl_get_adler32(r) (r)->m_check_adler32
712 
713 // Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability.
714 // This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output.
715 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);
716 
717 // Internal/private bits follow.
718 enum
719 {
722 };
723 
724 typedef struct
725 {
726  mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0];
727  mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
729 
730 #if MINIZ_HAS_64BIT_REGISTERS
731  #define TINFL_USE_64BIT_BITBUF 1
732 #endif
733 
734 #if TINFL_USE_64BIT_BITBUF
735  typedef mz_uint64 tinfl_bit_buf_t;
736  #define TINFL_BITBUF_SIZE (64)
737 #else
738  typedef mz_uint32 tinfl_bit_buf_t;
739  #define TINFL_BITBUF_SIZE (32)
740 #endif
741 
743 {
745  tinfl_bit_buf_t m_bit_buf;
749 };
750 
751 // ------------------- Low-level Compression API Definitions
752 
753 // Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly slower, and raw/dynamic blocks will be output more frequently).
754 #define TDEFL_LESS_MEMORY 0
755 
756 // tdefl_init() compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search):
757 // TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap compression), 4095=Huffman+LZ (slowest/best compression).
758 enum
759 {
761 };
762 
763 // TDEFL_WRITE_ZLIB_HEADER: If set, the compressor outputs a zlib header before the deflate data, and the Adler-32 of the source data at the end. Otherwise, you'll get raw deflate data.
764 // TDEFL_COMPUTE_ADLER32: Always compute the adler-32 of the input data (even when not writing zlib headers).
765 // TDEFL_GREEDY_PARSING_FLAG: Set to use faster greedy parsing, instead of more efficient lazy parsing.
766 // TDEFL_NONDETERMINISTIC_PARSING_FLAG: Enable to decrease the compressor's initialization time to the minimum, but the output may vary from run to run given the same input (depending on the contents of memory).
767 // TDEFL_RLE_MATCHES: Only look for RLE matches (matches with a distance of 1)
768 // TDEFL_FILTER_MATCHES: Discards matches <= 5 chars if enabled.
769 // TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables.
770 // TDEFL_FORCE_ALL_RAW_BLOCKS: Only use raw (uncompressed) deflate blocks.
771 enum
772 {
777  TDEFL_RLE_MATCHES = 0x10000,
781 };
782 
783 // High level compression functions:
784 // tdefl_compress_mem_to_heap() compresses a block in memory to a heap block allocated via malloc().
785 // On entry:
786 // pSrc_buf, src_buf_len: Pointer and size of source block to compress.
787 // flags: The max match finder probes (default is 128) logically OR'd against the above flags. Higher probes are slower but improve compression.
788 // On return:
789 // Function returns a pointer to the compressed data, or NULL on failure.
790 // *pOut_len will be set to the compressed data's size, which could be larger than src_buf_len on uncompressible data.
791 // The caller must free() the returned block when it's no longer needed.
792 void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
793 
794 // tdefl_compress_mem_to_mem() compresses a block in memory to another block in memory.
795 // Returns 0 on failure.
796 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);
797 
798 // Compresses an image to a compressed PNG file in memory.
799 // On entry:
800 // pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4.
801 // On return:
802 // Function returns a pointer to the compressed data, or NULL on failure.
803 // *pLen_out will be set to the size of the PNG image file.
804 // The caller must free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed.
805 void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out);
806 
807 // Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time.
808 typedef mz_bool (*tdefl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser);
809 
810 // tdefl_compress_mem_to_output() compresses a block to an output stream. The above helpers use this function internally.
811 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);
812 
814 
815 // TDEFL_OUT_BUF_SIZE MUST be large enough to hold a single entire compressed output block (using static/fixed Huffman codes).
816 #if TDEFL_LESS_MEMORY
818 #else
820 #endif
821 
822 // The low-level tdefl functions below may be used directly if the above helper functions aren't flexible enough. The low-level functions don't make any heap allocations, unlike the above helper functions.
823 typedef enum
824 {
829 } tdefl_status;
830 
831 // Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums
832 typedef enum
833 {
838 } tdefl_flush;
839 
840 // tdefl's compression state structure.
841 typedef struct
842 {
845  mz_uint m_flags, m_max_probes[2];
847  mz_uint m_adler32, m_lookahead_pos, m_lookahead_size, m_dict_size;
848  mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end;
849  mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in, m_bit_buffer;
850  mz_uint m_saved_match_dist, m_saved_match_len, m_saved_lit, m_output_flush_ofs, m_output_flush_remaining, m_finished, m_block_index, m_wants_to_finish;
852  const void *m_pIn_buf;
853  void *m_pOut_buf;
854  size_t *m_pIn_buf_size, *m_pOut_buf_size;
856  const mz_uint8 *m_pSrc;
857  size_t m_src_buf_left, m_out_buf_ofs;
858  mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE + TDEFL_MAX_MATCH_LEN - 1];
861  mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
862  mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE];
863  mz_uint16 m_next[TDEFL_LZ_DICT_SIZE];
864  mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE];
865  mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE];
867 
868 // Initializes the compressor.
869 // There is no corresponding deinit() function because the tdefl API's do not dynamically allocate memory.
870 // pBut_buf_func: If NULL, output data will be supplied to the specified callback. In this case, the user should call the tdefl_compress_buffer() API for compression.
871 // If pBut_buf_func is NULL the user should always call the tdefl_compress() API.
872 // flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, etc.)
873 tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
874 
875 // Compresses a block of data, consuming as much of the specified input buffer as possible, and writing as much compressed data to the specified output buffer as possible.
876 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);
877 
878 // tdefl_compress_buffer() is only usable when the tdefl_init() is called with a non-NULL tdefl_put_buf_func_ptr.
879 // tdefl_compress_buffer() always consumes the entire input buffer.
880 tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush);
881 
883 mz_uint32 tdefl_get_adler32(tdefl_compressor *d);
884 
885 // Can't use tdefl_create_comp_flags_from_zip_params if MINIZ_NO_ZLIB_APIS isn't defined, because it uses some of its macros.
886 #ifndef MINIZ_NO_ZLIB_APIS
887 // Create tdefl_compress() flags given zlib-style compression parameters.
888 // level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files)
889 // window_bits may be -15 (raw deflate) or 15 (zlib)
890 // strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED
891 mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy);
892 #endif // #ifndef MINIZ_NO_ZLIB_APIS
893 
894 #ifdef __cplusplus
895 }
896 #endif
897 
898 #endif // MINIZ_HEADER_INCLUDED
899 
900 // ------------------- End of Header: Implementation follows. (If you only want the header, define MINIZ_HEADER_FILE_ONLY.)
901 
902 #ifndef MINIZ_HEADER_FILE_ONLY
903 
904 typedef unsigned char mz_validate_uint16[sizeof(mz_uint16)==2 ? 1 : -1];
905 typedef unsigned char mz_validate_uint32[sizeof(mz_uint32)==4 ? 1 : -1];
906 typedef unsigned char mz_validate_uint64[sizeof(mz_uint64)==8 ? 1 : -1];
907 
908 #include <string.h>
909 #include <assert.h>
910 
911 #define MZ_ASSERT(x) assert(x)
912 
913 #ifdef MINIZ_NO_MALLOC
914  #define MZ_MALLOC(x) NULL
915  #define MZ_FREE(x) (void)x, ((void)0)
916  #define MZ_REALLOC(p, x) NULL
917 #else
918  #define MZ_MALLOC(x) malloc(x)
919  #define MZ_FREE(x) free(x)
920  #define MZ_REALLOC(p, x) realloc(p, x)
921 #endif
922 
923 #define MZ_MAX(a,b) (((a)>(b))?(a):(b))
924 #define MZ_MIN(a,b) (((a)<(b))?(a):(b))
925 #define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
926 
927 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
928  #define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
929  #define MZ_READ_LE32(p) *((const mz_uint32 *)(p))
930 #else
931  #define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U))
932  #define MZ_READ_LE32(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U))
933 #endif
934 
935 #ifdef _MSC_VER
936  #define MZ_FORCEINLINE __forceinline
937 #elif defined(__GNUC__)
938  #define MZ_FORCEINLINE __attribute__((__always_inline__))
939 #else
940  #define MZ_FORCEINLINE inline
941 #endif
942 
943 #ifdef __cplusplus
944  extern "C" {
945 #endif
946 
947 // ------------------- zlib-style API's
948 
949 mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len)
950 {
951  mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16); size_t block_len = buf_len % 5552;
952  if (!ptr) return MZ_ADLER32_INIT;
953  while (buf_len) {
954  for (i = 0; i + 7 < block_len; i += 8, ptr += 8) {
955  s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1;
956  s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1;
957  }
958  for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1;
959  s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552;
960  }
961  return (s2 << 16) + s1;
962 }
963 
964 // Karl Malbrain's compact CRC-32. See "A compact CCITT crc16 and crc32 C implementation that balances processor cache usage against speed": http://www.geocities.com/malbrain/
965 mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
966 {
967  static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
968  0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c };
969  mz_uint32 crcu32 = (mz_uint32)crc;
970  if (!ptr) return MZ_CRC32_INIT;
971  crcu32 = ~crcu32; while (buf_len--) { mz_uint8 b = *ptr++; crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)]; crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)]; }
972  return ~crcu32;
973 }
974 
975 #ifndef MINIZ_NO_ZLIB_APIS
976 
977 static void *def_alloc_func(void *opaque, size_t items, size_t size) { (void)opaque, (void)items, (void)size; return MZ_MALLOC(items * size); }
978 static void def_free_func(void *opaque, void *address) { (void)opaque, (void)address; MZ_FREE(address); }
979 static void *def_realloc_func(void *opaque, void *address, size_t items, size_t size) { (void)opaque, (void)address, (void)items, (void)size; return MZ_REALLOC(address, items * size); }
980 
981 const char *mz_version(void)
982 {
983  return MZ_VERSION;
984 }
985 
986 int mz_deflateInit(mz_streamp pStream, int level)
987 {
989 }
990 
991 int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy)
992 {
993  tdefl_compressor *pComp;
994  mz_uint comp_flags = TDEFL_COMPUTE_ADLER32 | tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy);
995 
996  if (!pStream) return MZ_STREAM_ERROR;
997  if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) || ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS))) return MZ_PARAM_ERROR;
998 
999  pStream->data_type = 0;
1000  pStream->adler = MZ_ADLER32_INIT;
1001  pStream->msg = NULL;
1002  pStream->reserved = 0;
1003  pStream->total_in = 0;
1004  pStream->total_out = 0;
1005  if (!pStream->zalloc) pStream->zalloc = def_alloc_func;
1006  if (!pStream->zfree) pStream->zfree = def_free_func;
1007 
1008  pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, sizeof(tdefl_compressor));
1009  if (!pComp)
1010  return MZ_MEM_ERROR;
1011 
1012  pStream->state = (struct mz_internal_state *)pComp;
1013 
1014  if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY)
1015  {
1016  mz_deflateEnd(pStream);
1017  return MZ_PARAM_ERROR;
1018  }
1019 
1020  return MZ_OK;
1021 }
1022 
1023 int mz_deflateReset(mz_streamp pStream)
1024 {
1025  if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree)) return MZ_STREAM_ERROR;
1026  pStream->total_in = pStream->total_out = 0;
1027  tdefl_init((tdefl_compressor*)pStream->state, NULL, NULL, ((tdefl_compressor*)pStream->state)->m_flags);
1028  return MZ_OK;
1029 }
1030 
1031 int mz_deflate(mz_streamp pStream, int flush)
1032 {
1033  size_t in_bytes, out_bytes;
1034  mz_ulong orig_total_in, orig_total_out;
1035  int mz_status = MZ_OK;
1036 
1037  if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || (!pStream->next_out)) return MZ_STREAM_ERROR;
1038  if (!pStream->avail_out) return MZ_BUF_ERROR;
1039 
1040  if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH;
1041 
1042  if (((tdefl_compressor*)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE)
1043  return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR;
1044 
1045  orig_total_in = pStream->total_in; orig_total_out = pStream->total_out;
1046  for ( ; ; )
1047  {
1048  tdefl_status defl_status;
1049  in_bytes = pStream->avail_in; out_bytes = pStream->avail_out;
1050 
1051  defl_status = tdefl_compress((tdefl_compressor*)pStream->state, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, (tdefl_flush)flush);
1052  pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes;
1053  pStream->total_in += (mz_uint)in_bytes; pStream->adler = tdefl_get_adler32((tdefl_compressor*)pStream->state);
1054 
1055  pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes;
1056  pStream->total_out += (mz_uint)out_bytes;
1057 
1058  if (defl_status < 0)
1059  {
1060  mz_status = MZ_STREAM_ERROR;
1061  break;
1062  }
1063  else if (defl_status == TDEFL_STATUS_DONE)
1064  {
1065  mz_status = MZ_STREAM_END;
1066  break;
1067  }
1068  else if (!pStream->avail_out)
1069  break;
1070  else if ((!pStream->avail_in) && (flush != MZ_FINISH))
1071  {
1072  if ((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out))
1073  break;
1074  return MZ_BUF_ERROR; // Can't make forward progress without some input.
1075  }
1076  }
1077  return mz_status;
1078 }
1079 
1080 int mz_deflateEnd(mz_streamp pStream)
1081 {
1082  if (!pStream) return MZ_STREAM_ERROR;
1083  if (pStream->state)
1084  {
1085  pStream->zfree(pStream->opaque, pStream->state);
1086  pStream->state = NULL;
1087  }
1088  return MZ_OK;
1089 }
1090 
1091 mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len)
1092 {
1093  (void)pStream;
1094  // This is really over conservative. (And lame, but it's actually pretty tricky to compute a true upper bound given the way tdefl's blocking works.)
1095  return MZ_MAX(128 + (source_len * 110) / 100, 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5);
1096 }
1097 
1098 int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level)
1099 {
1100  int status;
1101  mz_stream stream;
1102  memset(&stream, 0, sizeof(stream));
1103 
1104  // In case mz_ulong is 64-bits (argh I hate longs).
1105  if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR;
1106 
1107  stream.next_in = pSource;
1108  stream.avail_in = (mz_uint32)source_len;
1109  stream.next_out = pDest;
1110  stream.avail_out = (mz_uint32)*pDest_len;
1111 
1112  status = mz_deflateInit(&stream, level);
1113  if (status != MZ_OK) return status;
1114 
1115  status = mz_deflate(&stream, MZ_FINISH);
1116  if (status != MZ_STREAM_END)
1117  {
1118  mz_deflateEnd(&stream);
1119  return (status == MZ_OK) ? MZ_BUF_ERROR : status;
1120  }
1121 
1122  *pDest_len = stream.total_out;
1123  return mz_deflateEnd(&stream);
1124 }
1125 
1126 int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
1127 {
1128  return mz_compress2(pDest, pDest_len, pSource, source_len, MZ_DEFAULT_COMPRESSION);
1129 }
1130 
1131 mz_ulong mz_compressBound(mz_ulong source_len)
1132 {
1133  return mz_deflateBound(NULL, source_len);
1134 }
1135 
1136 typedef struct
1137 {
1139  mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed; int m_window_bits;
1140  mz_uint8 m_dict[TINFL_LZ_DICT_SIZE];
1142 } inflate_state;
1143 
1144 int mz_inflateInit2(mz_streamp pStream, int window_bits)
1145 {
1146  inflate_state *pDecomp;
1147  if (!pStream) return MZ_STREAM_ERROR;
1148  if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)) return MZ_PARAM_ERROR;
1149 
1150  pStream->data_type = 0;
1151  pStream->adler = 0;
1152  pStream->msg = NULL;
1153  pStream->total_in = 0;
1154  pStream->total_out = 0;
1155  pStream->reserved = 0;
1156  if (!pStream->zalloc) pStream->zalloc = def_alloc_func;
1157  if (!pStream->zfree) pStream->zfree = def_free_func;
1158 
1159  pDecomp = (inflate_state*)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state));
1160  if (!pDecomp) return MZ_MEM_ERROR;
1161 
1162  pStream->state = (struct mz_internal_state *)pDecomp;
1163 
1164  tinfl_init(&pDecomp->m_decomp);
1165  pDecomp->m_dict_ofs = 0;
1166  pDecomp->m_dict_avail = 0;
1168  pDecomp->m_first_call = 1;
1169  pDecomp->m_has_flushed = 0;
1170  pDecomp->m_window_bits = window_bits;
1171 
1172  return MZ_OK;
1173 }
1174 
1175 int mz_inflateInit(mz_streamp pStream)
1176 {
1177  return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS);
1178 }
1179 
1180 int mz_inflate(mz_streamp pStream, int flush)
1181 {
1182  inflate_state* pState;
1183  mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32;
1184  size_t in_bytes, out_bytes, orig_avail_in;
1185  tinfl_status status;
1186 
1187  if ((!pStream) || (!pStream->state)) return MZ_STREAM_ERROR;
1188  if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH;
1189  if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH)) return MZ_STREAM_ERROR;
1190 
1191  pState = (inflate_state*)pStream->state;
1192  if (pState->m_window_bits > 0) decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER;
1193  orig_avail_in = pStream->avail_in;
1194 
1195  first_call = pState->m_first_call; pState->m_first_call = 0;
1196  if (pState->m_last_status < 0) return MZ_DATA_ERROR;
1197 
1198  if (pState->m_has_flushed && (flush != MZ_FINISH)) return MZ_STREAM_ERROR;
1199  pState->m_has_flushed |= (flush == MZ_FINISH);
1200 
1201  if ((flush == MZ_FINISH) && (first_call))
1202  {
1203  // MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file.
1205  in_bytes = pStream->avail_in; out_bytes = pStream->avail_out;
1206  status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags);
1207  pState->m_last_status = status;
1208  pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; pStream->total_in += (mz_uint)in_bytes;
1209  pStream->adler = tinfl_get_adler32(&pState->m_decomp);
1210  pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes; pStream->total_out += (mz_uint)out_bytes;
1211 
1212  if (status < 0)
1213  return MZ_DATA_ERROR;
1214  else if (status != TINFL_STATUS_DONE)
1215  {
1217  return MZ_BUF_ERROR;
1218  }
1219  return MZ_STREAM_END;
1220  }
1221  // flush != MZ_FINISH then we must assume there's more input.
1222  if (flush != MZ_FINISH) decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT;
1223 
1224  if (pState->m_dict_avail)
1225  {
1226  n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
1227  memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
1228  pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n;
1229  pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
1230  return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
1231  }
1232 
1233  for ( ; ; )
1234  {
1235  in_bytes = pStream->avail_in;
1236  out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs;
1237 
1238  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);
1239  pState->m_last_status = status;
1240 
1241  pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes;
1242  pStream->total_in += (mz_uint)in_bytes; pStream->adler = tinfl_get_adler32(&pState->m_decomp);
1243 
1244  pState->m_dict_avail = (mz_uint)out_bytes;
1245 
1246  n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
1247  memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
1248  pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n;
1249  pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
1250 
1251  if (status < 0)
1252  return MZ_DATA_ERROR; // Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well).
1253  else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in))
1254  return MZ_BUF_ERROR; // Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH.
1255  else if (flush == MZ_FINISH)
1256  {
1257  // The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH.
1258  if (status == TINFL_STATUS_DONE)
1259  return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END;
1260  // status here must be TINFL_STATUS_HAS_MORE_OUTPUT, which means there's at least 1 more byte on the way. If there's no more room left in the output buffer then something is wrong.
1261  else if (!pStream->avail_out)
1262  return MZ_BUF_ERROR;
1263  }
1264  else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail))
1265  break;
1266  }
1267 
1268  return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
1269 }
1270 
1271 int mz_inflateEnd(mz_streamp pStream)
1272 {
1273  if (!pStream)
1274  return MZ_STREAM_ERROR;
1275  if (pStream->state)
1276  {
1277  pStream->zfree(pStream->opaque, pStream->state);
1278  pStream->state = NULL;
1279  }
1280  return MZ_OK;
1281 }
1282 
1283 int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
1284 {
1285  mz_stream stream;
1286  int status;
1287  memset(&stream, 0, sizeof(stream));
1288 
1289  // In case mz_ulong is 64-bits (argh I hate longs).
1290  if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR;
1291 
1292  stream.next_in = pSource;
1293  stream.avail_in = (mz_uint32)source_len;
1294  stream.next_out = pDest;
1295  stream.avail_out = (mz_uint32)*pDest_len;
1296 
1297  status = mz_inflateInit(&stream);
1298  if (status != MZ_OK)
1299  return status;
1300 
1301  status = mz_inflate(&stream, MZ_FINISH);
1302  if (status != MZ_STREAM_END)
1303  {
1304  mz_inflateEnd(&stream);
1305  return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status;
1306  }
1307  *pDest_len = stream.total_out;
1308 
1309  return mz_inflateEnd(&stream);
1310 }
1311 
1312 const char *mz_error(int err)
1313 {
1314  static struct { int m_err; const char *m_pDesc; } s_error_descs[] =
1315  {
1316  { MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" },
1317  { 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" }
1318  };
1319  mz_uint i; for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i) if (s_error_descs[i].m_err == err) return s_error_descs[i].m_pDesc;
1320  return NULL;
1321 }
1322 
1323 #endif //MINIZ_NO_ZLIB_APIS
1324 
1325 // ------------------- Low-level Decompression (completely independent from all compression API's)
1326 
1327 #define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
1328 #define TINFL_MEMSET(p, c, l) memset(p, c, l)
1329 
1330 #define TINFL_CR_BEGIN switch(r->m_state) { case 0:
1331 #define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END
1332 #define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END
1333 #define TINFL_CR_FINISH }
1334 
1335 // TODO: If the caller has indicated that there's no more input, and we attempt to read beyond the input buf, then something is wrong with the input because the inflator never
1336 // reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of the stream with 0's in this scenario.
1337 #define TINFL_GET_BYTE(state_index, c) do { \
1338  if (pIn_buf_cur >= pIn_buf_end) { \
1339  for ( ; ; ) { \
1340  if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \
1341  TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \
1342  if (pIn_buf_cur < pIn_buf_end) { \
1343  c = *pIn_buf_cur++; \
1344  break; \
1345  } \
1346  } else { \
1347  c = 0; \
1348  break; \
1349  } \
1350  } \
1351  } else c = *pIn_buf_cur++; } MZ_MACRO_END
1352 
1353 #define TINFL_NEED_BITS(state_index, n) do { mz_uint c; TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; } while (num_bits < (mz_uint)(n))
1354 #define TINFL_SKIP_BITS(state_index, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END
1355 #define TINFL_GET_BITS(state_index, b, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } b = bit_buf & ((1 << (n)) - 1); bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END
1356 
1357 // TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2.
1358 // It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a
1359 // Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the
1360 // bit buffer contains >=15 bits (deflate's max. Huffman code size).
1361 #define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \
1362  do { \
1363  temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
1364  if (temp >= 0) { \
1365  code_len = temp >> 9; \
1366  if ((code_len) && (num_bits >= code_len)) \
1367  break; \
1368  } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \
1369  code_len = TINFL_FAST_LOOKUP_BITS; \
1370  do { \
1371  temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
1372  } while ((temp < 0) && (num_bits >= (code_len + 1))); if (temp >= 0) break; \
1373  } TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; \
1374  } while (num_bits < 15);
1375 
1376 // TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex than you would initially expect because the zlib API expects the decompressor to never read
1377 // beyond the final byte of the deflate stream. (In other words, when this macro wants to read another byte from the input, it REALLY needs another byte in order to fully
1378 // decode the next Huffman code.) Handling this properly is particularly important on raw deflate (non-zlib) streams, which aren't followed by a byte aligned adler-32.
1379 // The slow path is only executed at the very end of the input buffer.
1380 #define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \
1381  int temp; mz_uint code_len, c; \
1382  if (num_bits < 15) { \
1383  if ((pIn_buf_end - pIn_buf_cur) < 2) { \
1384  TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
1385  } else { \
1386  bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); pIn_buf_cur += 2; num_bits += 16; \
1387  } \
1388  } \
1389  if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
1390  code_len = temp >> 9, temp &= 511; \
1391  else { \
1392  code_len = TINFL_FAST_LOOKUP_BITS; do { temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; } while (temp < 0); \
1393  } sym = temp; bit_buf >>= code_len; num_bits -= code_len; } MZ_MACRO_END
1394 
1395 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)
1396 {
1397  static const int s_length_base[31] = { 3,4,5,6,7,8,9,10,11,13, 15,17,19,23,27,31,35,43,51,59, 67,83,99,115,131,163,195,227,258,0,0 };
1398  static const int s_length_extra[31]= { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 };
1399  static const int s_dist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0};
1400  static const int s_dist_extra[32] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
1401  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 };
1402  static const int s_min_table_sizes[3] = { 257, 1, 4 };
1403 
1404  tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; tinfl_bit_buf_t bit_buf;
1405  const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size;
1406  mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size;
1407  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;
1408 
1409  // Ensure the output buffer's size is a power of 2, unless the output buffer is large enough to hold the entire output file (in which case it doesn't matter).
1410  if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start)) { *pIn_buf_size = *pOut_buf_size = 0; return TINFL_STATUS_BAD_PARAM; }
1411 
1412  num_bits = r->m_num_bits; bit_buf = r->m_bit_buf; dist = r->m_dist; counter = r->m_counter; num_extra = r->m_num_extra; dist_from_out_buf_start = r->m_dist_from_out_buf_start;
1414 
1415  bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0; r->m_z_adler32 = r->m_check_adler32 = 1;
1416  if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
1417  {
1419  counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8));
1420  if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1U << (8U + (r->m_zhdr0 >> 4)))));
1421  if (counter) { TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); }
1422  }
1423 
1424  do
1425  {
1426  TINFL_GET_BITS(3, r->m_final, 3); r->m_type = r->m_final >> 1;
1427  if (r->m_type == 0)
1428  {
1429  TINFL_SKIP_BITS(5, num_bits & 7);
1430  for (counter = 0; counter < 4; ++counter) { if (num_bits) TINFL_GET_BITS(6, r->m_raw_header[counter], 8); else TINFL_GET_BYTE(7, r->m_raw_header[counter]); }
1431  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)))) { TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED); }
1432  while ((counter) && (num_bits))
1433  {
1434  TINFL_GET_BITS(51, dist, 8);
1435  while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT); }
1436  *pOut_buf_cur++ = (mz_uint8)dist;
1437  counter--;
1438  }
1439  while (counter)
1440  {
1441  size_t n; while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); }
1442  while (pIn_buf_cur >= pIn_buf_end)
1443  {
1444  if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT)
1445  {
1447  }
1448  else
1449  {
1451  }
1452  }
1453  n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter);
1454  TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); pIn_buf_cur += n; pOut_buf_cur += n; counter -= (mz_uint)n;
1455  }
1456  }
1457  else if (r->m_type == 3)
1458  {
1460  }
1461  else
1462  {
1463  if (r->m_type == 1)
1464  {
1465  mz_uint8 *p = r->m_tables[0].m_code_size; mz_uint i;
1466  r->m_table_sizes[0] = 288; r->m_table_sizes[1] = 32; TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32);
1467  for ( i = 0; i <= 143; ++i) *p++ = 8; for ( ; i <= 255; ++i) *p++ = 9; for ( ; i <= 279; ++i) *p++ = 7; for ( ; i <= 287; ++i) *p++ = 8;
1468  }
1469  else
1470  {
1471  for (counter = 0; counter < 3; counter++) { TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); r->m_table_sizes[counter] += s_min_table_sizes[counter]; }
1472  MZ_CLEAR_OBJ(r->m_tables[2].m_code_size); for (counter = 0; counter < r->m_table_sizes[2]; counter++) { mz_uint s; TINFL_GET_BITS(14, s, 3); r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; }
1473  r->m_table_sizes[2] = 19;
1474  }
1475  for ( ; (int)r->m_type >= 0; r->m_type--)
1476  {
1477  int tree_next, tree_cur; tinfl_huff_table *pTable;
1478  mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; pTable = &r->m_tables[r->m_type]; MZ_CLEAR_OBJ(total_syms); MZ_CLEAR_OBJ(pTable->m_look_up); MZ_CLEAR_OBJ(pTable->m_tree);
1479  for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) total_syms[pTable->m_code_size[i]]++;
1480  used_syms = 0, total = 0; next_code[0] = next_code[1] = 0;
1481  for (i = 1; i <= 15; ++i) { used_syms += total_syms[i]; next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); }
1482  if ((65536 != total) && (used_syms > 1))
1483  {
1485  }
1486  for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index)
1487  {
1488  mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index]; if (!code_size) continue;
1489  cur_code = next_code[code_size]++; for (l = code_size; l > 0; l--, cur_code >>= 1) rev_code = (rev_code << 1) | (cur_code & 1);
1490  if (code_size <= TINFL_FAST_LOOKUP_BITS) { mz_int16 k = (mz_int16)((code_size << 9) | sym_index); while (rev_code < TINFL_FAST_LOOKUP_SIZE) { pTable->m_look_up[rev_code] = k; rev_code += (1 << code_size); } continue; }
1491  if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) { pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; }
1492  rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1);
1493  for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--)
1494  {
1495  tree_cur -= ((rev_code >>= 1) & 1);
1496  if (!pTable->m_tree[-tree_cur - 1]) { pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } else tree_cur = pTable->m_tree[-tree_cur - 1];
1497  }
1498  tree_cur -= ((rev_code >>= 1) & 1); pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
1499  }
1500  if (r->m_type == 2)
1501  {
1502  for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]); )
1503  {
1504  mz_uint s; TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); if (dist < 16) { r->m_len_codes[counter++] = (mz_uint8)dist; continue; }
1505  if ((dist == 16) && (!counter))
1506  {
1508  }
1509  num_extra = "\02\03\07"[dist - 16]; TINFL_GET_BITS(18, s, num_extra); s += "\03\03\013"[dist - 16];
1510  TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s); counter += s;
1511  }
1512  if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter)
1513  {
1515  }
1517  }
1518  }
1519  for ( ; ; )
1520  {
1521  mz_uint8 *pSrc;
1522  for ( ; ; )
1523  {
1524  if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2))
1525  {
1526  TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]);
1527  if (counter >= 256)
1528  break;
1529  while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT); }
1530  *pOut_buf_cur++ = (mz_uint8)counter;
1531  }
1532  else
1533  {
1534  int sym2; mz_uint code_len;
1535 #if TINFL_USE_64BIT_BITBUF
1536  if (num_bits < 30) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits); pIn_buf_cur += 4; num_bits += 32; }
1537 #else
1538  if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; }
1539 #endif
1540  if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
1541  code_len = sym2 >> 9;
1542  else
1543  {
1544  code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0);
1545  }
1546  counter = sym2; bit_buf >>= code_len; num_bits -= code_len;
1547  if (counter & 256)
1548  break;
1549 
1550 #if !TINFL_USE_64BIT_BITBUF
1551  if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; }
1552 #endif
1553  if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
1554  code_len = sym2 >> 9;
1555  else
1556  {
1557  code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0);
1558  }
1559  bit_buf >>= code_len; num_bits -= code_len;
1560 
1561  pOut_buf_cur[0] = (mz_uint8)counter;
1562  if (sym2 & 256)
1563  {
1564  pOut_buf_cur++;
1565  counter = sym2;
1566  break;
1567  }
1568  pOut_buf_cur[1] = (mz_uint8)sym2;
1569  pOut_buf_cur += 2;
1570  }
1571  }
1572  if ((counter &= 511) == 256) break;
1573 
1574  num_extra = s_length_extra[counter - 257]; counter = s_length_base[counter - 257];
1575  if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(25, extra_bits, num_extra); counter += extra_bits; }
1576 
1577  TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]);
1578  num_extra = s_dist_extra[dist]; dist = s_dist_base[dist];
1579  if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(27, extra_bits, num_extra); dist += extra_bits; }
1580 
1581  dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
1582  if ((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
1583  {
1585  }
1586 
1587  pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask);
1588 
1589  if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end)
1590  {
1591  while (counter--)
1592  {
1593  while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT); }
1594  *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask];
1595  }
1596  continue;
1597  }
1598 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
1599  else if ((counter >= 9) && (counter <= dist))
1600  {
1601  const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
1602  do
1603  {
1604  ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0];
1605  ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1];
1606  pOut_buf_cur += 8;
1607  } while ((pSrc += 8) < pSrc_end);
1608  if ((counter &= 7) < 3)
1609  {
1610  if (counter)
1611  {
1612  pOut_buf_cur[0] = pSrc[0];
1613  if (counter > 1)
1614  pOut_buf_cur[1] = pSrc[1];
1615  pOut_buf_cur += counter;
1616  }
1617  continue;
1618  }
1619  }
1620 #endif
1621  do
1622  {
1623  pOut_buf_cur[0] = pSrc[0];
1624  pOut_buf_cur[1] = pSrc[1];
1625  pOut_buf_cur[2] = pSrc[2];
1626  pOut_buf_cur += 3; pSrc += 3;
1627  } while ((int)(counter -= 3) > 2);
1628  if ((int)counter > 0)
1629  {
1630  pOut_buf_cur[0] = pSrc[0];
1631  if ((int)counter > 1)
1632  pOut_buf_cur[1] = pSrc[1];
1633  pOut_buf_cur += counter;
1634  }
1635  }
1636  }
1637  } while (!(r->m_final & 1));
1638  if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
1639  {
1640  TINFL_SKIP_BITS(32, num_bits & 7); for (counter = 0; counter < 4; ++counter) { mz_uint s; if (num_bits) TINFL_GET_BITS(41, s, 8); else TINFL_GET_BYTE(42, s); r->m_z_adler32 = (r->m_z_adler32 << 8) | s; }
1641  }
1644 
1645 common_exit:
1646  r->m_num_bits = num_bits; r->m_bit_buf = bit_buf; r->m_dist = dist; r->m_counter = counter; r->m_num_extra = num_extra; r->m_dist_from_out_buf_start = dist_from_out_buf_start;
1647  *pIn_buf_size = pIn_buf_cur - pIn_buf_next; *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
1648  if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0))
1649  {
1650  const mz_uint8 *ptr = pOut_buf_next; size_t buf_len = *pOut_buf_size;
1651  mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16; size_t block_len = buf_len % 5552;
1652  while (buf_len)
1653  {
1654  for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
1655  {
1656  s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1;
1657  s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1;
1658  }
1659  for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1;
1660  s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552;
1661  }
1662  r->m_check_adler32 = (s2 << 16) + s1; if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32)) status = TINFL_STATUS_ADLER32_MISMATCH;
1663  }
1664  return status;
1665 }
1666 
1667 // Higher level helper functions.
1668 void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
1669 {
1670  tinfl_decompressor decomp; void *pBuf = NULL, *pNew_buf; size_t src_buf_ofs = 0, out_buf_capacity = 0;
1671  *pOut_len = 0;
1672  tinfl_init(&decomp);
1673  for ( ; ; )
1674  {
1675  size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity;
1676  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,
1678  if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT))
1679  {
1680  MZ_FREE(pBuf); *pOut_len = 0; return NULL;
1681  }
1682  src_buf_ofs += src_buf_size;
1683  *pOut_len += dst_buf_size;
1684  if (status == TINFL_STATUS_DONE) break;
1685  new_out_buf_capacity = out_buf_capacity * 2; if (new_out_buf_capacity < 128) new_out_buf_capacity = 128;
1686  pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity);
1687  if (!pNew_buf)
1688  {
1689  MZ_FREE(pBuf); *pOut_len = 0; return NULL;
1690  }
1691  pBuf = pNew_buf; out_buf_capacity = new_out_buf_capacity;
1692  }
1693  return pBuf;
1694 }
1695 
1696 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)
1697 {
1698  tinfl_decompressor decomp; tinfl_status status; tinfl_init(&decomp);
1699  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);
1700  return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len;
1701 }
1702 
1703 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)
1704 {
1705  int result = 0;
1706  tinfl_decompressor decomp;
1707  mz_uint8 *pDict = (mz_uint8*)MZ_MALLOC(TINFL_LZ_DICT_SIZE); size_t in_buf_ofs = 0, dict_ofs = 0;
1708  if (!pDict)
1709  return TINFL_STATUS_FAILED;
1710  tinfl_init(&decomp);
1711  for ( ; ; )
1712  {
1713  size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs;
1714  tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size,
1716  in_buf_ofs += in_buf_size;
1717  if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user)))
1718  break;
1719  if (status != TINFL_STATUS_HAS_MORE_OUTPUT)
1720  {
1721  result = (status == TINFL_STATUS_DONE);
1722  break;
1723  }
1724  dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1);
1725  }
1726  MZ_FREE(pDict);
1727  *pIn_buf_size = in_buf_ofs;
1728  return result;
1729 }
1730 
1731 // ------------------- Low-level Compression (independent from all decompression API's)
1732 
1733 // Purposely making these tables static for faster init and thread safety.
1734 static const mz_uint16 s_tdefl_len_sym[256] = {
1735  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,
1736  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,
1737  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,
1738  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,
1739  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,
1740  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,
1741  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,
1742  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 };
1743 
1744 static const mz_uint8 s_tdefl_len_extra[256] = {
1745  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,
1746  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,
1747  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1748  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,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 };
1749 
1750 static const mz_uint8 s_tdefl_small_dist_sym[512] = {
1751  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,
1752  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,
1753  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,
1754  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,
1755  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,
1756  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,
1757  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,
1758  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,
1759  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,
1760  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,
1761  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,
1762  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 };
1763 
1764 static const mz_uint8 s_tdefl_small_dist_extra[512] = {
1765  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,
1766  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,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,
1767  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1768  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,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,
1769  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1770  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1771  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1772  7,7,7,7,7,7,7,7 };
1773 
1774 static const mz_uint8 s_tdefl_large_dist_sym[128] = {
1775  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,
1776  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,
1777  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 };
1778 
1779 static const mz_uint8 s_tdefl_large_dist_extra[128] = {
1780  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,
1781  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,
1782  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 };
1783 
1784 // Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted values.
1785 typedef struct { mz_uint16 m_key, m_sym_index; } tdefl_sym_freq;
1786 static tdefl_sym_freq* tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq* pSyms0, tdefl_sym_freq* pSyms1)
1787 {
1788  mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2]; tdefl_sym_freq* pCur_syms = pSyms0, *pNew_syms = pSyms1; MZ_CLEAR_OBJ(hist);
1789  for (i = 0; i < num_syms; i++) { mz_uint freq = pSyms0[i].m_key; hist[freq & 0xFF]++; hist[256 + ((freq >> 8) & 0xFF)]++; }
1790  while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256])) total_passes--;
1791  for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8)
1792  {
1793  const mz_uint32* pHist = &hist[pass << 8];
1794  mz_uint offsets[256], cur_ofs = 0;
1795  for (i = 0; i < 256; i++) { offsets[i] = cur_ofs; cur_ofs += pHist[i]; }
1796  for (i = 0; i < num_syms; i++) pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = pCur_syms[i];
1797  { tdefl_sym_freq* t = pCur_syms; pCur_syms = pNew_syms; pNew_syms = t; }
1798  }
1799  return pCur_syms;
1800 }
1801 
1802 // tdefl_calculate_minimum_redundancy() originally written by: Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996.
1804 {
1805  int root, leaf, next, avbl, used, dpth;
1806  if (n==0) return; else if (n==1) { A[0].m_key = 1; return; }
1807  A[0].m_key += A[1].m_key; root = 0; leaf = 2;
1808  for (next=1; next < n-1; next++)
1809  {
1810  if (leaf>=n || A[root].m_key<A[leaf].m_key) { A[next].m_key = A[root].m_key; A[root++].m_key = (mz_uint16)next; } else A[next].m_key = A[leaf++].m_key;
1811  if (leaf>=n || (root<next && A[root].m_key<A[leaf].m_key)) { A[next].m_key = (mz_uint16)(A[next].m_key + A[root].m_key); A[root++].m_key = (mz_uint16)next; } else A[next].m_key = (mz_uint16)(A[next].m_key + A[leaf++].m_key);
1812  }
1813  A[n-2].m_key = 0; for (next=n-3; next>=0; next--) A[next].m_key = A[A[next].m_key].m_key+1;
1814  avbl = 1; used = dpth = 0; root = n-2; next = n-1;
1815  while (avbl>0)
1816  {
1817  while (root>=0 && (int)A[root].m_key==dpth) { used++; root--; }
1818  while (avbl>used) { A[next--].m_key = (mz_uint16)(dpth); avbl--; }
1819  avbl = 2*used; dpth++; used = 0;
1820  }
1821 }
1822 
1823 // Limits canonical Huffman code table's max code size.
1825 static void tdefl_huffman_enforce_max_code_size(int *pNum_codes, int code_list_len, int max_code_size)
1826 {
1827  int i; mz_uint32 total = 0; if (code_list_len <= 1) return;
1828  for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++) pNum_codes[max_code_size] += pNum_codes[i];
1829  for (i = max_code_size; i > 0; i--) total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i));
1830  while (total != (1UL << max_code_size))
1831  {
1832  pNum_codes[max_code_size]--;
1833  for (i = max_code_size - 1; i > 0; i--) if (pNum_codes[i]) { pNum_codes[i]--; pNum_codes[i + 1] += 2; break; }
1834  total--;
1835  }
1836 }
1837 
1838 static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int table_len, int code_size_limit, int static_table)
1839 {
1840  int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE]; mz_uint next_code[TDEFL_MAX_SUPPORTED_HUFF_CODESIZE + 1]; MZ_CLEAR_OBJ(num_codes);
1841  if (static_table)
1842  {
1843  for (i = 0; i < table_len; i++) num_codes[d->m_huff_code_sizes[table_num][i]]++;
1844  }
1845  else
1846  {
1848  int num_used_syms = 0;
1849  const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0];
1850  for (i = 0; i < table_len; i++) if (pSym_count[i]) { syms0[num_used_syms].m_key = (mz_uint16)pSym_count[i]; syms0[num_used_syms++].m_sym_index = (mz_uint16)i; }
1851 
1852  pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1); tdefl_calculate_minimum_redundancy(pSyms, num_used_syms);
1853 
1854  for (i = 0; i < num_used_syms; i++) num_codes[pSyms[i].m_key]++;
1855 
1856  tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, code_size_limit);
1857 
1858  MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]); MZ_CLEAR_OBJ(d->m_huff_codes[table_num]);
1859  for (i = 1, j = num_used_syms; i <= code_size_limit; i++)
1860  for (l = num_codes[i]; l > 0; l--) d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i);
1861  }
1862 
1863  next_code[1] = 0; for (j = 0, i = 2; i <= code_size_limit; i++) next_code[i] = j = ((j + num_codes[i - 1]) << 1);
1864 
1865  for (i = 0; i < table_len; i++)
1866  {
1867  mz_uint rev_code = 0, code, code_size; if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0) continue;
1868  code = next_code[code_size]++; for (l = code_size; l > 0; l--, code >>= 1) rev_code = (rev_code << 1) | (code & 1);
1869  d->m_huff_codes[table_num][i] = (mz_uint16)rev_code;
1870  }
1871 }
1872 
1873 #define TDEFL_PUT_BITS(b, l) do { \
1874  mz_uint bits = b; mz_uint len = l; MZ_ASSERT(bits <= ((1U << len) - 1U)); \
1875  d->m_bit_buffer |= (bits << d->m_bits_in); d->m_bits_in += len; \
1876  while (d->m_bits_in >= 8) { \
1877  if (d->m_pOutput_buf < d->m_pOutput_buf_end) \
1878  *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \
1879  d->m_bit_buffer >>= 8; \
1880  d->m_bits_in -= 8; \
1881  } \
1882 } MZ_MACRO_END
1883 
1884 #define TDEFL_RLE_PREV_CODE_SIZE() { if (rle_repeat_count) { \
1885  if (rle_repeat_count < 3) { \
1886  d->m_huff_count[2][prev_code_size] = (mz_uint16)(d->m_huff_count[2][prev_code_size] + rle_repeat_count); \
1887  while (rle_repeat_count--) packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \
1888  } else { \
1889  d->m_huff_count[2][16] = (mz_uint16)(d->m_huff_count[2][16] + 1); packed_code_sizes[num_packed_code_sizes++] = 16; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_repeat_count - 3); \
1890 } rle_repeat_count = 0; } }
1891 
1892 #define TDEFL_RLE_ZERO_CODE_SIZE() { if (rle_z_count) { \
1893  if (rle_z_count < 3) { \
1894  d->m_huff_count[2][0] = (mz_uint16)(d->m_huff_count[2][0] + rle_z_count); while (rle_z_count--) packed_code_sizes[num_packed_code_sizes++] = 0; \
1895  } else if (rle_z_count <= 10) { \
1896  d->m_huff_count[2][17] = (mz_uint16)(d->m_huff_count[2][17] + 1); packed_code_sizes[num_packed_code_sizes++] = 17; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 3); \
1897  } else { \
1898  d->m_huff_count[2][18] = (mz_uint16)(d->m_huff_count[2][18] + 1); packed_code_sizes[num_packed_code_sizes++] = 18; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 11); \
1899 } rle_z_count = 0; } }
1900 
1901 static mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
1902 
1904 {
1905  int num_lit_codes, num_dist_codes, num_bit_lengths; mz_uint i, total_code_sizes_to_pack, num_packed_code_sizes, rle_z_count, rle_repeat_count, packed_code_sizes_index;
1906  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;
1907 
1908  d->m_huff_count[0][256] = 1;
1909 
1912 
1913  for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--) if (d->m_huff_code_sizes[0][num_lit_codes - 1]) break;
1914  for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--) if (d->m_huff_code_sizes[1][num_dist_codes - 1]) break;
1915 
1916  memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes);
1917  memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0], num_dist_codes);
1918  total_code_sizes_to_pack = num_lit_codes + num_dist_codes; num_packed_code_sizes = 0; rle_z_count = 0; rle_repeat_count = 0;
1919 
1920  memset(&d->m_huff_count[2][0], 0, sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2);
1921  for (i = 0; i < total_code_sizes_to_pack; i++)
1922  {
1923  mz_uint8 code_size = code_sizes_to_pack[i];
1924  if (!code_size)
1925  {
1927  if (++rle_z_count == 138) { TDEFL_RLE_ZERO_CODE_SIZE(); }
1928  }
1929  else
1930  {
1932  if (code_size != prev_code_size)
1933  {
1935  d->m_huff_count[2][code_size] = (mz_uint16)(d->m_huff_count[2][code_size] + 1); packed_code_sizes[num_packed_code_sizes++] = code_size;
1936  }
1937  else if (++rle_repeat_count == 6)
1938  {
1940  }
1941  }
1942  prev_code_size = code_size;
1943  }
1944  if (rle_repeat_count) { TDEFL_RLE_PREV_CODE_SIZE(); } else { TDEFL_RLE_ZERO_CODE_SIZE(); }
1945 
1947 
1948  TDEFL_PUT_BITS(2, 2);
1949 
1950  TDEFL_PUT_BITS(num_lit_codes - 257, 5);
1951  TDEFL_PUT_BITS(num_dist_codes - 1, 5);
1952 
1953  for (num_bit_lengths = 18; num_bit_lengths >= 0; num_bit_lengths--) if (d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[num_bit_lengths]]) break;
1954  num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1)); TDEFL_PUT_BITS(num_bit_lengths - 4, 4);
1955  for (i = 0; (int)i < num_bit_lengths; i++) TDEFL_PUT_BITS(d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[i]], 3);
1956 
1957  for (packed_code_sizes_index = 0; packed_code_sizes_index < num_packed_code_sizes; )
1958  {
1959  mz_uint code = packed_code_sizes[packed_code_sizes_index++]; MZ_ASSERT(code < TDEFL_MAX_HUFF_SYMBOLS_2);
1960  TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]);
1961  if (code >= 16) TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++], "\02\03\07"[code - 16]);
1962  }
1963 }
1964 
1966 {
1967  mz_uint i;
1968  mz_uint8 *p = &d->m_huff_code_sizes[0][0];
1969 
1970  for (i = 0; i <= 143; ++i) *p++ = 8;
1971  for ( ; i <= 255; ++i) *p++ = 9;
1972  for ( ; i <= 279; ++i) *p++ = 7;
1973  for ( ; i <= 287; ++i) *p++ = 8;
1974 
1975  memset(d->m_huff_code_sizes[1], 5, 32);
1976 
1977  tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE);
1978  tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE);
1979 
1980  TDEFL_PUT_BITS(1, 2);
1981 }
1982 
1983 static const mz_uint mz_bitmasks[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
1984 
1985 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS
1986 static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d)
1987 {
1988  mz_uint flags;
1989  mz_uint8 *pLZ_codes;
1990  mz_uint8 *pOutput_buf = d->m_pOutput_buf;
1991  mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf;
1992  mz_uint64 bit_buffer = d->m_bit_buffer;
1993  mz_uint bits_in = d->m_bits_in;
1994 
1995 #define TDEFL_PUT_BITS_FAST(b, l) { bit_buffer |= (((mz_uint64)(b)) << bits_in); bits_in += (l); }
1996 
1997  flags = 1;
1998  for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end; flags >>= 1)
1999  {
2000  if (flags == 1)
2001  flags = *pLZ_codes++ | 0x100;
2002 
2003  if (flags & 1)
2004  {
2005  mz_uint s0, s1, n0, n1, sym, num_extra_bits;
2006  mz_uint match_len = pLZ_codes[0], match_dist = *(const mz_uint16 *)(pLZ_codes + 1); pLZ_codes += 3;
2007 
2008  MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
2009  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]]);
2010  TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]);
2011 
2012  // This sequence coaxes MSVC into using cmov's vs. jmp's.
2013  s0 = s_tdefl_small_dist_sym[match_dist & 511];
2014  n0 = s_tdefl_small_dist_extra[match_dist & 511];
2015  s1 = s_tdefl_large_dist_sym[match_dist >> 8];
2016  n1 = s_tdefl_large_dist_extra[match_dist >> 8];
2017  sym = (match_dist < 512) ? s0 : s1;
2018  num_extra_bits = (match_dist < 512) ? n0 : n1;
2019 
2020  MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
2021  TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
2022  TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
2023  }
2024  else
2025  {
2026  mz_uint lit = *pLZ_codes++;
2027  MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
2028  TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
2029 
2030  if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
2031  {
2032  flags >>= 1;
2033  lit = *pLZ_codes++;
2034  MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
2035  TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
2036 
2037  if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
2038  {
2039  flags >>= 1;
2040  lit = *pLZ_codes++;
2041  MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
2042  TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
2043  }
2044  }
2045  }
2046 
2047  if (pOutput_buf >= d->m_pOutput_buf_end)
2048  return MZ_FALSE;
2049 
2050  *(mz_uint64*)pOutput_buf = bit_buffer;
2051  pOutput_buf += (bits_in >> 3);
2052  bit_buffer >>= (bits_in & ~7);
2053  bits_in &= 7;
2054  }
2055 
2056 #undef TDEFL_PUT_BITS_FAST
2057 
2058  d->m_pOutput_buf = pOutput_buf;
2059  d->m_bits_in = 0;
2060  d->m_bit_buffer = 0;
2061 
2062  while (bits_in)
2063  {
2064  mz_uint32 n = MZ_MIN(bits_in, 16);
2065  TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n);
2066  bit_buffer >>= n;
2067  bits_in -= n;
2068  }
2069 
2070  TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
2071 
2072  return (d->m_pOutput_buf < d->m_pOutput_buf_end);
2073 }
2074 #else
2076 {
2077  mz_uint flags;
2078  mz_uint8 *pLZ_codes;
2079 
2080  flags = 1;
2081  for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf; flags >>= 1)
2082  {
2083  if (flags == 1)
2084  flags = *pLZ_codes++ | 0x100;
2085  if (flags & 1)
2086  {
2087  mz_uint sym, num_extra_bits;
2088  mz_uint match_len = pLZ_codes[0], match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8)); pLZ_codes += 3;
2089 
2090  MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
2091  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]]);
2092  TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]);
2093 
2094  if (match_dist < 512)
2095  {
2096  sym = s_tdefl_small_dist_sym[match_dist]; num_extra_bits = s_tdefl_small_dist_extra[match_dist];
2097  }
2098  else
2099  {
2100  sym = s_tdefl_large_dist_sym[match_dist >> 8]; num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8];
2101  }
2102  MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
2103  TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
2104  TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
2105  }
2106  else
2107  {
2108  mz_uint lit = *pLZ_codes++;
2109  MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
2110  TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
2111  }
2112  }
2113 
2114  TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
2115 
2116  return (d->m_pOutput_buf < d->m_pOutput_buf_end);
2117 }
2118 #endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS
2119 
2120 static mz_bool tdefl_compress_block(tdefl_compressor *d, mz_bool static_block)
2121 {
2122  if (static_block)
2124  else
2126  return tdefl_compress_lz_codes(d);
2127 }
2128 
2129 static int tdefl_flush_block(tdefl_compressor *d, int flush)
2130 {
2131  mz_uint saved_bit_buf, saved_bits_in;
2132  mz_uint8 *pSaved_output_buf;
2133  mz_bool comp_block_succeeded = MZ_FALSE;
2134  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;
2135  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;
2136 
2137  d->m_pOutput_buf = pOutput_buf_start;
2139 
2141  d->m_output_flush_ofs = 0;
2142  d->m_output_flush_remaining = 0;
2143 
2144  *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left);
2145  d->m_pLZ_code_buf -= (d->m_num_flags_left == 8);
2146 
2147  if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index))
2148  {
2149  TDEFL_PUT_BITS(0x78, 8); TDEFL_PUT_BITS(0x01, 8);
2150  }
2151 
2152  TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1);
2153 
2154  pSaved_output_buf = d->m_pOutput_buf; saved_bit_buf = d->m_bit_buffer; saved_bits_in = d->m_bits_in;
2155 
2156  if (!use_raw_block)
2157  comp_block_succeeded = tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || (d->m_total_lz_bytes < 48));
2158 
2159  // If the block gets expanded, forget the current contents of the output buffer and send a raw block instead.
2160  if ( ((use_raw_block) || ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >= d->m_total_lz_bytes))) &&
2162  {
2163  mz_uint i; d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
2164  TDEFL_PUT_BITS(0, 2);
2165  if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); }
2166  for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF)
2167  {
2168  TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16);
2169  }
2170  for (i = 0; i < d->m_total_lz_bytes; ++i)
2171  {
2173  }
2174  }
2175  // Check for the extremely unlikely (if not impossible) case of the compressed block not fitting into the output buffer when using dynamic codes.
2176  else if (!comp_block_succeeded)
2177  {
2178  d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
2180  }
2181 
2182  if (flush)
2183  {
2184  if (flush == TDEFL_FINISH)
2185  {
2186  if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); }
2187  if (d->m_flags & TDEFL_WRITE_ZLIB_HEADER) { mz_uint i, a = d->m_adler32; for (i = 0; i < 4; i++) { TDEFL_PUT_BITS((a >> 24) & 0xFF, 8); a <<= 8; } }
2188  }
2189  else
2190  {
2191  mz_uint i, z = 0; TDEFL_PUT_BITS(0, 3); if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); } for (i = 2; i; --i, z ^= 0xFFFF) { TDEFL_PUT_BITS(z & 0xFFFF, 16); }
2192  }
2193  }
2194 
2196 
2197  memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
2198  memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
2199 
2201 
2202  if ((n = (int)(d->m_pOutput_buf - pOutput_buf_start)) != 0)
2203  {
2204  if (d->m_pPut_buf_func)
2205  {
2206  *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf;
2207  if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user))
2209  }
2210  else if (pOutput_buf_start == d->m_output_buf)
2211  {
2212  int bytes_to_copy = (int)MZ_MIN((size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs));
2213  memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf, bytes_to_copy);
2214  d->m_out_buf_ofs += bytes_to_copy;
2215  if ((n -= bytes_to_copy) != 0)
2216  {
2217  d->m_output_flush_ofs = bytes_to_copy;
2218  d->m_output_flush_remaining = n;
2219  }
2220  }
2221  else
2222  {
2223  d->m_out_buf_ofs += n;
2224  }
2225  }
2226 
2227  return d->m_output_flush_remaining;
2228 }
2229 
2230 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
2231 #define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16*)(p)
2232 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)
2233 {
2234  mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len;
2235  mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
2236  const mz_uint16 *s = (const mz_uint16*)(d->m_dict + pos), *p, *q;
2237  mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]), s01 = TDEFL_READ_UNALIGNED_WORD(s);
2238  MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return;
2239  for ( ; ; )
2240  {
2241  for ( ; ; )
2242  {
2243  if (--num_probes_left == 0) return;
2244  #define TDEFL_PROBE \
2245  next_probe_pos = d->m_next[probe_pos]; \
2246  if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \
2247  probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
2248  if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) break;
2250  }
2251  if (!dist) break; q = (const mz_uint16*)(d->m_dict + probe_pos); if (TDEFL_READ_UNALIGNED_WORD(q) != s01) continue; p = s; probe_len = 32;
2252  do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) &&
2253  (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0) );
2254  if (!probe_len)
2255  {
2256  *pMatch_dist = dist; *pMatch_len = MZ_MIN(max_match_len, TDEFL_MAX_MATCH_LEN); break;
2257  }
2258  else if ((probe_len = ((mz_uint)(p - s) * 2) + (mz_uint)(*(const mz_uint8*)p == *(const mz_uint8*)q)) > match_len)
2259  {
2260  *pMatch_dist = dist; if ((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) == max_match_len) break;
2261  c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]);
2262  }
2263  }
2264 }
2265 #else
2266 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)
2267 {
2268  mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len;
2269  mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
2270  const mz_uint8 *s = d->m_dict + pos, *p, *q;
2271  mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1];
2272  MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return;
2273  for ( ; ; )
2274  {
2275  for ( ; ; )
2276  {
2277  if (--num_probes_left == 0) return;
2278  #define TDEFL_PROBE \
2279  next_probe_pos = d->m_next[probe_pos]; \
2280  if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \
2281  probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
2282  if ((d->m_dict[probe_pos + match_len] == c0) && (d->m_dict[probe_pos + match_len - 1] == c1)) break;
2284  }
2285  if (!dist) break; p = s; q = d->m_dict + probe_pos; for (probe_len = 0; probe_len < max_match_len; probe_len++) if (*p++ != *q++) break;
2286  if (probe_len > match_len)
2287  {
2288  *pMatch_dist = dist; if ((*pMatch_len = match_len = probe_len) == max_match_len) return;
2289  c0 = d->m_dict[pos + match_len]; c1 = d->m_dict[pos + match_len - 1];
2290  }
2291  }
2292 }
2293 #endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
2294 
2295 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
2296 static mz_bool tdefl_compress_fast(tdefl_compressor *d)
2297 {
2298  // Faster, minimally featured LZRW1-style match+parse loop with better register utilization. Intended for applications where raw throughput is valued more highly than ratio.
2299  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;
2300  mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags;
2301  mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
2302 
2303  while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size)))
2304  {
2305  const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096;
2306  mz_uint dst_pos = (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK;
2307  mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size);
2308  d->m_src_buf_left -= num_bytes_to_process;
2309  lookahead_size += num_bytes_to_process;
2310 
2311  while (num_bytes_to_process)
2312  {
2313  mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process);
2314  memcpy(d->m_dict + dst_pos, d->m_pSrc, n);
2315  if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
2316  memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc, MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos));
2317  d->m_pSrc += n;
2318  dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK;
2319  num_bytes_to_process -= n;
2320  }
2321 
2322  dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size);
2323  if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE)) break;
2324 
2325  while (lookahead_size >= 4)
2326  {
2327  mz_uint cur_match_dist, cur_match_len = 1;
2328  mz_uint8 *pCur_dict = d->m_dict + cur_pos;
2329  mz_uint first_trigram = (*(const mz_uint32 *)pCur_dict) & 0xFFFFFF;
2330  mz_uint hash = (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) & TDEFL_LEVEL1_HASH_SIZE_MASK;
2331  mz_uint probe_pos = d->m_hash[hash];
2332  d->m_hash[hash] = (mz_uint16)lookahead_pos;
2333 
2334  if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <= dict_size) && ((*(const mz_uint32 *)(d->m_dict + (probe_pos &= TDEFL_LZ_DICT_SIZE_MASK)) & 0xFFFFFF) == first_trigram))
2335  {
2336  const mz_uint16 *p = (const mz_uint16 *)pCur_dict;
2337  const mz_uint16 *q = (const mz_uint16 *)(d->m_dict + probe_pos);
2338  mz_uint32 probe_len = 32;
2339  do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) &&
2340  (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0) );
2341  cur_match_len = ((mz_uint)(p - (const mz_uint16 *)pCur_dict) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q);
2342  if (!probe_len)
2343  cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0;
2344 
2345  if ((cur_match_len < TDEFL_MIN_MATCH_LEN) || ((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U*1024U)))
2346  {
2347  cur_match_len = 1;
2348  *pLZ_code_buf++ = (mz_uint8)first_trigram;
2349  *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
2350  d->m_huff_count[0][(mz_uint8)first_trigram]++;
2351  }
2352  else
2353  {
2354  mz_uint32 s0, s1;
2355  cur_match_len = MZ_MIN(cur_match_len, lookahead_size);
2356 
2357  MZ_ASSERT((cur_match_len >= TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 1) && (cur_match_dist <= TDEFL_LZ_DICT_SIZE));
2358 
2359  cur_match_dist--;
2360 
2361  pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN);
2362  *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist;
2363  pLZ_code_buf += 3;
2364  *pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80);
2365 
2366  s0 = s_tdefl_small_dist_sym[cur_match_dist & 511];
2367  s1 = s_tdefl_large_dist_sym[cur_match_dist >> 8];
2368  d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++;
2369 
2370  d->m_huff_count[0][s_tdefl_len_sym[cur_match_len - TDEFL_MIN_MATCH_LEN]]++;
2371  }
2372  }
2373  else
2374  {
2375  *pLZ_code_buf++ = (mz_uint8)first_trigram;
2376  *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
2377  d->m_huff_count[0][(mz_uint8)first_trigram]++;
2378  }
2379 
2380  if (--num_flags_left == 0) { num_flags_left = 8; pLZ_flags = pLZ_code_buf++; }
2381 
2382  total_lz_bytes += cur_match_len;
2383  lookahead_pos += cur_match_len;
2384  dict_size = MZ_MIN(dict_size + cur_match_len, TDEFL_LZ_DICT_SIZE);
2385  cur_pos = (cur_pos + cur_match_len) & TDEFL_LZ_DICT_SIZE_MASK;
2386  MZ_ASSERT(lookahead_size >= cur_match_len);
2387  lookahead_size -= cur_match_len;
2388 
2389  if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8])
2390  {
2391  int n;
2392  d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size;
2393  d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left;
2394  if ((n = tdefl_flush_block(d, 0)) != 0)
2395  return (n < 0) ? MZ_FALSE : MZ_TRUE;
2396  total_lz_bytes = d->m_total_lz_bytes; pLZ_code_buf = d->m_pLZ_code_buf; pLZ_flags = d->m_pLZ_flags; num_flags_left = d->m_num_flags_left;
2397  }
2398  }
2399 
2400  while (lookahead_size)
2401  {
2402  mz_uint8 lit = d->m_dict[cur_pos];
2403 
2404  total_lz_bytes++;
2405  *pLZ_code_buf++ = lit;
2406  *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
2407  if (--num_flags_left == 0) { num_flags_left = 8; pLZ_flags = pLZ_code_buf++; }
2408 
2409  d->m_huff_count[0][lit]++;
2410 
2411  lookahead_pos++;
2412  dict_size = MZ_MIN(dict_size + 1, TDEFL_LZ_DICT_SIZE);
2413  cur_pos = (cur_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK;
2414  lookahead_size--;
2415 
2416  if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8])
2417  {
2418  int n;
2419  d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size;
2420  d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left;
2421  if ((n = tdefl_flush_block(d, 0)) != 0)
2422  return (n < 0) ? MZ_FALSE : MZ_TRUE;
2423  total_lz_bytes = d->m_total_lz_bytes; pLZ_code_buf = d->m_pLZ_code_buf; pLZ_flags = d->m_pLZ_flags; num_flags_left = d->m_num_flags_left;
2424  }
2425  }
2426  }
2427 
2428  d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size;
2429  d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left;
2430  return MZ_TRUE;
2431 }
2432 #endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
2433 
2435 {
2436  d->m_total_lz_bytes++;
2437  *d->m_pLZ_code_buf++ = lit;
2438  *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1); if (--d->m_num_flags_left == 0) { d->m_num_flags_left = 8; d->m_pLZ_flags = d->m_pLZ_code_buf++; }
2439  d->m_huff_count[0][lit]++;
2440 }
2441 
2442 static MZ_FORCEINLINE void tdefl_record_match(tdefl_compressor *d, mz_uint match_len, mz_uint match_dist)
2443 {
2444  mz_uint32 s0, s1;
2445 
2446  MZ_ASSERT((match_len >= TDEFL_MIN_MATCH_LEN) && (match_dist >= 1) && (match_dist <= TDEFL_LZ_DICT_SIZE));
2447 
2448  d->m_total_lz_bytes += match_len;
2449 
2450  d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN);
2451 
2452  match_dist -= 1;
2453  d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF);
2454  d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8); d->m_pLZ_code_buf += 3;
2455 
2456  *d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80); if (--d->m_num_flags_left == 0) { d->m_num_flags_left = 8; d->m_pLZ_flags = d->m_pLZ_code_buf++; }
2457 
2458  s0 = s_tdefl_small_dist_sym[match_dist & 511]; s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127];
2459  d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++;
2460 
2461  if (match_len >= TDEFL_MIN_MATCH_LEN) d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++;
2462 }
2463 
2465 {
2466  const mz_uint8 *pSrc = d->m_pSrc; size_t src_buf_left = d->m_src_buf_left;
2467  tdefl_flush flush = d->m_flush;
2468 
2469  while ((src_buf_left) || ((flush) && (d->m_lookahead_size)))
2470  {
2471  mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos;
2472  // Update dictionary and hash chains. Keeps the lookahead size equal to TDEFL_MAX_MATCH_LEN.
2473  if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1))
2474  {
2475  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;
2476  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];
2477  mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size);
2478  const mz_uint8 *pSrc_end = pSrc + num_bytes_to_process;
2479  src_buf_left -= num_bytes_to_process;
2480  d->m_lookahead_size += num_bytes_to_process;
2481  while (pSrc != pSrc_end)
2482  {
2483  mz_uint8 c = *pSrc++; d->m_dict[dst_pos] = c; if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
2484  hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1);
2485  d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; d->m_hash[hash] = (mz_uint16)(ins_pos);
2486  dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; ins_pos++;
2487  }
2488  }
2489  else
2490  {
2491  while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
2492  {
2493  mz_uint8 c = *pSrc++;
2494  mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK;
2495  src_buf_left--;
2496  d->m_dict[dst_pos] = c;
2497  if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
2498  d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
2500  {
2501  mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2;
2502  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);
2503  d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; d->m_hash[hash] = (mz_uint16)(ins_pos);
2504  }
2505  }
2506  }
2508  if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
2509  break;
2510 
2511  // Simple lazy/greedy parsing state machine.
2512  len_to_move = 1; cur_match_dist = 0; cur_match_len = d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1); cur_pos = d->m_lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
2514  {
2515  if ((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS)))
2516  {
2517  mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK];
2518  cur_match_len = 0; while (cur_match_len < d->m_lookahead_size) { if (d->m_dict[cur_pos + cur_match_len] != c) break; cur_match_len++; }
2519  if (cur_match_len < TDEFL_MIN_MATCH_LEN) cur_match_len = 0; else cur_match_dist = 1;
2520  }
2521  }
2522  else
2523  {
2524  tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size, d->m_lookahead_size, &cur_match_dist, &cur_match_len);
2525  }
2526  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)))
2527  {
2528  cur_match_dist = cur_match_len = 0;
2529  }
2530  if (d->m_saved_match_len)
2531  {
2532  if (cur_match_len > d->m_saved_match_len)
2533  {
2534  tdefl_record_literal(d, (mz_uint8)d->m_saved_lit);
2535  if (cur_match_len >= 128)
2536  {
2537  tdefl_record_match(d, cur_match_len, cur_match_dist);
2538  d->m_saved_match_len = 0; len_to_move = cur_match_len;
2539  }
2540  else
2541  {
2542  d->m_saved_lit = d->m_dict[cur_pos]; d->m_saved_match_dist = cur_match_dist; d->m_saved_match_len = cur_match_len;
2543  }
2544  }
2545  else
2546  {
2548  len_to_move = d->m_saved_match_len - 1; d->m_saved_match_len = 0;
2549  }
2550  }
2551  else if (!cur_match_dist)
2552  tdefl_record_literal(d, d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]);
2553  else if ((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) || (cur_match_len >= 128))
2554  {
2555  tdefl_record_match(d, cur_match_len, cur_match_dist);
2556  len_to_move = cur_match_len;
2557  }
2558  else
2559  {
2560  d->m_saved_lit = d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]; d->m_saved_match_dist = cur_match_dist; d->m_saved_match_len = cur_match_len;
2561  }
2562  // Move the lookahead forward by len_to_move bytes.
2563  d->m_lookahead_pos += len_to_move;
2564  MZ_ASSERT(d->m_lookahead_size >= len_to_move);
2565  d->m_lookahead_size -= len_to_move;
2566  d->m_dict_size = MZ_MIN(d->m_dict_size + len_to_move, TDEFL_LZ_DICT_SIZE);
2567  // Check if it's time to flush the current LZ codes to the internal output buffer.
2568  if ( (d->m_pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) ||
2569  ( (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))) )
2570  {
2571  int n;
2572  d->m_pSrc = pSrc; d->m_src_buf_left = src_buf_left;
2573  if ((n = tdefl_flush_block(d, 0)) != 0)
2574  return (n < 0) ? MZ_FALSE : MZ_TRUE;
2575  }
2576  }
2577 
2578  d->m_pSrc = pSrc; d->m_src_buf_left = src_buf_left;
2579  return MZ_TRUE;
2580 }
2581 
2583 {
2584  if (d->m_pIn_buf_size)
2585  {
2586  *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf;
2587  }
2588 
2589  if (d->m_pOut_buf_size)
2590  {
2592  memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf + d->m_output_flush_ofs, n);
2593  d->m_output_flush_ofs += (mz_uint)n;
2595  d->m_out_buf_ofs += n;
2596 
2597  *d->m_pOut_buf_size = d->m_out_buf_ofs;
2598  }
2599 
2601 }
2602 
2603 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)
2604 {
2605  if (!d)
2606  {
2607  if (pIn_buf_size) *pIn_buf_size = 0;
2608  if (pOut_buf_size) *pOut_buf_size = 0;
2609  return TDEFL_STATUS_BAD_PARAM;
2610  }
2611 
2612  d->m_pIn_buf = pIn_buf; d->m_pIn_buf_size = pIn_buf_size;
2613  d->m_pOut_buf = pOut_buf; d->m_pOut_buf_size = pOut_buf_size;
2614  d->m_pSrc = (const mz_uint8 *)(pIn_buf); d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0;
2615  d->m_out_buf_ofs = 0;
2616  d->m_flush = flush;
2617 
2618  if ( ((d->m_pPut_buf_func != NULL) == ((pOut_buf != NULL) || (pOut_buf_size != NULL))) || (d->m_prev_return_status != TDEFL_STATUS_OKAY) ||
2619  (d->m_wants_to_finish && (flush != TDEFL_FINISH)) || (pIn_buf_size && *pIn_buf_size && !pIn_buf) || (pOut_buf_size && *pOut_buf_size && !pOut_buf) )
2620  {
2621  if (pIn_buf_size) *pIn_buf_size = 0;
2622  if (pOut_buf_size) *pOut_buf_size = 0;
2624  }
2625  d->m_wants_to_finish |= (flush == TDEFL_FINISH);
2626 
2627  if ((d->m_output_flush_remaining) || (d->m_finished))
2629 
2630 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
2631  if (((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) &&
2632  ((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) &&
2634  {
2635  if (!tdefl_compress_fast(d))
2636  return d->m_prev_return_status;
2637  }
2638  else
2639 #endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
2640  {
2641  if (!tdefl_compress_normal(d))
2642  return d->m_prev_return_status;
2643  }
2644 
2645  if ((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) && (pIn_buf))
2646  d->m_adler32 = (mz_uint32)mz_adler32(d->m_adler32, (const mz_uint8 *)pIn_buf, d->m_pSrc - (const mz_uint8 *)pIn_buf);
2647 
2648  if ((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) && (!d->m_output_flush_remaining))
2649  {
2650  if (tdefl_flush_block(d, flush) < 0)
2651  return d->m_prev_return_status;
2652  d->m_finished = (flush == TDEFL_FINISH);
2653  if (flush == TDEFL_FULL_FLUSH) { MZ_CLEAR_OBJ(d->m_hash); MZ_CLEAR_OBJ(d->m_next); d->m_dict_size = 0; }
2654  }
2655 
2657 }
2658 
2659 tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush)
2660 {
2661  MZ_ASSERT(d->m_pPut_buf_func); return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush);
2662 }
2663 
2664 tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
2665 {
2666  d->m_pPut_buf_func = pPut_buf_func; d->m_pPut_buf_user = pPut_buf_user;
2667  d->m_flags = (mz_uint)(flags); d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3; d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0;
2668  d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3;
2674  d->m_saved_match_dist = d->m_saved_match_len = d->m_saved_lit = 0; d->m_adler32 = 1;
2675  d->m_pIn_buf = NULL; d->m_pOut_buf = NULL;
2676  d->m_pIn_buf_size = NULL; d->m_pOut_buf_size = NULL;
2677  d->m_flush = TDEFL_NO_FLUSH; d->m_pSrc = NULL; d->m_src_buf_left = 0; d->m_out_buf_ofs = 0;
2678  memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
2679  memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
2680  return TDEFL_STATUS_OKAY;
2681 }
2682 
2684 {
2685  return d->m_prev_return_status;
2686 }
2687 
2689 {
2690  return d->m_adler32;
2691 }
2692 
2693 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)
2694 {
2695  tdefl_compressor *pComp; mz_bool succeeded; if (((buf_len) && (!pBuf)) || (!pPut_buf_func)) return MZ_FALSE;
2696  pComp = (tdefl_compressor*)MZ_MALLOC(sizeof(tdefl_compressor)); if (!pComp) return MZ_FALSE;
2697  succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags) == TDEFL_STATUS_OKAY);
2698  succeeded = succeeded && (tdefl_compress_buffer(pComp, pBuf, buf_len, TDEFL_FINISH) == TDEFL_STATUS_DONE);
2699  MZ_FREE(pComp); return succeeded;
2700 }
2701 
2702 typedef struct
2703 {
2704  size_t m_size, m_capacity;
2705  mz_uint8 *m_pBuf;
2706  mz_bool m_expandable;
2708 
2709 static mz_bool tdefl_output_buffer_putter(const void *pBuf, int len, void *pUser)
2710 {
2712  size_t new_size = p->m_size + len;
2713  if (new_size > p->m_capacity)
2714  {
2715  size_t new_capacity = p->m_capacity; mz_uint8 *pNew_buf; if (!p->m_expandable) return MZ_FALSE;
2716  do { new_capacity = MZ_MAX(128U, new_capacity << 1U); } while (new_size > new_capacity);
2717  pNew_buf = (mz_uint8*)MZ_REALLOC(p->m_pBuf, new_capacity); if (!pNew_buf) return MZ_FALSE;
2718  p->m_pBuf = pNew_buf; p->m_capacity = new_capacity;
2719  }
2720  memcpy((mz_uint8*)p->m_pBuf + p->m_size, pBuf, len); p->m_size = new_size;
2721  return MZ_TRUE;
2722 }
2723 
2724 void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
2725 {
2726  tdefl_output_buffer out_buf; MZ_CLEAR_OBJ(out_buf);
2727  if (!pOut_len) return MZ_FALSE; else *pOut_len = 0;
2728  out_buf.m_expandable = MZ_TRUE;
2729  if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) return NULL;
2730  *pOut_len = out_buf.m_size; return out_buf.m_pBuf;
2731 }
2732 
2733 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)
2734 {
2735  tdefl_output_buffer out_buf; MZ_CLEAR_OBJ(out_buf);
2736  if (!pOut_buf) return 0;
2737  out_buf.m_pBuf = (mz_uint8*)pOut_buf; out_buf.m_capacity = out_buf_len;
2738  if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) return 0;
2739  return out_buf.m_size;
2740 }
2741 
2742 #ifndef MINIZ_NO_ZLIB_APIS
2743 static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
2744 
2745 // level may actually range from [0,10] (10 is a "hidden" max level, where we want a bit more compression and it's fine if throughput to fall off a cliff on some files).
2746 mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy)
2747 {
2748  mz_uint comp_flags = s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0);
2749  if (window_bits > 0) comp_flags |= TDEFL_WRITE_ZLIB_HEADER;
2750 
2751  if (!level) comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS;
2752  else if (strategy == MZ_FILTERED) comp_flags |= TDEFL_FILTER_MATCHES;
2753  else if (strategy == MZ_HUFFMAN_ONLY) comp_flags &= ~TDEFL_MAX_PROBES_MASK;
2754  else if (strategy == MZ_FIXED) comp_flags |= TDEFL_FORCE_ALL_STATIC_BLOCKS;
2755  else if (strategy == MZ_RLE) comp_flags |= TDEFL_RLE_MATCHES;
2756 
2757  return comp_flags;
2758 }
2759 #endif //MINIZ_NO_ZLIB_APIS
2760 
2761 #ifdef _MSC_VER
2762 #pragma warning (push)
2763 #pragma warning (disable:4204) // nonstandard extension used : non-constant aggregate initializer (also supported by GNU C and C99, so no big deal)
2764 #endif
2765 
2766 // Simple PNG writer function by Alex Evans, 2011. Released into the public domain: https://gist.github.com/908299, more context at
2767 // http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/.
2768 void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out)
2769 {
2770  tdefl_compressor *pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); tdefl_output_buffer out_buf; int i, bpl = w * num_chans, y, z; mz_uint32 c; *pLen_out = 0;
2771  if (!pComp) return NULL;
2772  MZ_CLEAR_OBJ(out_buf); out_buf.m_expandable = MZ_TRUE; out_buf.m_capacity = 57+MZ_MAX(64, (1+bpl)*h); if (NULL == (out_buf.m_pBuf = (mz_uint8*)MZ_MALLOC(out_buf.m_capacity))) { MZ_FREE(pComp); return NULL; }
2773  // write dummy header
2774  for (z = 41; z; --z) tdefl_output_buffer_putter(&z, 1, &out_buf);
2775  // compress image data
2777  for (y = 0; y < h; ++y) { tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH); tdefl_compress_buffer(pComp, (mz_uint8*)pImage + y * bpl, bpl, TDEFL_NO_FLUSH); }
2778  if (tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) != TDEFL_STATUS_DONE) { MZ_FREE(pComp); MZ_FREE(out_buf.m_pBuf); return NULL; }
2779  // write real header
2780  *pLen_out = out_buf.m_size-41;
2781  {
2782  mz_uint8 pnghdr[41]={0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
2783  0,0,(mz_uint8)(w>>8),(mz_uint8)w,0,0,(mz_uint8)(h>>8),(mz_uint8)h,8,"\0\0\04\02\06"[num_chans],0,0,0,0,0,0,0,
2784  (mz_uint8)(*pLen_out>>24),(mz_uint8)(*pLen_out>>16),(mz_uint8)(*pLen_out>>8),(mz_uint8)*pLen_out,0x49,0x44,0x41,0x54};
2785  c=(mz_uint32)mz_crc32(MZ_CRC32_INIT,pnghdr+12,17); for (i=0; i<4; ++i, c<<=8) ((mz_uint8*)(pnghdr+29))[i]=(mz_uint8)(c>>24);
2786  memcpy(out_buf.m_pBuf, pnghdr, 41);
2787  }
2788  // write footer (IDAT CRC-32, followed by IEND chunk)
2789  if (!tdefl_output_buffer_putter("\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf)) { *pLen_out = 0; MZ_FREE(pComp); MZ_FREE(out_buf.m_pBuf); return NULL; }
2790  c = (mz_uint32)mz_crc32(MZ_CRC32_INIT,out_buf.m_pBuf+41-4, *pLen_out+4); for (i=0; i<4; ++i, c<<=8) (out_buf.m_pBuf+out_buf.m_size-16)[i] = (mz_uint8)(c >> 24);
2791  // compute final size of file, grab compressed data buffer and return
2792  *pLen_out += 57; MZ_FREE(pComp); return out_buf.m_pBuf;
2793 }
2794 
2795 #ifdef _MSC_VER
2796 #pragma warning (pop)
2797 #endif
2798 
2799 // ------------------- .ZIP archive reading
2800 
2801 #ifndef MINIZ_NO_ARCHIVE_APIS
2802 
2803 #ifdef MINIZ_NO_STDIO
2804  #define MZ_FILE void *
2805 #else
2806  #include <stdio.h>
2807  #include <sys/stat.h>
2808  #if defined(_MSC_VER) || defined(__MINGW64__)
2809  #include <sys/utime.h>
2810  #define MZ_FILE FILE
2811  #define MZ_FOPEN fopen
2812  #define MZ_FCLOSE fclose
2813  #define MZ_FREAD fread
2814  #define MZ_FWRITE fwrite
2815  #define MZ_FTELL64 _ftelli64
2816  #define MZ_FSEEK64 _fseeki64
2817  #define MZ_FILE_STAT_STRUCT _stat
2818  #define MZ_FILE_STAT _stat
2819  #define MZ_FFLUSH fflush
2820  #define MZ_FREOPEN freopen
2821  #define MZ_DELETE_FILE remove
2822  #elif defined(__MINGW32__)
2823  #include <sys/utime.h>
2824  #define MZ_FILE FILE
2825  #define MZ_FOPEN fopen
2826  #define MZ_FCLOSE fclose
2827  #define MZ_FREAD fread
2828  #define MZ_FWRITE fwrite
2829  #define MZ_FTELL64 ftello64
2830  #define MZ_FSEEK64 fseeko64
2831  #define MZ_FILE_STAT_STRUCT _stat
2832  #define MZ_FILE_STAT _stat
2833  #define MZ_FFLUSH fflush
2834  #define MZ_FREOPEN freopen
2835  #define MZ_DELETE_FILE remove
2836  #else
2837  #include <utime.h>
2838  #define MZ_FILE FILE
2839  #define MZ_FOPEN fopen
2840  #define MZ_FCLOSE fclose
2841  #define MZ_FREAD fread
2842  #define MZ_FWRITE fwrite
2843  #define MZ_FTELL64 ftello
2844  #define MZ_FSEEK64 fseeko
2845  #define MZ_FILE_STAT_STRUCT stat
2846  #define MZ_FILE_STAT stat
2847  #define MZ_FFLUSH fflush
2848  #define MZ_FREOPEN freopen
2849  #define MZ_DELETE_FILE remove
2850  #endif // #ifdef _MSC_VER
2851 #endif // #ifdef MINIZ_NO_STDIO
2852 
2853 #define MZ_TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c))
2854 
2855 // Various ZIP archive enums. To completely avoid cross platform compiler alignment and platform endian issues, miniz.c doesn't use structs for any of this stuff.
2856 enum
2857 {
2858  // ZIP archive identifiers and record sizes
2861  // Central directory header record offsets
2866  // Local directory header offsets
2870  // End of central directory offsets
2873 };
2874 
2875 typedef struct
2876 {
2877  void *m_p;
2878  size_t m_size, m_capacity;
2880 } mz_zip_array;
2881 
2883 {
2888  void *m_pMem;
2889  size_t m_mem_size;
2891 };
2892 
2893 #define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size) (array_ptr)->m_element_size = element_size
2894 #define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[index]
2895 
2897 {
2898  pZip->m_pFree(pZip->m_pAlloc_opaque, pArray->m_p);
2899  memset(pArray, 0, sizeof(mz_zip_array));
2900 }
2901 
2902 static mz_bool mz_zip_array_ensure_capacity(mz_zip_archive *pZip, mz_zip_array *pArray, size_t min_new_capacity, mz_uint growing)
2903 {
2904  void *pNew_p; size_t new_capacity = min_new_capacity; MZ_ASSERT(pArray->m_element_size); if (pArray->m_capacity >= min_new_capacity) return MZ_TRUE;
2905  if (growing) { new_capacity = MZ_MAX(1, pArray->m_capacity); while (new_capacity < min_new_capacity) new_capacity *= 2; }
2906  if (NULL == (pNew_p = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pArray->m_p, pArray->m_element_size, new_capacity))) return MZ_FALSE;
2907  pArray->m_p = pNew_p; pArray->m_capacity = new_capacity;
2908  return MZ_TRUE;
2909 }
2910 
2911 static MZ_FORCEINLINE mz_bool mz_zip_array_reserve(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_capacity, mz_uint growing)
2912 {
2913  if (new_capacity > pArray->m_capacity) { if (!mz_zip_array_ensure_capacity(pZip, pArray, new_capacity, growing)) return MZ_FALSE; }
2914  return MZ_TRUE;
2915 }
2916 
2917 static MZ_FORCEINLINE mz_bool mz_zip_array_resize(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_size, mz_uint growing)
2918 {
2919  if (new_size > pArray->m_capacity) { if (!mz_zip_array_ensure_capacity(pZip, pArray, new_size, growing)) return MZ_FALSE; }
2920  pArray->m_size = new_size;
2921  return MZ_TRUE;
2922 }
2923 
2924 static MZ_FORCEINLINE mz_bool mz_zip_array_ensure_room(mz_zip_archive *pZip, mz_zip_array *pArray, size_t n)
2925 {
2926  return mz_zip_array_reserve(pZip, pArray, pArray->m_size + n, MZ_TRUE);
2927 }
2928 
2929 static MZ_FORCEINLINE mz_bool mz_zip_array_push_back(mz_zip_archive *pZip, mz_zip_array *pArray, const void *pElements, size_t n)
2930 {
2931  size_t orig_size = pArray->m_size; if (!mz_zip_array_resize(pZip, pArray, orig_size + n, MZ_TRUE)) return MZ_FALSE;
2932  memcpy((mz_uint8*)pArray->m_p + orig_size * pArray->m_element_size, pElements, n * pArray->m_element_size);
2933  return MZ_TRUE;
2934 }
2935 
2936 #ifndef MINIZ_NO_TIME
2937 static time_t mz_zip_dos_to_time_t(int dos_time, int dos_date)
2938 {
2939  struct tm tm;
2940  memset(&tm, 0, sizeof(tm)); tm.tm_isdst = -1;
2941  tm.tm_year = ((dos_date >> 9) & 127) + 1980 - 1900; tm.tm_mon = ((dos_date >> 5) & 15) - 1; tm.tm_mday = dos_date & 31;
2942  tm.tm_hour = (dos_time >> 11) & 31; tm.tm_min = (dos_time >> 5) & 63; tm.tm_sec = (dos_time << 1) & 62;
2943  return mktime(&tm);
2944 }
2945 
2946 static void mz_zip_time_to_dos_time(time_t time, mz_uint16 *pDOS_time, mz_uint16 *pDOS_date)
2947 {
2948  struct tm *tm = localtime(&time);
2949  *pDOS_time = (mz_uint16)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) + ((tm->tm_sec) >> 1));
2950  *pDOS_date = (mz_uint16)(((tm->tm_year + 1900 - 1980) << 9) + ((tm->tm_mon + 1) << 5) + tm->tm_mday);
2951 }
2952 #endif
2953 
2954 #ifndef MINIZ_NO_STDIO
2955 static mz_bool mz_zip_get_file_modified_time(const char *pFilename, mz_uint16 *pDOS_time, mz_uint16 *pDOS_date)
2956 {
2957 #ifdef MINIZ_NO_TIME
2958  (void)pFilename; *pDOS_date = *pDOS_time = 0;
2959 #else
2960  struct MZ_FILE_STAT_STRUCT file_stat; if (MZ_FILE_STAT(pFilename, &file_stat) != 0) return MZ_FALSE;
2961  mz_zip_time_to_dos_time(file_stat.st_mtime, pDOS_time, pDOS_date);
2962 #endif // #ifdef MINIZ_NO_TIME
2963  return MZ_TRUE;
2964 }
2965 
2966 static mz_bool mz_zip_set_file_times(const char *pFilename, time_t access_time, time_t modified_time)
2967 {
2968 #ifndef MINIZ_NO_TIME
2969  struct utimbuf t; t.actime = access_time; t.modtime = modified_time;
2970  return !utime(pFilename, &t);
2971 #else
2972  pFilename, access_time, modified_time;
2973  return MZ_TRUE;
2974 #endif // #ifndef MINIZ_NO_TIME
2975 }
2976 #endif
2977 
2978 static mz_bool mz_zip_reader_init_internal(mz_zip_archive *pZip, mz_uint32 flags)
2979 {
2980  (void)flags;
2981  if ((!pZip) || (pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
2982  return MZ_FALSE;
2983 
2984  if (!pZip->m_pAlloc) pZip->m_pAlloc = def_alloc_func;
2985  if (!pZip->m_pFree) pZip->m_pFree = def_free_func;
2986  if (!pZip->m_pRealloc) pZip->m_pRealloc = def_realloc_func;
2987 
2989  pZip->m_archive_size = 0;
2990  pZip->m_central_directory_file_ofs = 0;
2991  pZip->m_total_files = 0;
2992 
2993  if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state))))
2994  return MZ_FALSE;
2995  memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state));
2996  MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, sizeof(mz_uint8));
2997  MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, sizeof(mz_uint32));
2999  return MZ_TRUE;
3000 }
3001 
3002 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)
3003 {
3004  const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE;
3005  const mz_uint8 *pR = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, r_index));
3007  mz_uint8 l = 0, r = 0;
3009  pE = pL + MZ_MIN(l_len, r_len);
3010  while (pL < pE)
3011  {
3012  if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR)))
3013  break;
3014  pL++; pR++;
3015  }
3016  return (pL == pE) ? (l_len < r_len) : (l < r);
3017 }
3018 
3019 #define MZ_SWAP_UINT32(a, b) do { mz_uint32 t = a; a = b; b = t; } MZ_MACRO_END
3020 
3021 // Heap sort of lowercased filenames, used to help accelerate plain central directory searches by mz_zip_reader_locate_file(). (Could also use qsort(), but it could allocate memory.)
3023 {
3024  mz_zip_internal_state *pState = pZip->m_pState;
3025  const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
3026  const mz_zip_array *pCentral_dir = &pState->m_central_dir;
3027  mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0);
3028  const int size = pZip->m_total_files;
3029  int start = (size - 2) >> 1, end;
3030  while (start >= 0)
3031  {
3032  int child, root = start;
3033  for ( ; ; )
3034  {
3035  if ((child = (root << 1) + 1) >= size)
3036  break;
3037  child += (((child + 1) < size) && (mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1])));
3038  if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child]))
3039  break;
3040  MZ_SWAP_UINT32(pIndices[root], pIndices[child]); root = child;
3041  }
3042  start--;
3043  }
3044 
3045  end = size - 1;
3046  while (end > 0)
3047  {
3048  int child, root = 0;
3049  MZ_SWAP_UINT32(pIndices[end], pIndices[0]);
3050  for ( ; ; )
3051  {
3052  if ((child = (root << 1) + 1) >= end)
3053  break;
3054  child += (((child + 1) < end) && mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1]));
3055  if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child]))
3056  break;
3057  MZ_SWAP_UINT32(pIndices[root], pIndices[child]); root = child;
3058  }
3059  end--;
3060  }
3061 }
3062 
3063 static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint32 flags)
3064 {
3065  mz_uint cdir_size, num_this_disk, cdir_disk_index;
3066  mz_uint64 cdir_ofs;
3067  mz_int64 cur_file_ofs;
3068  const mz_uint8 *p;
3069  mz_uint32 buf_u32[4096 / sizeof(mz_uint32)]; mz_uint8 *pBuf = (mz_uint8 *)buf_u32;
3070  // Basic sanity checks - reject files which are too small, and check the first 4 bytes of the file to make sure a local header is there.
3072  return MZ_FALSE;
3073  // Find the end of central directory record by scanning the file from the end towards the beginning.
3074  cur_file_ofs = MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)sizeof(buf_u32), 0);
3075  for ( ; ; )
3076  {
3077  int i, n = (int)MZ_MIN(sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs);
3078  if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n)
3079  return MZ_FALSE;
3080  for (i = n - 4; i >= 0; --i)
3082  break;
3083  if (i >= 0)
3084  {
3085  cur_file_ofs += i;
3086  break;
3087  }
3088  if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >= (0xFFFF + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)))
3089  return MZ_FALSE;
3090  cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0);
3091  }
3092  // Read and verify the end of central directory record.
3094  return MZ_FALSE;
3097  return MZ_FALSE;
3098 
3099  num_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS);
3100  cdir_disk_index = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS);
3101  if (((num_this_disk | cdir_disk_index) != 0) && ((num_this_disk != 1) || (cdir_disk_index != 1)))
3102  return MZ_FALSE;
3103 
3105  return MZ_FALSE;
3106 
3107  cdir_ofs = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS);
3108  if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size)
3109  return MZ_FALSE;
3110 
3111  pZip->m_central_directory_file_ofs = cdir_ofs;
3112 
3113  if (pZip->m_total_files)
3114  {
3115  mz_uint i, n;
3116  // Read the entire central directory into a heap block, and allocate another heap block to hold the unsorted central dir file record offsets, and another to hold the sorted indices.
3117  if ((!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir, cdir_size, MZ_FALSE)) ||
3120  return MZ_FALSE;
3121  if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs, pZip->m_pState->m_central_dir.m_p, cdir_size) != cdir_size)
3122  return MZ_FALSE;
3123 
3124  // Now create an index into the central directory file records, do some basic sanity checking on each record, and check for zip64 entries (which are not yet supported).
3125  p = (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p;
3126  for (n = cdir_size, i = 0; i < pZip->m_total_files; ++i)
3127  {
3128  mz_uint total_header_size, comp_size, decomp_size, disk_index;
3130  return MZ_FALSE;
3131  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);
3132  MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_sorted_central_dir_offsets, mz_uint32, i) = i;
3135  if (((!MZ_READ_LE32(p + MZ_ZIP_CDH_METHOD_OFS)) && (decomp_size != comp_size)) || (decomp_size && !comp_size) || (decomp_size == 0xFFFFFFFF) || (comp_size == 0xFFFFFFFF))
3136  return MZ_FALSE;
3137  disk_index = MZ_READ_LE16(p + MZ_ZIP_CDH_DISK_START_OFS);
3138  if ((disk_index != num_this_disk) && (disk_index != 1))
3139  return MZ_FALSE;
3140  if (((mz_uint64)MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS) + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + comp_size) > pZip->m_archive_size)
3141  return MZ_FALSE;
3143  return MZ_FALSE;
3144  n -= total_header_size; p += total_header_size;
3145  }
3146  }
3147 
3148  if ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0)
3150 
3151  return MZ_TRUE;
3152 }
3153 
3154 mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint32 flags)
3155 {
3156  if ((!pZip) || (!pZip->m_pRead))
3157  return MZ_FALSE;
3158  if (!mz_zip_reader_init_internal(pZip, flags))
3159  return MZ_FALSE;
3160  pZip->m_archive_size = size;
3161  if (!mz_zip_reader_read_central_dir(pZip, flags))
3162  {
3163  mz_zip_reader_end(pZip);
3164  return MZ_FALSE;
3165  }
3166  return MZ_TRUE;
3167 }
3168 
3169 static size_t mz_zip_mem_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
3170 {
3171  mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
3172  size_t s = (file_ofs >= pZip->m_archive_size) ? 0 : (size_t)MZ_MIN(pZip->m_archive_size - file_ofs, n);
3173  memcpy(pBuf, (const mz_uint8 *)pZip->m_pState->m_pMem + file_ofs, s);
3174  return s;
3175 }
3176 
3177 mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint32 flags)
3178 {
3179  if (!mz_zip_reader_init_internal(pZip, flags))
3180  return MZ_FALSE;
3181  pZip->m_archive_size = size;
3182  pZip->m_pRead = mz_zip_mem_read_func;
3183  pZip->m_pIO_opaque = pZip;
3184  pZip->m_pState->m_pMem = (void *)pMem;
3185  pZip->m_pState->m_mem_size = size;
3186  if (!mz_zip_reader_read_central_dir(pZip, flags))
3187  {
3188  mz_zip_reader_end(pZip);
3189  return MZ_FALSE;
3190  }
3191  return MZ_TRUE;
3192 }
3193 
3194 #ifndef MINIZ_NO_STDIO
3195 static size_t mz_zip_file_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
3196 {
3197  mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
3198  mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
3199  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))))
3200  return 0;
3201  return MZ_FREAD(pBuf, 1, n, pZip->m_pState->m_pFile);
3202 }
3203 
3204 mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags)
3205 {
3206  mz_uint64 file_size;
3207  MZ_FILE *pFile = MZ_FOPEN(pFilename, "rb");
3208  if (!pFile)
3209  return MZ_FALSE;
3210  if (MZ_FSEEK64(pFile, 0, SEEK_END))
3211  return MZ_FALSE;
3212  file_size = MZ_FTELL64(pFile);
3213  if (!mz_zip_reader_init_internal(pZip, flags))
3214  {
3215  MZ_FCLOSE(pFile);
3216  return MZ_FALSE;
3217  }
3219  pZip->m_pIO_opaque = pZip;
3220  pZip->m_pState->m_pFile = pFile;
3221  pZip->m_archive_size = file_size;
3222  if (!mz_zip_reader_read_central_dir(pZip, flags))
3223  {
3224  mz_zip_reader_end(pZip);
3225  return MZ_FALSE;
3226  }
3227  return MZ_TRUE;
3228 }
3229 #endif // #ifndef MINIZ_NO_STDIO
3230 
3232 {
3233  return pZip ? pZip->m_total_files : 0;
3234 }
3235 
3236 static MZ_FORCEINLINE const mz_uint8 *mz_zip_reader_get_cdh(mz_zip_archive *pZip, mz_uint file_index)
3237 {
3238  if ((!pZip) || (!pZip->m_pState) || (file_index >= pZip->m_total_files) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
3239  return NULL;
3240  return &MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index));
3241 }
3242 
3243 mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index)
3244 {
3245  mz_uint m_bit_flag;
3246  const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
3247  if (!p)
3248  return MZ_FALSE;
3249  m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
3250  return (m_bit_flag & 1);
3251 }
3252 
3253 mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index)
3254 {
3255  mz_uint filename_len, internal_attr, external_attr;
3256  const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
3257  if (!p)
3258  return MZ_FALSE;
3259 
3260  internal_attr = MZ_READ_LE16(p + MZ_ZIP_CDH_INTERNAL_ATTR_OFS);
3261  external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS);
3262  if ((!internal_attr) && ((external_attr & 0x10) != 0))
3263  return MZ_TRUE;
3264 
3265  filename_len = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
3266  if (filename_len)
3267  {
3268  if (*(p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_len - 1) == '/')
3269  return MZ_TRUE;
3270  }
3271 
3272  return MZ_FALSE;
3273 }
3274 
3275 mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat)
3276 {
3277  mz_uint n;
3278  const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
3279  if ((!p) || (!pStat))
3280  return MZ_FALSE;
3281 
3282  // Unpack the central directory record.
3283  pStat->m_file_index = file_index;
3284  pStat->m_central_dir_ofs = MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index);
3289 #ifndef MINIZ_NO_TIME
3291 #endif
3298 
3299  // Copy as much of the filename and comment as possible.
3301  memcpy(pStat->m_filename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n); pStat->m_filename[n] = '\0';
3302 
3304  pStat->m_comment_size = n;
3306 
3307  return MZ_TRUE;
3308 }
3309 
3310 mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size)
3311 {
3312  mz_uint n;
3313  const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
3314  if (!p) { if (filename_buf_size) pFilename[0] = '\0'; return 0; }
3316  if (filename_buf_size)
3317  {
3318  n = MZ_MIN(n, filename_buf_size - 1);
3319  memcpy(pFilename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n);
3320  pFilename[n] = '\0';
3321  }
3322  return n + 1;
3323 }
3324 
3325 static MZ_FORCEINLINE mz_bool mz_zip_reader_string_equal(const char *pA, const char *pB, mz_uint len, mz_uint flags)
3326 {
3327  mz_uint i;
3328  if (flags & MZ_ZIP_FLAG_CASE_SENSITIVE)
3329  return 0 == memcmp(pA, pB, len);
3330  for (i = 0; i < len; ++i)
3331  if (MZ_TOLOWER(pA[i]) != MZ_TOLOWER(pB[i]))
3332  return MZ_FALSE;
3333  return MZ_TRUE;
3334 }
3335 
3336 static MZ_FORCEINLINE int mz_zip_reader_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)
3337 {
3338  const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE;
3339  mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS);
3340  mz_uint8 l = 0, r = 0;
3342  pE = pL + MZ_MIN(l_len, r_len);
3343  while (pL < pE)
3344  {
3345  if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR)))
3346  break;
3347  pL++; pR++;
3348  }
3349  return (pL == pE) ? (int)(l_len - r_len) : (l - r);
3350 }
3351 
3352 static int mz_zip_reader_locate_file_binary_search(mz_zip_archive *pZip, const char *pFilename)
3353 {
3354  mz_zip_internal_state *pState = pZip->m_pState;
3355  const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
3356  const mz_zip_array *pCentral_dir = &pState->m_central_dir;
3357  mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0);
3358  const int size = pZip->m_total_files;
3359  const mz_uint filename_len = (mz_uint)strlen(pFilename);
3360  int l = 0, h = size - 1;
3361  while (l <= h)
3362  {
3363  int m = (l + h) >> 1, file_index = pIndices[m], comp = mz_zip_reader_filename_compare(pCentral_dir, pCentral_dir_offsets, file_index, pFilename, filename_len);
3364  if (!comp)
3365  return file_index;
3366  else if (comp < 0)
3367  l = m + 1;
3368  else
3369  h = m - 1;
3370  }
3371  return -1;
3372 }
3373 
3374 int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags)
3375 {
3376  mz_uint file_index; size_t name_len, comment_len;
3377  if ((!pZip) || (!pZip->m_pState) || (!pName) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
3378  return -1;
3379  if (((flags & (MZ_ZIP_FLAG_IGNORE_PATH | MZ_ZIP_FLAG_CASE_SENSITIVE)) == 0) && (!pComment) && (pZip->m_pState->m_sorted_central_dir_offsets.m_p))
3380  return mz_zip_reader_locate_file_binary_search(pZip, pName);
3381  name_len = strlen(pName); if (name_len > 0xFFFF) return -1;
3382  comment_len = pComment ? strlen(pComment) : 0; if (comment_len > 0xFFFF) return -1;
3383  for (file_index = 0; file_index < pZip->m_total_files; file_index++)
3384  {
3385  const mz_uint8 *pHeader = &MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index));
3386  mz_uint filename_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_FILENAME_LEN_OFS);
3387  const char *pFilename = (const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
3388  if (filename_len < name_len)
3389  continue;
3390  if (comment_len)
3391  {
3392  mz_uint file_extra_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_EXTRA_LEN_OFS), file_comment_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_COMMENT_LEN_OFS);
3393  const char *pFile_comment = pFilename + filename_len + file_extra_len;
3394  if ((file_comment_len != comment_len) || (!mz_zip_reader_string_equal(pComment, pFile_comment, file_comment_len, flags)))
3395  continue;
3396  }
3397  if ((flags & MZ_ZIP_FLAG_IGNORE_PATH) && (filename_len))
3398  {
3399  int ofs = filename_len - 1;
3400  do
3401  {
3402  if ((pFilename[ofs] == '/') || (pFilename[ofs] == '\\') || (pFilename[ofs] == ':'))
3403  break;
3404  } while (--ofs >= 0);
3405  ofs++;
3406  pFilename += ofs; filename_len -= ofs;
3407  }
3408  if ((filename_len == name_len) && (mz_zip_reader_string_equal(pName, pFilename, filename_len, flags)))
3409  return file_index;
3410  }
3411  return -1;
3412 }
3413 
3414 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)
3415 {
3416  int status = TINFL_STATUS_DONE;
3417  mz_uint64 needed_size, cur_file_ofs, comp_remaining, out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail;
3418  mz_zip_archive_file_stat file_stat;
3419  void *pRead_buf;
3420  mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
3421  tinfl_decompressor inflator;
3422 
3423  if ((buf_size) && (!pBuf))
3424  return MZ_FALSE;
3425 
3426  if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
3427  return MZ_FALSE;
3428 
3429  if (!file_stat.m_comp_size)
3430  return MZ_TRUE;
3431 
3432  // Encryption and patch files are not supported.
3433  if (file_stat.m_bit_flag & (1 | 32))
3434  return MZ_FALSE;
3435 
3436  // This function only supports stored and deflate.
3437  if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
3438  return MZ_FALSE;
3439 
3440  // Ensure supplied output buffer is large enough.
3441  needed_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size : file_stat.m_uncomp_size;
3442  if (buf_size < needed_size)
3443  return MZ_FALSE;
3444 
3445  // Read and parse the local directory entry.
3446  cur_file_ofs = file_stat.m_local_header_ofs;
3447  if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
3448  return MZ_FALSE;
3449  if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
3450  return MZ_FALSE;
3451 
3453  if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
3454  return MZ_FALSE;
3455 
3456  if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method))
3457  {
3458  // The file is stored or the caller has requested the compressed data.
3459  if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, (size_t)needed_size) != needed_size)
3460  return MZ_FALSE;
3461  return ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) != 0) || (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) == file_stat.m_crc32);
3462  }
3463 
3464  // Decompress the file either directly from memory or from a file input buffer.
3465  tinfl_init(&inflator);
3466 
3467  if (pZip->m_pState->m_pMem)
3468  {
3469  // Read directly from the archive in memory.
3470  pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
3471  read_buf_size = read_buf_avail = file_stat.m_comp_size;
3472  comp_remaining = 0;
3473  }
3474  else if (pUser_read_buf)
3475  {
3476  // Use a user provided read buffer.
3477  if (!user_read_buf_size)
3478  return MZ_FALSE;
3479  pRead_buf = (mz_uint8 *)pUser_read_buf;
3480  read_buf_size = user_read_buf_size;
3481  read_buf_avail = 0;
3482  comp_remaining = file_stat.m_uncomp_size;
3483  }
3484  else
3485  {
3486  // Temporarily allocate a read buffer.
3487  read_buf_size = MZ_MIN(file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE);
3488 #ifdef _MSC_VER
3489  if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
3490 #else
3491  if (((sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
3492 #endif
3493  return MZ_FALSE;
3494  if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size)))
3495  return MZ_FALSE;
3496  read_buf_avail = 0;
3497  comp_remaining = file_stat.m_comp_size;
3498  }
3499 
3500  do
3501  {
3502  size_t in_buf_size, out_buf_size = (size_t)(file_stat.m_uncomp_size - out_buf_ofs);
3503  if ((!read_buf_avail) && (!pZip->m_pState->m_pMem))
3504  {
3505  read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
3506  if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
3507  {
3508  status = TINFL_STATUS_FAILED;
3509  break;
3510  }
3511  cur_file_ofs += read_buf_avail;
3512  comp_remaining -= read_buf_avail;
3513  read_buf_ofs = 0;
3514  }
3515  in_buf_size = (size_t)read_buf_avail;
3516  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));
3517  read_buf_avail -= in_buf_size;
3518  read_buf_ofs += in_buf_size;
3519  out_buf_ofs += out_buf_size;
3520  } while (status == TINFL_STATUS_NEEDS_MORE_INPUT);
3521 
3522  if (status == TINFL_STATUS_DONE)
3523  {
3524  // Make sure the entire file was decompressed, and check its CRC.
3525  if ((out_buf_ofs != file_stat.m_uncomp_size) || (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32))
3526  status = TINFL_STATUS_FAILED;
3527  }
3528 
3529  if ((!pZip->m_pState->m_pMem) && (!pUser_read_buf))
3530  pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
3531 
3532  return status == TINFL_STATUS_DONE;
3533 }
3534 
3535 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)
3536 {
3537  int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags);
3538  if (file_index < 0)
3539  return MZ_FALSE;
3540  return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, pUser_read_buf, user_read_buf_size);
3541 }
3542 
3543 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)
3544 {
3545  return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, NULL, 0);
3546 }
3547 
3548 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)
3549 {
3550  return mz_zip_reader_extract_file_to_mem_no_alloc(pZip, pFilename, pBuf, buf_size, flags, NULL, 0);
3551 }
3552 
3553 void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags)
3554 {
3555  mz_uint64 comp_size, uncomp_size, alloc_size;
3556  const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
3557  void *pBuf;
3558 
3559  if (pSize)
3560  *pSize = 0;
3561  if (!p)
3562  return NULL;
3563 
3566 
3567  alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size;
3568 #ifdef _MSC_VER
3569  if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
3570 #else
3571  if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
3572 #endif
3573  return NULL;
3574  if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size)))
3575  return NULL;
3576 
3577  if (!mz_zip_reader_extract_to_mem(pZip, file_index, pBuf, (size_t)alloc_size, flags))
3578  {
3579  pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
3580  return NULL;
3581  }
3582 
3583  if (pSize) *pSize = (size_t)alloc_size;
3584  return pBuf;
3585 }
3586 
3587 void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags)
3588 {
3589  int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags);
3590  if (file_index < 0)
3591  {
3592  if (pSize) *pSize = 0;
3593  return MZ_FALSE;
3594  }
3595  return mz_zip_reader_extract_to_heap(pZip, file_index, pSize, flags);
3596 }
3597 
3598 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)
3599 {
3600  int status = TINFL_STATUS_DONE; mz_uint file_crc32 = MZ_CRC32_INIT;
3601  mz_uint64 read_buf_size, read_buf_ofs = 0, read_buf_avail, comp_remaining, out_buf_ofs = 0, cur_file_ofs;
3602  mz_zip_archive_file_stat file_stat;
3603  void *pRead_buf = NULL; void *pWrite_buf = NULL;
3604  mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
3605 
3606  if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
3607  return MZ_FALSE;
3608 
3609  if (!file_stat.m_comp_size)
3610  return MZ_TRUE;
3611 
3612  // Encryption and patch files are not supported.
3613  if (file_stat.m_bit_flag & (1 | 32))
3614  return MZ_FALSE;
3615 
3616  // This function only supports stored and deflate.
3617  if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
3618  return MZ_FALSE;
3619 
3620  // Read and parse the local directory entry.
3621  cur_file_ofs = file_stat.m_local_header_ofs;
3622  if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
3623  return MZ_FALSE;
3624  if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
3625  return MZ_FALSE;
3626 
3628  if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
3629  return MZ_FALSE;
3630 
3631  // Decompress the file either directly from memory or from a file input buffer.
3632  if (pZip->m_pState->m_pMem)
3633  {
3634  pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
3635  read_buf_size = read_buf_avail = file_stat.m_comp_size;
3636  comp_remaining = 0;
3637  }
3638  else
3639  {
3640  read_buf_size = MZ_MIN(file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE);
3641  if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size)))
3642  return MZ_FALSE;
3643  read_buf_avail = 0;
3644  comp_remaining = file_stat.m_comp_size;
3645  }
3646 
3647  if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method))
3648  {
3649  // The file is stored or the caller has requested the compressed data.
3650  if (pZip->m_pState->m_pMem)
3651  {
3652 #ifdef _MSC_VER
3653  if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (file_stat.m_comp_size > 0xFFFFFFFF))
3654 #else
3655  if (((sizeof(size_t) == sizeof(mz_uint32))) && (file_stat.m_comp_size > 0xFFFFFFFF))
3656 #endif
3657  return MZ_FALSE;
3658  if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)file_stat.m_comp_size) != file_stat.m_comp_size)
3659  status = TINFL_STATUS_FAILED;
3660  else if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
3661  file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)file_stat.m_comp_size);
3662  cur_file_ofs += file_stat.m_comp_size;
3663  out_buf_ofs += file_stat.m_comp_size;
3664  comp_remaining = 0;
3665  }
3666  else
3667  {
3668  while (comp_remaining)
3669  {
3670  read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
3671  if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
3672  {
3673  status = TINFL_STATUS_FAILED;
3674  break;
3675  }
3676 
3677  if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
3678  file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)read_buf_avail);
3679 
3680  if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
3681  {
3682  status = TINFL_STATUS_FAILED;
3683  break;
3684  }
3685  cur_file_ofs += read_buf_avail;
3686  out_buf_ofs += read_buf_avail;
3687  comp_remaining -= read_buf_avail;
3688  }
3689  }
3690  }
3691  else
3692  {
3693  tinfl_decompressor inflator;
3694  tinfl_init(&inflator);
3695 
3696  if (NULL == (pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, TINFL_LZ_DICT_SIZE)))
3697  status = TINFL_STATUS_FAILED;
3698  else
3699  {
3700  do
3701  {
3702  mz_uint8 *pWrite_buf_cur = (mz_uint8 *)pWrite_buf + (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
3703  size_t in_buf_size, out_buf_size = TINFL_LZ_DICT_SIZE - (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
3704  if ((!read_buf_avail) && (!pZip->m_pState->m_pMem))
3705  {
3706  read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
3707  if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail)
3708  {
3709  status = TINFL_STATUS_FAILED;
3710  break;
3711  }
3712  cur_file_ofs += read_buf_avail;
3713  comp_remaining -= read_buf_avail;
3714  read_buf_ofs = 0;
3715  }
3716 
3717  in_buf_size = (size_t)read_buf_avail;
3718  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);
3719  read_buf_avail -= in_buf_size;
3720  read_buf_ofs += in_buf_size;
3721 
3722  if (out_buf_size)
3723  {
3724  if (pCallback(pOpaque, out_buf_ofs, pWrite_buf_cur, out_buf_size) != out_buf_size)
3725  {
3726  status = TINFL_STATUS_FAILED;
3727  break;
3728  }
3729  file_crc32 = (mz_uint32)mz_crc32(file_crc32, pWrite_buf_cur, out_buf_size);
3730  if ((out_buf_ofs += out_buf_size) > file_stat.m_uncomp_size)
3731  {
3732  status = TINFL_STATUS_FAILED;
3733  break;
3734  }
3735  }
3736  } while ((status == TINFL_STATUS_NEEDS_MORE_INPUT) || (status == TINFL_STATUS_HAS_MORE_OUTPUT));
3737  }
3738  }
3739 
3740  if ((status == TINFL_STATUS_DONE) && (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)))
3741  {
3742  // Make sure the entire file was decompressed, and check its CRC.
3743  if ((out_buf_ofs != file_stat.m_uncomp_size) || (file_crc32 != file_stat.m_crc32))
3744  status = TINFL_STATUS_FAILED;
3745  }
3746 
3747  if (!pZip->m_pState->m_pMem)
3748  pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
3749  if (pWrite_buf)
3750  pZip->m_pFree(pZip->m_pAlloc_opaque, pWrite_buf);
3751 
3752  return status == TINFL_STATUS_DONE;
3753 }
3754 
3755 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)
3756 {
3757  int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags);
3758  if (file_index < 0)
3759  return MZ_FALSE;
3760  return mz_zip_reader_extract_to_callback(pZip, file_index, pCallback, pOpaque, flags);
3761 }
3762 
3763 #ifndef MINIZ_NO_STDIO
3764 static size_t mz_zip_file_write_callback(void *pOpaque, mz_uint64 ofs, const void *pBuf, size_t n)
3765 {
3766  (void)ofs; return MZ_FWRITE(pBuf, 1, n, (MZ_FILE*)pOpaque);
3767 }
3768 
3769 mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags)
3770 {
3771  mz_bool status;
3772  mz_zip_archive_file_stat file_stat;
3773  MZ_FILE *pFile;
3774  if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
3775  return MZ_FALSE;
3776  pFile = MZ_FOPEN(pDst_filename, "wb");
3777  if (!pFile)
3778  return MZ_FALSE;
3779  status = mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_file_write_callback, pFile, flags);
3780  if (MZ_FCLOSE(pFile) == EOF)
3781  return MZ_FALSE;
3782 #ifndef MINIZ_NO_TIME
3783  if (status)
3784  mz_zip_set_file_times(pDst_filename, file_stat.m_time, file_stat.m_time);
3785 #endif
3786  return status;
3787 }
3788 #endif // #ifndef MINIZ_NO_STDIO
3789 
3791 {
3792  if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
3793  return MZ_FALSE;
3794 
3795  if (pZip->m_pState)
3796  {
3797  mz_zip_internal_state *pState = pZip->m_pState; pZip->m_pState = NULL;
3798  mz_zip_array_clear(pZip, &pState->m_central_dir);
3799  mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
3801 
3802 #ifndef MINIZ_NO_STDIO
3803  if (pState->m_pFile)
3804  {
3805  MZ_FCLOSE(pState->m_pFile);
3806  pState->m_pFile = NULL;
3807  }
3808 #endif // #ifndef MINIZ_NO_STDIO
3809 
3810  pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
3811  }
3813 
3814  return MZ_TRUE;
3815 }
3816 
3817 #ifndef MINIZ_NO_STDIO
3818 mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags)
3819 {
3820  int file_index = mz_zip_reader_locate_file(pZip, pArchive_filename, NULL, flags);
3821  if (file_index < 0)
3822  return MZ_FALSE;
3823  return mz_zip_reader_extract_to_file(pZip, file_index, pDst_filename, flags);
3824 }
3825 #endif
3826 
3827 // ------------------- .ZIP archive writing
3828 
3829 #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
3830 
3831 static void mz_write_le16(mz_uint8 *p, mz_uint16 v) { p[0] = (mz_uint8)v; p[1] = (mz_uint8)(v >> 8); }
3832 static void mz_write_le32(mz_uint8 *p, mz_uint32 v) { p[0] = (mz_uint8)v; p[1] = (mz_uint8)(v >> 8); p[2] = (mz_uint8)(v >> 16); p[3] = (mz_uint8)(v >> 24); }
3833 #define MZ_WRITE_LE16(p, v) mz_write_le16((mz_uint8 *)(p), (mz_uint16)(v))
3834 #define MZ_WRITE_LE32(p, v) mz_write_le32((mz_uint8 *)(p), (mz_uint32)(v))
3835 
3836 mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size)
3837 {
3838  if ((!pZip) || (pZip->m_pState) || (!pZip->m_pWrite) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
3839  return MZ_FALSE;
3840 
3841  if (pZip->m_file_offset_alignment)
3842  {
3843  // Ensure user specified file offset alignment is a power of 2.
3844  if (pZip->m_file_offset_alignment & (pZip->m_file_offset_alignment - 1))
3845  return MZ_FALSE;
3846  }
3847 
3848  if (!pZip->m_pAlloc) pZip->m_pAlloc = def_alloc_func;
3849  if (!pZip->m_pFree) pZip->m_pFree = def_free_func;
3850  if (!pZip->m_pRealloc) pZip->m_pRealloc = def_realloc_func;
3851 
3853  pZip->m_archive_size = existing_size;
3854  pZip->m_central_directory_file_ofs = 0;
3855  pZip->m_total_files = 0;
3856 
3857  if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state))))
3858  return MZ_FALSE;
3859  memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state));
3860  MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, sizeof(mz_uint8));
3861  MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, sizeof(mz_uint32));
3863  return MZ_TRUE;
3864 }
3865 
3866 static size_t mz_zip_heap_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
3867 {
3868  mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
3869  mz_zip_internal_state *pState = pZip->m_pState;
3870  mz_uint64 new_size = MZ_MAX(file_ofs + n, pState->m_mem_size);
3871 #ifdef _MSC_VER
3872  if ((!n) || ((0, sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF)))
3873 #else
3874  if ((!n) || ((sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF)))
3875 #endif
3876  return 0;
3877  if (new_size > pState->m_mem_capacity)
3878  {
3879  void *pNew_block;
3880  size_t new_capacity = MZ_MAX(64, pState->m_mem_capacity); while (new_capacity < new_size) new_capacity *= 2;
3881  if (NULL == (pNew_block = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pState->m_pMem, 1, new_capacity)))
3882  return 0;
3883  pState->m_pMem = pNew_block; pState->m_mem_capacity = new_capacity;
3884  }
3885  memcpy((mz_uint8 *)pState->m_pMem + file_ofs, pBuf, n);
3886  pState->m_mem_size = (size_t)new_size;
3887  return n;
3888 }
3889 
3890 mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size)
3891 {
3893  pZip->m_pIO_opaque = pZip;
3894  if (!mz_zip_writer_init(pZip, size_to_reserve_at_beginning))
3895  return MZ_FALSE;
3896  if (0 != (initial_allocation_size = MZ_MAX(initial_allocation_size, size_to_reserve_at_beginning)))
3897  {
3898  if (NULL == (pZip->m_pState->m_pMem = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, initial_allocation_size)))
3899  {
3900  mz_zip_writer_end(pZip);
3901  return MZ_FALSE;
3902  }
3903  pZip->m_pState->m_mem_capacity = initial_allocation_size;
3904  }
3905  return MZ_TRUE;
3906 }
3907 
3908 #ifndef MINIZ_NO_STDIO
3909 static size_t mz_zip_file_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n)
3910 {
3911  mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
3912  mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
3913  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))))
3914  return 0;
3915  return MZ_FWRITE(pBuf, 1, n, pZip->m_pState->m_pFile);
3916 }
3917 
3918 mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning)
3919 {
3920  MZ_FILE *pFile;
3922  pZip->m_pIO_opaque = pZip;
3923  if (!mz_zip_writer_init(pZip, size_to_reserve_at_beginning))
3924  return MZ_FALSE;
3925  if (NULL == (pFile = MZ_FOPEN(pFilename, "wb")))
3926  {
3927  mz_zip_writer_end(pZip);
3928  return MZ_FALSE;
3929  }
3930  pZip->m_pState->m_pFile = pFile;
3931  if (size_to_reserve_at_beginning)
3932  {
3933  mz_uint64 cur_ofs = 0; char buf[4096]; MZ_CLEAR_OBJ(buf);
3934  do
3935  {
3936  size_t n = (size_t)MZ_MIN(sizeof(buf), size_to_reserve_at_beginning);
3937  if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_ofs, buf, n) != n)
3938  {
3939  mz_zip_writer_end(pZip);
3940  return MZ_FALSE;
3941  }
3942  cur_ofs += n; size_to_reserve_at_beginning -= n;
3943  } while (size_to_reserve_at_beginning);
3944  }
3945  return MZ_TRUE;
3946 }
3947 #endif // #ifndef MINIZ_NO_STDIO
3948 
3949 mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename)
3950 {
3951  mz_zip_internal_state *pState;
3952  if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
3953  return MZ_FALSE;
3954  // No sense in trying to write to an archive that's already at the support max size
3955  if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_ZIP_LOCAL_DIR_HEADER_SIZE) > 0xFFFFFFFF))
3956  return MZ_FALSE;
3957 
3958  pState = pZip->m_pState;
3959 
3960  if (pState->m_pFile)
3961  {
3962 #ifdef MINIZ_NO_STDIO
3963  pFilename; return MZ_FALSE;
3964 #else
3965  // Archive is being read from stdio - try to reopen as writable.
3966  if (pZip->m_pIO_opaque != pZip)
3967  return MZ_FALSE;
3968  if (!pFilename)
3969  return MZ_FALSE;
3971  if (NULL == (pState->m_pFile = MZ_FREOPEN(pFilename, "r+b", pState->m_pFile)))
3972  {
3973  // The mz_zip_archive is now in a bogus state because pState->m_pFile is NULL, so just close it.
3974  mz_zip_reader_end(pZip);
3975  return MZ_FALSE;
3976  }
3977 #endif // #ifdef MINIZ_NO_STDIO
3978  }
3979  else if (pState->m_pMem)
3980  {
3981  // Archive lives in a memory block. Assume it's from the heap that we can resize using the realloc callback.
3982  if (pZip->m_pIO_opaque != pZip)
3983  return MZ_FALSE;
3984  pState->m_mem_capacity = pState->m_mem_size;
3986  }
3987  // Archive is being read via a user provided read function - make sure the user has specified a write function too.
3988  else if (!pZip->m_pWrite)
3989  return MZ_FALSE;
3990 
3991  // Start writing new files at the archive's current central directory location.
3994  pZip->m_central_directory_file_ofs = 0;
3995 
3996  return MZ_TRUE;
3997 }
3998 
3999 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)
4000 {
4001  return mz_zip_writer_add_mem_ex(pZip, pArchive_name, pBuf, buf_size, NULL, 0, level_and_flags, 0, 0);
4002 }
4003 
4004 typedef struct
4005 {
4008  mz_uint64 m_comp_size;
4010 
4011 static mz_bool mz_zip_writer_add_put_buf_callback(const void* pBuf, int len, void *pUser)
4012 {
4014  if ((int)pState->m_pZip->m_pWrite(pState->m_pZip->m_pIO_opaque, pState->m_cur_archive_file_ofs, pBuf, len) != len)
4015  return MZ_FALSE;
4016  pState->m_cur_archive_file_ofs += len;
4017  pState->m_comp_size += len;
4018  return MZ_TRUE;
4019 }
4020 
4021 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)
4022 {
4023  (void)pZip;
4024  memset(pDst, 0, MZ_ZIP_LOCAL_DIR_HEADER_SIZE);
4026  MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_VERSION_NEEDED_OFS, method ? 20 : 0);
4027  MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_BIT_FLAG_OFS, bit_flags);
4028  MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_METHOD_OFS, method);
4029  MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_TIME_OFS, dos_time);
4030  MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_DATE_OFS, dos_date);
4031  MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_CRC32_OFS, uncomp_crc32);
4032  MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS, comp_size);
4033  MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS, uncomp_size);
4034  MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILENAME_LEN_OFS, filename_size);
4035  MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_EXTRA_LEN_OFS, extra_size);
4036  return MZ_TRUE;
4037 }
4038 
4039 static mz_bool mz_zip_writer_create_central_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, mz_uint16 extra_size, mz_uint16 comment_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, mz_uint64 local_header_ofs, mz_uint32 ext_attributes)
4040 {
4041  (void)pZip;
4042  memset(pDst, 0, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE);
4044  MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_VERSION_NEEDED_OFS, method ? 20 : 0);
4045  MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_BIT_FLAG_OFS, bit_flags);
4046  MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_METHOD_OFS, method);
4047  MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_TIME_OFS, dos_time);
4048  MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_DATE_OFS, dos_date);
4049  MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_CRC32_OFS, uncomp_crc32);
4050  MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS, comp_size);
4051  MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS, uncomp_size);
4052  MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILENAME_LEN_OFS, filename_size);
4053  MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_EXTRA_LEN_OFS, extra_size);
4054  MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_COMMENT_LEN_OFS, comment_size);
4055  MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS, ext_attributes);
4056  MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_LOCAL_HEADER_OFS, local_header_ofs);
4057  return MZ_TRUE;
4058 }
4059 
4060 static mz_bool mz_zip_writer_add_to_central_dir(mz_zip_archive *pZip, const char *pFilename, mz_uint16 filename_size, const void *pExtra, mz_uint16 extra_size, const void *pComment, mz_uint16 comment_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, mz_uint64 local_header_ofs, mz_uint32 ext_attributes)
4061 {
4062  mz_zip_internal_state *pState = pZip->m_pState;
4063  mz_uint32 central_dir_ofs = (mz_uint32)pState->m_central_dir.m_size;
4064  size_t orig_central_dir_size = pState->m_central_dir.m_size;
4065  mz_uint8 central_dir_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE];
4066 
4067  // No zip64 support yet
4068  if ((local_header_ofs > 0xFFFFFFFF) || (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + extra_size + comment_size) > 0xFFFFFFFF))
4069  return MZ_FALSE;
4070 
4071  if (!mz_zip_writer_create_central_dir_header(pZip, central_dir_header, filename_size, extra_size, comment_size, uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, dos_date, local_header_ofs, ext_attributes))
4072  return MZ_FALSE;
4073 
4074  if ((!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_dir_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) ||
4075  (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pFilename, filename_size)) ||
4076  (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pExtra, extra_size)) ||
4077  (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pComment, comment_size)) ||
4078  (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &central_dir_ofs, 1)))
4079  {
4080  // Try to push the central directory array back into its original state.
4081  mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
4082  return MZ_FALSE;
4083  }
4084 
4085  return MZ_TRUE;
4086 }
4087 
4088 static mz_bool mz_zip_writer_validate_archive_name(const char *pArchive_name)
4089 {
4090  // Basic ZIP archive filename validity checks: Valid filenames cannot start with a forward slash, cannot contain a drive letter, and cannot use DOS-style backward slashes.
4091  if (*pArchive_name == '/')
4092  return MZ_FALSE;
4093  while (*pArchive_name)
4094  {
4095  if ((*pArchive_name == '\\') || (*pArchive_name == ':'))
4096  return MZ_FALSE;
4097  pArchive_name++;
4098  }
4099  return MZ_TRUE;
4100 }
4101 
4103 {
4104  mz_uint32 n;
4105  if (!pZip->m_file_offset_alignment)
4106  return 0;
4107  n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1));
4108  return (pZip->m_file_offset_alignment - n) & (pZip->m_file_offset_alignment - 1);
4109 }
4110 
4111 static mz_bool mz_zip_writer_write_zeros(mz_zip_archive *pZip, mz_uint64 cur_file_ofs, mz_uint32 n)
4112 {
4113  char buf[4096];
4114  memset(buf, 0, MZ_MIN(sizeof(buf), n));
4115  while (n)
4116  {
4117  mz_uint32 s = MZ_MIN(sizeof(buf), n);
4118  if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_file_ofs, buf, s) != s)
4119  return MZ_FALSE;
4120  cur_file_ofs += s; n -= s;
4121  }
4122  return MZ_TRUE;
4123 }
4124 
4125 mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32)
4126 {
4127  mz_uint16 method = 0, dos_time = 0, dos_date = 0;
4128  mz_uint level, ext_attributes = 0, num_alignment_padding_bytes;
4129  mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, comp_size = 0;
4130  size_t archive_name_size;
4131  mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
4132  tdefl_compressor *pComp = NULL;
4133  mz_bool store_data_uncompressed;
4134  mz_zip_internal_state *pState;
4135 
4136  if ((int)level_and_flags < 0)
4137  level_and_flags = MZ_DEFAULT_LEVEL;
4138  level = level_and_flags & 0xF;
4139  store_data_uncompressed = ((!level) || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA));
4140 
4141  if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || ((buf_size) && (!pBuf)) || (!pArchive_name) || ((comment_size) && (!pComment)) || (pZip->m_total_files == 0xFFFF) || (level > MZ_UBER_COMPRESSION))
4142  return MZ_FALSE;
4143 
4144  pState = pZip->m_pState;
4145 
4146  if ((!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (uncomp_size))
4147  return MZ_FALSE;
4148  // No zip64 support yet
4149  if ((buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF))
4150  return MZ_FALSE;
4151  if (!mz_zip_writer_validate_archive_name(pArchive_name))
4152  return MZ_FALSE;
4153 
4154 #ifndef MINIZ_NO_TIME
4155  {
4156  time_t cur_time; time(&cur_time);
4157  mz_zip_time_to_dos_time(cur_time, &dos_time, &dos_date);
4158  }
4159 #endif // #ifndef MINIZ_NO_TIME
4160 
4161  archive_name_size = strlen(pArchive_name);
4162  if (archive_name_size > 0xFFFF)
4163  return MZ_FALSE;
4164 
4165  num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
4166 
4167  // no zip64 support yet
4168  if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + comment_size + archive_name_size) > 0xFFFFFFFF))
4169  return MZ_FALSE;
4170 
4171  if ((archive_name_size) && (pArchive_name[archive_name_size - 1] == '/'))
4172  {
4173  // Set DOS Subdirectory attribute bit.
4174  ext_attributes |= 0x10;
4175  // Subdirectories cannot contain data.
4176  if ((buf_size) || (uncomp_size))
4177  return MZ_FALSE;
4178  }
4179 
4180  // Try to do any allocations before writing to the archive, so if an allocation fails the file remains unmodified. (A good idea if we're doing an in-place modification.)
4181  if ((!mz_zip_array_ensure_room(pZip, &pState->m_central_dir, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size)) || (!mz_zip_array_ensure_room(pZip, &pState->m_central_dir_offsets, 1)))
4182  return MZ_FALSE;
4183 
4184  if ((!store_data_uncompressed) && (buf_size))
4185  {
4186  if (NULL == (pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor))))
4187  return MZ_FALSE;
4188  }
4189 
4190  if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes + sizeof(local_dir_header)))
4191  {
4192  pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
4193  return MZ_FALSE;
4194  }
4195  local_dir_header_ofs += num_alignment_padding_bytes;
4196  if (pZip->m_file_offset_alignment) { MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); }
4197  cur_archive_file_ofs += num_alignment_padding_bytes + sizeof(local_dir_header);
4198 
4199  MZ_CLEAR_OBJ(local_dir_header);
4200  if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
4201  {
4202  pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
4203  return MZ_FALSE;
4204  }
4205  cur_archive_file_ofs += archive_name_size;
4206 
4207  if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
4208  {
4209  uncomp_crc32 = (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8*)pBuf, buf_size);
4210  uncomp_size = buf_size;
4211  if (uncomp_size <= 3)
4212  {
4213  level = 0;
4214  store_data_uncompressed = MZ_TRUE;
4215  }
4216  }
4217 
4218  if (store_data_uncompressed)
4219  {
4220  if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pBuf, buf_size) != buf_size)
4221  {
4222  pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
4223  return MZ_FALSE;
4224  }
4225 
4226  cur_archive_file_ofs += buf_size;
4227  comp_size = buf_size;
4228 
4229  if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)
4230  method = MZ_DEFLATED;
4231  }
4232  else if (buf_size)
4233  {
4235 
4236  state.m_pZip = pZip;
4237  state.m_cur_archive_file_ofs = cur_archive_file_ofs;
4238  state.m_comp_size = 0;
4239 
4241  (tdefl_compress_buffer(pComp, pBuf, buf_size, TDEFL_FINISH) != TDEFL_STATUS_DONE))
4242  {
4243  pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
4244  return MZ_FALSE;
4245  }
4246 
4247  comp_size = state.m_comp_size;
4248  cur_archive_file_ofs = state.m_cur_archive_file_ofs;
4249 
4250  method = MZ_DEFLATED;
4251  }
4252 
4253  pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
4254  pComp = NULL;
4255 
4256  // no zip64 support yet
4257  if ((comp_size > 0xFFFFFFFF) || (cur_archive_file_ofs > 0xFFFFFFFF))
4258  return MZ_FALSE;
4259 
4260  if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, 0, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date))
4261  return MZ_FALSE;
4262 
4263  if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header))
4264  return MZ_FALSE;
4265 
4266  if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, NULL, 0, pComment, comment_size, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date, local_dir_header_ofs, ext_attributes))
4267  return MZ_FALSE;
4268 
4269  pZip->m_total_files++;
4270  pZip->m_archive_size = cur_archive_file_ofs;
4271 
4272  return MZ_TRUE;
4273 }
4274 
4275 #ifndef MINIZ_NO_STDIO
4276 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)
4277 {
4278  mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes;
4279  mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0;
4280  mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, uncomp_size = 0, comp_size = 0;
4281  size_t archive_name_size;
4282  mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
4283  MZ_FILE *pSrc_file = NULL;
4284 
4285  if ((int)level_and_flags < 0)
4286  level_and_flags = MZ_DEFAULT_LEVEL;
4287  level = level_and_flags & 0xF;
4288 
4289  if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION))
4290  return MZ_FALSE;
4291  if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)
4292  return MZ_FALSE;
4293  if (!mz_zip_writer_validate_archive_name(pArchive_name))
4294  return MZ_FALSE;
4295 
4296  archive_name_size = strlen(pArchive_name);
4297  if (archive_name_size > 0xFFFF)
4298  return MZ_FALSE;
4299 
4300  num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
4301 
4302  // no zip64 support yet
4303  if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + comment_size + archive_name_size) > 0xFFFFFFFF))
4304  return MZ_FALSE;
4305 
4306  if (!mz_zip_get_file_modified_time(pSrc_filename, &dos_time, &dos_date))
4307  return MZ_FALSE;
4308 
4309  pSrc_file = MZ_FOPEN(pSrc_filename, "rb");
4310  if (!pSrc_file)
4311  return MZ_FALSE;
4312  MZ_FSEEK64(pSrc_file, 0, SEEK_END);
4313  uncomp_size = MZ_FTELL64(pSrc_file);
4314  MZ_FSEEK64(pSrc_file, 0, SEEK_SET);
4315 
4316  if (uncomp_size > 0xFFFFFFFF)
4317  {
4318  // No zip64 support yet
4319  MZ_FCLOSE(pSrc_file);
4320  return MZ_FALSE;
4321  }
4322  if (uncomp_size <= 3)
4323  level = 0;
4324 
4325  if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes + sizeof(local_dir_header)))
4326  return MZ_FALSE;
4327  local_dir_header_ofs += num_alignment_padding_bytes;
4328  if (pZip->m_file_offset_alignment) { MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); }
4329  cur_archive_file_ofs += num_alignment_padding_bytes + sizeof(local_dir_header);
4330 
4331  MZ_CLEAR_OBJ(local_dir_header);
4332  if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
4333  {
4334  MZ_FCLOSE(pSrc_file);
4335  return MZ_FALSE;
4336  }
4337  cur_archive_file_ofs += archive_name_size;
4338 
4339  if (uncomp_size)
4340  {
4341  mz_uint64 uncomp_remaining = uncomp_size;
4342  void *pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, MZ_ZIP_MAX_IO_BUF_SIZE);
4343  if (!pRead_buf)
4344  {
4345  MZ_FCLOSE(pSrc_file);
4346  return MZ_FALSE;
4347  }
4348 
4349  if (!level)
4350  {
4351  while (uncomp_remaining)
4352  {
4353  mz_uint n = (mz_uint)MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE, uncomp_remaining);
4354  if ((MZ_FREAD(pRead_buf, 1, n, pSrc_file) != n) || (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf, n) != n))
4355  {
4356  pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
4357  MZ_FCLOSE(pSrc_file);
4358  return MZ_FALSE;
4359  }
4360  uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n);
4361  uncomp_remaining -= n;
4362  cur_archive_file_ofs += n;
4363  }
4364  comp_size = uncomp_size;
4365  }
4366  else
4367  {
4368  mz_bool result = MZ_FALSE;
4370  tdefl_compressor *pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor));
4371  if (!pComp)
4372  {
4373  pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
4374  MZ_FCLOSE(pSrc_file);
4375  return MZ_FALSE;
4376  }
4377 
4378  state.m_pZip = pZip;
4379  state.m_cur_archive_file_ofs = cur_archive_file_ofs;
4380  state.m_comp_size = 0;
4381 
4383  {
4384  pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
4385  pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
4386  MZ_FCLOSE(pSrc_file);
4387  return MZ_FALSE;
4388  }
4389 
4390  for ( ; ; )
4391  {
4392  size_t in_buf_size = (mz_uint32)MZ_MIN(uncomp_remaining, MZ_ZIP_MAX_IO_BUF_SIZE);
4393  tdefl_status status;
4394 
4395  if (MZ_FREAD(pRead_buf, 1, in_buf_size, pSrc_file) != in_buf_size)
4396  break;
4397 
4398  uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, in_buf_size);
4399  uncomp_remaining -= in_buf_size;
4400 
4401  status = tdefl_compress_buffer(pComp, pRead_buf, in_buf_size, uncomp_remaining ? TDEFL_NO_FLUSH : TDEFL_FINISH);
4402  if (status == TDEFL_STATUS_DONE)
4403  {
4404  result = MZ_TRUE;
4405  break;
4406  }
4407  else if (status != TDEFL_STATUS_OKAY)
4408  break;
4409  }
4410 
4411  pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
4412 
4413  if (!result)
4414  {
4415  pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
4416  MZ_FCLOSE(pSrc_file);
4417  return MZ_FALSE;
4418  }
4419 
4420  comp_size = state.m_comp_size;
4421  cur_archive_file_ofs = state.m_cur_archive_file_ofs;
4422 
4423  method = MZ_DEFLATED;
4424  }
4425 
4426  pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
4427  }
4428 
4429  MZ_FCLOSE(pSrc_file); pSrc_file = NULL;
4430 
4431  // no zip64 support yet
4432  if ((comp_size > 0xFFFFFFFF) || (cur_archive_file_ofs > 0xFFFFFFFF))
4433  return MZ_FALSE;
4434 
4435  if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, 0, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date))
4436  return MZ_FALSE;
4437 
4438  if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header))
4439  return MZ_FALSE;
4440 
4441  if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, NULL, 0, pComment, comment_size, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date, local_dir_header_ofs, ext_attributes))
4442  return MZ_FALSE;
4443 
4444  pZip->m_total_files++;
4445  pZip->m_archive_size = cur_archive_file_ofs;
4446 
4447  return MZ_TRUE;
4448 }
4449 #endif // #ifndef MINIZ_NO_STDIO
4450 
4451 mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint file_index)
4452 {
4453  mz_uint n, bit_flags, num_alignment_padding_bytes;
4454  mz_uint64 comp_bytes_remaining, local_dir_header_ofs;
4455  mz_uint64 cur_src_file_ofs, cur_dst_file_ofs;
4456  mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
4457  mz_uint8 central_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE];
4458  size_t orig_central_dir_size;
4459  mz_zip_internal_state *pState;
4460  void *pBuf; const mz_uint8 *pSrc_central_header;
4461 
4462  if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING))
4463  return MZ_FALSE;
4464  if (NULL == (pSrc_central_header = mz_zip_reader_get_cdh(pSource_zip, file_index)))
4465  return MZ_FALSE;
4466  pState = pZip->m_pState;
4467 
4468  num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
4469 
4470  // no zip64 support yet
4471  if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF))
4472  return MZ_FALSE;
4473 
4474  cur_src_file_ofs = MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
4475  cur_dst_file_ofs = pZip->m_archive_size;
4476 
4477  if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
4478  return MZ_FALSE;
4479  if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
4480  return MZ_FALSE;
4481  cur_src_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE;
4482 
4483  if (!mz_zip_writer_write_zeros(pZip, cur_dst_file_ofs, num_alignment_padding_bytes))
4484  return MZ_FALSE;
4485  cur_dst_file_ofs += num_alignment_padding_bytes;
4486  local_dir_header_ofs = cur_dst_file_ofs;
4487  if (pZip->m_file_offset_alignment) { MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); }
4488 
4489  if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
4490  return MZ_FALSE;
4491  cur_dst_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE;
4492 
4493  n = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
4494  comp_bytes_remaining = n + MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
4495 
4496  if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)MZ_MAX(sizeof(mz_uint32) * 4, MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE, comp_bytes_remaining)))))
4497  return MZ_FALSE;
4498 
4499  while (comp_bytes_remaining)
4500  {
4501  n = (mz_uint)MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE, comp_bytes_remaining);
4502  if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, n) != n)
4503  {
4504  pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
4505  return MZ_FALSE;
4506  }
4507  cur_src_file_ofs += n;
4508 
4509  if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n)
4510  {
4511  pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
4512  return MZ_FALSE;
4513  }
4514  cur_dst_file_ofs += n;
4515 
4516  comp_bytes_remaining -= n;
4517  }
4518 
4519  bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS);
4520  if (bit_flags & 8)
4521  {
4522  // Copy data descriptor
4523  if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, sizeof(mz_uint32) * 4) != sizeof(mz_uint32) * 4)
4524  {
4525  pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
4526  return MZ_FALSE;
4527  }
4528 
4529  n = sizeof(mz_uint32) * ((MZ_READ_LE32(pBuf) == 0x08074b50) ? 4 : 3);
4530  if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n)
4531  {
4532  pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
4533  return MZ_FALSE;
4534  }
4535 
4536  cur_src_file_ofs += n;
4537  cur_dst_file_ofs += n;
4538  }
4539  pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
4540 
4541  // no zip64 support yet
4542  if (cur_dst_file_ofs > 0xFFFFFFFF)
4543  return MZ_FALSE;
4544 
4545  orig_central_dir_size = pState->m_central_dir.m_size;
4546 
4547  memcpy(central_header, pSrc_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE);
4548  MZ_WRITE_LE32(central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS, local_dir_header_ofs);
4549  if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE))
4550  return MZ_FALSE;
4551 
4552  n = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS) + MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_COMMENT_LEN_OFS);
4553  if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n))
4554  {
4555  mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
4556  return MZ_FALSE;
4557  }
4558 
4559  if (pState->m_central_dir.m_size > 0xFFFFFFFF)
4560  return MZ_FALSE;
4561  n = (mz_uint32)pState->m_central_dir.m_size;
4562  if (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &n, 1))
4563  {
4564  mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE);
4565  return MZ_FALSE;
4566  }
4567 
4568  pZip->m_total_files++;
4569  pZip->m_archive_size = cur_dst_file_ofs;
4570 
4571  return MZ_TRUE;
4572 }
4573 
4575 {
4576  mz_zip_internal_state *pState;
4577  mz_uint64 central_dir_ofs, central_dir_size;
4579 
4580  if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING))
4581  return MZ_FALSE;
4582 
4583  pState = pZip->m_pState;
4584 
4585  // no zip64 support yet
4586  if ((pZip->m_total_files > 0xFFFF) || ((pZip->m_archive_size + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF))
4587  return MZ_FALSE;
4588 
4589  central_dir_ofs = 0;
4590  central_dir_size = 0;
4591  if (pZip->m_total_files)
4592  {
4593  // Write central directory
4594  central_dir_ofs = pZip->m_archive_size;
4595  central_dir_size = pState->m_central_dir.m_size;
4596  pZip->m_central_directory_file_ofs = central_dir_ofs;
4597  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)
4598  return MZ_FALSE;
4599  pZip->m_archive_size += central_dir_size;
4600  }
4601 
4602  // Write end of central directory record
4603  MZ_CLEAR_OBJ(hdr);
4607  MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_SIZE_OFS, central_dir_size);
4608  MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_OFS_OFS, central_dir_ofs);
4609 
4610  if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, sizeof(hdr)) != sizeof(hdr))
4611  return MZ_FALSE;
4612 #ifndef MINIZ_NO_STDIO
4613  if ((pState->m_pFile) && (MZ_FFLUSH(pState->m_pFile) == EOF))
4614  return MZ_FALSE;
4615 #endif // #ifndef MINIZ_NO_STDIO
4616 
4617  pZip->m_archive_size += sizeof(hdr);
4618 
4620  return MZ_TRUE;
4621 }
4622 
4623 mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **pBuf, size_t *pSize)
4624 {
4625  if ((!pZip) || (!pZip->m_pState) || (!pBuf) || (!pSize))
4626  return MZ_FALSE;
4627  if (pZip->m_pWrite != mz_zip_heap_write_func)
4628  return MZ_FALSE;
4629  if (!mz_zip_writer_finalize_archive(pZip))
4630  return MZ_FALSE;
4631 
4632  *pBuf = pZip->m_pState->m_pMem;
4633  *pSize = pZip->m_pState->m_mem_size;
4634  pZip->m_pState->m_pMem = NULL;
4635  pZip->m_pState->m_mem_size = pZip->m_pState->m_mem_capacity = 0;
4636  return MZ_TRUE;
4637 }
4638 
4640 {
4641  mz_zip_internal_state *pState;
4642  mz_bool status = MZ_TRUE;
4643  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)))
4644  return MZ_FALSE;
4645 
4646  pState = pZip->m_pState;
4647  pZip->m_pState = NULL;
4648  mz_zip_array_clear(pZip, &pState->m_central_dir);
4649  mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
4651 
4652 #ifndef MINIZ_NO_STDIO
4653  if (pState->m_pFile)
4654  {
4655  MZ_FCLOSE(pState->m_pFile);
4656  pState->m_pFile = NULL;
4657  }
4658 #endif // #ifndef MINIZ_NO_STDIO
4659 
4660  if ((pZip->m_pWrite == mz_zip_heap_write_func) && (pState->m_pMem))
4661  {
4662  pZip->m_pFree(pZip->m_pAlloc_opaque, pState->m_pMem);
4663  pState->m_pMem = NULL;
4664  }
4665 
4666  pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
4668  return status;
4669 }
4670 
4671 #ifndef MINIZ_NO_STDIO
4672 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)
4673 {
4674  mz_bool status, created_new_archive = MZ_FALSE;
4675  mz_zip_archive zip_archive;
4676  struct MZ_FILE_STAT_STRUCT file_stat;
4677  MZ_CLEAR_OBJ(zip_archive);
4678  if ((int)level_and_flags < 0)
4679  level_and_flags = MZ_DEFAULT_LEVEL;
4680  if ((!pZip_filename) || (!pArchive_name) || ((buf_size) && (!pBuf)) || ((comment_size) && (!pComment)) || ((level_and_flags & 0xF) > MZ_UBER_COMPRESSION))
4681  return MZ_FALSE;
4682  if (!mz_zip_writer_validate_archive_name(pArchive_name))
4683  return MZ_FALSE;
4684  if (MZ_FILE_STAT(pZip_filename, &file_stat) != 0)
4685  {
4686  // Create a new archive.
4687  if (!mz_zip_writer_init_file(&zip_archive, pZip_filename, 0))
4688  return MZ_FALSE;
4689  created_new_archive = MZ_TRUE;
4690  }
4691  else
4692  {
4693  // Append to an existing archive.
4694  if (!mz_zip_reader_init_file(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY))
4695  return MZ_FALSE;
4696  if (!mz_zip_writer_init_from_reader(&zip_archive, pZip_filename))
4697  {
4698  mz_zip_reader_end(&zip_archive);
4699  return MZ_FALSE;
4700  }
4701  }
4702  status = mz_zip_writer_add_mem_ex(&zip_archive, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, 0, 0);
4703  // Always finalize, even if adding failed for some reason, so we have a valid central directory. (This may not always succeed, but we can try.)
4704  if (!mz_zip_writer_finalize_archive(&zip_archive))
4705  status = MZ_FALSE;
4706  if (!mz_zip_writer_end(&zip_archive))
4707  status = MZ_FALSE;
4708  if ((!status) && (created_new_archive))
4709  {
4710  // It's a new archive and something went wrong, so just delete it.
4711  int ignoredStatus = MZ_DELETE_FILE(pZip_filename);
4712  (void)ignoredStatus;
4713  }
4714  return status;
4715 }
4716 
4717 void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags)
4718 {
4719  int file_index;
4720  mz_zip_archive zip_archive;
4721  void *p = NULL;
4722 
4723  if (pSize)
4724  *pSize = 0;
4725 
4726  if ((!pZip_filename) || (!pArchive_name))
4727  return NULL;
4728 
4729  MZ_CLEAR_OBJ(zip_archive);
4730  if (!mz_zip_reader_init_file(&zip_archive, pZip_filename, flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY))
4731  return NULL;
4732 
4733  if ((file_index = mz_zip_reader_locate_file(&zip_archive, pArchive_name, NULL, flags)) >= 0)
4734  p = mz_zip_reader_extract_to_heap(&zip_archive, file_index, pSize, flags);
4735 
4736  mz_zip_reader_end(&zip_archive);
4737  return p;
4738 }
4739 
4740 #endif // #ifndef MINIZ_NO_STDIO
4741 
4742 #endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
4743 
4744 #endif // #ifndef MINIZ_NO_ARCHIVE_APIS
4745 
4746 #ifdef __cplusplus
4747 }
4748 #endif
4749 
4750 #endif // MINIZ_HEADER_FILE_ONLY
4751 
4752 /*
4753  This is free and unencumbered software released into the public domain.
4754 
4755  Anyone is free to copy, modify, publish, use, compile, sell, or
4756  distribute this software, either in source code form or as a compiled
4757  binary, for any purpose, commercial or non-commercial, and by any
4758  means.
4759 
4760  In jurisdictions that recognize copyright laws, the author or authors
4761  of this software dedicate any and all copyright interest in the
4762  software to the public domain. We make this dedication for the benefit
4763  of the public at large and to the detriment of our heirs and
4764  successors. We intend this dedication to be an overt act of
4765  relinquishment in perpetuity of all present and future rights to this
4766  software under copyright law.
4767 
4768  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
4769  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
4770  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
4771  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
4772  OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
4773  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
4774  OTHER DEALINGS IN THE SOFTWARE.
4775 
4776  For more information, please refer to <http://unlicense.org/>
4777 */