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