miniz.h
author Sam Lantinga <slouken@libsdl.org>
Sun, 15 Jun 2014 13:16:42 -0700
changeset 451 48116d511e5d
parent 432 20877bfa2e4e
child 481 e77ad79ab3e0
permissions -rw-r--r--
Fixed format warnings: format not a string literal and no format arguments
slouken@431
     1
/* miniz.c v1.15 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
slouken@391
     2
   See "unlicense" statement at the end of this file.
slouken@431
     3
   Rich Geldreich <richgel99@gmail.com>, last updated Oct. 13, 2013
slouken@391
     4
   Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
slouken@391
     5
slouken@391
     6
   Most API's defined in miniz.c are optional. For example, to disable the archive related functions just define
slouken@391
     7
   MINIZ_NO_ARCHIVE_APIS, or to get rid of all stdio usage define MINIZ_NO_STDIO (see the list below for more macros).
slouken@391
     8
slouken@391
     9
   * Change History
slouken@431
    10
     10/13/13 v1.15 r4 - Interim bugfix release while I work on the next major release with Zip64 support (almost there!):
slouken@431
    11
       - Critical fix for the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY bug (thanks kahmyong.moon@hp.com) which could cause locate files to not find files. This bug
slouken@431
    12
        would only have occured in earlier versions if you explicitly used this flag, OR if you used mz_zip_extract_archive_file_to_heap() or mz_zip_add_mem_to_archive_file_in_place()
slouken@431
    13
        (which used this flag). If you can't switch to v1.15 but want to fix this bug, just remove the uses of this flag from both helper funcs (and of course don't use the flag).
slouken@431
    14
       - Bugfix in mz_zip_reader_extract_to_mem_no_alloc() from kymoon when pUser_read_buf is not NULL and compressed size is > uncompressed size
slouken@431
    15
       - Fixing mz_zip_reader_extract_*() funcs so they don't try to extract compressed data from directory entries, to account for weird zipfiles which contain zero-size compressed data on dir entries.
slouken@431
    16
         Hopefully this fix won't cause any issues on weird zip archives, because it assumes the low 16-bits of zip external attributes are DOS attributes (which I believe they always are in practice).
slouken@431
    17
       - Fixing mz_zip_reader_is_file_a_directory() so it doesn't check the internal attributes, just the filename and external attributes
slouken@431
    18
       - mz_zip_reader_init_file() - missing MZ_FCLOSE() call if the seek failed
slouken@431
    19
       - Added cmake support for Linux builds which builds all the examples, tested with clang v3.3 and gcc v4.6.
slouken@431
    20
       - Clang fix for tdefl_write_image_to_png_file_in_memory() from toffaletti
slouken@431
    21
       - Merged MZ_FORCEINLINE fix from hdeanclark
slouken@431
    22
       - Fix <time.h> include before config #ifdef, thanks emil.brink
slouken@431
    23
       - Added tdefl_write_image_to_png_file_in_memory_ex(): supports Y flipping (super useful for OpenGL apps), and explicit control over the compression level (so you can
slouken@431
    24
        set it to 1 for real-time compression).
slouken@431
    25
       - Merged in some compiler fixes from paulharris's github repro.
slouken@431
    26
       - Retested this build under Windows (VS 2010, including static analysis), tcc  0.9.26, gcc v4.6 and clang v3.3.
slouken@431
    27
       - Added example6.c, which dumps an image of the mandelbrot set to a PNG file.
slouken@431
    28
       - Modified example2 to help test the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY flag more.
slouken@431
    29
       - In r3: Bugfix to mz_zip_writer_add_file() found during merge: Fix possible src file fclose() leak if alignment bytes+local header file write faiiled
slouken@431
    30
       - In r4: Minor bugfix to mz_zip_writer_add_from_zip_reader(): Was pushing the wrong central dir header offset, appears harmless in this release, but it became a problem in the zip64 branch
slouken@391
    31
     5/20/12 v1.14 - MinGW32/64 GCC 4.6.1 compiler fixes: added MZ_FORCEINLINE, #include <time.h> (thanks fermtect).
slouken@391
    32
     5/19/12 v1.13 - From jason@cornsyrup.org and kelwert@mtu.edu - Fix mz_crc32() so it doesn't compute the wrong CRC-32's when mz_ulong is 64-bit.
slouken@431
    33
       - Temporarily/locally slammed in "typedef unsigned long mz_ulong" and re-ran a randomized regression test on ~500k files.
slouken@431
    34
       - Eliminated a bunch of warnings when compiling with GCC 32-bit/64.
slouken@431
    35
       - Ran all examples, miniz.c, and tinfl.c through MSVC 2008's /analyze (static analysis) option and fixed all warnings (except for the silly
slouken@431
    36
        "Use of the comma-operator in a tested expression.." analysis warning, which I purposely use to work around a MSVC compiler warning).
slouken@431
    37
       - Created 32-bit and 64-bit Codeblocks projects/workspace. Built and tested Linux executables. The codeblocks workspace is compatible with Linux+Win32/x64.
slouken@431
    38
       - Added miniz_tester solution/project, which is a useful little app derived from LZHAM's tester app that I use as part of the regression test.
slouken@431
    39
       - Ran miniz.c and tinfl.c through another series of regression testing on ~500,000 files and archives.
slouken@431
    40
       - Modified example5.c so it purposely disables a bunch of high-level functionality (MINIZ_NO_STDIO, etc.). (Thanks to corysama for the MINIZ_NO_STDIO bug report.)
slouken@431
    41
       - Fix ftell() usage in examples so they exit with an error on files which are too large (a limitation of the examples, not miniz itself).
slouken@391
    42
     4/12/12 v1.12 - More comments, added low-level example5.c, fixed a couple minor level_and_flags issues in the archive API's.
slouken@391
    43
      level_and_flags can now be set to MZ_DEFAULT_COMPRESSION. Thanks to Bruce Dawson <bruced@valvesoftware.com> for the feedback/bug report.
slouken@391
    44
     5/28/11 v1.11 - Added statement from unlicense.org
slouken@391
    45
     5/27/11 v1.10 - Substantial compressor optimizations:
slouken@431
    46
      - Level 1 is now ~4x faster than before. The L1 compressor's throughput now varies between 70-110MB/sec. on a
slouken@431
    47
      - Core i7 (actual throughput varies depending on the type of data, and x64 vs. x86).
slouken@431
    48
      - Improved baseline L2-L9 compression perf. Also, greatly improved compression perf. issues on some file types.
slouken@431
    49
      - Refactored the compression code for better readability and maintainability.
slouken@431
    50
      - Added level 10 compression level (L10 has slightly better ratio than level 9, but could have a potentially large
slouken@431
    51
       drop in throughput on some files).
slouken@391
    52
     5/15/11 v1.09 - Initial stable release.
slouken@391
    53
slouken@391
    54
   * Low-level Deflate/Inflate implementation notes:
slouken@391
    55
slouken@391
    56
     Compression: Use the "tdefl" API's. The compressor supports raw, static, and dynamic blocks, lazy or
slouken@391
    57
     greedy parsing, match length filtering, RLE-only, and Huffman-only streams. It performs and compresses
slouken@391
    58
     approximately as well as zlib.
slouken@391
    59
slouken@391
    60
     Decompression: Use the "tinfl" API's. The entire decompressor is implemented as a single function
slouken@391
    61
     coroutine: see tinfl_decompress(). It supports decompression into a 32KB (or larger power of 2) wrapping buffer, or into a memory
slouken@391
    62
     block large enough to hold the entire file.
slouken@391
    63
slouken@391
    64
     The low-level tdefl/tinfl API's do not make any use of dynamic memory allocation.
slouken@391
    65
slouken@391
    66
   * zlib-style API notes:
slouken@391
    67
slouken@391
    68
     miniz.c implements a fairly large subset of zlib. There's enough functionality present for it to be a drop-in
slouken@391
    69
     zlib replacement in many apps:
slouken@391
    70
        The z_stream struct, optional memory allocation callbacks
slouken@391
    71
        deflateInit/deflateInit2/deflate/deflateReset/deflateEnd/deflateBound
slouken@391
    72
        inflateInit/inflateInit2/inflate/inflateEnd
slouken@391
    73
        compress, compress2, compressBound, uncompress
slouken@391
    74
        CRC-32, Adler-32 - Using modern, minimal code size, CPU cache friendly routines.
slouken@391
    75
        Supports raw deflate streams or standard zlib streams with adler-32 checking.
slouken@391
    76
slouken@391
    77
     Limitations:
slouken@391
    78
      The callback API's are not implemented yet. No support for gzip headers or zlib static dictionaries.
slouken@391
    79
      I've tried to closely emulate zlib's various flavors of stream flushing and return status codes, but
slouken@391
    80
      there are no guarantees that miniz.c pulls this off perfectly.
slouken@391
    81
slouken@391
    82
   * PNG writing: See the tdefl_write_image_to_png_file_in_memory() function, originally written by
slouken@391
    83
     Alex Evans. Supports 1-4 bytes/pixel images.
slouken@391
    84
slouken@391
    85
   * ZIP archive API notes:
slouken@391
    86
slouken@391
    87
     The ZIP archive API's where designed with simplicity and efficiency in mind, with just enough abstraction to
slouken@391
    88
     get the job done with minimal fuss. There are simple API's to retrieve file information, read files from
slouken@391
    89
     existing archives, create new archives, append new files to existing archives, or clone archive data from
slouken@391
    90
     one archive to another. It supports archives located in memory or the heap, on disk (using stdio.h),
slouken@391
    91
     or you can specify custom file read/write callbacks.
slouken@391
    92
slouken@391
    93
     - Archive reading: Just call this function to read a single file from a disk archive:
slouken@391
    94
slouken@391
    95
      void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name,
slouken@391
    96
        size_t *pSize, mz_uint zip_flags);
slouken@391
    97
slouken@391
    98
     For more complex cases, use the "mz_zip_reader" functions. Upon opening an archive, the entire central
slouken@391
    99
     directory is located and read as-is into memory, and subsequent file access only occurs when reading individual files.
slouken@391
   100
slouken@391
   101
     - Archives file scanning: The simple way is to use this function to scan a loaded archive for a specific file:
slouken@391
   102
slouken@391
   103
     int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);
slouken@391
   104
slouken@391
   105
     The locate operation can optionally check file comments too, which (as one example) can be used to identify
slouken@391
   106
     multiple versions of the same file in an archive. This function uses a simple linear search through the central
slouken@391
   107
     directory, so it's not very fast.
slouken@391
   108
slouken@391
   109
     Alternately, you can iterate through all the files in an archive (using mz_zip_reader_get_num_files()) and
slouken@391
   110
     retrieve detailed info on each file by calling mz_zip_reader_file_stat().
slouken@391
   111
slouken@391
   112
     - Archive creation: Use the "mz_zip_writer" functions. The ZIP writer immediately writes compressed file data
slouken@391
   113
     to disk and builds an exact image of the central directory in memory. The central directory image is written
slouken@391
   114
     all at once at the end of the archive file when the archive is finalized.
slouken@391
   115
slouken@391
   116
     The archive writer can optionally align each file's local header and file data to any power of 2 alignment,
slouken@391
   117
     which can be useful when the archive will be read from optical media. Also, the writer supports placing
slouken@391
   118
     arbitrary data blobs at the very beginning of ZIP archives. Archives written using either feature are still
slouken@391
   119
     readable by any ZIP tool.
slouken@391
   120
slouken@391
   121
     - Archive appending: The simple way to add a single file to an archive is to call this function:
slouken@391
   122
slouken@391
   123
      mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name,
slouken@391
   124
        const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
slouken@391
   125
slouken@391
   126
     The archive will be created if it doesn't already exist, otherwise it'll be appended to.
slouken@391
   127
     Note the appending is done in-place and is not an atomic operation, so if something goes wrong
slouken@391
   128
     during the operation it's possible the archive could be left without a central directory (although the local
slouken@391
   129
     file headers and file data will be fine, so the archive will be recoverable).
slouken@391
   130
slouken@391
   131
     For more complex archive modification scenarios:
slouken@391
   132
     1. The safest way is to use a mz_zip_reader to read the existing archive, cloning only those bits you want to
slouken@391
   133
     preserve into a new archive using using the mz_zip_writer_add_from_zip_reader() function (which compiles the
slouken@391
   134
     compressed file data as-is). When you're done, delete the old archive and rename the newly written archive, and
slouken@391
   135
     you're done. This is safe but requires a bunch of temporary disk space or heap memory.
slouken@391
   136
slouken@391
   137
     2. Or, you can convert an mz_zip_reader in-place to an mz_zip_writer using mz_zip_writer_init_from_reader(),
slouken@391
   138
     append new files as needed, then finalize the archive which will write an updated central directory to the
slouken@391
   139
     original archive. (This is basically what mz_zip_add_mem_to_archive_file_in_place() does.) There's a
slouken@391
   140
     possibility that the archive's central directory could be lost with this method if anything goes wrong, though.
slouken@391
   141
slouken@391
   142
     - ZIP archive support limitations:
slouken@391
   143
     No zip64 or spanning support. Extraction functions can only handle unencrypted, stored or deflated files.
slouken@391
   144
     Requires streams capable of seeking.
slouken@391
   145
slouken@391
   146
   * This is a header file library, like stb_image.c. To get only a header file, either cut and paste the
slouken@391
   147
     below header, or create miniz.h, #define MINIZ_HEADER_FILE_ONLY, and then include miniz.c from it.
slouken@391
   148
slouken@391
   149
   * Important: For best perf. be sure to customize the below macros for your target platform:
slouken@391
   150
     #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
slouken@391
   151
     #define MINIZ_LITTLE_ENDIAN 1
slouken@391
   152
     #define MINIZ_HAS_64BIT_REGISTERS 1
slouken@431
   153
slouken@431
   154
   * On platforms using glibc, Be sure to "#define _LARGEFILE64_SOURCE 1" before including miniz.c to ensure miniz
slouken@431
   155
     uses the 64-bit variants: fopen64(), stat64(), etc. Otherwise you won't be able to process large files
slouken@431
   156
     (i.e. 32-bit stat() fails for me on files > 0x7FFFFFFF bytes).
slouken@391
   157
*/
slouken@391
   158
slouken@391
   159
#ifndef MINIZ_HEADER_INCLUDED
slouken@391
   160
#define MINIZ_HEADER_INCLUDED
slouken@391
   161
slouken@391
   162
#include <stdlib.h>
slouken@391
   163
slouken@391
   164
// Defines to completely disable specific portions of miniz.c:
slouken@391
   165
// If all macros here are defined the only functionality remaining will be CRC-32, adler-32, tinfl, and tdefl.
slouken@391
   166
slouken@391
   167
// Define MINIZ_NO_STDIO to disable all usage and any functions which rely on stdio for file I/O.
slouken@391
   168
#define MINIZ_NO_STDIO
slouken@391
   169
slouken@391
   170
// If MINIZ_NO_TIME is specified then the ZIP archive functions will not be able to get the current time, or
slouken@431
   171
// get/set file times, and the C run-time funcs that get/set times won't be called.
slouken@431
   172
// The current downside is the times written to your archives will be from 1979.
slouken@391
   173
#define MINIZ_NO_TIME
slouken@391
   174
slouken@391
   175
// Define MINIZ_NO_ARCHIVE_APIS to disable all ZIP archive API's.
slouken@391
   176
#define MINIZ_NO_ARCHIVE_APIS
slouken@391
   177
slouken@391
   178
// Define MINIZ_NO_ARCHIVE_APIS to disable all writing related ZIP archive API's.
slouken@391
   179
#define MINIZ_NO_ARCHIVE_WRITING_APIS
slouken@391
   180
slouken@391
   181
// Define MINIZ_NO_ZLIB_APIS to remove all ZLIB-style compression/decompression API's.
slouken@391
   182
#define MINIZ_NO_ZLIB_APIS
slouken@391
   183
slouken@391
   184
// Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent conflicts against stock zlib.
slouken@391
   185
#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES
slouken@391
   186
slouken@391
   187
// Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc.
slouken@391
   188
// Note if MINIZ_NO_MALLOC is defined then the user must always provide custom user alloc/free/realloc
slouken@391
   189
// callbacks to the zlib and archive API's, and a few stand-alone helper API's which don't provide custom user
slouken@391
   190
// functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work.
slouken@391
   191
//#define MINIZ_NO_MALLOC
slouken@391
   192
#define MINIZ_SDL_MALLOC
slouken@391
   193
slouken@428
   194
// Define MINIZ_STATIC_FUNCTIONS to make all functions static. You probably
slouken@428
   195
// want this if you're using miniz in a library
slouken@428
   196
#define MINIZ_STATIC_FUNCTIONS
slouken@428
   197
slouken@431
   198
#if defined(__TINYC__) && (defined(__linux) || defined(__linux__))
slouken@431
   199
  // TODO: Work around "error: include file 'sys\utime.h' when compiling with tcc on Linux
slouken@431
   200
  #define MINIZ_NO_TIME
slouken@431
   201
#endif
slouken@431
   202
slouken@431
   203
#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_ARCHIVE_APIS)
slouken@431
   204
  #include <time.h>
slouken@431
   205
#endif
slouken@431
   206
slouken@391
   207
#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__)
slouken@391
   208
