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