1/* miniz.c v1.15 - deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
2 Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
3
4 Forked from the public domain/unlicense version at: https://code.google.com/archive/p/miniz/
5
6 Copyright (C) 2019-2021 Binomial LLC. All Rights Reserved.
7
8 Licensed under the Apache License, Version 2.0 (the "License");
9 you may not use this file except in compliance with the License.
10 You may obtain a copy of the License at
11
12 http://www.apache.org/licenses/LICENSE-2.0
13
14 Unless required by applicable law or agreed to in writing, software
15 distributed under the License is distributed on an "AS IS" BASIS,
16 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 See the License for the specific language governing permissions and
18 limitations under the License.
19*/
20
21#ifndef MINIZ_HEADER_INCLUDED
22#define MINIZ_HEADER_INCLUDED
23
24#include <stdlib.h>
25
26// Defines to completely disable specific portions of miniz.c:
27// If all macros here are defined the only functionality remaining will be CRC-32, adler-32, tinfl, and tdefl.
28
29// Define MINIZ_NO_STDIO to disable all usage and any functions which rely on stdio for file I/O.
30//#define MINIZ_NO_STDIO
31
32// If MINIZ_NO_TIME is specified then the ZIP archive functions will not be able to get the current time, or
33// get/set file times, and the C run-time funcs that get/set times won't be called.
34// The current downside is the times written to your archives will be from 1979.
35//#define MINIZ_NO_TIME
36
37// Define MINIZ_NO_ARCHIVE_APIS to disable all ZIP archive API's.
38//#define MINIZ_NO_ARCHIVE_APIS
39
40// Define MINIZ_NO_ARCHIVE_APIS to disable all writing related ZIP archive API's.
41//#define MINIZ_NO_ARCHIVE_WRITING_APIS
42
43// Define MINIZ_NO_ZLIB_APIS to remove all ZLIB-style compression/decompression API's.
44//#define MINIZ_NO_ZLIB_APIS
45
46// Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent conflicts against stock zlib.
47//#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES
48
49// Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc.
50// Note if MINIZ_NO_MALLOC is defined then the user must always provide custom user alloc/free/realloc
51// callbacks to the zlib and archive API's, and a few stand-alone helper API's which don't provide custom user
52// functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work.
53//#define MINIZ_NO_MALLOC
54
55#if defined(__TINYC__) && (defined(__linux) || defined(__linux__))
56 // TODO: Work around "error: include file 'sys\utime.h' when compiling with tcc on Linux
57 #define MINIZ_NO_TIME
58#endif
59
60#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_ARCHIVE_APIS)
61 #include <time.h>
62#endif
63
64#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__)
65// MINIZ_X86_OR_X64_CPU is only used to help set the below macros.
66#define MINIZ_X86_OR_X64_CPU 1
67#endif
68
69#if (__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU
70// Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian.
71#define MINIZ_LITTLE_ENDIAN 1
72#endif
73
74#if MINIZ_X86_OR_X64_CPU
75// Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient integer loads and stores from unaligned addresses.
76#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
77#endif
78
79// Using unaligned loads and stores causes errors when using UBSan. Jam it off.
80#if defined(__has_feature)
81#if __has_feature(undefined_behavior_sanitizer)
82#undef MINIZ_USE_UNALIGNED_LOADS_AND_STORES
83#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0
84#endif
85#endif
86
87#if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) || defined(__ia64__) || defined(__x86_64__)
88// 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).
89#define MINIZ_HAS_64BIT_REGISTERS 1
90#endif
91
92namespace buminiz {
93
94// ------------------- zlib-style API Definitions.
95
96// 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!
97typedef unsigned long mz_ulong;
98
99// 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.
100void mz_free(void *p);
101
102#define MZ_ADLER32_INIT (1)
103// mz_adler32() returns the initial adler-32 value to use when called with ptr==NULL.
104mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len);
105
106#define MZ_CRC32_INIT (0)
107// mz_crc32() returns the initial CRC-32 value to use when called with ptr==NULL.
108mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len);
109
110// Compression strategies.
111enum { MZ_DEFAULT_STRATEGY = 0, MZ_FILTERED = 1, MZ_HUFFMAN_ONLY = 2, MZ_RLE = 3, MZ_FIXED = 4 };
112
113// Method
114#define MZ_DEFLATED 8
115
116#ifndef MINIZ_NO_ZLIB_APIS
117
118// Heap allocation callbacks.
119// Note that mz_alloc_func parameter types purpsosely differ from zlib's: items/size is size_t, not unsigned long.
120typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size);
121typedef void (*mz_free_func)(void *opaque, void *address);
122typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size);
123
124#define MZ_VERSION "9.1.15"
125#define MZ_VERNUM 0x91F0
126#define MZ_VER_MAJOR 9
127#define MZ_VER_MINOR 1
128#define MZ_VER_REVISION 15
129#define MZ_VER_SUBREVISION 0
130
131// 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).
132enum { MZ_NO_FLUSH = 0, MZ_PARTIAL_FLUSH = 1, MZ_SYNC_FLUSH = 2, MZ_FULL_FLUSH = 3, MZ_FINISH = 4, MZ_BLOCK = 5 };
133
134// Return status codes. MZ_PARAM_ERROR is non-standard.
135enum { 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 };
136
137// 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.
138enum { MZ_NO_COMPRESSION = 0, MZ_BEST_SPEED = 1, MZ_BEST_COMPRESSION = 9, MZ_UBER_COMPRESSION = 10, MZ_DEFAULT_LEVEL = 6, MZ_DEFAULT_COMPRESSION = -1 };
139
140// Window bits
141#define MZ_DEFAULT_WINDOW_BITS 15
142
143struct mz_internal_state;
144
145// Compression/decompression stream struct.
146typedef struct mz_stream_s
147{
148 const unsigned char *next_in; // pointer to next byte to read
149 unsigned int avail_in; // number of bytes available at next_in
150 mz_ulong total_in; // total number of bytes consumed so far
151
152 unsigned char *next_out; // pointer to next byte to write
153 unsigned int avail_out; // number of bytes that can be written to next_out
154 mz_ulong total_out; // total number of bytes produced so far
155
156 char *msg; // error msg (unused)
157 struct mz_internal_state *state; // internal state, allocated by zalloc/zfree
158
159 mz_alloc_func zalloc; // optional heap allocation function (defaults to malloc)
160 mz_free_func zfree; // optional heap free function (defaults to free)
161 void *opaque; // heap alloc function user pointer
162
163 int data_type; // data_type (unused)
164 mz_ulong adler; // adler32 of the source or uncompressed data
165 mz_ulong reserved; // not used
166} mz_stream;
167
168typedef mz_stream *mz_streamp;
169
170// Returns the version string of miniz.c.
171const char *mz_version(void);
172
173// mz_deflateInit() initializes a compressor with default options:
174// Parameters:
175// pStream must point to an initialized mz_stream struct.
176// level must be between [MZ_NO_COMPRESSION, MZ_BEST_COMPRESSION].
177// level 1 enables a specially optimized compression function that's been optimized purely for performance, not ratio.
178// (This special func. is currently only enabled when MINIZ_USE_UNALIGNED_LOADS_AND_STORES and MINIZ_LITTLE_ENDIAN are defined.)
179// Return values:
180// MZ_OK on success.
181// MZ_STREAM_ERROR if the stream is bogus.
182// MZ_PARAM_ERROR if the input parameters are bogus.
183// MZ_MEM_ERROR on out of memory.
184int mz_deflateInit(mz_streamp pStream, int level);
185
186// mz_deflateInit2() is like mz_deflate(), except with more control:
187// Additional parameters:
188// method must be MZ_DEFLATED
189// 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)
190// mem_level must be between [1, 9] (it's checked but ignored by miniz.c)
191int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy);
192
193// Quickly resets a compressor without having to reallocate anything. Same as calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2().
194int mz_deflateReset(mz_streamp pStream);
195
196// mz_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible.
197// Parameters:
198// 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.
199// flush may be MZ_NO_FLUSH, MZ_PARTIAL_FLUSH/MZ_SYNC_FLUSH, MZ_FULL_FLUSH, or MZ_FINISH.
200// Return values:
201// 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).
202// 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.
203// MZ_STREAM_ERROR if the stream is bogus.
204// MZ_PARAM_ERROR if one of the parameters is invalid.
205// 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.)
206int mz_deflate(mz_streamp pStream, int flush);
207
208// mz_deflateEnd() deinitializes a compressor:
209// Return values:
210// MZ_OK on success.
211// MZ_STREAM_ERROR if the stream is bogus.
212int mz_deflateEnd(mz_streamp pStream);
213
214// 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.
215mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len);
216
217// Single-call compression functions mz_compress() and mz_compress2():
218// Returns MZ_OK on success, or one of the error codes from mz_deflate() on failure.
219int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
220int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level);
221
222// mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress().
223mz_ulong mz_compressBound(mz_ulong source_len);
224
225// Initializes a decompressor.
226int mz_inflateInit(mz_streamp pStream);
227
228// 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:
229// window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate).
230int mz_inflateInit2(mz_streamp pStream, int window_bits);
231
232// 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.
233// Parameters:
234// 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.
235// flush may be MZ_NO_FLUSH, MZ_SYNC_FLUSH, or MZ_FINISH.
236// 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).
237// 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.
238// Return values:
239// 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.
240// 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.
241// MZ_STREAM_ERROR if the stream is bogus.
242// MZ_DATA_ERROR if the deflate stream is invalid.
243// MZ_PARAM_ERROR if one of the parameters is invalid.
244// 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
245// with more input data, or with more room in the output buffer (except when using single call decompression, described above).
246int mz_inflate(mz_streamp pStream, int flush);
247int mz_inflate2(mz_streamp pStream, int flush, int adler32_checking);
248
249// Deinitializes a decompressor.
250int mz_inflateEnd(mz_streamp pStream);
251
252// Single-call decompression.
253// Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure.
254int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
255
256// Returns a string description of the specified error code, or NULL if the error code is invalid.
257const char *mz_error(int err);
258
259// 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.
260// Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project.
261#ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
262 typedef unsigned char Byte;
263 typedef unsigned int uInt;
264 typedef mz_ulong uLong;
265 typedef Byte Bytef;
266 typedef uInt uIntf;
267 typedef char charf;
268 typedef int intf;
269 typedef void *voidpf;
270 typedef uLong uLongf;
271 typedef void *voidp;
272 typedef void *const voidpc;
273 #define Z_NULL 0
274 #define Z_NO_FLUSH MZ_NO_FLUSH
275 #define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH
276 #define Z_SYNC_FLUSH MZ_SYNC_FLUSH
277 #define Z_FULL_FLUSH MZ_FULL_FLUSH
278 #define Z_FINISH MZ_FINISH
279 #define Z_BLOCK MZ_BLOCK
280 #define Z_OK MZ_OK
281 #define Z_STREAM_END MZ_STREAM_END
282 #define Z_NEED_DICT MZ_NEED_DICT
283 #define Z_ERRNO MZ_ERRNO
284 #define Z_STREAM_ERROR MZ_STREAM_ERROR
285 #define Z_DATA_ERROR MZ_DATA_ERROR
286 #define Z_MEM_ERROR MZ_MEM_ERROR
287 #define Z_BUF_ERROR MZ_BUF_ERROR
288 #define Z_VERSION_ERROR MZ_VERSION_ERROR
289 #define Z_PARAM_ERROR MZ_PARAM_ERROR
290 #define Z_NO_COMPRESSION MZ_NO_COMPRESSION
291 #define Z_BEST_SPEED MZ_BEST_SPEED
292 #define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION
293 #define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION
294 #define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY
295 #define Z_FILTERED MZ_FILTERED
296 #define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY
297 #define Z_RLE MZ_RLE
298 #define Z_FIXED MZ_FIXED
299 #define Z_DEFLATED MZ_DEFLATED
300 #define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS
301 #define alloc_func mz_alloc_func
302 #define free_func mz_free_func
303 #define internal_state mz_internal_state
304 #define z_stream mz_stream
305 #define deflateInit mz_deflateInit
306 #define deflateInit2 mz_deflateInit2
307 #define deflateReset mz_deflateReset
308 #define deflate mz_deflate
309 #define deflateEnd mz_deflateEnd
310 #define deflateBound mz_deflateBound
311 #define compress mz_compress
312 #define compress2 mz_compress2
313 #define compressBound mz_compressBound
314 #define inflateInit mz_inflateInit
315 #define inflateInit2 mz_inflateInit2
316 #define inflate mz_inflate
317 #define inflateEnd mz_inflateEnd
318 #define uncompress mz_uncompress
319 #define crc32 mz_crc32
320 #define adler32 mz_adler32
321 #define MAX_WBITS 15
322 #define MAX_MEM_LEVEL 9
323 #define zError mz_error
324 #define ZLIB_VERSION MZ_VERSION
325 #define ZLIB_VERNUM MZ_VERNUM
326 #define ZLIB_VER_MAJOR MZ_VER_MAJOR
327 #define ZLIB_VER_MINOR MZ_VER_MINOR
328 #define ZLIB_VER_REVISION MZ_VER_REVISION
329 #define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION
330 #define zlibVersion mz_version
331 #define zlib_version mz_version()
332#endif // #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
333
334#endif // MINIZ_NO_ZLIB_APIS
335
336// ------------------- Types and macros
337
338typedef unsigned char mz_uint8;
339typedef signed short mz_int16;
340typedef unsigned short mz_uint16;
341typedef unsigned int mz_uint32;
342typedef unsigned int mz_uint;
343typedef long long mz_int64;
344typedef unsigned long long mz_uint64;
345typedef int mz_bool;
346
347#define MZ_FALSE (0)
348#define MZ_TRUE (1)
349
350// An attempt to work around MSVC's spammy "warning C4127: conditional expression is constant" message.
351#ifdef _MSC_VER
352 #define MZ_MACRO_END while (0, 0)
353#else
354 #define MZ_MACRO_END while (0)
355#endif
356
357// ------------------- Low-level Decompression API Definitions
358
359// Decompression flags used by tinfl_decompress().
360// 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.
361// 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.
362// 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).
363// TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the decompressed bytes.
364enum
365{
366 TINFL_FLAG_PARSE_ZLIB_HEADER = 1,
367 TINFL_FLAG_HAS_MORE_INPUT = 2,
368 TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4,
369 TINFL_FLAG_COMPUTE_ADLER32 = 8
370};
371
372// High level decompression functions:
373// tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block allocated via malloc().
374// On entry:
375// pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data to decompress.
376// On return:
377// Function returns a pointer to the decompressed data, or NULL on failure.
378// *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data.
379// The caller must call mz_free() on the returned block when it's no longer needed.
380void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
381
382// tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory.
383// Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success.
384#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1))
385size_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);
386
387// 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.
388// Returns 1 on success or 0 on failure.
389typedef int (*tinfl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser);
390int 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);
391
392struct tinfl_decompressor_tag; typedef struct tinfl_decompressor_tag tinfl_decompressor;
393
394// Max size of LZ dictionary.
395#define TINFL_LZ_DICT_SIZE 32768
396
397// Return status.
398typedef enum
399{
400 TINFL_STATUS_BAD_PARAM = -3,
401 TINFL_STATUS_ADLER32_MISMATCH = -2,
402 TINFL_STATUS_FAILED = -1,
403 TINFL_STATUS_DONE = 0,
404 TINFL_STATUS_NEEDS_MORE_INPUT = 1,
405 TINFL_STATUS_HAS_MORE_OUTPUT = 2
406} tinfl_status;
407
408// Initializes the decompressor to its initial state.
409#define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END
410#define tinfl_get_adler32(r) (r)->m_check_adler32
411
412// 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.
413// 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.
414tinfl_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);
415
416// Internal/private bits follow.
417enum
418{
419 TINFL_MAX_HUFF_TABLES = 3, TINFL_MAX_HUFF_SYMBOLS_0 = 288, TINFL_MAX_HUFF_SYMBOLS_1 = 32, TINFL_MAX_HUFF_SYMBOLS_2 = 19,
420 TINFL_FAST_LOOKUP_BITS = 10, TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS
421};
422
423typedef struct
424{
425 mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0];
426 mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
427} tinfl_huff_table;
428
429#if MINIZ_HAS_64BIT_REGISTERS
430 #define TINFL_USE_64BIT_BITBUF 1
431#endif
432
433#if TINFL_USE_64BIT_BITBUF
434 typedef mz_uint64 tinfl_bit_buf_t;
435 #define TINFL_BITBUF_SIZE (64)
436#else
437 typedef mz_uint32 tinfl_bit_buf_t;
438 #define TINFL_BITBUF_SIZE (32)
439#endif
440
441struct tinfl_decompressor_tag
442{
443 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];
444 tinfl_bit_buf_t m_bit_buf;
445 size_t m_dist_from_out_buf_start;
446 tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES];
447 mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137];
448};
449
450// ------------------- Low-level Compression API Definitions
451
452// Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly slower, and raw/dynamic blocks will be output more frequently).
453#define TDEFL_LESS_MEMORY 0
454
455// tdefl_init() compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search):
456// 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).
457enum
458{
459 TDEFL_HUFFMAN_ONLY = 0, TDEFL_DEFAULT_MAX_PROBES = 128, TDEFL_MAX_PROBES_MASK = 0xFFF
460};
461
462// 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.
463// TDEFL_COMPUTE_ADLER32: Always compute the adler-32 of the input data (even when not writing zlib headers).
464// TDEFL_GREEDY_PARSING_FLAG: Set to use faster greedy parsing, instead of more efficient lazy parsing.
465// 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).
466// TDEFL_RLE_MATCHES: Only look for RLE matches (matches with a distance of 1)
467// TDEFL_FILTER_MATCHES: Discards matches <= 5 chars if enabled.
468// TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables.
469// TDEFL_FORCE_ALL_RAW_BLOCKS: Only use raw (uncompressed) deflate blocks.
470// The low 12 bits are reserved to control the max # of hash probes per dictionary lookup (see TDEFL_MAX_PROBES_MASK).
471enum
472{
473 TDEFL_WRITE_ZLIB_HEADER = 0x01000,
474 TDEFL_COMPUTE_ADLER32 = 0x02000,
475 TDEFL_GREEDY_PARSING_FLAG = 0x04000,
476 TDEFL_NONDETERMINISTIC_PARSING_FLAG = 0x08000,
477 TDEFL_RLE_MATCHES = 0x10000,
478 TDEFL_FILTER_MATCHES = 0x20000,
479 TDEFL_FORCE_ALL_STATIC_BLOCKS = 0x40000,
480 TDEFL_FORCE_ALL_RAW_BLOCKS = 0x80000
481};
482
483// High level compression functions:
484// tdefl_compress_mem_to_heap() compresses a block in memory to a heap block allocated via malloc().
485// On entry:
486// pSrc_buf, src_buf_len: Pointer and size of source block to compress.
487// flags: The max match finder probes (default is 128) logically OR'd against the above flags. Higher probes are slower but improve compression.
488// On return:
489// Function returns a pointer to the compressed data, or NULL on failure.
490// *pOut_len will be set to the compressed data's size, which could be larger than src_buf_len on uncompressible data.
491// The caller must free() the returned block when it's no longer needed.
492void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
493
494// tdefl_compress_mem_to_mem() compresses a block in memory to another block in memory.
495// Returns 0 on failure.
496size_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);
497
498// Compresses an image to a compressed PNG file in memory.
499// On entry:
500// pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4.
501// The image pitch in bytes per scanline will be w*num_chans. The leftmost pixel on the top scanline is stored first in memory.
502// 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
503// If flip is true, the image will be flipped on the Y axis (useful for OpenGL apps).
504// On return:
505// Function returns a pointer to the compressed data, or NULL on failure.
506// *pLen_out will be set to the size of the PNG image file.
507// The caller must mz_free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed.
508void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip);
509void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out);
510
511// Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time.
512typedef mz_bool (*tdefl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser);
513
514// tdefl_compress_mem_to_output() compresses a block to an output stream. The above helpers use this function internally.
515mz_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);
516
517enum { 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 };
518
519// TDEFL_OUT_BUF_SIZE MUST be large enough to hold a single entire compressed output block (using static/fixed Huffman codes).
520#if TDEFL_LESS_MEMORY
521enum { 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 };
522#else
523enum { 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 };
524#endif
525
526// 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.
527typedef enum
528{
529 TDEFL_STATUS_BAD_PARAM = -2,
530 TDEFL_STATUS_PUT_BUF_FAILED = -1,
531 TDEFL_STATUS_OKAY = 0,
532 TDEFL_STATUS_DONE = 1,
533} tdefl_status;
534
535// Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums
536typedef enum
537{
538 TDEFL_NO_FLUSH = 0,
539 TDEFL_SYNC_FLUSH = 2,
540 TDEFL_FULL_FLUSH = 3,
541 TDEFL_FINISH = 4
542} tdefl_flush;
543
544// tdefl's compression state structure.
545typedef struct
546{
547 tdefl_put_buf_func_ptr m_pPut_buf_func;
548 void *m_pPut_buf_user;
549 mz_uint m_flags, m_max_probes[2];
550 int m_greedy_parsing;
551 mz_uint m_adler32, m_lookahead_pos, m_lookahead_size, m_dict_size;
552 mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end;
553 mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in, m_bit_buffer;
554 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;
555 tdefl_status m_prev_return_status;
556 const void *m_pIn_buf;
557 void *m_pOut_buf;
558 size_t *m_pIn_buf_size, *m_pOut_buf_size;
559 tdefl_flush m_flush;
560 const mz_uint8 *m_pSrc;
561 size_t m_src_buf_left, m_out_buf_ofs;
562 mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE + TDEFL_MAX_MATCH_LEN - 1];
563 mz_uint16 m_huff_count[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
564 mz_uint16 m_huff_codes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
565 mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
566 mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE];
567 mz_uint16 m_next[TDEFL_LZ_DICT_SIZE];
568 mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE];
569 mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE];
570} tdefl_compressor;
571
572// Initializes the compressor.
573// There is no corresponding deinit() function because the tdefl API's do not dynamically allocate memory.
574// 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.
575// If pBut_buf_func is NULL the user should always call the tdefl_compress() API.
576// flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, etc.)
577tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
578
579// 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.
580tdefl_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);
581
582// tdefl_compress_buffer() is only usable when the tdefl_init() is called with a non-NULL tdefl_put_buf_func_ptr.
583// tdefl_compress_buffer() always consumes the entire input buffer.
584tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush);
585
586tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d);
587mz_uint32 tdefl_get_adler32(tdefl_compressor *d);
588
589// 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.
590#ifndef MINIZ_NO_ZLIB_APIS
591// Create tdefl_compress() flags given zlib-style compression parameters.
592// level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files)
593// window_bits may be -15 (raw deflate) or 15 (zlib)
594// strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED
595mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy);
596#endif // #ifndef MINIZ_NO_ZLIB_APIS
597
598} // namespace buminiz
599
600#endif // MINIZ_HEADER_INCLUDED
601
602// ------------------- End of Header: Implementation follows. (If you only want the header, define MINIZ_HEADER_FILE_ONLY.)
603
604#ifndef MINIZ_HEADER_FILE_ONLY
605
606#include <string.h>
607#include <assert.h>
608
609namespace buminiz {
610
611typedef unsigned char mz_validate_uint16[sizeof(mz_uint16)==2 ? 1 : -1];
612typedef unsigned char mz_validate_uint32[sizeof(mz_uint32)==4 ? 1 : -1];
613typedef unsigned char mz_validate_uint64[sizeof(mz_uint64)==8 ? 1 : -1];
614
615#define MZ_ASSERT(x) assert(x)
616
617#ifdef MINIZ_NO_MALLOC
618 #define MZ_MALLOC(x) NULL
619 #define MZ_FREE(x) (void)x, ((void)0)
620 #define MZ_REALLOC(p, x) NULL
621#else
622 #define MZ_MALLOC(x) malloc(x)
623 #define MZ_FREE(x) free(x)
624 #define MZ_REALLOC(p, x) realloc(p, x)
625#endif
626
627#define MZ_MAX(a,b) (((a)>(b))?(a):(b))
628#define MZ_MIN(a,b) (((a)<(b))?(a):(b))
629#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
630
631#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
632 #define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
633 #define MZ_READ_LE32(p) *((const mz_uint32 *)(p))
634#else
635 #define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U))
636 #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))
637#endif
638
639#ifdef _MSC_VER
640 #define MZ_FORCEINLINE __forceinline
641#elif defined(__GNUC__)
642 #define MZ_FORCEINLINE inline __attribute__((__always_inline__))
643#else
644 #define MZ_FORCEINLINE inline
645#endif
646
647// ------------------- zlib-style API's
648
649mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len)
650{
651 mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16); size_t block_len = buf_len % 5552;
652 if (!ptr) return MZ_ADLER32_INIT;
653 while (buf_len) {
654 for (i = 0; i + 7 < block_len; i += 8, ptr += 8) {
655 s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1;
656 s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1;
657 }
658 for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1;
659 s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552;
660 }
661 return (s2 << 16) + s1;
662}
663
664// 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/
665mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
666{
667 static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
668 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c };
669 mz_uint32 crcu32 = (mz_uint32)crc;
670 if (!ptr) return MZ_CRC32_INIT;
671 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)]; }
672 return ~crcu32;
673}
674
675void mz_free(void *p)
676{
677 MZ_FREE(p);
678}
679
680#ifndef MINIZ_NO_ZLIB_APIS
681
682static void *def_alloc_func(void *opaque, size_t items, size_t size) { (void)opaque, (void)items, (void)size; return MZ_MALLOC(items * size); }
683static void def_free_func(void *opaque, void *address) { (void)opaque, (void)address; MZ_FREE(address); }
684//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); }
685
686const char *mz_version(void)
687{
688 return MZ_VERSION;
689}
690
691int mz_deflateInit(mz_streamp pStream, int level)
692{
693 return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY);
694}
695
696int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy)
697{
698 tdefl_compressor *pComp;
699 mz_uint comp_flags = TDEFL_COMPUTE_ADLER32 | tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy);
700
701 if (!pStream) return MZ_STREAM_ERROR;
702 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;
703
704 pStream->data_type = 0;
705 pStream->adler = MZ_ADLER32_INIT;
706 pStream->msg = NULL;
707 pStream->reserved = 0;
708 pStream->total_in = 0;
709 pStream->total_out = 0;
710 if (!pStream->zalloc) pStream->zalloc = def_alloc_func;
711 if (!pStream->zfree) pStream->zfree = def_free_func;
712
713 pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, sizeof(tdefl_compressor));
714 if (!pComp)
715 return MZ_MEM_ERROR;
716
717 pStream->state = (struct mz_internal_state *)pComp;
718
719 if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY)
720 {
721 mz_deflateEnd(pStream);
722 return MZ_PARAM_ERROR;
723 }
724
725 return MZ_OK;
726}
727
728int mz_deflateReset(mz_streamp pStream)
729{
730 if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree)) return MZ_STREAM_ERROR;
731 pStream->total_in = pStream->total_out = 0;
732 tdefl_init((tdefl_compressor*)pStream->state, NULL, NULL, ((tdefl_compressor*)pStream->state)->m_flags);
733 return MZ_OK;
734}
735
736int mz_deflate(mz_streamp pStream, int flush)
737{
738 size_t in_bytes, out_bytes;
739 mz_ulong orig_total_in, orig_total_out;
740 int mz_status = MZ_OK;
741
742 if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || (!pStream->next_out)) return MZ_STREAM_ERROR;
743 if (!pStream->avail_out) return MZ_BUF_ERROR;
744
745 if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH;
746
747 if (((tdefl_compressor*)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE)
748 return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR;
749
750 orig_total_in = pStream->total_in; orig_total_out = pStream->total_out;
751 for ( ; ; )
752 {
753 tdefl_status defl_status;
754 in_bytes = pStream->avail_in; out_bytes = pStream->avail_out;
755
756 defl_status = tdefl_compress((tdefl_compressor*)pStream->state, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, (tdefl_flush)flush);
757 pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes;
758 pStream->total_in += (mz_uint)in_bytes; pStream->adler = tdefl_get_adler32((tdefl_compressor*)pStream->state);
759
760 pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes;
761 pStream->total_out += (mz_uint)out_bytes;
762
763 if (defl_status < 0)
764 {
765 mz_status = MZ_STREAM_ERROR;
766 break;
767 }
768 else if (defl_status == TDEFL_STATUS_DONE)
769 {
770 mz_status = MZ_STREAM_END;
771 break;
772 }
773 else if (!pStream->avail_out)
774 break;
775 else if ((!pStream->avail_in) && (flush != MZ_FINISH))
776 {
777 if ((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out))
778 break;
779 return MZ_BUF_ERROR; // Can't make forward progress without some input.
780 }
781 }
782 return mz_status;
783}
784
785int mz_deflateEnd(mz_streamp pStream)
786{
787 if (!pStream) return MZ_STREAM_ERROR;
788 if (pStream->state)
789 {
790 pStream->zfree(pStream->opaque, pStream->state);
791 pStream->state = NULL;
792 }
793 return MZ_OK;
794}
795
796mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len)
797{
798 (void)pStream;
799 // 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.)
800 mz_uint64 a = 128ULL + (source_len * 110ULL) / 100ULL;
801 mz_uint64 b = 128ULL + (mz_uint64)source_len + ((source_len / (31 * 1024)) + 1ULL) * 5ULL;
802
803 mz_uint64 t = MZ_MAX(a, b);
804 if (((mz_ulong)t) != t)
805 t = (mz_ulong)(-1);
806
807 return (mz_ulong)t;
808}
809
810int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level)
811{
812 int status;
813 mz_stream stream;
814 memset(&stream, 0, sizeof(stream));
815
816 // In case mz_ulong is 64-bits (argh I hate longs).
817 if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR;
818
819 stream.next_in = pSource;
820 stream.avail_in = (mz_uint32)source_len;
821 stream.next_out = pDest;
822 stream.avail_out = (mz_uint32)*pDest_len;
823
824 status = mz_deflateInit(&stream, level);
825 if (status != MZ_OK) return status;
826
827 status = mz_deflate(&stream, MZ_FINISH);
828 if (status != MZ_STREAM_END)
829 {
830 mz_deflateEnd(&stream);
831 return (status == MZ_OK) ? MZ_BUF_ERROR : status;
832 }
833
834 *pDest_len = stream.total_out;
835 return mz_deflateEnd(&stream);
836}
837
838int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
839{
840 return mz_compress2(pDest, pDest_len, pSource, source_len, MZ_DEFAULT_COMPRESSION);
841}
842
843mz_ulong mz_compressBound(mz_ulong source_len)
844{
845 return mz_deflateBound(NULL, source_len);
846}
847
848typedef struct
849{
850 tinfl_decompressor m_decomp;
851 mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed; int m_window_bits;
852 mz_uint8 m_dict[TINFL_LZ_DICT_SIZE];
853 tinfl_status m_last_status;
854} inflate_state;
855
856int mz_inflateInit2(mz_streamp pStream, int window_bits)
857{
858 inflate_state *pDecomp;
859 if (!pStream) return MZ_STREAM_ERROR;
860 if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)) return MZ_PARAM_ERROR;
861
862 pStream->data_type = 0;
863 pStream->adler = 0;
864 pStream->msg = NULL;
865 pStream->total_in = 0;
866 pStream->total_out = 0;
867 pStream->reserved = 0;
868 if (!pStream->zalloc) pStream->zalloc = def_alloc_func;
869 if (!pStream->zfree) pStream->zfree = def_free_func;
870
871 pDecomp = (inflate_state*)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state));
872 if (!pDecomp) return MZ_MEM_ERROR;
873
874 pStream->state = (struct mz_internal_state *)pDecomp;
875
876 tinfl_init(&pDecomp->m_decomp);
877 pDecomp->m_dict_ofs = 0;
878 pDecomp->m_dict_avail = 0;
879 pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
880 pDecomp->m_first_call = 1;
881 pDecomp->m_has_flushed = 0;
882 pDecomp->m_window_bits = window_bits;
883
884 return MZ_OK;
885}
886
887int mz_inflateInit(mz_streamp pStream)
888{
889 return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS);
890}
891
892int mz_inflate2(mz_streamp pStream, int flush, int adler32_checking)
893{
894 inflate_state* pState;
895 mz_uint n, first_call, decomp_flags = adler32_checking ? TINFL_FLAG_COMPUTE_ADLER32 : 0;
896 size_t in_bytes, out_bytes, orig_avail_in;
897 tinfl_status status;
898
899 if ((!pStream) || (!pStream->state)) return MZ_STREAM_ERROR;
900 if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH;
901 if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH)) return MZ_STREAM_ERROR;
902
903 pState = (inflate_state*)pStream->state;
904 if (pState->m_window_bits > 0) decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER;
905 orig_avail_in = pStream->avail_in;
906
907 first_call = pState->m_first_call; pState->m_first_call = 0;
908 if (pState->m_last_status < 0) return MZ_DATA_ERROR;
909
910 if (pState->m_has_flushed && (flush != MZ_FINISH)) return MZ_STREAM_ERROR;
911 pState->m_has_flushed |= (flush == MZ_FINISH);
912
913 if ((flush == MZ_FINISH) && (first_call))
914 {
915 // MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file.
916 decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF;
917 in_bytes = pStream->avail_in; out_bytes = pStream->avail_out;
918 status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags);
919 pState->m_last_status = status;
920 pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; pStream->total_in += (mz_uint)in_bytes;
921 pStream->adler = tinfl_get_adler32(&pState->m_decomp);
922 pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes; pStream->total_out += (mz_uint)out_bytes;
923
924 if (status < 0)
925 return MZ_DATA_ERROR;
926 else if (status != TINFL_STATUS_DONE)
927 {
928 pState->m_last_status = TINFL_STATUS_FAILED;
929 return MZ_BUF_ERROR;
930 }
931 return MZ_STREAM_END;
932 }
933 // flush != MZ_FINISH then we must assume there's more input.
934 if (flush != MZ_FINISH) decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT;
935
936 if (pState->m_dict_avail)
937 {
938 n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
939 memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
940 pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n;
941 pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
942 return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
943 }
944
945 for ( ; ; )
946 {
947 in_bytes = pStream->avail_in;
948 out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs;
949
950 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);
951 pState->m_last_status = status;
952
953 pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes;
954 pStream->total_in += (mz_uint)in_bytes; pStream->adler = tinfl_get_adler32(&pState->m_decomp);
955
956 pState->m_dict_avail = (mz_uint)out_bytes;
957
958 n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
959 memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
960 pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n;
961 pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
962
963 if (status < 0)
964 return MZ_DATA_ERROR; // Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well).
965 else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in))
966 return MZ_BUF_ERROR; // Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH.
967 else if (flush == MZ_FINISH)
968 {
969 // The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH.
970 if (status == TINFL_STATUS_DONE)
971 return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END;
972 // 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.
973 else if (!pStream->avail_out)
974 return MZ_BUF_ERROR;
975 }
976 else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail))
977 break;
978 }
979
980 return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
981}
982
983int mz_inflate(mz_streamp pStream, int flush)
984{
985 return mz_inflate2(pStream, flush, MZ_TRUE);
986}
987
988int mz_inflateEnd(mz_streamp pStream)
989{
990 if (!pStream)
991 return MZ_STREAM_ERROR;
992 if (pStream->state)
993 {
994 pStream->zfree(pStream->opaque, pStream->state);
995 pStream->state = NULL;
996 }
997 return MZ_OK;
998}
999
1000int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
1001{
1002 mz_stream stream;
1003 int status;
1004 memset(&stream, 0, sizeof(stream));
1005
1006 // In case mz_ulong is 64-bits (argh I hate longs).
1007 if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR;
1008
1009 stream.next_in = pSource;
1010 stream.avail_in = (mz_uint32)source_len;
1011 stream.next_out = pDest;
1012 stream.avail_out = (mz_uint32)*pDest_len;
1013
1014 status = mz_inflateInit(&stream);
1015 if (status != MZ_OK)
1016 return status;
1017
1018 status = mz_inflate(&stream, MZ_FINISH);
1019 if (status != MZ_STREAM_END)
1020 {
1021 mz_inflateEnd(&stream);
1022 return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status;
1023 }
1024 *pDest_len = stream.total_out;
1025
1026 return mz_inflateEnd(&stream);
1027}
1028
1029const char *mz_error(int err)
1030{
1031 static struct { int m_err; const char *m_pDesc; } s_error_descs[] =
1032 {
1033 { MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" },
1034 { 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" }
1035 };
1036 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;
1037 return NULL;
1038}
1039
1040#endif //MINIZ_NO_ZLIB_APIS
1041
1042// ------------------- Low-level Decompression (completely independent from all compression API's)
1043
1044#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
1045#define TINFL_MEMSET(p, c, l) memset(p, c, l)
1046
1047#define TINFL_CR_BEGIN switch(r->m_state) { case 0:
1048#define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END
1049#define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END
1050#define TINFL_CR_FINISH }
1051
1052// 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
1053// reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of the stream with 0's in this scenario.
1054#define TINFL_GET_BYTE(state_index, c) do { \
1055 if (pIn_buf_cur >= pIn_buf_end) { \
1056 for ( ; ; ) { \
1057 if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \
1058 TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \
1059 if (pIn_buf_cur < pIn_buf_end) { \
1060 c = *pIn_buf_cur++; \
1061 break; \
1062 } \
1063 } else { \
1064 c = 0; \
1065 break; \
1066 } \
1067 } \
1068 } else c = *pIn_buf_cur++; } MZ_MACRO_END
1069
1070#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))
1071#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
1072#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
1073
1074// TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2.
1075// 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
1076// 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
1077// bit buffer contains >=15 bits (deflate's max. Huffman code size).
1078#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \
1079 do { \
1080 temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
1081 if (temp >= 0) { \
1082 code_len = temp >> 9; \
1083 if ((code_len) && (num_bits >= code_len)) \
1084 break; \
1085 } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \
1086 code_len = TINFL_FAST_LOOKUP_BITS; \
1087 do { \
1088 temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
1089 } while ((temp < 0) && (num_bits >= (code_len + 1))); if (temp >= 0) break; \
1090 } TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; \
1091 } while (num_bits < 15);
1092
1093// 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
1094// 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
1095// 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.
1096// The slow path is only executed at the very end of the input buffer.
1097#define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \
1098 int temp; mz_uint code_len, c; \
1099 if (num_bits < 15) { \
1100 if ((pIn_buf_end - pIn_buf_cur) < 2) { \
1101 TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
1102 } else { \
1103 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; \
1104 } \
1105 } \
1106 if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
1107 code_len = temp >> 9, temp &= 511; \
1108 else { \
1109 code_len = TINFL_FAST_LOOKUP_BITS; do { temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; } while (temp < 0); \
1110 } sym = temp; bit_buf >>= code_len; num_bits -= code_len; } MZ_MACRO_END
1111
1112tinfl_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)
1113{
1114 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 };
1115 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 };
1116 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};
1117 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};
1118 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 };
1119 static const int s_min_table_sizes[3] = { 257, 1, 4 };
1120
1121 tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; tinfl_bit_buf_t bit_buf;
1122 const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size;
1123 mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size;
1124 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;
1125
1126 // 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).
1127 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; }
1128
1129 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;
1130 TINFL_CR_BEGIN
1131
1132 bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0; r->m_z_adler32 = r->m_check_adler32 = 1;
1133 if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
1134 {
1135 TINFL_GET_BYTE(1, r->m_zhdr0); TINFL_GET_BYTE(2, r->m_zhdr1);
1136 counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8));
1137 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)(1ULL << (8U + (r->m_zhdr0 >> 4)))));
1138 if (counter) { TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); }
1139 }
1140
1141 do
1142 {
1143 TINFL_GET_BITS(3, r->m_final, 3); r->m_type = r->m_final >> 1;
1144 if (r->m_type == 0)
1145 {
1146 TINFL_SKIP_BITS(5, num_bits & 7);
1147 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]); }
1148 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); }
1149 while ((counter) && (num_bits))
1150 {
1151 TINFL_GET_BITS(51, dist, 8);
1152 while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT); }
1153 *pOut_buf_cur++ = (mz_uint8)dist;
1154 counter--;
1155 }
1156 while (counter)
1157 {
1158 size_t n; while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); }
1159 while (pIn_buf_cur >= pIn_buf_end)
1160 {
1161 if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT)
1162 {
1163 TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT);
1164 }
1165 else
1166 {
1167 TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED);
1168 }
1169 }
1170 n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter);
1171 TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); pIn_buf_cur += n; pOut_buf_cur += n; counter -= (mz_uint)n;
1172 }
1173 }
1174 else if (r->m_type == 3)
1175 {
1176 TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED);
1177 }
1178 else
1179 {
1180 if (r->m_type == 1)
1181 {
1182 mz_uint8 *p = r->m_tables[0].m_code_size; mz_uint i;
1183 r->m_table_sizes[0] = 288; r->m_table_sizes[1] = 32; TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32);
1184 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;
1185 }
1186 else
1187 {
1188 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]; }
1189 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; }
1190 r->m_table_sizes[2] = 19;
1191 }
1192 for ( ; (int)r->m_type >= 0; r->m_type--)
1193 {
1194 int tree_next, tree_cur; tinfl_huff_table *pTable;
1195 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);
1196 for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) total_syms[pTable->m_code_size[i]]++;
1197 used_syms = 0, total = 0; next_code[0] = next_code[1] = 0;
1198 for (i = 1; i <= 15; ++i) { used_syms += total_syms[i]; next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); }
1199 if ((65536 != total) && (used_syms > 1))
1200 {
1201 TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED);
1202 }
1203 for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index)
1204 {
1205 mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index]; if (!code_size) continue;
1206 cur_code = next_code[code_size]++; for (l = code_size; l > 0; l--, cur_code >>= 1) rev_code = (rev_code << 1) | (cur_code & 1);
1207 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; }
1208 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; }
1209 rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1);
1210 for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--)
1211 {
1212 tree_cur -= ((rev_code >>= 1) & 1);
1213 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];
1214 }
1215 tree_cur -= ((rev_code >>= 1) & 1); pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
1216 }
1217 if (r->m_type == 2)
1218 {
1219 for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]); )
1220 {
1221 mz_uint s; TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); if (dist < 16) { r->m_len_codes[counter++] = (mz_uint8)dist; continue; }
1222 if ((dist == 16) && (!counter))
1223 {
1224 TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED);
1225 }
1226 num_extra = "\02\03\07"[dist - 16]; TINFL_GET_BITS(18, s, num_extra); s += "\03\03\013"[dist - 16];
1227 TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s); counter += s;
1228 }
1229 if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter)
1230 {
1231 TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED);
1232 }
1233 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]);
1234 }
1235 }
1236 for ( ; ; )
1237 {
1238 mz_uint8 *pSrc;
1239 for ( ; ; )
1240 {
1241 if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2))
1242 {
1243 TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]);
1244 if (counter >= 256)
1245 break;
1246 while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT); }
1247 *pOut_buf_cur++ = (mz_uint8)counter;
1248 }
1249 else
1250 {
1251 int sym2; mz_uint code_len;
1252#if TINFL_USE_64BIT_BITBUF
1253 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; }
1254#else
1255 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; }
1256#endif
1257 if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
1258 code_len = sym2 >> 9;
1259 else
1260 {
1261 code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0);
1262 }
1263 counter = sym2; bit_buf >>= code_len; num_bits -= code_len;
1264 if (counter & 256)
1265 break;
1266
1267#if !TINFL_USE_64BIT_BITBUF
1268 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; }
1269#endif
1270 if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
1271 code_len = sym2 >> 9;
1272 else
1273 {
1274 code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0);
1275 }
1276 bit_buf >>= code_len; num_bits -= code_len;
1277
1278 pOut_buf_cur[0] = (mz_uint8)counter;
1279 if (sym2 & 256)
1280 {
1281 pOut_buf_cur++;
1282 counter = sym2;
1283 break;
1284 }
1285 pOut_buf_cur[1] = (mz_uint8)sym2;
1286 pOut_buf_cur += 2;
1287 }
1288 }
1289 if ((counter &= 511) == 256) break;
1290
1291 num_extra = s_length_extra[counter - 257]; counter = s_length_base[counter - 257];
1292 if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(25, extra_bits, num_extra); counter += extra_bits; }
1293
1294 TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]);
1295 num_extra = s_dist_extra[dist]; dist = s_dist_base[dist];
1296 if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(27, extra_bits, num_extra); dist += extra_bits; }
1297
1298 dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
1299 if ((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
1300 {
1301 TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED);
1302 }
1303
1304 pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask);
1305
1306 if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end)
1307 {
1308 while (counter--)
1309 {
1310 while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT); }
1311 *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask];
1312 }
1313 continue;
1314 }
1315#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
1316 else if ((counter >= 9) && (counter <= dist))
1317 {
1318 const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
1319 do
1320 {
1321 ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0];
1322 ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1];
1323 pOut_buf_cur += 8;
1324 } while ((pSrc += 8) < pSrc_end);
1325 if ((counter &= 7) < 3)
1326 {
1327 if (counter)
1328 {
1329 pOut_buf_cur[0] = pSrc[0];
1330 if (counter > 1)
1331 pOut_buf_cur[1] = pSrc[1];
1332 pOut_buf_cur += counter;
1333 }
1334 continue;
1335 }
1336 }
1337#endif
1338 do
1339 {
1340 pOut_buf_cur[0] = pSrc[0];
1341 pOut_buf_cur[1] = pSrc[1];
1342 pOut_buf_cur[2] = pSrc[2];
1343 pOut_buf_cur += 3; pSrc += 3;
1344 } while ((int)(counter -= 3) > 2);
1345 if ((int)counter > 0)
1346 {
1347 pOut_buf_cur[0] = pSrc[0];
1348 if ((int)counter > 1)
1349 pOut_buf_cur[1] = pSrc[1];
1350 pOut_buf_cur += counter;
1351 }
1352 }
1353 }
1354 } while (!(r->m_final & 1));
1355 if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
1356 {
1357 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; }
1358 }
1359 TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE);
1360 TINFL_CR_FINISH
1361
1362common_exit:
1363 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;
1364 *pIn_buf_size = pIn_buf_cur - pIn_buf_next; *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
1365 //if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0))
1366 if ((decomp_flags & TINFL_FLAG_COMPUTE_ADLER32) && (status >= 0))
1367 {
1368 const mz_uint8 *ptr = pOut_buf_next; size_t buf_len = *pOut_buf_size;
1369 mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16; size_t block_len = buf_len % 5552;
1370 while (buf_len)
1371 {
1372 for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
1373 {
1374 s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1;
1375 s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1;
1376 }
1377 for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1;
1378 s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552;
1379 }
1380 r->m_check_adler32 = (s2 << 16) + s1;
1381 if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32))
1382 status = TINFL_STATUS_ADLER32_MISMATCH;
1383 }
1384 return status;
1385}
1386
1387// Higher level helper functions.
1388void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
1389{
1390 tinfl_decompressor decomp; void *pBuf = NULL, *pNew_buf; size_t src_buf_ofs = 0, out_buf_capacity = 0;
1391 *pOut_len = 0;
1392 tinfl_init(&decomp);
1393 for ( ; ; )
1394 {
1395 size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity;
1396 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,
1397 (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
1398 if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT))
1399 {
1400 MZ_FREE(pBuf); *pOut_len = 0; return NULL;
1401 }
1402 src_buf_ofs += src_buf_size;
1403 *pOut_len += dst_buf_size;
1404 if (status == TINFL_STATUS_DONE) break;
1405 new_out_buf_capacity = out_buf_capacity * 2; if (new_out_buf_capacity < 128) new_out_buf_capacity = 128;
1406 pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity);
1407 if (!pNew_buf)
1408 {
1409 MZ_FREE(pBuf); *pOut_len = 0; return NULL;
1410 }
1411 pBuf = pNew_buf; out_buf_capacity = new_out_buf_capacity;
1412 }
1413 return pBuf;
1414}
1415
1416size_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)
1417{
1418 tinfl_decompressor decomp; tinfl_status status; tinfl_init(&decomp);
1419 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);
1420 return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len;
1421}
1422
1423int 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)
1424{
1425 int result = 0;
1426 tinfl_decompressor decomp;
1427 mz_uint8 *pDict = (mz_uint8*)MZ_MALLOC(TINFL_LZ_DICT_SIZE); size_t in_buf_ofs = 0, dict_ofs = 0;
1428 if (!pDict)
1429 return TINFL_STATUS_FAILED;
1430 tinfl_init(&decomp);
1431 for ( ; ; )
1432 {
1433 size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs;
1434 tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size,
1435 (flags & ~(TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)));
1436 in_buf_ofs += in_buf_size;
1437 if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user)))
1438 break;
1439 if (status != TINFL_STATUS_HAS_MORE_OUTPUT)
1440 {
1441 result = (status == TINFL_STATUS_DONE);
1442 break;
1443 }
1444 dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1);
1445 }
1446 MZ_FREE(pDict);
1447 *pIn_buf_size = in_buf_ofs;
1448 return result;
1449}
1450
1451// ------------------- Low-level Compression (independent from all decompression API's)
1452
1453// Purposely making these tables static for faster init and thread safety.
1454static const mz_uint16 s_tdefl_len_sym[256] = {
1455 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,
1456 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,
1457 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,
1458 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,
1459 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,
1460 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,
1461 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,
1462 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 };
1463
1464static const mz_uint8 s_tdefl_len_extra[256] = {
1465 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,
1466 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,
1467 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1468 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,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 };
1469
1470static const mz_uint8 s_tdefl_small_dist_sym[512] = {
1471 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,
1472 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,
1473 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,
1474 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,
1475 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,
1476 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,
1477 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,
1478 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,
1479 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,
1480 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,
1481 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,
1482 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 };
1483
1484static const mz_uint8 s_tdefl_small_dist_extra[512] = {
1485 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,
1486 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,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,
1487 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1488 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,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,
1489 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1490 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1491 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1492 7,7,7,7,7,7,7,7 };
1493
1494static const mz_uint8 s_tdefl_large_dist_sym[128] = {
1495 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,
1496 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,
1497 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 };
1498
1499static const mz_uint8 s_tdefl_large_dist_extra[128] = {
1500 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,
1501 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,
1502 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 };
1503
1504// Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted values.
1505typedef struct { mz_uint16 m_key, m_sym_index; } tdefl_sym_freq;
1506static tdefl_sym_freq* tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq* pSyms0, tdefl_sym_freq* pSyms1)
1507{
1508 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);
1509 for (i = 0; i < num_syms; i++) { mz_uint freq = pSyms0[i].m_key; hist[freq & 0xFF]++; hist[256 + ((freq >> 8) & 0xFF)]++; }
1510 while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256])) total_passes--;
1511 for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8)
1512 {
1513 const mz_uint32* pHist = &hist[pass << 8];
1514 mz_uint offsets[256], cur_ofs = 0;
1515 for (i = 0; i < 256; i++) { offsets[i] = cur_ofs; cur_ofs += pHist[i]; }
1516 for (i = 0; i < num_syms; i++) pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = pCur_syms[i];
1517 { tdefl_sym_freq* t = pCur_syms; pCur_syms = pNew_syms; pNew_syms = t; }
1518 }
1519 return pCur_syms;
1520}
1521
1522// tdefl_calculate_minimum_redundancy() originally written by: Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996.
1523static void tdefl_calculate_minimum_redundancy(tdefl_sym_freq *A, int n)
1524{
1525 int root, leaf, next, avbl, used, dpth;
1526 if (n==0) return; else if (n==1) { A[0].m_key = 1; return; }
1527 A[0].m_key += A[1].m_key; root = 0; leaf = 2;
1528 for (next=1; next < n-1; next++)
1529 {
1530 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;
1531 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);
1532 }
1533 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;
1534 avbl = 1; used = dpth = 0; root = n-2; next = n-1;
1535 while (avbl>0)
1536 {
1537 while (root>=0 && (int)A[root].m_key==dpth) { used++; root--; }
1538 while (avbl>used) { A[next--].m_key = (mz_uint16)(dpth); avbl--; }
1539 avbl = 2*used; dpth++; used = 0;
1540 }
1541}
1542
1543// Limits canonical Huffman code table's max code size.
1544enum { TDEFL_MAX_SUPPORTED_HUFF_CODESIZE = 32 };
1545static void tdefl_huffman_enforce_max_code_size(int *pNum_codes, int code_list_len, int max_code_size)
1546{
1547 int i; mz_uint32 total = 0; if (code_list_len <= 1) return;
1548 for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++) pNum_codes[max_code_size] += pNum_codes[i];
1549 for (i = max_code_size; i > 0; i--) total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i));
1550 while (total != (1UL << max_code_size))
1551 {
1552 pNum_codes[max_code_size]--;
1553 for (i = max_code_size - 1; i > 0; i--) if (pNum_codes[i]) { pNum_codes[i]--; pNum_codes[i + 1] += 2; break; }
1554 total--;
1555 }
1556}
1557
1558static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int table_len, int code_size_limit, int static_table)
1559{
1560 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);
1561 if (static_table)
1562 {
1563 for (i = 0; i < table_len; i++) num_codes[d->m_huff_code_sizes[table_num][i]]++;
1564 }
1565 else
1566 {
1567 tdefl_sym_freq syms0[TDEFL_MAX_HUFF_SYMBOLS], syms1[TDEFL_MAX_HUFF_SYMBOLS], *pSyms;
1568 int num_used_syms = 0;
1569 const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0];
1570 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; }
1571
1572 pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1); tdefl_calculate_minimum_redundancy(pSyms, num_used_syms);
1573
1574 for (i = 0; i < num_used_syms; i++) num_codes[pSyms[i].m_key]++;
1575
1576 tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, code_size_limit);
1577
1578 MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]); MZ_CLEAR_OBJ(d->m_huff_codes[table_num]);
1579 for (i = 1, j = num_used_syms; i <= code_size_limit; i++)
1580 for (l = num_codes[i]; l > 0; l--) d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i);
1581 }
1582
1583 next_code[1] = 0; for (j = 0, i = 2; i <= code_size_limit; i++) next_code[i] = j = ((j + num_codes[i - 1]) << 1);
1584
1585 for (i = 0; i < table_len; i++)
1586 {
1587 mz_uint rev_code = 0, code, code_size; if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0) continue;
1588 code = next_code[code_size]++; for (l = code_size; l > 0; l--, code >>= 1) rev_code = (rev_code << 1) | (code & 1);
1589 d->m_huff_codes[table_num][i] = (mz_uint16)rev_code;
1590 }
1591}
1592
1593#define TDEFL_PUT_BITS(b, l) do { \
1594 mz_uint bits = b; mz_uint len = l; MZ_ASSERT(bits <= ((1U << len) - 1U)); \
1595 d->m_bit_buffer |= (bits << d->m_bits_in); d->m_bits_in += len; \
1596 while (d->m_bits_in >= 8) { \
1597 if (d->m_pOutput_buf < d->m_pOutput_buf_end) \
1598 *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \
1599 d->m_bit_buffer >>= 8; \
1600 d->m_bits_in -= 8; \
1601 } \
1602} MZ_MACRO_END
1603
1604#define TDEFL_RLE_PREV_CODE_SIZE() { if (rle_repeat_count) { \
1605 if (rle_repeat_count < 3) { \
1606 d->m_huff_count[2][prev_code_size] = (mz_uint16)(d->m_huff_count[2][prev_code_size] + rle_repeat_count); \
1607 while (rle_repeat_count--) packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \
1608 } else { \
1609 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); \
1610} rle_repeat_count = 0; } }
1611
1612#define TDEFL_RLE_ZERO_CODE_SIZE() { if (rle_z_count) { \
1613 if (rle_z_count < 3) { \
1614 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; \
1615 } else if (rle_z_count <= 10) { \
1616 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); \
1617 } else { \
1618 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); \
1619} rle_z_count = 0; } }
1620
1621static 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 };
1622
1623static void tdefl_start_dynamic_block(tdefl_compressor *d)
1624{
1625 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;
1626 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;
1627
1628 d->m_huff_count[0][256] = 1;
1629
1630 tdefl_optimize_huffman_table(d, 0, TDEFL_MAX_HUFF_SYMBOLS_0, 15, MZ_FALSE);
1631 tdefl_optimize_huffman_table(d, 1, TDEFL_MAX_HUFF_SYMBOLS_1, 15, MZ_FALSE);
1632
1633 for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--) if (d->m_huff_code_sizes[0][num_lit_codes - 1]) break;
1634 for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--) if (d->m_huff_code_sizes[1][num_dist_codes - 1]) break;
1635
1636 memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes);
1637 memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0], num_dist_codes);
1638 total_code_sizes_to_pack = num_lit_codes + num_dist_codes; num_packed_code_sizes = 0; rle_z_count = 0; rle_repeat_count = 0;
1639
1640 memset(&d->m_huff_count[2][0], 0, sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2);
1641 for (i = 0; i < total_code_sizes_to_pack; i++)
1642 {
1643 mz_uint8 code_size = code_sizes_to_pack[i];
1644 if (!code_size)
1645 {
1646 TDEFL_RLE_PREV_CODE_SIZE();
1647 if (++rle_z_count == 138) { TDEFL_RLE_ZERO_CODE_SIZE(); }
1648 }
1649 else
1650 {
1651 TDEFL_RLE_ZERO_CODE_SIZE();
1652 if (code_size != prev_code_size)
1653 {
1654 TDEFL_RLE_PREV_CODE_SIZE();
1655 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;
1656 }
1657 else if (++rle_repeat_count == 6)
1658 {
1659 TDEFL_RLE_PREV_CODE_SIZE();
1660 }
1661 }
1662 prev_code_size = code_size;
1663 }
1664 if (rle_repeat_count) { TDEFL_RLE_PREV_CODE_SIZE(); } else { TDEFL_RLE_ZERO_CODE_SIZE(); }
1665
1666 tdefl_optimize_huffman_table(d, 2, TDEFL_MAX_HUFF_SYMBOLS_2, 7, MZ_FALSE);
1667
1668 TDEFL_PUT_BITS(2, 2);
1669
1670 TDEFL_PUT_BITS(num_lit_codes - 257, 5);
1671 TDEFL_PUT_BITS(num_dist_codes - 1, 5);
1672
1673 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;
1674 num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1)); TDEFL_PUT_BITS(num_bit_lengths - 4, 4);
1675 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);
1676
1677 for (packed_code_sizes_index = 0; packed_code_sizes_index < num_packed_code_sizes; )
1678 {
1679 mz_uint code = packed_code_sizes[packed_code_sizes_index++]; MZ_ASSERT(code < TDEFL_MAX_HUFF_SYMBOLS_2);
1680 TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]);
1681 if (code >= 16) TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++], "\02\03\07"[code - 16]);
1682 }
1683}
1684
1685static void tdefl_start_static_block(tdefl_compressor *d)
1686{
1687 mz_uint i;
1688 mz_uint8 *p = &d->m_huff_code_sizes[0][0];
1689
1690 for (i = 0; i <= 143; ++i) *p++ = 8;
1691 for ( ; i <= 255; ++i) *p++ = 9;
1692 for ( ; i <= 279; ++i) *p++ = 7;
1693 for ( ; i <= 287; ++i) *p++ = 8;
1694
1695 memset(d->m_huff_code_sizes[1], 5, 32);
1696
1697 tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE);
1698 tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE);
1699
1700 TDEFL_PUT_BITS(1, 2);
1701}
1702
1703static const mz_uint mz_bitmasks[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
1704
1705#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS
1706static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d)
1707{
1708 mz_uint flags;
1709 mz_uint8 *pLZ_codes;
1710 mz_uint8 *pOutput_buf = d->m_pOutput_buf;
1711 mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf;
1712 mz_uint64 bit_buffer = d->m_bit_buffer;
1713 mz_uint bits_in = d->m_bits_in;
1714
1715#define TDEFL_PUT_BITS_FAST(b, l) { bit_buffer |= (((mz_uint64)(b)) << bits_in); bits_in += (l); }
1716
1717 flags = 1;
1718 for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end; flags >>= 1)
1719 {
1720 if (flags == 1)
1721 flags = *pLZ_codes++ | 0x100;
1722
1723 if (flags & 1)
1724 {
1725 mz_uint s0, s1, n0, n1, sym, num_extra_bits;
1726 mz_uint match_len = pLZ_codes[0], match_dist = *(const mz_uint16 *)(pLZ_codes + 1); pLZ_codes += 3;
1727
1728 MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
1729 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]]);
1730 TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]);
1731
1732 // This sequence coaxes MSVC into using cmov's vs. jmp's.
1733 s0 = s_tdefl_small_dist_sym[match_dist & 511];
1734 n0 = s_tdefl_small_dist_extra[match_dist & 511];
1735 s1 = s_tdefl_large_dist_sym[match_dist >> 8];
1736 n1 = s_tdefl_large_dist_extra[match_dist >> 8];
1737 sym = (match_dist < 512) ? s0 : s1;
1738 num_extra_bits = (match_dist < 512) ? n0 : n1;
1739
1740 MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
1741 TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
1742 TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
1743 }
1744 else
1745 {
1746 mz_uint lit = *pLZ_codes++;
1747 MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
1748 TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
1749
1750 if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
1751 {
1752 flags >>= 1;
1753 lit = *pLZ_codes++;
1754 MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
1755 TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
1756
1757 if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end))
1758 {
1759 flags >>= 1;
1760 lit = *pLZ_codes++;
1761 MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
1762 TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
1763 }
1764 }
1765 }
1766
1767 if (pOutput_buf >= d->m_pOutput_buf_end)
1768 return MZ_FALSE;
1769
1770 *(mz_uint64*)pOutput_buf = bit_buffer;
1771 pOutput_buf += (bits_in >> 3);
1772 bit_buffer >>= (bits_in & ~7);
1773 bits_in &= 7;
1774 }
1775
1776#undef TDEFL_PUT_BITS_FAST
1777
1778 d->m_pOutput_buf = pOutput_buf;
1779 d->m_bits_in = 0;
1780 d->m_bit_buffer = 0;
1781
1782 while (bits_in)
1783 {
1784 mz_uint32 n = MZ_MIN(bits_in, 16);
1785 TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n);
1786 bit_buffer >>= n;
1787 bits_in -= n;
1788 }
1789
1790 TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
1791
1792 return (d->m_pOutput_buf < d->m_pOutput_buf_end);
1793}
1794#else
1795static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d)
1796{
1797 mz_uint flags;
1798 mz_uint8 *pLZ_codes;
1799
1800 flags = 1;
1801 for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf; flags >>= 1)
1802 {
1803 if (flags == 1)
1804 flags = *pLZ_codes++ | 0x100;
1805 if (flags & 1)
1806 {
1807 mz_uint sym, num_extra_bits;
1808 mz_uint match_len = pLZ_codes[0], match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8)); pLZ_codes += 3;
1809
1810 MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
1811 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]]);
1812 TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]);
1813
1814 if (match_dist < 512)
1815 {
1816 sym = s_tdefl_small_dist_sym[match_dist]; num_extra_bits = s_tdefl_small_dist_extra[match_dist];
1817 }
1818 else
1819 {
1820 sym = s_tdefl_large_dist_sym[match_dist >> 8]; num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8];
1821 }
1822 MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
1823 TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
1824 TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
1825 }
1826 else
1827 {
1828 mz_uint lit = *pLZ_codes++;
1829 MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
1830 TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
1831 }
1832 }
1833
1834 TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
1835
1836 return (d->m_pOutput_buf < d->m_pOutput_buf_end);
1837}
1838#endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS
1839
1840static mz_bool tdefl_compress_block(tdefl_compressor *d, mz_bool static_block)
1841{
1842 if (static_block)
1843 tdefl_start_static_block(d);
1844 else
1845 tdefl_start_dynamic_block(d);
1846 return tdefl_compress_lz_codes(d);
1847}
1848
1849static int tdefl_flush_block(tdefl_compressor *d, int flush)
1850{
1851 mz_uint saved_bit_buf, saved_bits_in;
1852 mz_uint8 *pSaved_output_buf;
1853 mz_bool comp_block_succeeded = MZ_FALSE;
1854 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;
1855 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;
1856
1857 d->m_pOutput_buf = pOutput_buf_start;
1858 d->m_pOutput_buf_end = d->m_pOutput_buf + TDEFL_OUT_BUF_SIZE - 16;
1859
1860 MZ_ASSERT(!d->m_output_flush_remaining);
1861 d->m_output_flush_ofs = 0;
1862 d->m_output_flush_remaining = 0;
1863
1864 *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left);
1865 d->m_pLZ_code_buf -= (d->m_num_flags_left == 8);
1866
1867 if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index))
1868 {
1869 TDEFL_PUT_BITS(0x78, 8); TDEFL_PUT_BITS(0x01, 8);
1870 }
1871
1872 TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1);
1873
1874 pSaved_output_buf = d->m_pOutput_buf; saved_bit_buf = d->m_bit_buffer; saved_bits_in = d->m_bits_in;
1875
1876 if (!use_raw_block)
1877 comp_block_succeeded = tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || (d->m_total_lz_bytes < 48));
1878
1879 // If the block gets expanded, forget the current contents of the output buffer and send a raw block instead.
1880 if ( ((use_raw_block) || ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >= d->m_total_lz_bytes))) &&
1881 ((d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size) )
1882 {
1883 mz_uint i; d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
1884 TDEFL_PUT_BITS(0, 2);
1885 if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); }
1886 for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF)
1887 {
1888 TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16);
1889 }
1890 for (i = 0; i < d->m_total_lz_bytes; ++i)
1891 {
1892 TDEFL_PUT_BITS(d->m_dict[(d->m_lz_code_buf_dict_pos + i) & TDEFL_LZ_DICT_SIZE_MASK], 8);
1893 }
1894 }
1895 // Check for the extremely unlikely (if not impossible) case of the compressed block not fitting into the output buffer when using dynamic codes.
1896 else if (!comp_block_succeeded)
1897 {
1898 d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
1899 tdefl_compress_block(d, MZ_TRUE);
1900 }
1901
1902 if (flush)
1903 {
1904 if (flush == TDEFL_FINISH)
1905 {
1906 if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); }
1907 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; } }
1908 }
1909 else
1910 {
1911 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); }
1912 }
1913 }
1914
1915 MZ_ASSERT(d->m_pOutput_buf < d->m_pOutput_buf_end);
1916
1917 memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
1918 memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
1919
1920 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++;
1921
1922 if ((n = (int)(d->m_pOutput_buf - pOutput_buf_start)) != 0)
1923 {
1924 if (d->m_pPut_buf_func)
1925 {
1926 *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf;
1927 if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user))
1928 return (d->m_prev_return_status = TDEFL_STATUS_PUT_BUF_FAILED);
1929 }
1930 else if (pOutput_buf_start == d->m_output_buf)
1931 {
1932 int bytes_to_copy = (int)MZ_MIN((size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs));
1933 memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf, bytes_to_copy);
1934 d->m_out_buf_ofs += bytes_to_copy;
1935 if ((n -= bytes_to_copy) != 0)
1936 {
1937 d->m_output_flush_ofs = bytes_to_copy;
1938 d->m_output_flush_remaining = n;
1939 }
1940 }
1941 else
1942 {
1943 d->m_out_buf_ofs += n;
1944 }
1945 }
1946
1947 return d->m_output_flush_remaining;
1948}
1949
1950#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
1951#define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16*)(p)
1952static 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)
1953{
1954 mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len;
1955 mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
1956 const mz_uint16 *s = (const mz_uint16*)(d->m_dict + pos), *p, *q;
1957 mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]), s01 = TDEFL_READ_UNALIGNED_WORD(s);
1958 MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return;
1959 for ( ; ; )
1960 {
1961 for ( ; ; )
1962 {
1963 if (--num_probes_left == 0) return;
1964 #define TDEFL_PROBE \
1965 next_probe_pos = d->m_next[probe_pos]; \
1966 if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \
1967 probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
1968 if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) break;
1969 TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE;
1970 }
1971 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;
1972 do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) &&
1973 (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0) );
1974 if (!probe_len)
1975 {
1976 *pMatch_dist = dist; *pMatch_len = MZ_MIN(max_match_len, TDEFL_MAX_MATCH_LEN); break;
1977 }
1978 else if ((probe_len = ((mz_uint)(p - s) * 2) + (mz_uint)(*(const mz_uint8*)p == *(const mz_uint8*)q)) > match_len)
1979 {
1980 *pMatch_dist = dist; if ((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) == max_match_len) break;
1981 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]);
1982 }
1983 }
1984}
1985#else
1986static 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)
1987{
1988 mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len;
1989 mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
1990 const mz_uint8 *s = d->m_dict + pos, *p, *q;
1991 mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1];
1992 MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return;
1993 for ( ; ; )
1994 {
1995 for ( ; ; )
1996 {
1997 if (--num_probes_left == 0) return;
1998 #define TDEFL_PROBE \
1999 next_probe_pos = d->m_next[probe_pos]; \
2000 if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \
2001 probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
2002 if ((d->m_dict[probe_pos + match_len] == c0) && (d->m_dict[probe_pos + match_len - 1] == c1)) break;
2003 TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE;
2004 }
2005 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;
2006 if (probe_len > match_len)
2007 {
2008 *pMatch_dist = dist; if ((*pMatch_len = match_len = probe_len) == max_match_len) return;
2009 c0 = d->m_dict[pos + match_len]; c1 = d->m_dict[pos + match_len - 1];
2010 }
2011 }
2012}
2013#endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
2014
2015#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
2016static mz_bool tdefl_compress_fast(tdefl_compressor *d)
2017{
2018 // Faster, minimally featured LZRW1-style match+parse loop with better register utilization. Intended for applications where raw throughput is valued more highly than ratio.
2019 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;
2020 mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags;
2021 mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
2022
2023 while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size)))
2024 {
2025 const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096;
2026 mz_uint dst_pos = (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK;
2027 mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size);
2028 d->m_src_buf_left -= num_bytes_to_process;
2029 lookahead_size += num_bytes_to_process;
2030
2031 while (num_bytes_to_process)
2032 {
2033 mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process);
2034 memcpy(d->m_dict + dst_pos, d->m_pSrc, n);
2035 if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
2036 memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc, MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos));
2037 d->m_pSrc += n;
2038 dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK;
2039 num_bytes_to_process -= n;
2040 }
2041
2042 dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size);
2043 if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE)) break;
2044
2045 while (lookahead_size >= 4)
2046 {
2047 mz_uint cur_match_dist, cur_match_len = 1;
2048 mz_uint8 *pCur_dict = d->m_dict + cur_pos;
2049 mz_uint first_trigram = (*(const mz_uint32 *)pCur_dict) & 0xFFFFFF;
2050 mz_uint hash = (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) & TDEFL_LEVEL1_HASH_SIZE_MASK;
2051 mz_uint probe_pos = d->m_hash[hash];
2052 d->m_hash[hash] = (mz_uint16)lookahead_pos;
2053
2054 if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <= dict_size) && ((*(const mz_uint32 *)(d->m_dict + (probe_pos &= TDEFL_LZ_DICT_SIZE_MASK)) & 0xFFFFFF) == first_trigram))
2055 {
2056 const mz_uint16 *p = (const mz_uint16 *)pCur_dict;
2057 const mz_uint16 *q = (const mz_uint16 *)(d->m_dict + probe_pos);
2058 mz_uint32 probe_len = 32;
2059 do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) &&
2060 (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0) );
2061 cur_match_len = ((mz_uint)(p - (const mz_uint16 *)pCur_dict) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q);
2062 if (!probe_len)
2063 cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0;
2064
2065 if ((cur_match_len < TDEFL_MIN_MATCH_LEN) || ((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U*1024U)))
2066 {
2067 cur_match_len = 1;
2068 *pLZ_code_buf++ = (mz_uint8)first_trigram;
2069 *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
2070 d->m_huff_count[0][(mz_uint8)first_trigram]++;
2071 }
2072 else
2073 {
2074 mz_uint32 s0, s1;
2075 cur_match_len = MZ_MIN(cur_match_len, lookahead_size);
2076
2077 MZ_ASSERT((cur_match_len >= TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 1) && (cur_match_dist <= TDEFL_LZ_DICT_SIZE));
2078
2079 cur_match_dist--;
2080
2081 pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN);
2082 *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist;
2083 pLZ_code_buf += 3;
2084 *pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80);
2085
2086 s0 = s_tdefl_small_dist_sym[cur_match_dist & 511];
2087 s1 = s_tdefl_large_dist_sym[cur_match_dist >> 8];
2088 d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++;
2089
2090 d->m_huff_count[0][s_tdefl_len_sym[cur_match_len - TDEFL_MIN_MATCH_LEN]]++;
2091 }
2092 }
2093 else
2094 {
2095 *pLZ_code_buf++ = (mz_uint8)first_trigram;
2096 *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
2097 d->m_huff_count[0][(mz_uint8)first_trigram]++;
2098 }
2099
2100 if (--num_flags_left == 0) { num_flags_left = 8; pLZ_flags = pLZ_code_buf++; }
2101
2102 total_lz_bytes += cur_match_len;
2103 lookahead_pos += cur_match_len;
2104 dict_size = MZ_MIN(dict_size + cur_match_len, TDEFL_LZ_DICT_SIZE);
2105 cur_pos = (cur_pos + cur_match_len) & TDEFL_LZ_DICT_SIZE_MASK;
2106 MZ_ASSERT(lookahead_size >= cur_match_len);
2107 lookahead_size -= cur_match_len;
2108
2109 if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8])
2110 {
2111 int n;
2112 d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size;
2113 d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left;
2114 if ((n = tdefl_flush_block(d, 0)) != 0)
2115 return (n < 0) ? MZ_FALSE : MZ_TRUE;
2116 total_lz_bytes = d->m_total_lz_bytes; pLZ_code_buf = d->m_pLZ_code_buf; pLZ_flags = d->m_pLZ_flags; num_flags_left = d->m_num_flags_left;
2117 }
2118 }
2119
2120 while (lookahead_size)
2121 {
2122 mz_uint8 lit = d->m_dict[cur_pos];
2123
2124 total_lz_bytes++;
2125 *pLZ_code_buf++ = lit;
2126 *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
2127 if (--num_flags_left == 0) { num_flags_left = 8; pLZ_flags = pLZ_code_buf++; }
2128
2129 d->m_huff_count[0][lit]++;
2130
2131 lookahead_pos++;
2132 dict_size = MZ_MIN(dict_size + 1, TDEFL_LZ_DICT_SIZE);
2133 cur_pos = (cur_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK;
2134 lookahead_size--;
2135
2136 if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8])
2137 {
2138 int n;
2139 d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size;
2140 d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left;
2141 if ((n = tdefl_flush_block(d, 0)) != 0)
2142 return (n < 0) ? MZ_FALSE : MZ_TRUE;
2143 total_lz_bytes = d->m_total_lz_bytes; pLZ_code_buf = d->m_pLZ_code_buf; pLZ_flags = d->m_pLZ_flags; num_flags_left = d->m_num_flags_left;
2144 }
2145 }
2146 }
2147
2148 d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size;
2149 d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left;
2150 return MZ_TRUE;
2151}
2152#endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
2153
2154static MZ_FORCEINLINE void tdefl_record_literal(tdefl_compressor *d, mz_uint8 lit)
2155{
2156 d->m_total_lz_bytes++;
2157 *d->m_pLZ_code_buf++ = lit;
2158 *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1); if (--d->m_num_flags_left == 0) { d->m_num_flags_left = 8; d->m_pLZ_flags = d->m_pLZ_code_buf++; }
2159 d->m_huff_count[0][lit]++;
2160}
2161
2162static MZ_FORCEINLINE void tdefl_record_match(tdefl_compressor *d, mz_uint match_len, mz_uint match_dist)
2163{
2164 mz_uint32 s0, s1;
2165
2166 MZ_ASSERT((match_len >= TDEFL_MIN_MATCH_LEN) && (match_dist >= 1) && (match_dist <= TDEFL_LZ_DICT_SIZE));
2167
2168 d->m_total_lz_bytes += match_len;
2169
2170 d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN);
2171
2172 match_dist -= 1;
2173 d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF);
2174 d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8); d->m_pLZ_code_buf += 3;
2175
2176 *d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80); if (--d->m_num_flags_left == 0) { d->m_num_flags_left = 8; d->m_pLZ_flags = d->m_pLZ_code_buf++; }
2177
2178 s0 = s_tdefl_small_dist_sym[match_dist & 511]; s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127];
2179 d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++;
2180
2181 if (match_len >= TDEFL_MIN_MATCH_LEN) d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++;
2182}
2183
2184static mz_bool tdefl_compress_normal(tdefl_compressor *d)
2185{
2186 const mz_uint8 *pSrc = d->m_pSrc; size_t src_buf_left = d->m_src_buf_left;
2187 tdefl_flush flush = d->m_flush;
2188
2189 while ((src_buf_left) || ((flush) && (d->m_lookahead_size)))
2190 {
2191 mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos;
2192 // Update dictionary and hash chains. Keeps the lookahead size equal to TDEFL_MAX_MATCH_LEN.
2193 if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1))
2194 {
2195 mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK, ins_pos = d->m_lookahead_pos + d->m_lookahead_size - 2;
2196 mz_uint hash = (d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK];
2197 mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size);
2198 const mz_uint8 *pSrc_end = pSrc + num_bytes_to_process;
2199 src_buf_left -= num_bytes_to_process;
2200 d->m_lookahead_size += num_bytes_to_process;
2201 while (pSrc != pSrc_end)
2202 {
2203 mz_uint8 c = *pSrc++; d->m_dict[dst_pos] = c; if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
2204 hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1);
2205 d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; d->m_hash[hash] = (mz_uint16)(ins_pos);
2206 dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; ins_pos++;
2207 }
2208 }
2209 else
2210 {
2211 while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
2212 {
2213 mz_uint8 c = *pSrc++;
2214 mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK;
2215 src_buf_left--;
2216 d->m_dict[dst_pos] = c;
2217 if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
2218 d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
2219 if ((++d->m_lookahead_size + d->m_dict_size) >= TDEFL_MIN_MATCH_LEN)
2220 {
2221 mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2;
2222 mz_uint hash = ((d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << (TDEFL_LZ_HASH_SHIFT * 2)) ^ (d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1);
2223 d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; d->m_hash[hash] = (mz_uint16)(ins_pos);
2224 }
2225 }
2226 }
2227 d->m_dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - d->m_lookahead_size, d->m_dict_size);
2228 if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
2229 break;
2230
2231 // Simple lazy/greedy parsing state machine.
2232 len_to_move = 1; cur_match_dist = 0; cur_match_len = d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1); cur_pos = d->m_lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
2233 if (d->m_flags & (TDEFL_RLE_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS))
2234 {
2235 if ((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS)))
2236 {
2237 mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK];
2238 cur_match_len = 0; while (cur_match_len < d->m_lookahead_size) { if (d->m_dict[cur_pos + cur_match_len] != c) break; cur_match_len++; }
2239 if (cur_match_len < TDEFL_MIN_MATCH_LEN) cur_match_len = 0; else cur_match_dist = 1;
2240 }
2241 }
2242 else
2243 {
2244 tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size, d->m_lookahead_size, &cur_match_dist, &cur_match_len);
2245 }
2246 if (((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U*1024U)) || (cur_pos == cur_match_dist) || ((d->m_flags & TDEFL_FILTER_MATCHES) && (cur_match_len <= 5)))
2247 {
2248 cur_match_dist = cur_match_len = 0;
2249 }
2250 if (d->m_saved_match_len)
2251 {
2252 if (cur_match_len > d->m_saved_match_len)
2253 {
2254 tdefl_record_literal(d, (mz_uint8)d->m_saved_lit);
2255 if (cur_match_len >= 128)
2256 {
2257 tdefl_record_match(d, cur_match_len, cur_match_dist);
2258 d->m_saved_match_len = 0; len_to_move = cur_match_len;
2259 }
2260 else
2261 {
2262 d->m_saved_lit = d->m_dict[cur_pos]; d->m_saved_match_dist = cur_match_dist; d->m_saved_match_len = cur_match_len;
2263 }
2264 }
2265 else
2266 {
2267 tdefl_record_match(d, d->m_saved_match_len, d->m_saved_match_dist);
2268 len_to_move = d->m_saved_match_len - 1; d->m_saved_match_len = 0;
2269 }
2270 }
2271 else if (!cur_match_dist)
2272 tdefl_record_literal(d, d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]);
2273 else if ((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) || (cur_match_len >= 128))
2274 {
2275 tdefl_record_match(d, cur_match_len, cur_match_dist);
2276 len_to_move = cur_match_len;
2277 }
2278 else
2279 {
2280 d->m_saved_lit = d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]; d->m_saved_match_dist = cur_match_dist; d->m_saved_match_len = cur_match_len;
2281 }
2282 // Move the lookahead forward by len_to_move bytes.
2283 d->m_lookahead_pos += len_to_move;
2284 MZ_ASSERT(d->m_lookahead_size >= len_to_move);
2285 d->m_lookahead_size -= len_to_move;
2286 d->m_dict_size = MZ_MIN(d->m_dict_size + len_to_move, TDEFL_LZ_DICT_SIZE);
2287 // Check if it's time to flush the current LZ codes to the internal output buffer.
2288 if ( (d->m_pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) ||
2289 ( (d->m_total_lz_bytes > 31*1024) && (((((mz_uint)(d->m_pLZ_code_buf - d->m_lz_code_buf) * 115) >> 7) >= d->m_total_lz_bytes) || (d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))) )
2290 {
2291 int n;
2292 d->m_pSrc = pSrc; d->m_src_buf_left = src_buf_left;
2293 if ((n = tdefl_flush_block(d, 0)) != 0)
2294 return (n < 0) ? MZ_FALSE : MZ_TRUE;
2295 }
2296 }
2297
2298 d->m_pSrc = pSrc; d->m_src_buf_left = src_buf_left;
2299 return MZ_TRUE;
2300}
2301
2302static tdefl_status tdefl_flush_output_buffer(tdefl_compressor *d)
2303{
2304 if (d->m_pIn_buf_size)
2305 {
2306 *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf;
2307 }
2308
2309 if (d->m_pOut_buf_size)
2310 {
2311 size_t n = MZ_MIN(*d->m_pOut_buf_size - d->m_out_buf_ofs, d->m_output_flush_remaining);
2312 memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf + d->m_output_flush_ofs, n);
2313 d->m_output_flush_ofs += (mz_uint)n;
2314 d->m_output_flush_remaining -= (mz_uint)n;
2315 d->m_out_buf_ofs += n;
2316
2317 *d->m_pOut_buf_size = d->m_out_buf_ofs;
2318 }
2319
2320 return (d->m_finished && !d->m_output_flush_remaining) ? TDEFL_STATUS_DONE : TDEFL_STATUS_OKAY;
2321}
2322
2323tdefl_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)
2324{
2325 if (!d)
2326 {
2327 if (pIn_buf_size) *pIn_buf_size = 0;
2328 if (pOut_buf_size) *pOut_buf_size = 0;
2329 return TDEFL_STATUS_BAD_PARAM;
2330 }
2331
2332 d->m_pIn_buf = pIn_buf; d->m_pIn_buf_size = pIn_buf_size;
2333 d->m_pOut_buf = pOut_buf; d->m_pOut_buf_size = pOut_buf_size;
2334 d->m_pSrc = (const mz_uint8 *)(pIn_buf); d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0;
2335 d->m_out_buf_ofs = 0;
2336 d->m_flush = flush;
2337
2338 if ( ((d->m_pPut_buf_func != NULL) == ((pOut_buf != NULL) || (pOut_buf_size != NULL))) || (d->m_prev_return_status != TDEFL_STATUS_OKAY) ||
2339 (d->m_wants_to_finish && (flush != TDEFL_FINISH)) || (pIn_buf_size && *pIn_buf_size && !pIn_buf) || (pOut_buf_size && *pOut_buf_size && !pOut_buf) )
2340 {
2341 if (pIn_buf_size) *pIn_buf_size = 0;
2342 if (pOut_buf_size) *pOut_buf_size = 0;
2343 return (d->m_prev_return_status = TDEFL_STATUS_BAD_PARAM);
2344 }
2345 d->m_wants_to_finish |= (flush == TDEFL_FINISH);
2346
2347 if ((d->m_output_flush_remaining) || (d->m_finished))
2348 return (d->m_prev_return_status = tdefl_flush_output_buffer(d));
2349
2350#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
2351 if (((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) &&
2352 ((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) &&
2353 ((d->m_flags & (TDEFL_FILTER_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS | TDEFL_RLE_MATCHES)) == 0))
2354 {
2355 if (!tdefl_compress_fast(d))
2356 return d->m_prev_return_status;
2357 }
2358 else
2359#endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
2360 {
2361 if (!tdefl_compress_normal(d))
2362 return d->m_prev_return_status;
2363 }
2364
2365 if ((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) && (pIn_buf))
2366 d->m_adler32 = (mz_uint32)mz_adler32(d->m_adler32, (const mz_uint8 *)pIn_buf, d->m_pSrc - (const mz_uint8 *)pIn_buf);
2367
2368 if ((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) && (!d->m_output_flush_remaining))
2369 {
2370 if (tdefl_flush_block(d, flush) < 0)
2371 return d->m_prev_return_status;
2372 d->m_finished = (flush == TDEFL_FINISH);
2373 if (flush == TDEFL_FULL_FLUSH) { MZ_CLEAR_OBJ(d->m_hash); MZ_CLEAR_OBJ(d->m_next); d->m_dict_size = 0; }
2374 }
2375
2376 return (d->m_prev_return_status = tdefl_flush_output_buffer(d));
2377}
2378
2379tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush)
2380{
2381 MZ_ASSERT(d->m_pPut_buf_func); return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush);
2382}
2383
2384tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
2385{
2386 d->m_pPut_buf_func = pPut_buf_func; d->m_pPut_buf_user = pPut_buf_user;
2387 d->m_flags = (mz_uint)(flags); d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3; d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0;
2388 d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3;
2389 if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG)) MZ_CLEAR_OBJ(d->m_hash);
2390 d->m_lookahead_pos = d->m_lookahead_size = d->m_dict_size = d->m_total_lz_bytes = d->m_lz_code_buf_dict_pos = d->m_bits_in = 0;
2391 d->m_output_flush_ofs = d->m_output_flush_remaining = d->m_finished = d->m_block_index = d->m_bit_buffer = d->m_wants_to_finish = 0;
2392 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;
2393 d->m_pOutput_buf = d->m_output_buf; d->m_pOutput_buf_end = d->m_output_buf; d->m_prev_return_status = TDEFL_STATUS_OKAY;
2394 d->m_saved_match_dist = d->m_saved_match_len = d->m_saved_lit = 0; d->m_adler32 = 1;
2395 d->m_pIn_buf = NULL; d->m_pOut_buf = NULL;
2396 d->m_pIn_buf_size = NULL; d->m_pOut_buf_size = NULL;
2397 d->m_flush = TDEFL_NO_FLUSH; d->m_pSrc = NULL; d->m_src_buf_left = 0; d->m_out_buf_ofs = 0;
2398 memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
2399 memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
2400 return TDEFL_STATUS_OKAY;
2401}
2402
2403tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d)
2404{
2405 return d->m_prev_return_status;
2406}
2407
2408mz_uint32 tdefl_get_adler32(tdefl_compressor *d)
2409{
2410 return d->m_adler32;
2411}
2412
2413mz_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)
2414{
2415 tdefl_compressor *pComp; mz_bool succeeded; if (((buf_len) && (!pBuf)) || (!pPut_buf_func)) return MZ_FALSE;
2416 pComp = (tdefl_compressor*)MZ_MALLOC(sizeof(tdefl_compressor)); if (!pComp) return MZ_FALSE;
2417 succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags) == TDEFL_STATUS_OKAY);
2418 succeeded = succeeded && (tdefl_compress_buffer(pComp, pBuf, buf_len, TDEFL_FINISH) == TDEFL_STATUS_DONE);
2419 MZ_FREE(pComp); return succeeded;
2420}
2421
2422typedef struct
2423{
2424 size_t m_size, m_capacity;
2425 mz_uint8 *m_pBuf;
2426 mz_bool m_expandable;
2427} tdefl_output_buffer;
2428
2429static mz_bool tdefl_output_buffer_putter(const void *pBuf, int len, void *pUser)
2430{
2431 tdefl_output_buffer *p = (tdefl_output_buffer *)pUser;
2432 size_t new_size = p->m_size + len;
2433 if (new_size > p->m_capacity)
2434 {
2435 size_t new_capacity = p->m_capacity; mz_uint8 *pNew_buf; if (!p->m_expandable) return MZ_FALSE;
2436 do { new_capacity = MZ_MAX(128U, new_capacity << 1U); } while (new_size > new_capacity);
2437 pNew_buf = (mz_uint8*)MZ_REALLOC(p->m_pBuf, new_capacity); if (!pNew_buf) return MZ_FALSE;
2438 p->m_pBuf = pNew_buf; p->m_capacity = new_capacity;
2439 }
2440 memcpy((mz_uint8*)p->m_pBuf + p->m_size, pBuf, len); p->m_size = new_size;
2441 return MZ_TRUE;
2442}
2443
2444void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
2445{
2446 tdefl_output_buffer out_buf; MZ_CLEAR_OBJ(out_buf);
2447 if (!pOut_len) return MZ_FALSE; else *pOut_len = 0;
2448 out_buf.m_expandable = MZ_TRUE;
2449 if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) return NULL;
2450 *pOut_len = out_buf.m_size; return out_buf.m_pBuf;
2451}
2452
2453size_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)
2454{
2455 tdefl_output_buffer out_buf; MZ_CLEAR_OBJ(out_buf);
2456 if (!pOut_buf) return 0;
2457 out_buf.m_pBuf = (mz_uint8*)pOut_buf; out_buf.m_capacity = out_buf_len;
2458 if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) return 0;
2459 return out_buf.m_size;
2460}
2461
2462#ifndef MINIZ_NO_ZLIB_APIS
2463static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
2464
2465// level may actually range from [0,10] (10 is a "hidden" max level, where we want a bit more compression and it's fine if throughput to fall off a cliff on some files).
2466mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy)
2467{
2468 mz_uint comp_flags = s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0);
2469 if (window_bits > 0) comp_flags |= TDEFL_WRITE_ZLIB_HEADER;
2470
2471 if (!level) comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS;
2472 else if (strategy == MZ_FILTERED) comp_flags |= TDEFL_FILTER_MATCHES;
2473 else if (strategy == MZ_HUFFMAN_ONLY) comp_flags &= ~TDEFL_MAX_PROBES_MASK;
2474 else if (strategy == MZ_FIXED) comp_flags |= TDEFL_FORCE_ALL_STATIC_BLOCKS;
2475 else if (strategy == MZ_RLE) comp_flags |= TDEFL_RLE_MATCHES;
2476
2477 return comp_flags;
2478}
2479#endif //MINIZ_NO_ZLIB_APIS
2480
2481#ifdef _MSC_VER
2482#pragma warning (push)
2483#pragma warning (disable:4204) // nonstandard extension used : non-constant aggregate initializer (also supported by GNU C and C99, so no big deal)
2484#endif
2485
2486// Simple PNG writer function by Alex Evans, 2011. Released into the public domain: https://gist.github.com/908299, more context at
2487// http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/.
2488// This is actually a modification of Alex's original code so PNG files generated by this function pass pngcheck.
2489void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip)
2490{
2491 // Using a local copy of this array here in case MINIZ_NO_ZLIB_APIS was defined.
2492 static const mz_uint s_tdefl_png_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
2493 tdefl_compressor *pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); tdefl_output_buffer out_buf; int i, bpl = w * num_chans, y, z; mz_uint32 c; *pLen_out = 0;
2494 if (!pComp) return NULL;
2495 MZ_CLEAR_OBJ(out_buf); out_buf.m_expandable = MZ_TRUE; out_buf.m_capacity = 57+MZ_MAX(64, (1+bpl)*h); if (NULL == (out_buf.m_pBuf = (mz_uint8*)MZ_MALLOC(out_buf.m_capacity))) { MZ_FREE(pComp); return NULL; }
2496 // write dummy header
2497 for (z = 41; z; --z) tdefl_output_buffer_putter(&z, 1, &out_buf);
2498 // compress image data
2499 tdefl_init(pComp, tdefl_output_buffer_putter, &out_buf, s_tdefl_png_num_probes[MZ_MIN(10, level)] | TDEFL_WRITE_ZLIB_HEADER | (level <= 3 ? TDEFL_GREEDY_PARSING_FLAG : 0));
2500 for (y = 0; y < h; ++y) { tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH); tdefl_compress_buffer(pComp, (mz_uint8*)pImage + (flip ? (h - 1 - y) : y) * bpl, bpl, TDEFL_NO_FLUSH); }
2501 if (tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) != TDEFL_STATUS_DONE) { MZ_FREE(pComp); MZ_FREE(out_buf.m_pBuf); return NULL; }
2502 // write real header
2503 *pLen_out = out_buf.m_size-41;
2504 {
2505 static const mz_uint8 chans[] = {0x00, 0x00, 0x04, 0x02, 0x06};
2506 mz_uint8 pnghdr[41]={0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
2507 0,0,(mz_uint8)(w>>8),(mz_uint8)w,0,0,(mz_uint8)(h>>8),(mz_uint8)h,8,chans[num_chans],0,0,0,0,0,0,0,
2508 (mz_uint8)(*pLen_out>>24),(mz_uint8)(*pLen_out>>16),(mz_uint8)(*pLen_out>>8),(mz_uint8)*pLen_out,0x49,0x44,0x41,0x54};
2509 c=(mz_uint32)mz_crc32(MZ_CRC32_INIT,pnghdr+12,17); for (i=0; i<4; ++i, c<<=8) ((mz_uint8*)(pnghdr+29))[i]=(mz_uint8)(c>>24);
2510 memcpy(out_buf.m_pBuf, pnghdr, 41);
2511 }
2512 // write footer (IDAT CRC-32, followed by IEND chunk)
2513 if (!tdefl_output_buffer_putter("\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf)) { *pLen_out = 0; MZ_FREE(pComp); MZ_FREE(out_buf.m_pBuf); return NULL; }
2514 c = (mz_uint32)mz_crc32(MZ_CRC32_INIT,out_buf.m_pBuf+41-4, *pLen_out+4); for (i=0; i<4; ++i, c<<=8) (out_buf.m_pBuf+out_buf.m_size-16)[i] = (mz_uint8)(c >> 24);
2515 // compute final size of file, grab compressed data buffer and return
2516 *pLen_out += 57; MZ_FREE(pComp); return out_buf.m_pBuf;
2517}
2518void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out)
2519{
2520 // Level 6 corresponds to TDEFL_DEFAULT_MAX_PROBES or MZ_DEFAULT_LEVEL (but we can't depend on MZ_DEFAULT_LEVEL being available in case the zlib API's where #defined out)
2521 return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans, pLen_out, 6, MZ_FALSE);
2522}
2523
2524#ifdef _MSC_VER
2525#pragma warning (pop)
2526#endif
2527
2528} // namespace buminiz
2529
2530#endif // MINIZ_HEADER_FILE_ONLY
2531
2532