// MINIZ_X86_OR_X64_CPU is only used to help set the below macros.
slouken@391
   209
#define MINIZ_X86_OR_X64_CPU 1
slouken@391
   210
#endif
slouken@391
   211
slouken@391
   212
#if (__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU
slouken@391
   213
// Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian.
slouken@391
   214
#define MINIZ_LITTLE_ENDIAN 1
slouken@391
   215
#endif
slouken@391
   216
slouken@391
   217
#if MINIZ_X86_OR_X64_CPU
slouken@391
   218
// Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient integer loads and stores from unaligned addresses.
slouken@391
   219
#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
slouken@391
   220
#endif
slouken@391
   221
slouken@391
   222
#if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) || defined(__ia64__) || defined(__x86_64__)
slouken@391
   223
// 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).
slouken@391
   224
#define MINIZ_HAS_64BIT_REGISTERS 1
slouken@391
   225
#endif
slouken@391
   226
slouken@428
   227
#ifdef MINIZ_STATIC_FUNCTIONS
slouken@428
   228
#define MINIZ_STATIC static
slouken@428
   229
#else
slouken@428
   230
#define MINIZ_STATIC
slouken@428
   231
#endif
slouken@428
   232
slouken@391
   233
#ifdef __cplusplus
slouken@391
   234
extern "C" {
slouken@391
   235
#endif
slouken@391
   236
slouken@391
   237
// ------------------- zlib-style API Definitions.
slouken@391
   238
slouken@391
   239
// For more compatibility with zlib, miniz.c uses unsigned long for some parameters/struct members. Beware: mz_ulong can be either 32 or 64-bits!
slouken@391
   240
typedef unsigned long mz_ulong;
slouken@391
   241
slouken@431
   242
// mz_free() internally uses the MZ_FREE() macro (which by default calls free() unless you've modified the MZ_MALLOC macro) to release a block allocated from the heap.
slouken@432
   243
MINIZ_STATIC void mz_free(void *p);
slouken@431
   244
slouken@431
   245
#define MZ_ADLER32_INIT (1)
slouken@431
   246
// mz_adler32() returns the initial adler-32 value to use when called with ptr==NULL.
slouken@431
   247
MINIZ_STATIC mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len);
slouken@431
   248
slouken@431
   249
#define MZ_CRC32_INIT (0)
slouken@431
   250
// mz_crc32() returns the initial CRC-32 value to use when called with ptr==NULL.
slouken@431
   251
MINIZ_STATIC mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len);
slouken@431
   252
slouken@431
   253
// Compression strategies.
slouken@431
   254
enum { MZ_DEFAULT_STRATEGY = 0, MZ_FILTERED = 1, MZ_HUFFMAN_ONLY = 2, MZ_RLE = 3, MZ_FIXED = 4 };
slouken@431
   255
slouken@431
   256
// Method
slouken@431
   257
#define MZ_DEFLATED 8
slouken@431
   258
slouken@431
   259
#ifndef MINIZ_NO_ZLIB_APIS
slouken@431
   260
slouken@391
   261
// Heap allocation callbacks.
slouken@391
   262
// Note that mz_alloc_func parameter types purpsosely differ from zlib's: items/size is size_t, not unsigned long.
slouken@391
   263
typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size);
slouken@391
   264
typedef void (*mz_free_func)(void *opaque, void *address);
slouken@391
   265
typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size);
slouken@391
   266
slouken@431
   267
#define MZ_VERSION          "9.1.15"
slouken@431
   268
#define MZ_VERNUM           0x91F0
slouken@391
   269
#define MZ_VER_MAJOR        9
slouken@391
   270
#define MZ_VER_MINOR        1
slouken@431
   271
#define MZ_VER_REVISION     15
slouken@391
   272
#define MZ_VER_SUBREVISION  0
slouken@391
   273
slouken@391
   274
// Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The other values are for advanced use (refer to the zlib docs).
slouken@391
   275
enum { MZ_NO_FLUSH = 0, MZ_PARTIAL_FLUSH = 1, MZ_SYNC_FLUSH = 2, MZ_FULL_FLUSH = 3, MZ_FINISH = 4, MZ_BLOCK = 5 };
slouken@391
   276
slouken@391
   277
// Return status codes. MZ_PARAM_ERROR is non-standard.
slouken@391
   278
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 };
slouken@391
   279
slouken@391
   280
// Compression levels: 0-9 are the standard zlib-style levels, 10 is best possible compression (not zlib compatible, and may be very slow), MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL.
slouken@391
   281
enum { MZ_NO_COMPRESSION = 0, MZ_BEST_SPEED = 1, MZ_BEST_COMPRESSION = 9, MZ_UBER_COMPRESSION = 10, MZ_DEFAULT_LEVEL = 6, MZ_DEFAULT_COMPRESSION = -1 };
slouken@391
   282
slouken@391
   283
// Window bits
slouken@391
   284
#define MZ_DEFAULT_WINDOW_BITS 15
slouken@391
   285
slouken@391
   286
struct mz_internal_state;
slouken@391
   287
slouken@391
   288
// Compression/decompression stream struct.
slouken@391
   289
typedef struct mz_stream_s
slouken@391
   290
{
slouken@391
   291
  const unsigned char *next_in;     // pointer to next byte to read
slouken@391
   292
  unsigned int avail_in;            // number of bytes available at next_in
slouken@391
   293
  mz_ulong total_in;                // total number of bytes consumed so far
slouken@391
   294
slouken@391
   295
  unsigned char *next_out;          // pointer to next byte to write
slouken@391
   296
  unsigned int avail_out;           // number of bytes that can be written to next_out
slouken@391
   297
  mz_ulong total_out;               // total number of bytes produced so far
slouken@391
   298
slouken@391
   299
  char *msg;                        // error msg (unused)
slouken@391
   300
  struct mz_internal_state *state;  // internal state, allocated by zalloc/zfree
slouken@391
   301
slouken@391
   302
  mz_alloc_func zalloc;             // optional heap allocation function (defaults to malloc)
slouken@391
   303
  mz_free_func zfree;               // optional heap free function (defaults to free)
slouken@391
   304
  void *opaque;                     // heap alloc function user pointer
slouken@391
   305
slouken@391
   306
  int data_type;                    // data_type (unused)
slouken@391
   307
  mz_ulong adler;                   // adler32 of the source or uncompressed data
slouken@391
   308
  mz_ulong reserved;                // not used
slouken@391
   309
} mz_stream;
slouken@391
   310
slouken@391
   311
typedef mz_stream *mz_streamp;
slouken@391
   312
slouken@391
   313
// Returns the version string of miniz.c.
slouken@428
   314
MINIZ_STATIC const char *mz_version(void);
slouken@391
   315
slouken@391
   316
// mz_deflateInit() initializes a compressor with default options:
slouken@391
   317
// Parameters:
slouken@391
   318
//  pStream must point to an initialized mz_stream struct.
slouken@391
   319
//  level must be between [MZ_NO_COMPRESSION, MZ_BEST_COMPRESSION].
slouken@391
   320
//  level 1 enables a specially optimized compression function that's been optimized purely for performance, not ratio.
slouken@391
   321
//  (This special func. is currently only enabled when MINIZ_USE_UNALIGNED_LOADS_AND_STORES and MINIZ_LITTLE_ENDIAN are defined.)
slouken@391
   322
// Return values:
slouken@391
   323
//  MZ_OK on success.
slouken@391
   324
//  MZ_STREAM_ERROR if the stream is bogus.
slouken@391
   325
//  MZ_PARAM_ERROR if the input parameters are bogus.
slouken@391
   326
//  MZ_MEM_ERROR on out of memory.
slouken@428
   327
MINIZ_STATIC int mz_deflateInit(mz_streamp pStream, int level);
slouken@391
   328
slouken@391
   329
// mz_deflateInit2() is like mz_deflate(), except with more control:
slouken@391
   330
// Additional parameters:
slouken@391
   331
//   method must be MZ_DEFLATED
slouken@391
   332
//   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)
slouken@391
   333
//   mem_level must be between [1, 9] (it's checked but ignored by miniz.c)
slouken@428
   334
MINIZ_STATIC int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy);
slouken@391
   335
slouken@391
   336
// Quickly resets a compressor without having to reallocate anything. Same as calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2().
slouken@428
   337
MINIZ_STATIC int mz_deflateReset(mz_streamp pStream);
slouken@391
   338
slouken@391
   339
// mz_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible.
slouken@391
   340
// Parameters:
slouken@391
   341
//   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.
slouken@391
   342
//   flush may be MZ_NO_FLUSH, MZ_PARTIAL_FLUSH/MZ_SYNC_FLUSH, MZ_FULL_FLUSH, or MZ_FINISH.
slouken@391
   343
// Return values:
slouken@391
   344
//   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).
slouken@391
   345
//   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.
slouken@391
   346
//   MZ_STREAM_ERROR if the stream is bogus.
slouken@391
   347
//   MZ_PARAM_ERROR if one of the parameters is invalid.
slouken@391
   348
//   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.)
slouken@428
   349
MINIZ_STATIC int mz_deflate(mz_streamp pStream, int flush);
slouken@391
   350
slouken@391
   351
// mz_deflateEnd() deinitializes a compressor:
slouken@391
   352
// Return values:
slouken@391
   353
//  MZ_OK on success.
slouken@391
   354
//  MZ_STREAM_ERROR if the stream is bogus.
slouken@428
   355
MINIZ_STATIC int mz_deflateEnd(mz_streamp pStream);
slouken@391
   356
slouken@391
   357
// 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.
slouken@428
   358
MINIZ_STATIC mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len);
slouken@391
   359
slouken@391
   360
// Single-call compression functions mz_compress() and mz_compress2():
slouken@391
   361
// Returns MZ_OK on success, or one of the error codes from mz_deflate() on failure.
slouken@428
   362
MINIZ_STATIC int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
slouken@428
   363
MINIZ_STATIC int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level);
slouken@391
   364
slouken@391
   365
// mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress().
slouken@428
   366
MINIZ_STATIC mz_ulong mz_compressBound(mz_ulong source_len);
slouken@391
   367
slouken@391
   368
// Initializes a decompressor.
slouken@428
   369
MINIZ_STATIC int mz_inflateInit(mz_streamp pStream);
slouken@391
   370
slouken@391
   371
// 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:
slouken@391
   372
// window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate).
slouken@428
   373
MINIZ_STATIC int mz_inflateInit2(mz_streamp pStream, int window_bits);
slouken@391
   374
slouken@391
   375
// 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.
slouken@391
   376
// Parameters:
slouken@391
   377
//   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.
slouken@391
   378
//   flush may be MZ_NO_FLUSH, MZ_SYNC_FLUSH, or MZ_FINISH.
slouken@391
   379
//   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).
slouken@391
   380
//   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.
slouken@391
   381
// Return values:
slouken@391
   382
//   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.
slouken@391
   383
//   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.
slouken@391
   384
//   MZ_STREAM_ERROR if the stream is bogus.
slouken@391
   385
//   MZ_DATA_ERROR if the deflate stream is invalid.
slouken@391
   386
//   MZ_PARAM_ERROR if one of the parameters is invalid.
slouken@391
   387
//   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
slouken@391
   388
//   with more input data, or with more room in the output buffer (except when using single call decompression, described above).
slouken@428
   389
MINIZ_STATIC int mz_inflate(mz_streamp pStream, int flush);
slouken@391
   390
slouken@391
   391
// Deinitializes a decompressor.
slouken@428
   392
MINIZ_STATIC int mz_inflateEnd(mz_streamp pStream);
slouken@391
   393
slouken@391
   394
// Single-call decompression.
slouken@391
   395
// Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure.
slouken@428
   396
MINIZ_STATIC int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
slouken@391
   397
slouken@391
   398
// Returns a string description of the specified error code, or NULL if the error code is invalid.
slouken@428
   399
MINIZ_STATIC const char *mz_error(int err);
slouken@391
   400
slouken@391
   401
// 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.
slouken@391
   402
// Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project.
slouken@391
   403
#ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
slouken@391
   404
  typedef unsigned char Byte;
slouken@391
   405
  typedef unsigned int uInt;
slouken@391
   406
  typedef mz_ulong uLong;
slouken@391
   407
  typedef Byte Bytef;
slouken@391
   408
  typedef uInt uIntf;
slouken@391
   409
  typedef char charf;
slouken@391
   410
  typedef int intf;
slouken@391
   411
  typedef void *voidpf;
slouken@391
   412
  typedef uLong uLongf;
slouken@391
   413
  typedef void *voidp;
slouken@391
   414
  typedef void *const voidpc;
slouken@391
   415
  #define Z_NULL                0
slouken@391
   416
  #define Z_NO_FLUSH            MZ_NO_FLUSH
slouken@391
   417
  #define Z_PARTIAL_FLUSH       MZ_PARTIAL_FLUSH
slouken@391
   418
  #define Z_SYNC_FLUSH          MZ_SYNC_FLUSH
slouken@391
   419
  #define Z_FULL_FLUSH          MZ_FULL_FLUSH
slouken@391
   420
  #define Z_FINISH              MZ_FINISH
slouken@391
   421
  #define Z_BLOCK               MZ_BLOCK
slouken@391
   422
  #define Z_OK                  MZ_OK
slouken@391
   423
  #define Z_STREAM_END          MZ_STREAM_END
slouken@391
   424
  #define Z_NEED_DICT           MZ_NEED_DICT
slouken@391
   425
  #define Z_ERRNO               MZ_ERRNO
slouken@391
   426
  #define Z_STREAM_ERROR        MZ_STREAM_ERROR
slouken@391
   427
  #define Z_DATA_ERROR          MZ_DATA_ERROR
slouken@391
   428
  #define Z_MEM_ERROR           MZ_MEM_ERROR
slouken@391
   429
  #define Z_BUF_ERROR           MZ_BUF_ERROR
slouken@391
   430
  #define Z_VERSION_ERROR       MZ_VERSION_ERROR
slouken@391
   431
  #define Z_PARAM_ERROR         MZ_PARAM_ERROR
slouken@391
   432
  #define Z_NO_COMPRESSION      MZ_NO_COMPRESSION
slouken@391
   433
  #define Z_BEST_SPEED          MZ_BEST_SPEED
slouken@391
   434
  #define Z_BEST_COMPRESSION    MZ_BEST_COMPRESSION
slouken@391
   435
  #define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION
slouken@391
   436
  #define Z_DEFAULT_STRATEGY    MZ_DEFAULT_STRATEGY
slouken@391
   437
  #define Z_FILTERED            MZ_FILTERED
slouken@391
   438
  #define Z_HUFFMAN_ONLY        MZ_HUFFMAN_ONLY
slouken@391
   439
  #define Z_RLE                 MZ_RLE
slouken@391
   440
  #define Z_FIXED               MZ_FIXED
slouken@391
   441
  #define Z_DEFLATED            MZ_DEFLATED
slouken@391
   442
  #define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS
slouken@391
   443
  #define alloc_func            mz_alloc_func
slouken@391
   444
  #define free_func             mz_free_func
slouken@391
   445
  #define internal_state        mz_internal_state
slouken@391
   446
  #define z_stream              mz_stream
slouken@391
   447
  #define deflateInit           mz_deflateInit
slouken@391
   448
  #define deflateInit2          mz_deflateInit2
slouken@391
   449
  #define deflateReset          mz_deflateReset
slouken@391
   450
  #define deflate               mz_deflate
slouken@391
   451
  #define deflateEnd            mz_deflateEnd
slouken@391
   452
  #define deflateBound          mz_deflateBound
slouken@391
   453
  #define compress              mz_compress
slouken@391
   454
  #define compress2             mz_compress2
slouken@391
   455
  #define compressBound         mz_compressBound
slouken@391
   456
  #define inflateInit           mz_inflateInit
slouken@391
   457
  #define inflateInit2          mz_inflateInit2
slouken@391
   458
  #define inflate               mz_inflate
slouken@391
   459
  #define inflateEnd            mz_inflateEnd
slouken@391
   460
  #define uncompress            mz_uncompress
slouken@391
   461
  #define crc32                 mz_crc32
slouken@391
   462
  #define adler32               mz_adler32
slouken@391
   463
  #define MAX_WBITS             15
slouken@391
   464
  #define MAX_MEM_LEVEL         9
slouken@391
   465
  #define zError                mz_error
slouken@391
   466
  #define ZLIB_VERSION          MZ_VERSION
slouken@391
   467
  #define ZLIB_VERNUM           MZ_VERNUM
slouken@391
   468
  #define ZLIB_VER_MAJOR        MZ_VER_MAJOR
slouken@391
   469
  #define ZLIB_VER_MINOR        MZ_VER_MINOR
slouken@391
   470
  #define ZLIB_VER_REVISION     MZ_VER_REVISION
slouken@391
   471
  #define ZLIB_VER_SUBREVISION  MZ_VER_SUBREVISION
slouken@391
   472
  #define zlibVersion           mz_version
slouken@391
   473
  #define zlib_version          mz_version()
slouken@391
   474
#endif // #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
slouken@391
   475
slouken@391
   476
#endif // MINIZ_NO_ZLIB_APIS
slouken@391
   477
slouken@391
   478
// ------------------- Types and macros
slouken@391
   479
slouken@391
   480
typedef unsigned char mz_uint8;
slouken@391
   481
typedef signed short mz_int16;
slouken@391
   482
typedef unsigned short mz_uint16;
slouken@391
   483
typedef unsigned int mz_uint32;
slouken@391
   484
typedef unsigned int mz_uint;
slouken@391
   485
typedef long long mz_int64;
slouken@391
   486
typedef unsigned long long mz_uint64;
slouken@391
   487
typedef int mz_bool;
slouken@391
   488
slouken@391
   489
#define MZ_FALSE (0)
slouken@391
   490
#define MZ_TRUE (1)
slouken@391
   491
slouken@431
   492
// An attempt to work around MSVC's spammy "warning C4127: conditional expression is constant" message.
slouken@391
   493
#ifdef _MSC_VER
slouken@391
   494
   #define MZ_MACRO_END while (0, 0)
slouken@391
   495
#else
slouken@391
   496
   #define MZ_MACRO_END while (0)
slouken@391
   497
#endif
slouken@391
   498
slouken@391
   499
// ------------------- ZIP archive reading/writing
slouken@391
   500
slouken@391
   501
#ifndef MINIZ_NO_ARCHIVE_APIS
slouken@391
   502
slouken@391
   503
enum
slouken@391
   504
{
slouken@391
   505
  MZ_ZIP_MAX_IO_BUF_SIZE = 64*1024,
slouken@391
   506
  MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE = 260,
slouken@391
   507
  MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE = 256
slouken@391
   508
};
slouken@391
   509
slouken@391
   510
typedef struct
slouken@391
   511
{
slouken@391
   512
  mz_uint32 m_file_index;
slouken@391
   513
  mz_uint32 m_central_dir_ofs;
slouken@391
   514
  mz_uint16 m_version_made_by;
slouken@391
   515
  mz_uint16 m_version_needed;
slouken@391
   516
  mz_uint16 m_bit_flag;
slouken@391
   517
  mz_uint16 m_method;
slouken@391
   518
#ifndef MINIZ_NO_TIME
slouken@391
   519
  time_t m_time;
slouken@391
   520
#endif
slouken@391
   521
  mz_uint32 m_crc32;
slouken@391
   522
  mz_uint64 m_comp_size;
slouken@391
   523
  mz_uint64 m_uncomp_size;
slouken@391
   524
  mz_uint16 m_internal_attr;
slouken@391
   525
  mz_uint32 m_external_attr;
slouken@391
   526
  mz_uint64 m_local_header_ofs;
slouken@391
   527
  mz_uint32 m_comment_size;
slouken@391
   528
  char m_filename[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE];
slouken@391
   529
  char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE];
slouken@391
   530
} mz_zip_archive_file_stat;
slouken@391
   531
slouken@391
   532
typedef size_t (*mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n);
slouken@391
   533
typedef size_t (*mz_file_write_func)(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n);
slouken@391
   534
slouken@391
   535
struct mz_zip_internal_state_tag;
slouken@391
   536
typedef struct mz_zip_internal_state_tag mz_zip_internal_state;
slouken@391
   537
slouken@391
   538
typedef enum
slouken@391
   539
{
slouken@391
   540
  MZ_ZIP_MODE_INVALID = 0,
slouken@391
   541
  MZ_ZIP_MODE_READING = 1,
slouken@391
   542
  MZ_ZIP_MODE_WRITING = 2,
slouken@391
   543
  MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3
slouken@391
   544
} mz_zip_mode;
slouken@391
   545
slouken@431
   546
typedef struct mz_zip_archive_tag
slouken@391
   547
{
slouken@391
   548
  mz_uint64 m_archive_size;
slouken@391
   549
  mz_uint64 m_central_directory_file_ofs;
slouken@391
   550
  mz_uint m_total_files;
slouken@391
   551
  mz_zip_mode m_zip_mode;
slouken@391
   552
slouken@391
   553
  mz_uint m_file_offset_alignment;
slouken@391
   554
slouken@391
   555
  mz_alloc_func m_pAlloc;
slouken@391
   556
  mz_free_func m_pFree;
slouken@391
   557
  mz_realloc_func m_pRealloc;
slouken@391
   558
  void *m_pAlloc_opaque;
slouken@391
   559
slouken@391
   560
  mz_file_read_func m_pRead;
slouken@391
   561
  mz_file_write_func m_pWrite;
slouken@391
   562
  void *m_pIO_opaque;
slouken@391
   563
slouken@391
   564
  mz_zip_internal_state *m_pState;
slouken@391
   565
slouken@391
   566
} mz_zip_archive;
slouken@391
   567
slouken@391
   568
typedef enum
slouken@391
   569
{
slouken@391
   570
  MZ_ZIP_FLAG_CASE_SENSITIVE                = 0x0100,
slouken@391
   571
  MZ_ZIP_FLAG_IGNORE_PATH                   = 0x0200,
slouken@391
   572
  MZ_ZIP_FLAG_COMPRESSED_DATA               = 0x0400,
slouken@391
   573
  MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY = 0x0800
slouken@391
   574
} mz_zip_flags;
slouken@391
   575
slouken@391
   576
// ZIP archive reading
slouken@391
   577
slouken@391
   578
// Inits a ZIP archive reader.
slouken@391
   579
// These functions read and validate the archive's central directory.
slouken@428
   580
MINIZ_STATIC mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint32 flags);
slouken@428
   581
MINIZ_STATIC mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint32 flags);
slouken@391
   582
slouken@391
   583
#ifndef MINIZ_NO_STDIO
slouken@428
   584
MINIZ_STATIC mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags);
slouken@391
   585
#endif
slouken@391
   586
slouken@391
   587
// Returns the total number of files in the archive.
slouken@428
   588
MINIZ_STATIC mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip);
slouken@391
   589
slouken@391
   590
// Returns detailed information about an archive file entry.
slouken@428
   591
MINIZ_STATIC mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat);
slouken@391
   592
slouken@391
   593
// Determines if an archive file entry is a directory entry.
slouken@428
   594
MINIZ_STATIC mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index);
slouken@428
   595
MINIZ_STATIC mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index);
slouken@391
   596
slouken@391
   597
// Retrieves the filename of an archive file entry.
slouken@391
   598
// 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.
slouken@428
   599
MINIZ_STATIC mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size);
slouken@391
   600
slouken@391
   601
// Attempts to locates a file in the archive's central directory.
slouken@391
   602
// Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH
slouken@391
   603
// Returns -1 if the file cannot be found.
slouken@428
   604
MINIZ_STATIC int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);
slouken@391
   605
slouken@391
   606
// Extracts a archive file to a memory buffer using no memory allocation.
slouken@428
   607
MINIZ_STATIC 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);
slouken@428
   608
MINIZ_STATIC 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);
slouken@391
   609
slouken@391
   610
// Extracts a archive file to a memory buffer.
slouken@428
   611
MINIZ_STATIC 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);
slouken@428
   612
MINIZ_STATIC 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);
slouken@391
   613
slouken@391
   614
// Extracts a archive file to a dynamically allocated heap buffer.
slouken@428
   615
MINIZ_STATIC void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags);
slouken@428
   616
MINIZ_STATIC void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags);
slouken@391
   617
slouken@391
   618
// Extracts a archive file using a callback function to output the file's data.
slouken@428
   619
MINIZ_STATIC 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);
slouken@428
   620
MINIZ_STATIC 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);
slouken@391
   621
slouken@391
   622
#ifndef MINIZ_NO_STDIO
slouken@391
   623
// Extracts a archive file to a disk file and sets its last accessed and modified times.
slouken@391
   624
// This function only extracts files, not archive directory records.
slouken@428
   625
MINIZ_STATIC mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags);
slouken@428
   626
MINIZ_STATIC mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags);
slouken@391
   627
#endif
slouken@391
   628
slouken@391
   629
// Ends archive reading, freeing all allocations, and closing the input archive file if mz_zip_reader_init_file() was used.
slouken@428
   630
MINIZ_STATIC mz_bool mz_zip_reader_end(mz_zip_archive *pZip);
slouken@391
   631
slouken@391
   632
// ZIP archive writing
slouken@391
   633
slouken@391
   634
#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
slouken@391
   635
slouken@391
   636
// Inits a ZIP archive writer.
slouken@428
   637
MINIZ_STATIC mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size);
slouken@428
   638
MINIZ_STATIC mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size);
slouken@391
   639
slouken@391
   640
#ifndef MINIZ_NO_STDIO
slouken@428
   641
MINIZ_STATIC mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning);
slouken@391
   642
#endif
slouken@391
   643
slouken@391
   644
// Converts a ZIP archive reader object into a writer object, to allow efficient in-place file appends to occur on an existing archive.
slouken@391
   645
// 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.
slouken@391
   646
// 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).
slouken@391
   647
// Finally, for archives opened using mz_zip_reader_init, the mz_zip_archive's user provided m_pWrite function cannot be NULL.
slouken@391
   648
// Note: In-place archive modification is not recommended unless you know what you're doing, because if execution stops or something goes wrong before
slouken@391
   649
// the archive is finalized the file's central directory will be hosed.
slouken@428
   650
MINIZ_STATIC mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename);
slouken@391
   651
slouken@391
   652
// Adds the contents of a memory buffer to an archive. These functions record the current local time into the archive.
slouken@391
   653
// To add a directory entry, call this method with an archive name ending in a forwardslash with empty buffer.
slouken@391
   654
// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
slouken@428
   655
MINIZ_STATIC 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);
slouken@428
   656
MINIZ_STATIC 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);
slouken@391
   657
slouken@391
   658
#ifndef MINIZ_NO_STDIO
slouken@391
   659
// Adds the contents of a disk file to an archive. This function also records the disk file's modified time into the archive.
slouken@391
   660
// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
slouken@428
   661
MINIZ_STATIC 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);
slouken@391
   662
#endif
slouken@391
   663
slouken@391
   664
// Adds a file to an archive by fully cloning the data from another archive.
slouken@391
   665
// This function fully clones the source file's compressed data (no recompression), along with its full filename, extra data, and comment fields.
slouken@428
   666
MINIZ_STATIC mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint file_index);
slouken@391
   667
slouken@391
   668
// Finalizes the archive by writing the central directory records followed by the end of central directory record.
slouken@391
   669
// After an archive is finalized, the only valid call on the mz_zip_archive struct is mz_zip_writer_end().
slouken@391
   670
// An archive must be manually finalized by calling this function for it to be valid.
slouken@428
   671
MINIZ_STATIC mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip);
slouken@428
   672
MINIZ_STATIC mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **pBuf, size_t *pSize);
slouken@391
   673
slouken@391
   674
// Ends archive writing, freeing all allocations, and closing the output file if mz_zip_writer_init_file() was used.
slouken@391
   675
// Note for the archive to be valid, it must have been finalized before ending.
slouken@428
   676
MINIZ_STATIC mz_bool mz_zip_writer_end(mz_zip_archive *pZip);
slouken@391
   677
slouken@391
   678
// Misc. high-level helper functions:
slouken@391
   679
slouken@391
   680
// mz_zip_add_mem_to_archive_file_in_place() efficiently (but not atomically) appends a memory blob to a ZIP archive.
slouken@391
   681
// level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION.
slouken@428
   682
MINIZ_STATIC 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);
slouken@391
   683
slouken@391
   684
// Reads a single file from an archive into a heap block.
slouken@391
   685
// Returns NULL on failure.
slouken@428
   686
MINIZ_STATIC void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint zip_flags);
slouken@391
   687
slouken@391
   688
#endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
slouken@391
   689
slouken@391
   690
#endif // #ifndef MINIZ_NO_ARCHIVE_APIS
slouken@391
   691
slouken@391
   692
// ------------------- Low-level Decompression API Definitions
slouken@391
   693
slouken@391
   694
// Decompression flags used by tinfl_decompress().
slouken@391
   695
// TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream.
slouken@391
   696
// TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available beyond the end of the supplied input buffer. If clear, the input buffer contains all remaining input.
slouken@391
   697
// TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large enough to hold the entire decompressed stream. If clear, the output buffer is at least the size of the dictionary (typically 32KB).
slouken@391
   698
// TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the decompressed bytes.
slouken@391
   699
enum
slouken@391
   700
{
slouken@391
   701
  TINFL_FLAG_PARSE_ZLIB_HEADER = 1,
slouken@391
   702
  TINFL_FLAG_HAS_MORE_INPUT = 2,
slouken@391
   703
  TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4,
slouken@391
   704
  TINFL_FLAG_COMPUTE_ADLER32 = 8
slouken@391
   705
};
slouken@391
   706
slouken@391
   707
// High level decompression functions:
slouken@391
   708
// tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block allocated via malloc().
slouken@391
   709
// On entry:
slouken@391
   710
//  pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data to decompress.
slouken@391
   711
// On return:
slouken@391
   712
//  Function returns a pointer to the decompressed data, or NULL on failure.
slouken@391
   713
//  *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data.
slouken@431
   714
//  The caller must call mz_free() on the returned block when it's no longer needed.
slouken@428
   715
MINIZ_STATIC void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
slouken@391
   716
slouken@391
   717
// tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory.
slouken@391
   718
// Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success.
slouken@391
   719
#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1))
slouken@428
   720
MINIZ_STATIC 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);
slouken@391
   721
slouken@391
   722
// 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.
slouken@391
   723
// Returns 1 on success or 0 on failure.
slouken@391
   724
typedef int (*tinfl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser);
slouken@428
   725
MINIZ_STATIC 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);
slouken@391
   726
slouken@391
   727
struct tinfl_decompressor_tag; typedef struct tinfl_decompressor_tag tinfl_decompressor;
slouken@391
   728
slouken@391
   729
// Max size of LZ dictionary.
slouken@391
   730
#define TINFL_LZ_DICT_SIZE 32768
slouken@391
   731
slouken@391
   732
// Return status.
slouken@391
   733
typedef enum
slouken@391
   734
{
slouken@391
   735
  TINFL_STATUS_BAD_PARAM = -3,
slouken@391
   736
  TINFL_STATUS_ADLER32_MISMATCH = -2,
slouken@391
   737
  TINFL_STATUS_FAILED = -1,
slouken@391
   738
  TINFL_STATUS_DONE = 0,
slouken@391
   739
  TINFL_STATUS_NEEDS_MORE_INPUT = 1,
slouken@391
   740
  TINFL_STATUS_HAS_MORE_OUTPUT = 2
slouken@391
   741
} tinfl_status;
slouken@391
   742
slouken@391
   743
// Initializes the decompressor to its initial state.
slouken@391
   744
#define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END
slouken@391
   745
#define tinfl_get_adler32(r) (r)->m_check_adler32
slouken@391
   746
slouken@391
   747
// 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.
slouken@391
   748
// 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.
slouken@428
   749
MINIZ_STATIC 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);
slouken@391
   750
slouken@391
   751
// Internal/private bits follow.
slouken@391
   752
enum
slouken@391
   753
{
slouken@391
   754
  TINFL_MAX_HUFF_TABLES = 3, TINFL_MAX_HUFF_SYMBOLS_0 = 288, TINFL_MAX_HUFF_SYMBOLS_1 = 32, TINFL_MAX_HUFF_SYMBOLS_2 = 19,
slouken@391
   755
  TINFL_FAST_LOOKUP_BITS = 10, TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS
slouken@391
   756
};
slouken@391
   757
slouken@391
   758
typedef struct
slouken@391
   759
{
slouken@391
   760
  mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0];
slouken@391
   761
  mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
slouken@391
   762
} tinfl_huff_table;
slouken@391
   763
slouken@391
   764
#if MINIZ_HAS_64BIT_REGISTERS
slouken@391
   765
  #define TINFL_USE_64BIT_BITBUF 1
slouken@391
   766
#endif
slouken@391
   767
slouken@391
   768
#if TINFL_USE_64BIT_BITBUF
slouken@391
   769
  typedef mz_uint64 tinfl_bit_buf_t;
slouken@391
   770
  #define TINFL_BITBUF_SIZE (64)
slouken@391
   771
#else
slouken@391
   772
  typedef mz_uint32 tinfl_bit_buf_t;
slouken@391
   773
  #define TINFL_BITBUF_SIZE (32)
slouken@391
   774
#endif
slouken@391
   775
slouken@391
   776
struct tinfl_decompressor_tag
slouken@391
   777
{
slouken@391
   778
  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];
slouken@391
   779
  tinfl_bit_buf_t m_bit_buf;
slouken@391
   780
  size_t m_dist_from_out_buf_start;
slouken@391
   781
  tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES];
slouken@391
   782
  mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137];
slouken@391
   783
};
slouken@391
   784
slouken@391
   785
// ------------------- Low-level Compression API Definitions
slouken@391
   786
slouken@391
   787
// Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly slower, and raw/dynamic blocks will be output more frequently).
slouken@391
   788
#define TDEFL_LESS_MEMORY 0
slouken@391
   789
slouken@391
   790
// tdefl_init() compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search):
slouken@391
   791
// 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).
slouken@391
   792
enum
slouken@391
   793
{
slouken@391
   794
  TDEFL_HUFFMAN_ONLY = 0, TDEFL_DEFAULT_MAX_PROBES = 128, TDEFL_MAX_PROBES_MASK = 0xFFF
slouken@391
   795
};
slouken@391
   796
slouken@391
   797
// 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.
slouken@391
   798
// TDEFL_COMPUTE_ADLER32: Always compute the adler-32 of the input data (even when not writing zlib headers).
slouken@391
   799
// TDEFL_GREEDY_PARSING_FLAG: Set to use faster greedy parsing, instead of more efficient lazy parsing.
slouken@391
   800
// 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).
slouken@391
   801
// TDEFL_RLE_MATCHES: Only look for RLE matches (matches with a distance of 1)
slouken@391
   802
// TDEFL_FILTER_MATCHES: Discards matches <= 5 chars if enabled.
slouken@391
   803
// TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables.
slouken@391
   804
// TDEFL_FORCE_ALL_RAW_BLOCKS: Only use raw (uncompressed) deflate blocks.
slouken@431
   805
// The low 12 bits are reserved to control the max # of hash probes per dictionary lookup (see TDEFL_MAX_PROBES_MASK).
slouken@391
   806
enum
slouken@391
   807
{
slouken@391
   808
  TDEFL_WRITE_ZLIB_HEADER             = 0x01000,
slouken@391
   809
  TDEFL_COMPUTE_ADLER32               = 0x02000,
slouken@391
   810
  TDEFL_GREEDY_PARSING_FLAG           = 0x04000,
slouken@391
   811
  TDEFL_NONDETERMINISTIC_PARSING_FLAG = 0x08000,
slouken@391
   812
  TDEFL_RLE_MATCHES                   = 0x10000,
slouken@391
   813
  TDEFL_FILTER_MATCHES                = 0x20000,
slouken@391
   814
  TDEFL_FORCE_ALL_STATIC_BLOCKS       = 0x40000,
slouken@391
   815
  TDEFL_FORCE_ALL_RAW_BLOCKS          = 0x80000
slouken@391
   816
};
slouken@391
   817
slouken@391
   818
// High level compression functions:
slouken@391
   819
// tdefl_compress_mem_to_heap() compresses a block in memory to a heap block allocated via malloc().
slouken@391
   820
// On entry:
slouken@391
   821
//  pSrc_buf, src_buf_len: Pointer and size of source block to compress.
slouken@391
   822
//  flags: The max match finder probes (default is 128) logically OR'd against the above flags. Higher probes are slower but improve compression.
slouken@391
   823
// On return:
slouken@391
   824
//  Function returns a pointer to the compressed data, or NULL on failure.
slouken@391
   825
//  *pOut_len will be set to the compressed data's size, which could be larger than src_buf_len on uncompressible data.
slouken@391
   826
//  The caller must free() the returned block when it's no longer needed.
slouken@428
   827
MINIZ_STATIC void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
slouken@391
   828
slouken@391
   829
// tdefl_compress_mem_to_mem() compresses a block in memory to another block in memory.
slouken@391
   830
// Returns 0 on failure.
slouken@428
   831
MINIZ_STATIC 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);
slouken@391
   832
slouken@391
   833
// Compresses an image to a compressed PNG file in memory.
slouken@391
   834
// On entry:
slouken@431
   835
//  pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4. 
slouken@431
   836
//  The image pitch in bytes per scanline will be w*num_chans. The leftmost pixel on the top scanline is stored first in memory.
slouken@431
   837
//  level may range from [0,10], use MZ_NO_COMPRESSION, MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc. or a decent default is MZ_DEFAULT_LEVEL
slouken@431
   838
//  If flip is true, the image will be flipped on the Y axis (useful for OpenGL apps).
slouken@391
   839
// On return:
slouken@391
   840
//  Function returns a pointer to the compressed data, or NULL on failure.
slouken@391
   841
//  *pLen_out will be set to the size of the PNG image file.
slouken@431
   842
//  The caller must mz_free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed.
slouken@431
   843
MINIZ_STATIC void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, int bpl, size_t *pLen_out, mz_uint level, mz_bool flip);
slouken@431
   844
MINIZ_STATIC void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, int bpl, size_t *pLen_out);
slouken@391
   845
slouken@391
   846
// Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time.
slouken@391
   847
typedef mz_bool (*tdefl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser);
slouken@391
   848
slouken@391
   849
// tdefl_compress_mem_to_output() compresses a block to an output stream. The above helpers use this function internally.
slouken@428
   850
MINIZ_STATIC 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);
slouken@391
   851
slouken@391
   852
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 };
slouken@391
   853
slouken@391
   854
// TDEFL_OUT_BUF_SIZE MUST be large enough to hold a single entire compressed output block (using static/fixed Huffman codes).
slouken@391
   855
#if TDEFL_LESS_MEMORY
slouken@391
   856
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 };
slouken@391
   857
#else
slouken@391
   858
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 };
slouken@391
   859
#endif
slouken@391
   860
slouken@391
   861
// 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.
slouken@391
   862
typedef enum
slouken@391
   863
{
slouken@391
   864
  TDEFL_STATUS_BAD_PARAM = -2,
slouken@391
   865
  TDEFL_STATUS_PUT_BUF_FAILED = -1,
slouken@391
   866
  TDEFL_STATUS_OKAY = 0,
slouken@391
   867
  TDEFL_STATUS_DONE = 1,
slouken@391
   868
} tdefl_status;
slouken@391
   869
slouken@391
   870
// Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums
slouken@391
   871
typedef enum
slouken@391
   872
{
slouken@391
   873
  TDEFL_NO_FLUSH = 0,
slouken@391
   874
  TDEFL_SYNC_FLUSH = 2,
slouken@391
   875
  TDEFL_FULL_FLUSH = 3,
slouken@391
   876
  TDEFL_FINISH = 4
slouken@391
   877
} tdefl_flush;
slouken@391
   878
slouken@391
   879
// tdefl's compression state structure.
slouken@391
   880
typedef struct
slouken@391
   881
{
slouken@391
   882
  tdefl_put_buf_func_ptr m_pPut_buf_func;
slouken@391
   883
  void *m_pPut_buf_user;
slouken@391
   884
  mz_uint m_flags, m_max_probes[2];
slouken@391
   885
  int m_greedy_parsing;
slouken@391
   886
  mz_uint m_adler32, m_lookahead_pos, m_lookahead_size, m_dict_size;
slouken@391
   887
  mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end;
slouken@391
   888
  mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in, m_bit_buffer;
slouken@391
   889
  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;
slouken@391
   890
  tdefl_status m_prev_return_status;
slouken@391
   891
  const void *m_pIn_buf;
slouken@391
   892
  void *m_pOut_buf;
slouken@391
   893
  size_t *m_pIn_buf_size, *m_pOut_buf_size;
slouken@391
   894
  tdefl_flush m_flush;
slouken@391
   895
  const mz_uint8 *m_pSrc;
slouken@391
   896
  size_t m_src_buf_left, m_out_buf_ofs;
slouken@391
   897
  mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE + TDEFL_MAX_MATCH_LEN - 1];
slouken@391
   898
  mz_uint16 m_huff_count[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
slouken@391
   899
  mz_uint16 m_huff_codes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
slouken@391
   900
  mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
slouken@391
   901
  mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE];
slouken@391
   902
  mz_uint16 m_next[TDEFL_LZ_DICT_SIZE];
slouken@391
   903
  mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE];
slouken@391
   904
  mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE];
slouken@391
   905
} tdefl_compressor;
slouken@391
   906
slouken@391
   907
// Initializes the compressor.
slouken@391
   908
// There is no corresponding deinit() function because the tdefl API's do not dynamically allocate memory.
slouken@391
   909
// pBut_buf_func: If NULL, output data will be supplied to the specified callback. In this case, the user should call the tdefl_compress_buffer() API for compression.
slouken@391
   910
// If pBut_buf_func is NULL the user should always call the tdefl_compress() API.
slouken@391
   911
// flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, etc.)
slouken@428
   912
MINIZ_STATIC tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
slouken@391
   913
slouken@391
   914
// Compresses a block of data, consuming as much of the specified input buffer as possible, and writing as much compressed data to the specified output buffer as possible.
slouken@428
   915
MINIZ_STATIC 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);
slouken@391
   916
slouken@391
   917
// tdefl_compress_buffer() is only usable when the tdefl_init() is called with a non-NULL tdefl_put_buf_func_ptr.
slouken@391
   918
// tdefl_compress_buffer() always consumes the entire input buffer.
slouken@428
   919
MINIZ_STATIC tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush);
slouken@428
   920
slouken@428
   921
MINIZ_STATIC tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d);
slouken@428
   922
MINIZ_STATIC mz_uint32 tdefl_get_adler32(tdefl_compressor *d);
slouken@391
   923
slouken@391
   924
// Can't use tdefl_create_comp_flags_from_zip_params if MINIZ_NO_ZLIB_APIS isn't defined, because it uses some of its macros.
slouken@391
   925
#ifndef MINIZ_NO_ZLIB_APIS
slouken@391
   926
// Create tdefl_compress() flags given zlib-style compression parameters.
slouken@391
   927
// level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files)
slouken@391
   928
// window_bits may be -15 (raw deflate) or 15 (zlib)
slouken@391
   929
// strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED
slouken@428
   930
MINIZ_STATIC mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy);
slouken@391
   931
#endif // #ifndef MINIZ_NO_ZLIB_APIS
slouken@391
   932
slouken@391
   933
#ifdef __cplusplus
slouken@391
   934
}
slouken@391
   935
#endif
slouken@391
   936
slouken@391
   937
#endif // MINIZ_HEADER_INCLUDED
slouken@391
   938
slouken@391
   939
// ------------------- End of Header: Implementation follows. (If you only want the header, define MINIZ_HEADER_FILE_ONLY.)
slouken@391
   940
slouken@391
   941
#ifndef MINIZ_HEADER_FILE_ONLY
slouken@391
   942
slouken@391
   943
typedef unsigned char mz_validate_uint16[sizeof(mz_uint16)==2 ? 1 : -1];
slouken@391
   944
typedef unsigned char mz_validate_uint32[sizeof(mz_uint32)==4 ? 1 : -1];
slouken@391
   945
typedef unsigned char mz_validate_uint64[sizeof(mz_uint64)==8 ? 1 : -1];
slouken@391
   946
slouken@391
   947
#include <string.h>
slouken@391
   948
#include <assert.h>
slouken@391
   949
slouken@391
   950
#define MZ_ASSERT(x) assert(x)
slouken@391
   951
slouken@391
   952
#ifdef MINIZ_NO_MALLOC
slouken@391
   953
  #define MZ_MALLOC(x) NULL
slouken@391
   954
  #define MZ_FREE(x) (void)x, ((void)0)
slouken@391
   955
  #define MZ_REALLOC(p, x) NULL
slouken@391
   956
#elif defined(MINIZ_SDL_MALLOC)
slouken@391
   957
  #define MZ_MALLOC(x) SDL_malloc(x)
slouken@391
   958
  #define MZ_FREE(x) SDL_free(x)
slouken@391
   959
  #define MZ_REALLOC(p, x) SDL_realloc(p, x)
slouken@391
   960
#else
slouken@391
   961
  #define MZ_MALLOC(x) malloc(x)
slouken@391
   962
  #define MZ_FREE(x) free(x)
slouken@391
   963
  #define MZ_REALLOC(p, x) realloc(p, x)
slouken@391
   964
#endif
slouken@391
   965
slouken@391
   966
#define MZ_MAX(a,b) (((a)>(b))?(a):(b))
slouken@391
   967
#define MZ_MIN(a,b) (((a)<(b))?(a):(b))
slouken@391
   968
#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
slouken@391
   969
slouken@391
   970
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
slouken@391
   971
  #define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
slouken@391
   972
  #define MZ_READ_LE32(p) *((const mz_uint32 *)(p))
slouken@391
   973
#else
slouken@391
   974
  #define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U))
slouken@391
   975
  #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))
slouken@391
   976
#endif
slouken@391
   977
slouken@391
   978
#ifdef _MSC_VER
slouken@391
   979
  #define MZ_FORCEINLINE __forceinline
slouken@391
   980
#elif defined(__GNUC__)
slouken@431
   981
  #define MZ_FORCEINLINE inline __attribute__((__always_inline__))
slouken@391
   982
#else
slouken@391
   983
  #define MZ_FORCEINLINE inline
slouken@391
   984
#endif
slouken@391
   985
slouken@391
   986
#ifdef __cplusplus
slouken@391
   987
  extern "C" {
slouken@391
   988
#endif
slouken@391
   989
slouken@391
   990
// ------------------- zlib-style API's
slouken@391
   991
slouken@391
   992
mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len)
slouken@391
   993
{
slouken@391
   994
  mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16); size_t block_len = buf_len % 5552;
slouken@391
   995
  if (!ptr) return MZ_ADLER32_INIT;
slouken@391
   996
  while (buf_len) {
slouken@391
   997
    for (i = 0; i + 7 < block_len; i += 8, ptr += 8) {
slouken@391
   998
      s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1;
slouken@391
   999
      s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1;
slouken@391
  1000
    }
slouken@391
  1001
    for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1;
slouken@391
  1002
    s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552;
slouken@391
  1003
  }
slouken@391
  1004
  return (s2 << 16) + s1;
slouken@391
  1005
}
slouken@391
  1006
slouken@391
  1007
// 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/
slouken@391
  1008
mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
slouken@391
  1009
{
slouken@391
  1010
  static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
slouken@391
  1011
    0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c };
slouken@391
  1012
  mz_uint32 crcu32 = (mz_uint32)crc;
slouken@391
  1013
  if (!ptr) return MZ_CRC32_INIT;
slouken@391
  1014
  crcu32 = ~crcu32; while (buf_len--) { mz_uint8 b = *ptr++; crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)]; crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)]; }
slouken@391
  1015
  return ~crcu32;
slouken@391
  1016
}
slouken@391
  1017
slouken@432
  1018
MINIZ_STATIC void mz_free(void *p)
slouken@431
  1019
{
slouken@431
  1020
  MZ_FREE(p);
slouken@431
  1021
}
slouken@431
  1022
slouken@391
  1023
#ifndef MINIZ_NO_ZLIB_APIS
slouken@391
  1024
slouken@391
  1025
static void *def_alloc_func(void *opaque, size_t items, size_t size) { (void)opaque, (void)items, (void)size; return MZ_MALLOC(items * size); }
slouken@391
  1026
static void def_free_func(void *opaque, void *address) { (void)opaque, (void)address; MZ_FREE(address); }
slouken@391
  1027
static void *def_realloc_func(void *opaque, void *address, size_t items, size_t size) { (void)opaque, (void)address, (void)items, (void)size; return MZ_REALLOC(address, items * size); }
slouken@391
  1028
slouken@391
  1029
const char *mz_version(void)
slouken@391
  1030
{
slouken@391
  1031
  return MZ_VERSION;
slouken@391
  1032
}
slouken@391
  1033
slouken@391
  1034
int mz_deflateInit(mz_streamp pStream, int level)
slouken@391
  1035
{
slouken@391
  1036
  return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY);
slouken@391
  1037
}
slouken@391
  1038
slouken@391
  1039
int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy)
slouken@391
  1040
{
slouken@391
  1041
  tdefl_compressor *pComp;
slouken@391
  1042
  mz_uint comp_flags = TDEFL_COMPUTE_ADLER32 | tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy);
slouken@391
  1043
slouken@391
  1044
  if (!pStream) return MZ_STREAM_ERROR;
slouken@391
  1045
  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;
slouken@391
  1046
slouken@391
  1047
  pStream->data_type = 0;
slouken@391
  1048
  pStream->adler = MZ_ADLER32_INIT;
slouken@391
  1049
  pStream->msg = NULL;
slouken@391
  1050
  pStream->reserved = 0;
slouken@391
  1051
  pStream->total_in = 0;
slouken@391
  1052
  pStream->total_out = 0;
slouken@391
  1053
  if (!pStream->zalloc) pStream->zalloc = def_alloc_func;
slouken@391
  1054
  if (!pStream->zfree) pStream->zfree = def_free_func;
slouken@391
  1055
slouken@391
  1056
  pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, sizeof(tdefl_compressor));
slouken@391
  1057
  if (!pComp)
slouken@391
  1058
    return MZ_MEM_ERROR;
slouken@391
  1059
slouken@391
  1060
  pStream->state = (struct mz_internal_state *)pComp;
slouken@391
  1061
slouken@391
  1062
  if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY)
slouken@391
  1063
  {
slouken@391
  1064
    mz_deflateEnd(pStream);
slouken@391
  1065
    return MZ_PARAM_ERROR;
slouken@391
  1066
  }
slouken@391
  1067
slouken@391
  1068
  return MZ_OK;
slouken@391
  1069
}
slouken@391
  1070
slouken@391
  1071
int mz_deflateReset(mz_streamp pStream)
slouken@391
  1072
{
slouken@391
  1073
  if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree)) return MZ_STREAM_ERROR;
slouken@391
  1074
  pStream->total_in = pStream->total_out = 0;
slouken@391
  1075
  tdefl_init((tdefl_compressor*)pStream->state, NULL, NULL, ((tdefl_compressor*)pStream->state)->m_flags);
slouken@391
  1076
  return MZ_OK;
slouken@391
  1077
}
slouken@391
  1078
slouken@391
  1079
int mz_deflate(mz_streamp pStream, int flush)
slouken@391
  1080
{
slouken@391
  1081
  size_t in_bytes, out_bytes;
slouken@391
  1082
  mz_ulong orig_total_in, orig_total_out;
slouken@391
  1083
  int mz_status = MZ_OK;
slouken@391
  1084
slouken@391
  1085
  if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || (!pStream->next_out)) return MZ_STREAM_ERROR;
slouken@391
  1086
  if (!pStream->avail_out) return MZ_BUF_ERROR;
slouken@391
  1087
slouken@391
  1088
  if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH;
slouken@391
  1089
slouken@391
  1090
  if (((tdefl_compressor*)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE)
slouken@391
  1091
    return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR;
slouken@391
  1092
slouken@391
  1093
  orig_total_in = pStream->total_in; orig_total_out = pStream->total_out;
slouken@391
  1094
  for ( ; ; )
slouken@391
  1095
  {
slouken@391
  1096
    tdefl_status defl_status;
slouken@391
  1097
    in_bytes = pStream->avail_in; out_bytes = pStream->avail_out;
slouken@391
  1098
slouken@391
  1099
    defl_status = tdefl_compress((tdefl_compressor*)pStream->state, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, (tdefl_flush)flush);
slouken@391
  1100
    pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes;
slouken@391
  1101
    pStream->total_in += (mz_uint)in_bytes; pStream->adler = tdefl_get_adler32((tdefl_compressor*)pStream->state);
slouken@391
  1102
slouken@391
  1103
    pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes;
slouken@391
  1104
    pStream->total_out += (mz_uint)out_bytes;
slouken@391
  1105
slouken@391
  1106
    if (defl_status < 0)
slouken@391
  1107
    {
slouken@391
  1108
      mz_status = MZ_STREAM_ERROR;
slouken@391
  1109
      break;
slouken@391
  1110
    }
slouken@391
  1111
    else if (defl_status == TDEFL_STATUS_DONE)
slouken@391
  1112
    {
slouken@391
  1113
      mz_status = MZ_STREAM_END;
slouken@391
  1114
      break;
slouken@391
  1115
    }
slouken@391
  1116
    else if (!pStream->avail_out)
slouken@391
  1117
      break;
slouken@391
  1118
    else if ((!pStream->avail_in) && (flush != MZ_FINISH))
slouken@391
  1119
    {
slouken@391
  1120
      if ((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out))
slouken@391
  1121
        break;
slouken@391
  1122
      return MZ_BUF_ERROR; // Can't make forward progress without some input.
slouken@391
  1123
    }
slouken@391
  1124
  }
slouken@391
  1125
  return mz_status;
slouken@391
  1126
}
slouken@391
  1127
slouken@391
  1128
int mz_deflateEnd(mz_streamp pStream)
slouken@391
  1129
{
slouken@391
  1130
  if (!pStream) return MZ_STREAM_ERROR;
slouken@391
  1131
  if (pStream->state)
slouken@391
  1132
  {
slouken@391
  1133
    pStream->zfree(pStream->opaque, pStream->state);
slouken@391
  1134
    pStream->state = NULL;
slouken@391
  1135
  }
slouken@391
  1136
  return MZ_OK;
slouken@391
  1137
}
slouken@391
  1138
slouken@391
  1139
mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len)
slouken@391
  1140
{
slouken@391
  1141
  (void)pStream;
slouken@391
  1142
  // 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.)
slouken@391
  1143
  return MZ_MAX(128 + (source_len * 110) / 100, 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5);
slouken@391
  1144
}
slouken@391
  1145
slouken@391
  1146
int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level)
slouken@391
  1147
{
slouken@391
  1148
  int status;
slouken@391
  1149
  mz_stream stream;
slouken@391
  1150
  memset(&stream, 0, sizeof(stream));
slouken@391
  1151
slouken@391
  1152
  // In case mz_ulong is 64-bits (argh I hate longs).
slouken@391
  1153
  if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR;
slouken@391
  1154
slouken@391
  1155
  stream.next_in = pSource;
slouken@391
  1156
  stream.avail_in = (mz_uint32)source_len;
slouken@391
  1157
  stream.next_out = pDest;
slouken@391
  1158
  stream.avail_out = (mz_uint32)*pDest_len;
slouken@391
  1159
slouken@391
  1160
  status = mz_deflateInit(&stream, level);
slouken@391
  1161
  if (status != MZ_OK) return status;
slouken@391
  1162
slouken@391
  1163
  status = mz_deflate(&stream, MZ_FINISH);
slouken@391
  1164
  if (status != MZ_STREAM_END)
slouken@391
  1165
  {
slouken@391
  1166
    mz_deflateEnd(&stream);
slouken@391
  1167
    return (status == MZ_OK) ? MZ_BUF_ERROR : status;
slouken@391
  1168
  }
slouken@391
  1169
slouken@391
  1170
  *pDest_len = stream.total_out;
slouken@391
  1171
  return mz_deflateEnd(&stream);
slouken@391
  1172
}
slouken@391
  1173
slouken@391
  1174
int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
slouken@391
  1175
{
slouken@391
  1176
  return mz_compress2(pDest, pDest_len, pSource, source_len, MZ_DEFAULT_COMPRESSION);
slouken@391
  1177
}
slouken@391
  1178
slouken@391
  1179
mz_ulong mz_compressBound(mz_ulong source_len)
slouken@391
  1180
{
slouken@391
  1181
  return mz_deflateBound(NULL, source_len);
slouken@391
  1182
}
slouken@391
  1183
slouken@391
  1184
typedef struct
slouken@391
  1185
{
slouken@391
  1186
  tinfl_decompressor m_decomp;
slouken@391
  1187
  mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed; int m_window_bits;
slouken@391
  1188
  mz_uint8 m_dict[TINFL_LZ_DICT_SIZE];
slouken@391
  1189
  tinfl_status m_last_status;
slouken@391
  1190
} inflate_state;
slouken@391
  1191
slouken@391
  1192
int mz_inflateInit2(mz_streamp pStream, int window_bits)
slouken@391
  1193
{
slouken@391
  1194
  inflate_state *pDecomp;
slouken@391
  1195
  if (!pStream) return MZ_STREAM_ERROR;
slouken@391
  1196
  if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)) return MZ_PARAM_ERROR;
slouken@391
  1197
slouken@391
  1198
  pStream->data_type = 0;
slouken@391
  1199
  pStream->adler = 0;
slouken@391
  1200
  pStream->msg = NULL;
slouken@391
  1201
  pStream->total_in = 0;
slouken@391
  1202
  pStream->total_out = 0;
slouken@391
  1203
  pStream->reserved = 0;
slouken@391
  1204
  if (!pStream->zalloc) pStream->zalloc = def_alloc_func;
slouken@391
  1205
  if (!pStream->zfree) pStream->zfree = def_free_func;
slouken@391
  1206
slouken@391
  1207
  pDecomp = (inflate_state*)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state));
slouken@391
  1208
  if (!pDecomp) return MZ_MEM_ERROR;
slouken@391
  1209
slouken@391
  1210
  pStream->state = (struct mz_internal_state *)pDecomp;
slouken@391
  1211
slouken@391
  1212
  tinfl_init(&pDecomp->m_decomp);
slouken@391
  1213
  pDecomp->m_dict_ofs = 0;
slouken@391
  1214
  pDecomp->m_dict_avail = 0;
slouken@391
  1215
  pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
slouken@391
  1216
  pDecomp->m_first_call = 1;
slouken@391
  1217
  pDecomp->m_has_flushed = 0;
slouken@391
  1218
  pDecomp->m_window_bits = window_bits;
slouken@391
  1219
slouken@391
  1220
  return MZ_OK;
slouken@391
  1221
}
slouken@391
  1222
slouken@391
  1223
int mz_inflateInit(mz_streamp pStream)
slouken@391
  1224
{
slouken@391
  1225
   return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS);
slouken@391
  1226
}
slouken@391
  1227
slouken@391
  1228
int mz_inflate(mz_streamp pStream, int flush)
slouken@391
  1229
{
slouken@391
  1230
  inflate_state* pState;
slouken@391
  1231
  mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32;
slouken@391
  1232
  size_t in_bytes, out_bytes, orig_avail_in;
slouken@391
  1233
  tinfl_status status;
slouken@391
  1234
slouken@391
  1235
  if ((!pStream) || (!pStream->state)) return MZ_STREAM_ERROR;
slouken@391
  1236
  if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH;
slouken@391
  1237
  if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH)) return MZ_STREAM_ERROR;
slouken@391
  1238
slouken@391
  1239
  pState = (inflate_state*)pStream->state;
slouken@391
  1240
  if (pState->m_window_bits > 0) decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER;
slouken@391
  1241
  orig_avail_in = pStream->avail_in;
slouken@391
  1242
slouken@391
  1243
  first_call = pState->m_first_call; pState->m_first_call = 0;
slouken@391
  1244
  if (pState->m_last_status < 0) return MZ_DATA_ERROR;
slouken@391
  1245
slouken@391
  1246
  if (pState->m_has_flushed && (flush != MZ_FINISH)) return MZ_STREAM_ERROR;
slouken@391
  1247
  pState->m_has_flushed |= (flush == MZ_FINISH);
slouken@391
  1248
slouken@391
  1249
  if ((flush == MZ_FINISH) && (first_call))
slouken@391
  1250
  {
slouken@391
  1251
    // MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file.
slouken@391
  1252
    decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF;
slouken@391
  1253
    in_bytes = pStream->avail_in; out_bytes = pStream->avail_out;
slouken@391
  1254
    status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags);
slouken@391
  1255
    pState->m_last_status = status;
slouken@391
  1256
    pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; pStream->total_in += (mz_uint)in_bytes;
slouken@391
  1257
    pStream->adler = tinfl_get_adler32(&pState->m_decomp);
slouken@391
  1258
    pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes; pStream->total_out += (mz_uint)out_bytes;
slouken@391
  1259
slouken@391
  1260
    if (status < 0)
slouken@391
  1261
      return MZ_DATA_ERROR;
slouken@391
  1262
    else if (status != TINFL_STATUS_DONE)
slouken@391
  1263
    {
slouken@391
  1264
      pState->m_last_status = TINFL_STATUS_FAILED;
slouken@391
  1265
      return MZ_BUF_ERROR;
slouken@391
  1266
    }
slouken@391
  1267
    return MZ_STREAM_END;
slouken@391
  1268
  }
slouken@391
  1269
  // flush != MZ_FINISH then we must assume there's more input.
slouken@391
  1270
  if (flush != MZ_FINISH) decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT;
slouken@391
  1271
slouken@391
  1272
  if (pState->m_dict_avail)
slouken@391
  1273
  {
slouken@391
  1274
    n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
slouken@391
  1275
    memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
slouken@391
  1276
    pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n;
slouken@391
  1277
    pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
slouken@391
  1278
    return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
slouken@391
  1279
  }
slouken@391
  1280
slouken@391
  1281
  for ( ; ; )
slouken@391
  1282
  {
slouken@391
  1283
    in_bytes = pStream->avail_in;
slouken@391
  1284
    out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs;
slouken@391
  1285
slouken@391
  1286
    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);
slouken@391
  1287
    pState->m_last_status = status;
slouken@391
  1288
slouken@391
  1289
    pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes;
slouken@391
  1290
    pStream->total_in += (mz_uint)in_bytes; pStream->adler = tinfl_get_adler32(&pState->m_decomp);
slouken@391
  1291
slouken@391
  1292
    pState->m_dict_avail = (mz_uint)out_bytes;
slouken@391
  1293
slouken@391
  1294
    n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
slouken@391
  1295
    memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
slouken@391
  1296
    pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n;
slouken@391
  1297
    pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
slouken@391
  1298
slouken@391
  1299
    if (status < 0)
slouken@391
  1300
       return MZ_DATA_ERROR; // Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well).
slouken@391
  1301
    else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in))
slouken@391
  1302
      return MZ_BUF_ERROR; // Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH.
slouken@391
  1303
    else if (flush == MZ_FINISH)
slouken@391
  1304
    {
slouken@391
  1305
       // The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH.
slouken@391
  1306
       if (status == TINFL_STATUS_DONE)
slouken@391
  1307
          return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END;
slouken@391
  1308
       // 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.
slouken@391
  1309
       else if (!pStream->avail_out)
slouken@391
  1310
          return MZ_BUF_ERROR;
slouken@391
  1311
    }
slouken@391
  1312
    else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail))
slouken@391
  1313
      break;
slouken@391
  1314
  }
slouken@391
  1315
slouken@391
  1316
  return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
slouken@391
  1317
}
slouken@391
  1318
slouken@391
  1319
int mz_inflateEnd(mz_streamp pStream)
slouken@391
  1320
{
slouken@391
  1321
  if (!pStream)
slouken@391
  1322
    return MZ_STREAM_ERROR;
slouken@391
  1323
  if (pStream->state)
slouken@391
  1324
  {
slouken@391
  1325
    pStream->zfree(pStream->opaque, pStream->state);
slouken@391
  1326
    pStream->state = NULL;
slouken@391
  1327
  }
slouken@391
  1328
  return MZ_OK;
slouken@391
  1329
}
slouken@391
  1330
slouken@391
  1331
int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
slouken@391
  1332
{
slouken@391
  1333
  mz_stream stream;
slouken@391
  1334
  int status;
slouken@391
  1335
  memset(&stream, 0, sizeof(stream));
slouken@391
  1336
slouken@391
  1337
  // In case mz_ulong is 64-bits (argh I hate longs).
slouken@391
  1338
  if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR;
slouken@391
  1339
slouken@391
  1340
  stream.next_in = pSource;
slouken@391
  1341
  stream.avail_in = (mz_uint32)source_len;
slouken@391
  1342
  stream.next_out = pDest;
slouken@391
  1343
  stream.avail_out = (mz_uint32)*pDest_len;
slouken@391
  1344
slouken@391
  1345
  status = mz_inflateInit(&stream);
slouken@391
  1346
  if (status != MZ_OK)
slouken@391
  1347
    return status;
slouken@391
  1348
slouken@391
  1349
  status = mz_inflate(&stream, MZ_FINISH);
slouken@391
  1350
  if (status != MZ_STREAM_END)
slouken@391
  1351
  {
slouken@391
  1352
    mz_inflateEnd(&stream);
slouken@391
  1353
    return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status;
slouken@391
  1354
  }
slouken@391
  1355
  *pDest_len = stream.total_out;
slouken@391
  1356
slouken@391
  1357
  return mz_inflateEnd(&stream);
slouken@391
  1358
}
slouken@391
  1359
slouken@391
  1360
const char *mz_error(int err)
slouken@391
  1361
{
slouken@391
  1362
  static struct { int m_err; const char *m_pDesc; } s_error_descs[] =
slouken@391
  1363
  {
slouken@391
  1364
    { MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" },
slouken@391
  1365
    { 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" }
slouken@391
  1366
  };
slouken@391
  1367
  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;
slouken@391
  1368
  return NULL;
slouken@391
  1369
}
slouken@391
  1370
slouken@391
  1371
#endif //MINIZ_NO_ZLIB_APIS
slouken@391
  1372
slouken@391
  1373
// ------------------- Low-level Decompression (completely independent from all compression API's)
slouken@391
  1374
slouken@391
  1375
#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
slouken@391
  1376
#define TINFL_MEMSET(p, c, l) memset(p, c, l)
slouken@391
  1377
slouken@391
  1378
#define TINFL_CR_BEGIN switch(r->m_state) { case 0:
slouken@391
  1379
#define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END
slouken@391
  1380
#define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END
slouken@391
  1381
#define TINFL_CR_FINISH }
slouken@391
  1382
slouken@391
  1383
// 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
slouken@391
  1384
// reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of the stream with 0's in this scenario.
slouken@391
  1385
#define TINFL_GET_BYTE(state_index, c) do { \
slouken@391
  1386
  if (pIn_buf_cur >= pIn_buf_end) { \
slouken@391
  1387
    for ( ; ; ) { \
slouken@391
  1388
      if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \
slouken@391
  1389
        TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \
slouken@391
  1390
        if (pIn_buf_cur < pIn_buf_end) { \
slouken@391
  1391
          c = *pIn_buf_cur++; \
slouken@391
  1392
          break; \
slouken@391
  1393
        } \
slouken@391
  1394
      } else { \
slouken@391
  1395
        c = 0; \
slouken@391
  1396
        break; \
slouken@391
  1397
      } \
slouken@391
  1398
    } \
slouken@391
  1399
  } else c = *pIn_buf_cur++; } MZ_MACRO_END
slouken@391
  1400
slouken@391
  1401
#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))
slouken@391
  1402
#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
slouken@391
  1403
#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
slouken@391
  1404
slouken@391
  1405
// TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2.
slouken@391
  1406
// 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
slouken@391
  1407
// 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
slouken@391
  1408
// bit buffer contains >=15 bits (deflate's max. Huffman code size).
slouken@391
  1409
#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \
slouken@391
  1410
  do { \
slouken@391
  1411
    temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
slouken@391
  1412
    if (temp >= 0) { \
slouken@391
  1413
      code_len = temp >> 9; \
slouken@391
  1414
      if ((code_len) && (num_bits >= code_len)) \
slouken@391
  1415
      break; \
slouken@391
  1416
    } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \
slouken@391
  1417
       code_len = TINFL_FAST_LOOKUP_BITS; \
slouken@391
  1418
       do { \
slouken@391
  1419
          temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
slouken@391
  1420
       } while ((temp < 0) && (num_bits >= (code_len + 1))); if (temp >= 0) break; \
slouken@391
  1421
    } TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; \
slouken@391
  1422
  } while (num_bits < 15);
slouken@391
  1423
slouken@391
  1424
// 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
slouken@391
  1425
// 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
slouken@391
  1426
// 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.
slouken@391
  1427
// The slow path is only executed at the very end of the input buffer.
slouken@391
  1428
#define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \
slouken@391
  1429
  int temp; mz_uint code_len, c; \
slouken@391
  1430
  if (num_bits < 15) { \
slouken@391
  1431
    if ((pIn_buf_end - pIn_buf_cur) < 2) { \
slouken@391
  1432
       TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
slouken@391
  1433
    } else { \
slouken@391
  1434
       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; \
slouken@391
  1435
    } \
slouken@391
  1436
  } \
slouken@391
  1437
  if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
slouken@391
  1438
    code_len = temp >> 9, temp &= 511; \
slouken@391
  1439
  else { \
slouken@391
  1440
    code_len = TINFL_FAST_LOOKUP_BITS; do { temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; } while (temp < 0); \
slouken@391
  1441
  } sym = temp; bit_buf >>= code_len; num_bits -= code_len; } MZ_MACRO_END
slouken@391
  1442
slouken@391
  1443
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)
slouken@391
  1444
{
slouken@391
  1445
  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 };
slouken@391
  1446
  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 };
slouken@391
  1447
  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};
slouken@391
  1448
  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};
slouken@391
  1449
  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 };
slouken@391
  1450
  static const int s_min_table_sizes[3] = { 257, 1, 4 };
slouken@391
  1451
slouken@391
  1452
  tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; tinfl_bit_buf_t bit_buf;
slouken@391
  1453
  const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size;
slouken@391
  1454
  mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size;
slouken@391
  1455
  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;
slouken@391
  1456
slouken@391
  1457
  // 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).
slouken@391
  1458
  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; }
slouken@391
  1459
slouken@391
  1460
  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;
slouken@391
  1461
  TINFL_CR_BEGIN
slouken@391
  1462
slouken@391
  1463
  bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0; r->m_z_adler32 = r->m_check_adler32 = 1;
slouken@391
  1464
  if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
slouken@391
  1465
  {
slouken@391
  1466
    TINFL_GET_BYTE(1, r->m_zhdr0); TINFL_GET_BYTE(2, r->m_zhdr1);
slouken@391
  1467
    counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8));
slouken@391
  1468
    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)))));
slouken@391
  1469
    if (counter) { TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); }
slouken@391
  1470
  }
slouken@391
  1471
slouken@391
  1472
  do
slouken@391
  1473
  {
slouken@391
  1474
    TINFL_GET_BITS(3, r->m_final, 3); r->m_type = r->m_final >> 1;
slouken@391
  1475
    if (r->m_type == 0)
slouken@391
  1476
    {
slouken@391
  1477
      TINFL_SKIP_BITS(5, num_bits & 7);
slouken@391
  1478
      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]); }
slouken@391
  1479
      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); }
slouken@391
  1480
      while ((counter) && (num_bits))
slouken@391
  1481
      {
slouken@391
  1482
        TINFL_GET_BITS(51, dist, 8);
slouken@391
  1483
        while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT); }
slouken@391
  1484
        *pOut_buf_cur++ = (mz_uint8)dist;
slouken@391
  1485
        counter--;
slouken@391
  1486
      }
slouken@391
  1487
      while (counter)
slouken@391
  1488
      {
slouken@391
  1489
        size_t n; while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); }
slouken@391
  1490
        while (pIn_buf_cur >= pIn_buf_end)
slouken@391
  1491
        {
slouken@391
  1492
          if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT)
slouken@391
  1493
          {
slouken@391
  1494
            TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT);
slouken@391
  1495
          }
slouken@391
  1496
          else
slouken@391
  1497
          {
slouken@391
  1498
            TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED);
slouken@391
  1499
          }
slouken@391
  1500
        }
slouken@391
  1501
        n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter);
slouken@391
  1502
        TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); pIn_buf_cur += n; pOut_buf_cur += n; counter -= (mz_uint)n;
slouken@391
  1503
      }
slouken@391
  1504
    }
slouken@391
  1505
    else if (r->m_type == 3)
slouken@391
  1506
    {
slouken@391
  1507
      TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED);
slouken@391
  1508
    }
slouken@391
  1509
    else
slouken@391
  1510
    {
slouken@391
  1511
      if (r->m_type == 1)
slouken@391
  1512
      {
slouken@391
  1513
        mz_uint8 *p = r->m_tables[0].m_code_size; mz_uint i;
slouken@391
  1514
        r->m_table_sizes[0] = 288; r->m_table_sizes[1] = 32; TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32);
slouken@391
  1515
        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;
slouken@391
  1516
      }
slouken@391
  1517
      else
slouken@391
  1518
      {
slouken@391
  1519
        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]; }
slouken@391
  1520
        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; }
slouken@391
  1521
        r->m_table_sizes[2] = 19;
slouken@391
  1522
      }
slouken@391
  1523
      for ( ; (int)r->m_type >= 0; r->m_type--)
slouken@391
  1524
      {
slouken@391
  1525
        int tree_next, tree_cur; tinfl_huff_table *pTable;
slouken@391
  1526
        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);
slouken@391
  1527
        for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) total_syms[pTable->m_code_size[i]]++;
slouken@391
  1528
        used_syms = 0, total = 0; next_code[0] = next_code[1] = 0;
slouken@391
  1529
        for (i = 1; i <= 15; ++i) { used_syms += total_syms[i]; next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); }
slouken@391
  1530
        if ((65536 != total) && (used_syms > 1))
slouken@391
  1531
        {
slouken@391
  1532
          TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED);
slouken@391
  1533
        }
slouken@391
  1534
        for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index)
slouken@391
  1535
        {
slouken@391
  1536
          mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index]; if (!code_size) continue;
slouken@391
  1537
          cur_code = next_code[code_size]++; for (l = code_size; l > 0; l--, cur_code >>= 1) rev_code = (rev_code << 1) | (cur_code & 1);
slouken@391
  1538
          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; }
slouken@391
  1539
          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; }
slouken@391
  1540
          rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1);
slouken@391
  1541
          for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--)
slouken@391
  1542
          {
slouken@391
  1543
            tree_cur -= ((rev_code >>= 1) & 1);
slouken@391
  1544
            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];
slouken@391
  1545
          }
slouken@391
  1546
          tree_cur -= ((rev_code >>= 1) & 1); pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
slouken@391
  1547
        }
slouken@391
  1548
        if (r->m_type == 2)
slouken@391
  1549
        {
slouken@391
  1550
          for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]); )
slouken@391
  1551
          {
slouken@391
  1552
            mz_uint s; TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); if (dist < 16) { r->m_len_codes[counter++] = (mz_uint8)dist; continue; }
slouken@391
  1553
            if ((dist == 16) && (!counter))
slouken@391
  1554
            {
slouken@391
  1555
              TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED);
slouken@391
  1556
            }
slouken@391
  1557
            num_extra = "\02\03\07"[dist - 16]; TINFL_GET_BITS(18, s, num_extra); s += "\03\03\013"[dist - 16];
slouken@391
  1558
            TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s); counter += s;
slouken@391
  1559
          }
slouken@391
  1560
          if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter)
slouken@391
  1561
          {
slouken@391
  1562
            TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED);
slouken@391
  1563
          }
slouken@391
  1564
          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]);
slouken@391
  1565
        }
slouken@391
  1566
      }
slouken@391
  1567
      for ( ; ; )
slouken@391
  1568
      {
slouken@391
  1569
        mz_uint8 *pSrc;
slouken@391
  1570
        for ( ; ; )
slouken@391
  1571
        {
slouken@391
  1572
          if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2))
slouken@391
  1573
          {
slouken@391
  1574
            TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]);
slouken@391
  1575
            if (counter >= 256)
slouken@391
  1576
              break;
slouken@391
  1577
            while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT); }
slouken@391
  1578
            *pOut_buf_cur++ = (mz_uint8)counter;
slouken@391
  1579
          }
slouken@391
  1580
          else
slouken@391
  1581
          {
slouken@391
  1582
            int sym2; mz_uint code_len;
slouken@391
  1583
#if TINFL_USE_64BIT_BITBUF
slouken@391
  1584
            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; }
slouken@391
  1585
#else
slouken@391
  1586
            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; }
slouken@391
  1587
#endif
slouken@391
  1588
            if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
slouken@391
  1589
              code_len = sym2 >> 9;
slouken@391
  1590
            else
slouken@391
  1591
            {
slouken@391
  1592
              code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0);
slouken@391
  1593
            }
slouken@391
  1594
            counter = sym2; bit_buf >>= code_len; num_bits -= code_len;
slouken@391
  1595
            if (counter & 256)
slouken@391
  1596
              break;
slouken@391
  1597
slouken@391
  1598
#if !TINFL_USE_64BIT_BITBUF
slouken@391
  1599
            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; }
slouken@391
  1600
#endif
slouken@391
  1601
            if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
slouken@391
  1602
              code_len = sym2 >> 9;
slouken@391
  1603
            else
slouken@391
  1604
            {
slouken@391
  1605
              code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0);
slouken@391
  1606
            }
slouken@391
  1607
            bit_buf >>= code_len; num_bits -= code_len;
slouken@391
  1608
slouken@391
  1609
            pOut_buf_cur[0] = (mz_uint8)counter;
slouken@391
  1610
            if (sym2 & 256)
slouken@391
  1611
            {
slouken@391
  1612
              pOut_buf_cur++;
slouken@391
  1613
              counter = sym2;
slouken@391
  1614
              break;
slouken@391
  1615
            }
slouken@391
  1616
            pOut_buf_cur[1] = (mz_uint8)sym2;
slouken@391
  1617
            pOut_buf_cur += 2;
slouken@391
  1618
          }
slouken@391
  1619
        }
slouken@391
  1620
        if ((counter &= 511) == 256) break;
slouken@391
  1621
slouken@391
  1622
        num_extra = s_length_extra[counter - 257]; counter = s_length_base[counter - 257];
slouken@391
  1623
        if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(25, extra_bits, num_extra); counter += extra_bits; }
slouken@391
  1624
slouken@391
  1625
        TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]);
slouken@391
  1626
        num_extra = s_dist_extra[dist]; dist = s_dist_base[dist];
slouken@391
  1627
        if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(27, extra_bits, num_extra); dist += extra_bits; }
slouken@391
  1628
slouken@391
  1629
        dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
slouken@391
  1630
        if ((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
slouken@391
  1631
        {
slouken@391
  1632
          TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED);
slouken@391
  1633
        }
slouken@391
  1634
slouken@391
  1635
        pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask);
slouken@391
  1636
slouken@391
  1637
        if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end)
slouken@391
  1638
        {
slouken@391
  1639
          while (counter--)
slouken@391
  1640
          {
slouken@391
  1641
            while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT); }
slouken@391
  1642
            *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask];
slouken@391
  1643
          }
slouken@391
  1644
          continue;
slouken@391
  1645
        }
slouken@391
  1646
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
slouken@391
  1647
        else if ((counter >= 9) && (counter <= dist))
slouken@391
  1648
        {
slouken@391
  1649
          const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
slouken@391
  1650
          do
slouken@391
  1651
          {
slouken@391
  1652
            ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0];
slouken@391
  1653
            ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1];
slouken@391
  1654
            pOut_buf_cur += 8;
slouken@391
  1655
          } while ((pSrc += 8) < pSrc_end);
slouken@391
  1656
          if ((counter &= 7) < 3)
slouken@391
  1657
          {
slouken@391
  1658
            if (counter)
slouken@391
  1659
            {
slouken@391
  1660
              pOut_buf_cur[0] = pSrc[0];
slouken@391
  1661
              if (counter > 1)
slouken@391
  1662
                pOut_buf_cur[1] = pSrc[1];
slouken@391
  1663
              pOut_buf_cur += counter;
slouken@391
  1664
            }
slouken@391
  1665
            continue;
slouken@391
  1666
          }
slouken@391
  1667
        }
slouken@391
  1668
#endif
slouken@391
  1669
        do
slouken@391
  1670
        {
slouken@391
  1671
          pOut_buf_cur[0] = pSrc[0];
slouken@391
  1672
          pOut_buf_cur[1] = pSrc[1];
slouken@391
  1673
          pOut_buf_cur[2] = pSrc[2];
slouken@391
  1674
          pOut_buf_cur += 3; pSrc += 3;
slouken@391
  1675
        } while ((int)(counter -= 3) > 2);
slouken@391
  1676
        if ((int)counter > 0)
slouken@391
  1677
        {
slouken@391
  1678
          pOut_buf_cur[0] = pSrc[0];
slouken@391
  1679
          if ((int)counter > 1)
slouken@391
  1680
            pOut_buf_cur[1] = pSrc[1];
slouken@391
  1681
          pOut_buf_cur += counter;
slouken@391
  1682
        }
slouken@391
  1683
      }
slouken@391
  1684
    }
slouken@391
  1685
  } while (!(r->m_final & 1));
slouken@391
  1686
  if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
slouken@391
  1687
  {
slouken@391
  1688
    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; }
slouken@391
  1689
  }
slouken@391
  1690
  TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE);
slouken@391
  1691
  TINFL_CR_FINISH
slouken@391
  1692
slouken@391
  1693
common_exit:
slouken@391
  1694
  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;
slouken@391
  1695
  *pIn_buf_size = pIn_buf_cur - pIn_buf_next; *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
slouken@391
  1696
  if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0))
slouken@391
  1697
  {
slouken@391
  1698
    const mz_uint8 *ptr = pOut_buf_next; size_t buf_len = *pOut_buf_size;
slouken@391
  1699
    mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16; size_t block_len = buf_len % 5552;
slouken@391
  1700
    while (buf_len)
slouken@391
  1701
    {
slouken@391
  1702
      for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
slouken@391
  1703
      {
slouken@391
  1704
        s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1;
slouken@391
  1705
        s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1;
slouken@391
  1706
      }
slouken@391
  1707
      for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1;
slouken@391
  1708
      s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552;
slouken@391
  1709
    }
slouken@391
  1710
    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;
slouken@391
  1711
  }
slouken@391
  1712
  return status;
slouken@391
  1713
}
slouken@391
  1714
slouken@391
  1715
// Higher level helper functions.
slouken@391
  1716
void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
slouken@391
  1717
{
slouken@391
  1718
  tinfl_decompressor decomp; void *pBuf = NULL, *pNew_buf; size_t src_buf_ofs = 0, out_buf_capacity = 0;
slouken@391
  1719
  *pOut_len = 0;
slouken@391
  1720
  tinfl_init(&decomp);
slouken@391
  1721
  for ( ; ; )
slouken@391
  1722
  {
slouken@391
  1723
    size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity;
slouken@391
  1724
    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,
slouken@391
  1725
      (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
slouken@391
  1726
    if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT))
slouken@391
  1727
    {
slouken@391
  1728
      MZ_FREE(pBuf); *pOut_len = 0; return NULL;
slouken@391
  1729
    }
slouken@391
  1730
    src_buf_ofs += src_buf_size;
slouken@391
  1731
    *pOut_len += dst_buf_size;
slouken@391
  1732
    if (status == TINFL_STATUS_DONE) break;
slouken@391
  1733
    new_out_buf_capacity = out_buf_capacity * 2; if (new_out_buf_capacity < 128) new_out_buf_capacity = 128;
slouken@391
  1734
    pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity);
slouken@391
  1735
    if (!pNew_buf)
slouken@391
  1736
    {
slouken@391
  1737
      MZ_FREE(pBuf); *pOut_len = 0; return NULL;
slouken@391
  1738
    }
slouken@391
  1739
    pBuf = pNew_buf; out_buf_capacity = new_out_buf_capacity;
slouken@391
  1740
  }
slouken@391
  1741
  return pBuf;
slouken@391
  1742
}
slouken@391
  1743
slouken@391
  1744
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)
slouken@391
  1745
{
slouken@391
  1746
  tinfl_decompressor decomp; tinfl_status status; tinfl_init(&decomp);
slouken@391
  1747
  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);
slouken@391
  1748
  return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len;
slouken@391
  1749
}
slouken@391
  1750
slouken@391
  1751
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)
slouken@391
  1752
{
slouken@391
  1753
  int result = 0;
slouken@391
  1754
  tinfl_decompressor decomp;
slouken@391
  1755
  mz_uint8 *pDict = (mz_uint8*)MZ_MALLOC(TINFL_LZ_DICT_SIZE); size_t in_buf_ofs = 0, dict_ofs = 0;
slouken@391
  1756
  if (!pDict)
slouken@391
  1757
    return TINFL_STATUS_FAILED;
slouken@391
  1758
  tinfl_init(&decomp);
slouken@391
  1759
  for ( ; ; )
slouken@391
  1760
  {
slouken@391
  1761
    size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs;
slouken@391
  1762
    tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size,
slouken@391
  1763
      (flags & ~(TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)));
slouken@391
  1764
    in_buf_ofs += in_buf_size;
slouken@391
  1765
    if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user)))
slouken@391
  1766
      break;
slouken@391
  1767
    if (status != TINFL_STATUS_HAS_MORE_OUTPUT)
slouken@391
  1768
    {
slouken@391
  1769
      result = (status == TINFL_STATUS_DONE);
slouken@391
  1770
      break;
slouken@391
  1771
    }
slouken@391
  1772
    dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1);
slouken@391
  1773
  }
slouken@391
  1774
  MZ_FREE(pDict);
slouken@391
  1775
  *pIn_buf_size = in_buf_ofs;
slouken@391
  1776
  return result;
slouken@391
  1777
}
slouken@391
  1778
slouken@391
  1779
// ------------------- Low-level Compression (independent from all decompression API's)
slouken@391
  1780
slouken@391
  1781
// Purposely making these tables static for faster init and thread safety.
slouken@391
  1782
static const mz_uint16 s_tdefl_len_sym[256] = {
slouken@391
  1783
  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,
slouken@391
  1784
  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,
slouken@391
  1785
  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,
slouken@391
  1786
  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,
slouken@391
  1787
  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,
slouken@391
  1788
  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,
slouken@391
  1789
  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,
slouken@391
  1790
  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 };
slouken@391
  1791
slouken@391
  1792
static const mz_uint8 s_tdefl_len_extra[256] = {
slouken@391
  1793
  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,
slouken@391
  1794
  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,
slouken@391
  1795
  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
slouken@391
  1796
  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,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 };
slouken@391
  1797
slouken@391
  1798
static const mz_uint8 s_tdefl_small_dist_sym[512] = {
slouken@391
  1799
  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,
slouken@391
  1800
  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,
slouken@391
  1801
  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,
slouken@391
  1802
  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,
slouken@391
  1803
  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,
slouken@391
  1804
  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,
slouken@391
  1805
  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,
slouken@391
  1806
  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,
slouken@391
  1807
  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,
slouken@391
  1808
  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,
slouken@391
  1809
  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,
slouken@391
  1810
  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 };
slouken@391
  1811
slouken@391
  1812
static const mz_uint8 s_tdefl_small_dist_extra[512] = {
slouken@391
  1813
  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,
slouken@391
  1814
  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,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,
slouken@391
  1815
  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
slouken@391
  1816
  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,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,
slouken@391
  1817
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
slouken@391
  1818
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
slouken@391
  1819
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
slouken@391
  1820
  7,7,7,7,7,7,7,7 };
slouken@391
  1821
slouken@391
  1822
static const mz_uint8 s_tdefl_large_dist_sym[128] = {
slouken@391
  1823
  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,
slouken@391
  1824
  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,
slouken@391
  1825
  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 };
slouken@391
  1826
slouken@391
  1827
static const mz_uint8 s_tdefl_large_dist_extra[128] = {
slouken@391
  1828
  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,
slouken@391
  1829
  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,
slouken@391
  1830
  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 };
slouken@391
  1831
slouken@391
  1832
// Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted values.
slouken@391
  1833
typedef struct { mz_uint16 m_key, m_sym_index; } tdefl_sym_freq;
slouken@391
  1834
static tdefl_sym_freq* tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq* pSyms0, tdefl_sym_freq* pSyms1)
slouken@391
  1835
{
slouken@391
  1836
  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);
slouken@391
  1837
  for (i = 0; i < num_syms; i++) { mz_uint freq = pSyms0[i].m_key; hist[freq & 0xFF]++; hist[256 + ((freq >> 8) & 0xFF)]++; }
slouken@391
  1838
  while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256])) total_passes--;
slouken@391
  1839
  for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8)
slouken@391
  1840
  {
slouken@391
  1841
    const mz_uint32* pHist = &hist[pass << 8];
slouken@391
  1842
    mz_uint offsets[256], cur_ofs = 0;
slouken@391
  1843
    for (i = 0; i < 256; i++) { offsets[i] = cur_ofs; cur_ofs += pHist[i]; }
slouken@391
  1844
    for (i = 0; i < num_syms; i++) pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = pCur_syms[i];
slouken@391
  1845
    { tdefl_sym_freq* t = pCur_syms; pCur_syms = pNew_syms; pNew_syms = t; }
slouken@391
  1846
  }
slouken@391
  1847
  return pCur_syms;
slouken@391
  1848
}
slouken@391
  1849
slouken@391
  1850
// tdefl_calculate_minimum_redundancy() originally written by: Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996.
slouken@391
  1851
static void tdefl_calculate_minimum_redundancy(tdefl_sym_freq *A, int n)
slouken@391
  1852
{
slouken@391
  1853
  int root, leaf, next, avbl, used, dpth;
slouken@391
  1854
  if (n==0) return; else if (n==1) { A[0].m_key = 1; return; }
slouken@391
  1855
  A[0].m_key += A[1].m_key; root = 0; leaf = 2;
slouken@391
  1856
  for (next=1; next < n-1; next++)
slouken@391
  1857
  {
slouken@391
  1858
    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;
slouken@391
  1859
    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);
slouken@391
  1860
  }
slouken@391
  1861
  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;
slouken@391
  1862
  avbl = 1; used = dpth = 0; root = n-2; next = n-1;
slouken@391
  1863
  while (avbl>0)
slouken@391
  1864
  {
slouken@391
  1865
    while (root>=0 && (int)A[root].m_key==dpth) { used++; root--; }
slouken@391
  1866
    while (avbl>used) { A[next--].m_key = (mz_uint16)(dpth); avbl--; }
slouken@391
  1867
    avbl = 2*used; dpth++; used = 0;
slouken@391
  1868
  }
slouken@391
  1869
}
slouken@391
  1870
slouken@391
  1871
// Limits canonical Huffman code table's max code size.
slouken@391
  1872
enum { TDEFL_MAX_SUPPORTED_HUFF_CODESIZE = 32 };
slouken@391
  1873
static void tdefl_huffman_enforce_max_code_size(int *pNum_codes, int code_list_len, int max_code_size)
slouken@391
  1874
{
slouken@391
  1875
  int i; mz_uint32 total = 0; if (code_list_len <= 1) return;
slouken@391
  1876
  for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++) pNum_codes[max_code_size] += pNum_codes[i];
slouken@391
  1877
  for (i = max_code_size; i > 0; i--) total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i));
slouken@391
  1878
  while (total != (1UL << max_code_size))
slouken@391
  1879
  {
slouken@391
  1880
    pNum_codes[max_code_size]--;
slouken@391
  1881
    for (i = max_code_size - 1; i > 0; i--) if (pNum_codes[i]) { pNum_codes[i]--; pNum_codes[i + 1] += 2; break; }
slouken@391
  1882
    total--;
slouken@391
  1883
  }
slouken@391
  1884
}
slouken@391
  1885
slouken@391
  1886
static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int table_len, int code_size_limit, int static_table)
slouken@391
  1887
{
slouken@391
  1888
  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);
slouken@391
  1889
  if (static_table)
slouken@391
  1890
  {
slouken@391
  1891
    for (i = 0; i < table_len; i++) num_codes[d->m_huff_code_sizes[table_num][i]]++;
slouken@391
  1892
  }
slouken@391
  1893
  else
slouken@391
  1894
  {
slouken@391
  1895
    tdefl_sym_freq syms0[TDEFL_MAX_HUFF_SYMBOLS], syms1[TDEFL_MAX_HUFF_SYMBOLS], *pSyms;
slouken@391
  1896
    int num_used_syms = 0;
slouken@391
  1897
    const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0];
slouken@391
  1898
    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; }
slouken@391
  1899
slouken@391
  1900
    pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1); tdefl_calculate_minimum_redundancy(pSyms, num_used_syms);
slouken@391
  1901
slouken@391
  1902
    for (i = 0; i < num_used_syms; i++) num_codes[pSyms[i].m_key]++;
slouken@391
  1903
slouken@391
  1904
    tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, code_size_limit);
slouken@391
  1905
slouken@391
  1906
    MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]); MZ_CLEAR_OBJ(d->m_huff_codes[table_num]);
slouken@391
  1907
    for (i = 1, j = num_used_syms; i <= code_size_limit; i++)
slouken@391
  1908
      for (l = num_codes[i]; l > 0; l--) d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i);
slouken@391
  1909
  }
slouken@391
  1910
slouken@391
  1911
  next_code[1] = 0; for (j = 0, i = 2; i <= code_size_limit; i++) next_code[i] = j = ((j + num_codes[i - 1]) << 1);
slouken@391
  1912
slouken@391
  1913
  for (i = 0; i < table_len; i++)
slouken@391
  1914
  {
slouken@391
  1915
    mz_uint rev_code = 0, code, code_size; if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0) continue;
slouken@391
  1916
    code = next_code[code_size]++; for (l = code_size; l > 0; l--, code >>= 1) rev_code = (rev_code << 1) | (code & 1);
slouken@391
  1917
    d->m_huff_codes[table_num][i] = (mz_uint16)rev_code;
slouken@391
  1918
  }
slouken@391
  1919
}
slouken@391
  1920
slouken@391
  1921
#define TDEFL_PUT_BITS(b, l) do { \
slouken@391
  1922
  mz_uint bits = b; mz_uint len = l; MZ_ASSERT(bits <= ((1U << len) - 1U)); \
slouken@391
  1923
  d->m_bit_buffer |= (bits << d->m_bits_in); d->m_bits_in += len; \
slouken@391
  1924
  while (d->m_bits_in >= 8) { \
slouken@391
  1925
    if (d->m_pOutput_buf < d->m_pOutput_buf_end) \
slouken@391
  1926
      *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \
slouken@391
  1927
      d->m_bit_buffer >>= 8; \
slouken@391
  1928
      d->m_bits_in -= 8; \
slouken@391
  1929
  } \
slouken@391
  1930
} MZ_MACRO_END
slouken@391
  1931
slouken@391
  1932
#define TDEFL_RLE_PREV_CODE_SIZE() { if (rle_repeat_count) { \
slouken@391
  1933
  if (rle_repeat_count < 3) { \
slouken@391
  1934
    d->m_huff_count[2][prev_code_size] = (mz_uint16)(d->m_huff_count[2][prev_code_size] + rle_repeat_count); \
slouken@391
  1935
    while (rle_repeat_count--) packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \
slouken@391
  1936
  } else { \
slouken@391
  1937
    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); \
slouken@391
  1938
} rle_repeat_count = 0; } }
slouken@391
  1939
slouken@391
  1940
#define TDEFL_RLE_ZERO_CODE_SIZE() { if (rle_z_count) { \
slouken@391
  1941
  if (rle_z_count < 3) { \
slouken@391
  1942
    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; \
slouken@391
  1943
  } else if (rle_z_count <= 10) { \
slouken@391
  1944
    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); \
slouken@391
  1945
  } else { \
slouken@391
  1946
    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); \
slouken@391
  1947
} rle_z_count = 0; } }
slouken@391
  1948
slouken@391
  1949
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 };
slouken@391
  1950
slouken@391
  1951
static void tdefl_start_dynamic_block(tdefl_compressor *d)
slouken@391
  1952
{
slouken@391
  1953
  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;
slouken@391
  1954
  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;
slouken@391
  1955
slouken@391
  1956
  d->m_huff_count[0][256] = 1;
slouken@391
  1957
slouken@391
  1958
  tdefl_optimize_huffman_table(d, 0, TDEFL_MAX_HUFF_SYMBOLS_0, 15, MZ_FALSE);
slouken@391
  1959
  tdefl_optimize_huffman_table(d, 1, TDEFL_MAX_HUFF_SYMBOLS_1, 15, MZ_FALSE);
slouken@391
  1960
slouken@391
  1961
  for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--) if (d->m_huff_code_sizes[0][num_lit_codes - 1]) break;
slouken@391
  1962
  for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--) if (d->m_huff_code_sizes[1][num_dist_codes - 1]) break;
slouken@391
  1963
slouken@391
  1964
  memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes);
slouken@391
  1965
  memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0], num_dist_codes);
slouken@391
  1966
  total_code_sizes_to_pack = num_lit_codes + num_dist_codes; num_packed_code_sizes = 0; rle_z_count = 0; rle_repeat_count = 0;
slouken@391
  1967
slouken@391
  1968
  memset(&d->m_huff_count[2][0], 0, sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2);
slouken@391
  1969
  for (i = 0; i < total_code_sizes_to_pack; i++)
slouken@391
  1970
  {
slouken@391
  1971
    mz_uint8 code_size = code_sizes_to_pack[i];
slouken@391
  1972
    if (!code_size)
slouken@391
  1973
    {
slouken@391
  1974
      TDEFL_RLE_PREV_CODE_SIZE();
slouken@391
  1975
      if (++rle_z_count == 138) { TDEFL_RLE_ZERO_CODE_SIZE(); }
slouken@391
  1976
    }
slouken@391
  1977
    else
slouken@391
  1978
    {
slouken@391
  1979
      TDEFL_RLE_ZERO_CODE_SIZE();
slouken@391
  1980
      if (code_size != prev_code_size)
slouken@391
  1981
      {
slouken@391
  1982
        TDEFL_RLE_PREV_CODE_SIZE();
slouken@391
  1983
        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;
slouken@391
  1984
      }
slouken@391
  1985
      else if (++rle_repeat_count == 6)
slouken@391
  1986
      {
slouken@391
  1987
        TDEFL_RLE_PREV_CODE_SIZE();
slouken@391
  1988
      }
slouken@391
  1989
    }
slouken@391
  1990
    prev_code_size = code_size;
slouken@391
  1991
  }
slouken@391
  1992
  if (rle_repeat_count) { TDEFL_RLE_PREV_CODE_SIZE(); } else { TDEFL_RLE_ZERO_CODE_SIZE(); }
slouken@391
  1993
slouken@391
  1994
  tdefl_optimize_huffman_table(d, 2, TDEFL_MAX_HUFF_SYMBOLS_2, 7, MZ_FALSE);
slouken@391
  1995
slouken@391
  1996
  TDEFL_PUT_BITS(2, 2);
slouken@391
  1997
slouken@391
  1998
  TDEFL_PUT_BITS(num_lit_codes - 257, 5);
slouken@391
  1999
  TDEFL_PUT_BITS(num_dist_codes - 1, 5);
slouken@391
  2000
slouken@391
  2001
  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;
slouken@391
  2002
  num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1)); TDEFL_PUT_BITS(num_bit_lengths - 4, 4);
slouken@391
  2003
  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);
slouken@391
  2004
slouken@391
  2005
  for (packed_code_sizes_index = 0; packed_code_sizes_index < num_packed_code_sizes; )
slouken@391
  2006
  {
slouken@391
  2007
    mz_uint code = packed_code_sizes[packed_code_sizes_index++]; MZ_ASSERT(code < TDEFL_MAX_HUFF_SYMBOLS_2);
slouken@391
  2008
    TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]);
slouken@391
  2009
    if (code >= 16) TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++], "\02\03\07"[code - 16]);
slouken@391
  2010
  }
slouken@391
  2011
}
slouken@391
  2012
slouken@391
  2013
static void tdefl_start_static_block(tdefl_compressor *d)
slouken@391
  2014
{
slouken@391
  2015
  mz_uint i;
slouken@391
  2016
  mz_uint8 *p = &d->m_huff_code_sizes[0][0];
slouken@391
  2017
slouken@391
  2018
  for (i = 0; i <= 143; ++i) *p++ = 8;
slouken@391
  2019
  for ( ; i <= 255; ++i) *p++ = 9;
slouken@391
  2020
  for ( ; i <= 279; ++i) *p++ = 7;
slouken@391
  2021
  for ( ; i <= 287; ++i) *p++ = 8;
slouken@391
  2022
slouken@391
  2023
  memset(d->m_huff_code_sizes[1], 5, 32);
slouken@391
  2024
slouken@391
  2025
  tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE);
slouken@391
  2026
  tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE);
slouken@391
  2027
slouken@391
  2028
  TDEFL_PUT_BITS(1, 2);
slouken@391
  2029
}
slouken@391
  2030
slouken@391
  2031
static const mz_uint mz_bitmasks[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
slouken@391
  2032
slouken@391
  2033
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS
slouken@391
  2034
static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d)
slouken@391
  2035
{
slouken@391
  2036
  mz_uint flags;
slouken@391
  2037
  mz_uint8 *pLZ_codes;
slouken@391
  2038
  mz_uint8 *pOutput_buf = d->m_pOutput_buf;
slouken@391
  2039
  mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf;
slouken@391
  2040
  mz_uint64 bit_buffer = d->m_bit_buffer;
slouken@391
  2041
  mz_uint bits_in = d->m_bits_in;
slouken@391
  2042
slouken@391
  2043
#define TDEFL_PUT_BITS_FAST(b, l) { bit_buffer |= (((mz_uint64)(b)) << bits_in); bits_in += (l); }
slouken@391
  2044
slouken@391
  2045
  flags = 1;
slouken@391
  2046
  for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end; flags >>= 1)
slouken@391
  2047
  {
slouken@391
  2048
    if (flags == 1)
slouken@391
  2049
      flags = *pLZ_codes++ | 0x100;
slouken@391
  2050
slouken@391
  2051
    if (flags & 1)
slouken@391
  2052
    {
slouken@391
  2053
      mz_uint s0, s1, n0, n1, sym, num_extra_bits;
slouken@391
  2054
      mz_uint match_len = pLZ_codes[0], match_dist = *(const mz_uint16 *)(pLZ_codes + 1); pLZ_codes += 3;
slouken@391
  2055
slouken@391
  2056
      MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
slouken@391
  2057
      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]]);
slouken@391
  2058
      TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]);
slouken@391
  2059
slouken@391
  2060
      // This sequence coaxes MSVC into using cmov's vs. jmp's.
slouken@391
  2061
      s0 = s_tdefl_small_dist_sym[match_dist & 511];
slouken@391
  2062
      n0 = s_tdefl_small_dist_extra[match_dist & 511];
slouken@391
  2063
      s1 = s_tdefl_large_dist_sym[match_dist >> 8];
slouken@391
  2064
      n1 = s_tdefl_large_dist_extra[match_dist >> 8];
slouken@391
  2065
      sym = (match_dist < 512) ? s0 : s1;
slouken@391
  2066
      num_extra_bits = (match_dist < 512) ? n0 : n1;
slouken@391
  2067
slouken@391
  2068
      MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
slouken@391
  2069
      TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
slouken@391
  2070
      TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
slouken@391
  2071
    }
slouken@391
  2072
    else
slouken@391
  2073
    {
slouken@391
  2074
      mz_uint lit = *pLZ_codes++;
slouken@391
  2075
      MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
slouken@391
  2076
      TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
slouken@391
  2077
slouken@391
  2078
      if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
slouken@391
  2079
      {
slouken@391
  2080
        flags >>= 1;
slouken@391
  2081
        lit = *pLZ_codes++;
slouken@391
  2082
        MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
slouken@391
  2083
        TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
slouken@391
  2084
slouken@391
  2085
        if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
slouken@391
  2086
        {
slouken@391
  2087
          flags >>= 1;
slouken@391
  2088
          lit = *pLZ_codes++;
slouken@391
  2089
          MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
slouken@391
  2090
          TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
slouken@391
  2091
        }
slouken@391
  2092
      }
slouken@391
  2093
    }
slouken@391
  2094
slouken@391
  2095
    if (pOutput_buf >= d->m_pOutput_buf_end)
slouken@391
  2096
      return MZ_FALSE;
slouken@391
  2097
slouken@391
  2098
    *(mz_uint64*)pOutput_buf = bit_buffer;
slouken@391
  2099
    pOutput_buf += (bits_in >> 3);
slouken@391
  2100
    bit_buffer >>= (bits_in & ~7);
slouken@391
  2101
    bits_in &= 7;
slouken@391
  2102
  }
slouken@391
  2103
slouken@391
  2104
#undef TDEFL_PUT_BITS_FAST
slouken@391
  2105
slouken@391
  2106
  d->m_pOutput_buf = pOutput_buf;
slouken@391
  2107
  d->m_bits_in = 0;
slouken@391
  2108
  d->m_bit_buffer = 0;
slouken@391
  2109
slouken@391
  2110
  while (bits_in)
slouken@391
  2111
  {
slouken@391
  2112
    mz_uint32 n = MZ_MIN(bits_in, 16);
slouken@391
  2113
    TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n);
slouken@391
  2114
    bit_buffer >>= n;
slouken@391
  2115
    bits_in -= n;
slouken@391
  2116
  }
slouken@391
  2117
slouken@391
  2118
  TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
slouken@391
  2119
slouken@391
  2120
  return (d->m_pOutput_buf < d->m_pOutput_buf_end);
slouken@391
  2121
}
slouken@391
  2122
#else
slouken@391
  2123
static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d)
slouken@391
  2124
{
slouken@391
  2125
  mz_uint flags;
slouken@391
  2126
  mz_uint8 *pLZ_codes;
slouken@391
  2127
slouken@391
  2128
  flags = 1;
slouken@391
  2129
  for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf; flags >>= 1)
slouken@391
  2130
  {
slouken@391
  2131
    if (flags == 1)
slouken@391
  2132
      flags = *pLZ_codes++ | 0x100;
slouken@391
  2133
    if (flags & 1)
slouken@391
  2134
    {
slouken@391
  2135
      mz_uint sym, num_extra_bits;
slouken@391
  2136
      mz_uint match_len = pLZ_codes[0], match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8)); pLZ_codes += 3;
slouken@391
  2137
slouken@391
  2138
      MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
slouken@391
  2139
      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]]);
slouken@391
  2140
      TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]);
slouken@391
  2141
slouken@391
  2142
      if (match_dist < 512)
slouken@391
  2143
      {
slouken@391
  2144
        sym = s_tdefl_small_dist_sym[match_dist]; num_extra_bits = s_tdefl_small_dist_extra[match_dist];
slouken@391
  2145
      }
slouken@391
  2146
      else
slouken@391
  2147
      {
slouken@391
  2148
        sym = s_tdefl_large_dist_sym[match_dist >> 8]; num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8];
slouken@391
  2149
      }
slouken@391
  2150
      MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
slouken@391
  2151
      TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
slouken@391
  2152
      TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
slouken@391
  2153
    }
slouken@391
  2154
    else
slouken@391
  2155
    {
slouken@391
  2156
      mz_uint lit = *pLZ_codes++;
slouken@391
  2157
      MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
slouken@391
  2158
      TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
slouken@391
  2159
    }
slouken@391
  2160
  }
slouken@391
  2161
slouken@391
  2162
  TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
slouken@391
  2163
slouken@391
  2164
  return (d->m_pOutput_buf < d->m_pOutput_buf_end);
slouken@391
  2165
}
slouken@391
  2166
#endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS
slouken@391
  2167
slouken@391
  2168
static mz_bool tdefl_compress_block(tdefl_compressor *d, mz_bool static_block)
slouken@391
  2169
{
slouken@391
  2170
  if (static_block)
slouken@391
  2171
    tdefl_start_static_block(d);
slouken@391
  2172
  else
slouken@391
  2173
    tdefl_start_dynamic_block(d);
slouken@391
  2174
  return tdefl_compress_lz_codes(d);
slouken@391
  2175
}
slouken@391
  2176
slouken@391
  2177
static int tdefl_flush_block(tdefl_compressor *d, int flush)
slouken@391
  2178
{
slouken@391
  2179
  mz_uint saved_bit_buf, saved_bits_in;
slouken@391
  2180
  mz_uint8 *pSaved_output_buf;
slouken@391
  2181
  mz_bool comp_block_succeeded = MZ_FALSE;
slouken@391
  2182
  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;
slouken@391
  2183
  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;
slouken@391
  2184
slouken@391
  2185
  d->m_pOutput_buf = pOutput_buf_start;
slouken@391
  2186
  d->m_pOutput_buf_end = d->m_pOutput_buf + TDEFL_OUT_BUF_SIZE - 16;
slouken@391
  2187
slouken@391
  2188
  MZ_ASSERT(!d->m_output_flush_remaining);
slouken@391
  2189
  d->m_output_flush_ofs = 0;
slouken@391
  2190
  d->m_output_flush_remaining = 0;
slouken@391
  2191
slouken@391
  2192
  *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left);
slouken@391
  2193
  d->m_pLZ_code_buf -= (d->m_num_flags_left == 8);
slouken@391
  2194
slouken@391
  2195
  if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index))
slouken@391
  2196
  {
slouken@391
  2197
    TDEFL_PUT_BITS(0x78, 8); TDEFL_PUT_BITS(0x01, 8);
slouken@391
  2198
  }
slouken@391
  2199
slouken@391
  2200
  TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1);
slouken@391
  2201
slouken@391
  2202
  pSaved_output_buf = d->m_pOutput_buf; saved_bit_buf = d->m_bit_buffer; saved_bits_in = d->m_bits_in;
slouken@391
  2203
slouken@391
  2204
  if (!use_raw_block)
slouken@391
  2205
    comp_block_succeeded = tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || (d->m_total_lz_bytes < 48));
slouken@391
  2206
slouken@391
  2207
  // If the block gets expanded, forget the current contents of the output buffer and send a raw block instead.
slouken@391
  2208
  if ( ((use_raw_block) || ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >= d->m_total_lz_bytes))) &&
slouken@391
  2209
       ((d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size) )
slouken@391
  2210
  {
slouken@391
  2211
    mz_uint i; d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
slouken@391
  2212
    TDEFL_PUT_BITS(0, 2);
slouken@391
  2213
    if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); }
slouken@391
  2214
    for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF)
slouken@391
  2215
    {
slouken@391
  2216
      TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16);
slouken@391
  2217
    }
slouken@391
  2218
    for (i = 0; i < d->m_total_lz_bytes; ++i)
slouken@391
  2219
    {
slouken@391
  2220
      TDEFL_PUT_BITS(d->m_dict[(d->m_lz_code_buf_dict_pos + i) & TDEFL_LZ_DICT_SIZE_MASK], 8);
slouken@391
  2221
    }
slouken@391
  2222
  }
slouken@391
  2223
  // Check for the extremely unlikely (if not impossible) case of the compressed block not fitting into the output buffer when using dynamic codes.
slouken@391
  2224
  else if (!comp_block_succeeded)
slouken@391
  2225
  {
slouken@391
  2226
    d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
slouken@391
  2227
    tdefl_compress_block(d, MZ_TRUE);
slouken@391
  2228
  }
slouken@391
  2229
slouken@391
  2230
  if (flush)
slouken@391
  2231
  {
slouken@391
  2232
    if (flush == TDEFL_FINISH)
slouken@391
  2233
    {
slouken@391
  2234
      if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); }
slouken@391
  2235
      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; } }
slouken@391
  2236
    }
slouken@391
  2237
    else
slouken@391
  2238
    {
slouken@391
  2239
      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); }
slouken@391
  2240
    }
slouken@391
  2241
  }
slouken@391
  2242
slouken@391
  2243
  MZ_ASSERT(d->m_pOutput_buf < d->m_pOutput_buf_end);
slouken@391
  2244
slouken@391
  2245
  memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
slouken@391
  2246
  memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
slouken@391
  2247
slouken@391
  2248
  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++;
slouken@391
  2249
slouken@391
  2250
  if ((n = (int)(d->m_pOutput_buf - pOutput_buf_start)) != 0)
slouken@391
  2251
  {
slouken@391
  2252
    if (d->m_pPut_buf_func)
slouken@391
  2253
    {
slouken@391
  2254
      *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf;
slouken@391
  2255
      if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user))
slouken@391
  2256
        return (d->m_prev_return_status = TDEFL_STATUS_PUT_BUF_FAILED);
slouken@391
  2257
    }
slouken@391
  2258
    else if (pOutput_buf_start == d->m_output_buf)
slouken@391
  2259
    {
slouken@391
  2260
      int bytes_to_copy = (int)MZ_MIN((size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs));
slouken@391
  2261
      memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf, bytes_to_copy);
slouken@391
  2262
      d->m_out_buf_ofs += bytes_to_copy;
slouken@391
  2263
      if ((n -= bytes_to_copy) != 0)
slouken@391
  2264
      {
slouken@391
  2265
        d->m_output_flush_ofs = bytes_to_copy;
slouken@391
  2266
        d->m_output_flush_remaining = n;
slouken@391
  2267
      }
slouken@391
  2268
    }
slouken@391
  2269
    else
slouken@391
  2270
    {
slouken@391
  2271
      d->m_out_buf_ofs += n;
slouken@391
  2272
    }
slouken@391
  2273
  }
slouken@391
  2274
slouken@391
  2275
  return d->m_output_flush_remaining;
slouken@391
  2276
}
slouken@391
  2277
slouken@391
  2278
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
slouken@391
  2279
#define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16*)(p)
slouken@391
  2280
static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len)
slouken@391
  2281
{
slouken@391
  2282
  mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len;
slouken@391
  2283
  mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
slouken@391
  2284
  const mz_uint16 *s = (const mz_uint16*)(d->m_dict + pos), *p, *q;
slouken@391
  2285
  mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]), s01 = TDEFL_READ_UNALIGNED_WORD(s);
slouken@391
  2286
  MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return;
slouken@391
  2287
  for ( ; ; )
slouken@391
  2288
  {
slouken@391
  2289
    for ( ; ; )
slouken@391
  2290
    {
slouken@391
  2291
      if (--num_probes_left == 0) return;
slouken@391
  2292
      #define TDEFL_PROBE \
slouken@391
  2293
        next_probe_pos = d->m_next[probe_pos]; \
slouken@391
  2294
        if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \
slouken@391
  2295
        probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
slouken@391
  2296
        if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) break;
slouken@391
  2297
      TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE;
slouken@391
  2298
    }
slouken@391
  2299
    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;
slouken@391
  2300
    do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) &&
slouken@391
  2301
                   (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0) );
slouken@391
  2302
    if (!probe_len)
slouken@391
  2303
    {
slouken@391
  2304
      *pMatch_dist = dist; *pMatch_len = MZ_MIN(max_match_len, TDEFL_MAX_MATCH_LEN); break;
slouken@391
  2305
    }
slouken@391
  2306
    else if ((probe_len = ((mz_uint)(p - s) * 2) + (mz_uint)(*(const mz_uint8*)p == *(const mz_uint8*)q)) > match_len)
slouken@391
  2307
    {
slouken@391
  2308
      *pMatch_dist = dist; if ((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) == max_match_len) break;
slouken@391
  2309
      c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]);
slouken@391
  2310
    }
slouken@391
  2311
  }
slouken@391
  2312
}
slouken@391
  2313
#else
slouken@391
  2314
static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len)
slouken@391
  2315
{
slouken@391
  2316
  mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len;
slouken@391
  2317
  mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
slouken@391
  2318
  const mz_uint8 *s = d->m_dict + pos, *p, *q;
slouken@391
  2319
  mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1];
slouken@391
  2320
  MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return;
slouken@391
  2321
  for ( ; ; )
slouken@391
  2322
  {
slouken@391
  2323
    for ( ; ; )
slouken@391
  2324
    {
slouken@391
  2325
      if (--num_probes_left == 0) return;
slouken@391
  2326
      #define TDEFL_PROBE \
slouken@391
  2327
        next_probe_pos = d->m_next[probe_pos]; \
slouken@391
  2328
        if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \
slouken@391
  2329
        probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
slouken@391
  2330
        if ((d->m_dict[probe_pos + match_len] == c0) && (d->m_dict[probe_pos + match_len - 1] == c1)) break;
slouken@391
  2331
      TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE;
slouken@391
  2332
    }
slouken@391
  2333
    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;
slouken@391
  2334
    if (probe_len > match_len)
slouken@391
  2335
    {
slouken@391
  2336
      *pMatch_dist = dist; if ((*pMatch_len = match_len = probe_len) == max_match_len) return;
slouken@391
  2337
      c0 = d->m_dict[pos + match_len]; c1 = d->m_dict[pos + match_len - 1];
slouken@391
  2338
    }
slouken@391
  2339
  }
slouken@391
  2340
}
slouken@391
  2341
#endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
slouken@391
  2342
slouken@391
  2343
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
slouken@391
  2344
static mz_bool tdefl_compress_fast(tdefl_compressor *d)
slouken@391
  2345
{
slouken@391
  2346
  // Faster, minimally featured LZRW1-style match+parse loop with better register utilization. Intended for applications where raw throughput is valued more highly than ratio.
slouken@391
  2347
  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;
slouken@391
  2348
  mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags;
slouken@391
  2349
  mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
slouken@391
  2350
slouken@391
  2351
  while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size)))
slouken@391
  2352
  {
slouken@391
  2353
    const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096;
slouken@391
  2354
    mz_uint dst_pos = (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK;
slouken@391
  2355
    mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size);
slouken@391
  2356
    d->m_src_buf_left -= num_bytes_to_process;
slouken@391
  2357
    lookahead_size += num_bytes_to_process;
slouken@391
  2358
slouken@391
  2359
    while (num_bytes_to_process)
slouken@391
  2360
    {
slouken@391
  2361
      mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process);
slouken@391
  2362
      memcpy(d->m_dict + dst_pos, d->m_pSrc, n);
slouken@391
  2363
      if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
slouken@391
  2364
        memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc, MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos));
slouken@391
  2365
      d->m_pSrc += n;
slouken@391
  2366
      dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK;
slouken@391
  2367
      num_bytes_to_process -= n;
slouken@391
  2368
    }
slouken@391
  2369
slouken@391
  2370
    dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size);
slouken@391
  2371
    if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE)) break;
slouken@391
  2372
slouken@391
  2373
    while (lookahead_size >= 4)
slouken@391
  2374
    {
slouken@391
  2375
      mz_uint cur_match_dist, cur_match_len = 1;
slouken@391
  2376
      mz_uint8 *pCur_dict = d->m_dict + cur_pos;
slouken@391
  2377
      mz_uint first_trigram = (*(const mz_uint32 *)pCur_dict) & 0xFFFFFF;
slouken@391
  2378
      mz_uint hash = (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) & TDEFL_LEVEL1_HASH_SIZE_MASK;
slouken@391
  2379
      mz_uint probe_pos = d->m_hash[hash];
slouken@391
  2380
      d->m_hash[hash] = (mz_uint16