1 /* miniz.c v1.12 - public domain deflate/inflate
2 See "unlicense" statement at the end of this file.
3 Rich Geldreich <richgel99@gmail.com>, last updated April 12, 2012
4 Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
7 4/12/12 v1.12 - More comments, added low-level example5.c, fixed a couple minor level_and_flags issues in the archive API's.
8 level_and_flags can now be set to MZ_DEFAULT_COMPRESSION. Thanks to Bruce Dawson <bruced@valvesoftware.com> for the feedback/bug report.
9 5/28/11 v1.11 - Added statement from unlicense.org
10 5/27/11 v1.10 - Substantial compressor optimizations:
11 Level 1 is now ~4x faster than before. The L1 compressor's throughput now varies between 70-110MB/sec. on a
12 Core i7 (actual throughput varies depending on the type of data, and x64 vs. x86).
13 Improved baseline L2-L9 compression perf. Also, greatly improved compression perf. issues on some file types.
14 Refactored the compression code for better readability and maintainability.
15 Added level 10 compression level (L10 has slightly better ratio than level 9, but could have a potentially large
16 drop in throughput on some files).
17 5/15/11 v1.09 - Initial stable release.
19 * Low-level Deflate/Inflate implementation notes:
21 Compression: Use the "tdefl" API's. The compressor supports raw, static, and dynamic blocks, lazy or
22 greedy parsing, match length filtering, RLE-only, and Huffman-only streams. It performs and compresses
23 approximately as well as zlib.
25 Decompression: Use the "tinfl" API's. The entire decompressor is implemented as a single function
26 coroutine: see tinfl_decompress(). It supports decompression into a 32KB (or larger power of 2) wrapping buffer, or into a memory
27 block large enough to hold the entire file.
29 The low-level tdefl/tinfl API's do not make any use of dynamic memory allocation.
31 * zlib-style API notes:
33 miniz.c implements a fairly large subset of zlib. There's enough functionality present for it to be a drop-in
34 zlib replacement in many apps:
35 The z_stream struct, optional memory allocation callbacks
36 deflateInit/deflateInit2/deflate/deflateReset/deflateEnd/deflateBound
37 inflateInit/inflateInit2/inflate/inflateEnd
38 compress, compress2, compressBound, uncompress
39 CRC-32, Adler-32 - Using modern, minimal code size, CPU cache friendly routines.
40 Supports raw deflate streams or standard zlib streams with adler-32 checking.
43 The callback API's are not implemented yet. No support for gzip headers or zlib static dictionaries.
44 I've tried to closely emulate zlib's various flavors of stream flushing and return status codes, but
45 there are no guarantees that miniz.c pulls this off perfectly.
47 * PNG writing: See the tdefl_write_image_to_png_file_in_memory() function, originally written by
48 Alex Evans. Supports 1-4 bytes/pixel images.
50 * This is a header file library, like stb_image.c. To get only a header file, either cut and paste the
51 below header, or create miniz.h, #define MINIZ_HEADER_FILE_ONLY, and then include miniz.c from it.
53 * Important: For best perf. be sure to customize the below macros for your target platform:
54 #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0
55 #define MINIZ_LITTLE_ENDIAN 1
56 #define MINIZ_HAS_64BIT_REGISTERS 1
59 #ifndef MINIZ_HEADER_INCLUDED
60 #define MINIZ_HEADER_INCLUDED
62 #include <grub/types.h>
63 #include <grub/misc.h>
67 #include <grub/disk.h>
68 #include <grub/device.h>
69 #include <grub/term.h>
70 #include <grub/partition.h>
71 #include <grub/file.h>
72 #include <grub/normal.h>
73 #include <grub/extcmd.h>
74 #include <grub/datetime.h>
75 #include <grub/i18n.h>
77 #include <grub/misc.h>
78 #include <grub/kernel.h>
79 #include <grub/time.h>
80 #include <grub/video.h>
81 #include <grub/acpi.h>
82 #include <grub/charset.h>
83 #include <grub/crypto.h>
85 #pragma GCC diagnostic push
86 #pragma GCC diagnostic ignored "-Wundef"
88 #define size_t grub_size_t
89 #define uint8_t grub_uint8_t
90 #define uint16_t grub_uint16_t
91 #define uint32_t grub_uint32_t
92 #define uint64_t grub_uint64_t
96 #define memset grub_memset
97 #define memcpy grub_memcpy
98 #define memcmp grub_memcmp
100 // Defines to completely disable specific portions of miniz.c:
101 // If all macros here are defined the only functionality remaining will be CRC-32, adler-32, tinfl, and tdefl.
103 // Define MINIZ_NO_ZLIB_APIS to remove all ZLIB-style compression/decompression API's.
104 //#define MINIZ_NO_ZLIB_APIS
106 // Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent conflicts against stock zlib.
107 //#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES
109 // Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc.
110 // Note if MINIZ_NO_MALLOC is defined then the user must always provide custom user alloc/free/realloc
111 // callbacks to the zlib and archive API's, and a few stand-alone helper API's which don't provide custom user
112 // functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work.
113 //#define MINIZ_NO_MALLOC
115 #if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__)
116 // MINIZ_X86_OR_X64_CPU is only used to help set the below macros.
117 #define MINIZ_X86_OR_X64_CPU 1
120 #if (__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU
121 // Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian.
122 #define MINIZ_LITTLE_ENDIAN 1
124 #error ("Not little endian")
127 #if MINIZ_X86_OR_X64_CPU
128 // Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient integer loads and stores from unaligned addresses.
129 #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
132 #define MINIZ_HAS_64BIT_REGISTERS 1
134 // ------------------- zlib-style API Definitions.
136 // For more compatibility with zlib, miniz.c uses unsigned long for some parameters/struct members.
137 typedef unsigned long mz_ulong
;
139 // Heap allocation callbacks.
140 // Note that mz_alloc_func parameter types purpsosely differ from zlib's: items/size is size_t, not unsigned long.
141 typedef void *(*mz_alloc_func
)(void *opaque
, size_t items
, size_t size
);
142 typedef void (*mz_free_func
)(void *opaque
, void *address
);
143 typedef void *(*mz_realloc_func
)(void *opaque
, void *address
, size_t items
, size_t size
);
145 #define MZ_ADLER32_INIT (1)
146 // mz_adler32() returns the initial adler-32 value to use when called with ptr==NULL.
147 mz_ulong
mz_adler32(mz_ulong adler
, const unsigned char *ptr
, size_t buf_len
);
149 #define MZ_CRC32_INIT (0)
150 // mz_crc32() returns the initial CRC-32 value to use when called with ptr==NULL.
151 mz_ulong
mz_crc32(mz_ulong crc
, const unsigned char *ptr
, size_t buf_len
);
153 // Compression strategies.
154 enum { MZ_DEFAULT_STRATEGY
= 0, MZ_FILTERED
= 1, MZ_HUFFMAN_ONLY
= 2, MZ_RLE
= 3, MZ_FIXED
= 4 };
157 #define MZ_DEFLATED 8
159 #ifndef MINIZ_NO_ZLIB_APIS
161 #define MZ_VERSION "9.1.12"
162 #define MZ_VERNUM 0x91C0
163 #define MZ_VER_MAJOR 9
164 #define MZ_VER_MINOR 1
165 #define MZ_VER_REVISION 12
166 #define MZ_VER_SUBREVISION 0
168 // 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).
169 enum { MZ_NO_FLUSH
= 0, MZ_PARTIAL_FLUSH
= 1, MZ_SYNC_FLUSH
= 2, MZ_FULL_FLUSH
= 3, MZ_FINISH
= 4, MZ_BLOCK
= 5 };
171 // Return status codes. MZ_PARAM_ERROR is non-standard.
172 enum { MZ_OK
= 0, MZ_STREAM_END
= 1, MZ_NEED_DICT
= 2, MZ_ERRNO
= -1, MZ_STREAM_ERROR
= -2, MZ_DATA_ERROR
= -3, MZ_MEM_ERROR
= -4, MZ_BUF_ERROR
= -5, MZ_VERSION_ERROR
= -6, MZ_PARAM_ERROR
= -10000 };
174 // 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.
175 enum { MZ_NO_COMPRESSION
= 0, MZ_BEST_SPEED
= 1, MZ_BEST_COMPRESSION
= 9, MZ_UBER_COMPRESSION
= 10, MZ_DEFAULT_LEVEL
= 6, MZ_DEFAULT_COMPRESSION
= -1 };
178 #define MZ_DEFAULT_WINDOW_BITS 15
180 struct mz_internal_state
;
182 // Compression/decompression stream struct.
183 typedef struct mz_stream_s
185 const unsigned char *next_in
; // pointer to next byte to read
186 unsigned int avail_in
; // number of bytes available at next_in
187 mz_ulong total_in
; // total number of bytes consumed so far
189 unsigned char *next_out
; // pointer to next byte to write
190 unsigned int avail_out
; // number of bytes that can be written to next_out
191 mz_ulong total_out
; // total number of bytes produced so far
193 char *msg
; // error msg (unused)
194 struct mz_internal_state
*state
; // internal state, allocated by zalloc/zfree
196 mz_alloc_func zalloc
; // optional heap allocation function (defaults to malloc)
197 mz_free_func zfree
; // optional heap free function (defaults to free)
198 void *opaque
; // heap alloc function user pointer
200 int data_type
; // data_type (unused)
201 mz_ulong adler
; // adler32 of the source or uncompressed data
202 mz_ulong crc32
; // crc32 of the source or uncompressed data
206 typedef mz_stream
*mz_streamp
;
208 // Returns the version string of miniz.c.
209 const char *mz_version(void);
211 // mz_deflateInit() initializes a compressor with default options:
213 // pStream must point to an initialized mz_stream struct.
214 // level must be between [MZ_NO_COMPRESSION, MZ_BEST_COMPRESSION].
215 // level 1 enables a specially optimized compression function that's been optimized purely for performance, not ratio.
216 // (This special func. is currently only enabled when MINIZ_USE_UNALIGNED_LOADS_AND_STORES and MINIZ_LITTLE_ENDIAN are defined.)
219 // MZ_STREAM_ERROR if the stream is bogus.
220 // MZ_PARAM_ERROR if the input parameters are bogus.
221 // MZ_MEM_ERROR on out of memory.
222 int mz_deflateInit(mz_streamp pStream
, int level
);
224 // mz_deflateInit2() is like mz_deflate(), except with more control:
225 // Additional parameters:
226 // method must be MZ_DEFLATED
227 // 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)
228 // mem_level must be between [1, 9] (it's checked but ignored by miniz.c)
229 int mz_deflateInit2(mz_streamp pStream
, int level
, int method
, int window_bits
, int mem_level
, int strategy
);
231 // Quickly resets a compressor without having to reallocate anything. Same as calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2().
232 int mz_deflateReset(mz_streamp pStream
);
234 // mz_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible.
236 // 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.
237 // flush may be MZ_NO_FLUSH, MZ_PARTIAL_FLUSH/MZ_SYNC_FLUSH, MZ_FULL_FLUSH, or MZ_FINISH.
239 // 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).
240 // 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.
241 // MZ_STREAM_ERROR if the stream is bogus.
242 // MZ_PARAM_ERROR if one of the parameters is invalid.
243 // 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.)
244 int mz_deflate(mz_streamp pStream
, int flush
);
246 // mz_deflateEnd() deinitializes a compressor:
249 // MZ_STREAM_ERROR if the stream is bogus.
250 int mz_deflateEnd(mz_streamp pStream
);
252 // 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.
253 mz_ulong
mz_deflateBound(mz_streamp pStream
, mz_ulong source_len
);
255 // Single-call compression functions mz_compress() and mz_compress2():
256 // Returns MZ_OK on success, or one of the error codes from mz_deflate() on failure.
257 int mz_compress(unsigned char *pDest
, mz_ulong
*pDest_len
, const unsigned char *pSource
, mz_ulong source_len
);
258 int mz_compress2(unsigned char *pDest
, mz_ulong
*pDest_len
, const unsigned char *pSource
, mz_ulong source_len
, int level
);
260 // mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress().
261 mz_ulong
mz_compressBound(mz_ulong source_len
);
263 // Initializes a decompressor.
264 int mz_inflateInit(mz_streamp pStream
);
266 // 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:
267 // window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate).
268 int mz_inflateInit2(mz_streamp pStream
, int window_bits
);
270 // 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.
272 // 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.
273 // flush may be MZ_NO_FLUSH, MZ_SYNC_FLUSH, or MZ_FINISH.
274 // 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).
275 // 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.
277 // 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.
278 // 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.
279 // MZ_STREAM_ERROR if the stream is bogus.
280 // MZ_DATA_ERROR if the deflate stream is invalid.
281 // MZ_PARAM_ERROR if one of the parameters is invalid.
282 // 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
283 // with more input data, or with more room in the output buffer (except when using single call decompression, described above).
284 int mz_inflate(mz_streamp pStream
, int flush
);
286 // Deinitializes a decompressor.
287 int mz_inflateEnd(mz_streamp pStream
);
289 // Single-call decompression.
290 // Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure.
291 int mz_uncompress(unsigned char *pDest
, mz_ulong
*pDest_len
, const unsigned char *pSource
, mz_ulong source_len
);
293 // Returns a string description of the specified error code, or NULL if the error code is invalid.
294 const char *mz_error(int err
);
296 // 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.
297 // Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project.
298 #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
299 typedef unsigned char Byte
;
300 typedef unsigned int uInt
;
301 typedef mz_ulong uLong
;
306 typedef void *voidpf
;
307 typedef uLong uLongf
;
309 typedef void *const voidpc
;
311 #define Z_NO_FLUSH MZ_NO_FLUSH
312 #define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH
313 #define Z_SYNC_FLUSH MZ_SYNC_FLUSH
314 #define Z_FULL_FLUSH MZ_FULL_FLUSH
315 #define Z_FINISH MZ_FINISH
316 #define Z_BLOCK MZ_BLOCK
318 #define Z_STREAM_END MZ_STREAM_END
319 #define Z_NEED_DICT MZ_NEED_DICT
320 #define Z_ERRNO MZ_ERRNO
321 #define Z_STREAM_ERROR MZ_STREAM_ERROR
322 #define Z_DATA_ERROR MZ_DATA_ERROR
323 #define Z_MEM_ERROR MZ_MEM_ERROR
324 #define Z_BUF_ERROR MZ_BUF_ERROR
325 #define Z_VERSION_ERROR MZ_VERSION_ERROR
326 #define Z_PARAM_ERROR MZ_PARAM_ERROR
327 #define Z_NO_COMPRESSION MZ_NO_COMPRESSION
328 #define Z_BEST_SPEED MZ_BEST_SPEED
329 #define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION
330 #define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION
331 #define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY
332 #define Z_FILTERED MZ_FILTERED
333 #define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY
335 #define Z_FIXED MZ_FIXED
336 #define Z_DEFLATED MZ_DEFLATED
337 #define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS
338 #define alloc_func mz_alloc_func
339 #define free_func mz_free_func
340 #define internal_state mz_internal_state
341 #define z_stream mz_stream
342 #define deflateInit mz_deflateInit
343 #define deflateInit2 mz_deflateInit2
344 #define deflateReset mz_deflateReset
345 #define deflate mz_deflate
346 #define deflateEnd mz_deflateEnd
347 #define deflateBound mz_deflateBound
348 #define compress mz_compress
349 #define compress2 mz_compress2
350 #define compressBound mz_compressBound
351 #define inflateInit mz_inflateInit
352 #define inflateInit2 mz_inflateInit2
353 #define inflate mz_inflate
354 #define inflateEnd mz_inflateEnd
355 #define uncompress mz_uncompress
356 #define z_crc32 mz_crc32
357 #define z_adler32 mz_adler32
359 #define MAX_MEM_LEVEL 9
360 #define zError mz_error
361 #define ZLIB_VERSION MZ_VERSION
362 #define ZLIB_VERNUM MZ_VERNUM
363 #define ZLIB_VER_MAJOR MZ_VER_MAJOR
364 #define ZLIB_VER_MINOR MZ_VER_MINOR
365 #define ZLIB_VER_REVISION MZ_VER_REVISION
366 #define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION
367 #define zlibVersion mz_version
368 #define zlib_version mz_version()
369 #endif // #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
371 #endif // MINIZ_NO_ZLIB_APIS
373 // ------------------- Types and macros
375 typedef unsigned char mz_uint8
;
376 typedef signed short mz_int16
;
377 typedef unsigned short mz_uint16
;
378 typedef unsigned int mz_uint32
;
379 typedef unsigned int mz_uint
;
380 typedef long long mz_int64
;
381 typedef unsigned long long mz_uint64
;
388 #define MZ_MACRO_END while (0)
390 // Works around MSVC's spammy "warning C4127: conditional expression is constant" message.
391 #define MZ_MACRO_END while (0, 0)
394 // ------------------- Low-level Decompression API Definitions
396 // Decompression flags used by tinfl_decompress().
397 // 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.
398 // 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.
399 // 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).
400 // TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the decompressed bytes.
403 TINFL_FLAG_PARSE_ZLIB_HEADER
= 1,
404 TINFL_FLAG_HAS_MORE_INPUT
= 2,
405 TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF
= 4,
406 TINFL_FLAG_COMPUTE_ADLER32
= 8
409 // High level decompression functions:
410 // tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block allocated via malloc().
412 // pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data to decompress.
414 // Function returns a pointer to the decompressed data, or NULL on failure.
415 // *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data.
416 // The caller must free() the returned block when it's no longer needed.
417 void *tinfl_decompress_mem_to_heap(const void *pSrc_buf
, size_t src_buf_len
, size_t *pOut_len
, int flags
);
419 // tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory.
420 // Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success.
421 #define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1))
422 size_t tinfl_decompress_mem_to_mem(void *pOut_buf
, size_t out_buf_len
, const void *pSrc_buf
, size_t src_buf_len
, int flags
);
424 // 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.
425 // Returns 1 on success or 0 on failure.
426 typedef int (*tinfl_put_buf_func_ptr
)(const void* pBuf
, int len
, void *pUser
);
427 int tinfl_decompress_mem_to_callback(const void *pIn_buf
, size_t *pIn_buf_size
, tinfl_put_buf_func_ptr pPut_buf_func
, void *pPut_buf_user
, int flags
);
429 struct tinfl_decompressor_tag
; typedef struct tinfl_decompressor_tag tinfl_decompressor
;
431 // Max size of LZ dictionary.
432 #define TINFL_LZ_DICT_SIZE 32768
437 TINFL_STATUS_BAD_PARAM
= -3,
438 TINFL_STATUS_ADLER32_MISMATCH
= -2,
439 TINFL_STATUS_FAILED
= -1,
440 TINFL_STATUS_DONE
= 0,
441 TINFL_STATUS_NEEDS_MORE_INPUT
= 1,
442 TINFL_STATUS_HAS_MORE_OUTPUT
= 2
445 // Initializes the decompressor to its initial state.
446 #define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END
447 #define tinfl_get_adler32(r) (r)->m_check_adler32
448 #define tinfl_get_crc32(r) (r)->m_check_crc32
450 // 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.
451 // 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.
452 tinfl_status
tinfl_decompress(tinfl_decompressor
*r
, const mz_uint8
*pIn_buf_next
, size_t *pIn_buf_size
, mz_uint8
*pOut_buf_start
, mz_uint8
*pOut_buf_next
, size_t *pOut_buf_size
, const mz_uint32 decomp_flags
);
454 // Internal/private bits follow.
457 TINFL_MAX_HUFF_TABLES
= 3, TINFL_MAX_HUFF_SYMBOLS_0
= 288, TINFL_MAX_HUFF_SYMBOLS_1
= 32, TINFL_MAX_HUFF_SYMBOLS_2
= 19,
458 TINFL_FAST_LOOKUP_BITS
= 10, TINFL_FAST_LOOKUP_SIZE
= 1 << TINFL_FAST_LOOKUP_BITS
463 mz_uint8 m_code_size
[TINFL_MAX_HUFF_SYMBOLS_0
];
464 mz_int16 m_look_up
[TINFL_FAST_LOOKUP_SIZE
], m_tree
[TINFL_MAX_HUFF_SYMBOLS_0
* 2];
467 #if MINIZ_HAS_64BIT_REGISTERS
468 #define TINFL_USE_64BIT_BITBUF 1
471 #if TINFL_USE_64BIT_BITBUF
472 typedef mz_uint64 tinfl_bit_buf_t
;
473 #define TINFL_BITBUF_SIZE (64)
475 typedef mz_uint32 tinfl_bit_buf_t
;
476 #define TINFL_BITBUF_SIZE (32)
479 struct tinfl_decompressor_tag
481 mz_uint32 m_state
, m_num_bits
, m_zhdr0
, m_zhdr1
, m_z_adler32
, m_z_crc32
, m_final
, m_type
, m_check_adler32
, m_check_crc32
, m_dist
, m_counter
, m_num_extra
, m_table_sizes
[TINFL_MAX_HUFF_TABLES
];
482 tinfl_bit_buf_t m_bit_buf
;
483 size_t m_dist_from_out_buf_start
;
484 tinfl_huff_table m_tables
[TINFL_MAX_HUFF_TABLES
];
485 mz_uint8 m_raw_header
[4], m_len_codes
[TINFL_MAX_HUFF_SYMBOLS_0
+ TINFL_MAX_HUFF_SYMBOLS_1
+ 137];
488 // ------------------- Low-level Compression API Definitions
490 // Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly slower, and raw/dynamic blocks will be output more frequently).
491 #define TDEFL_LESS_MEMORY 0
493 // tdefl_init() compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search):
494 // 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).
497 TDEFL_HUFFMAN_ONLY
= 0, TDEFL_DEFAULT_MAX_PROBES
= 128, TDEFL_MAX_PROBES_MASK
= 0xFFF
500 // 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.
501 // TDEFL_COMPUTE_ADLER32: Always compute the adler-32 of the input data (even when not writing zlib headers).
502 // TDEFL_COMPUTE_CRC32: Always compute the crc-32 of the input data.
503 // TDEFL_GREEDY_PARSING_FLAG: Set to use faster greedy parsing, instead of more efficient lazy parsing.
504 // 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).
505 // TDEFL_RLE_MATCHES: Only look for RLE matches (matches with a distance of 1)
506 // TDEFL_FILTER_MATCHES: Discards matches <= 5 chars if enabled.
507 // TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables.
508 // TDEFL_FORCE_ALL_RAW_BLOCKS: Only use raw (uncompressed) deflate blocks.
511 TDEFL_WRITE_ZLIB_HEADER
= 0x001000,
512 TDEFL_COMPUTE_ADLER32
= 0x002000,
513 TDEFL_COMPUTE_CRC32
= 0x004000,
514 TDEFL_GREEDY_PARSING_FLAG
= 0x008000,
515 TDEFL_NONDETERMINISTIC_PARSING_FLAG
= 0x010000,
516 TDEFL_RLE_MATCHES
= 0x020000,
517 TDEFL_FILTER_MATCHES
= 0x040000,
518 TDEFL_FORCE_ALL_STATIC_BLOCKS
= 0x080000,
519 TDEFL_FORCE_ALL_RAW_BLOCKS
= 0x100000,
522 // High level compression functions:
523 // tdefl_compress_mem_to_heap() compresses a block in memory to a heap block allocated via malloc().
525 // pSrc_buf, src_buf_len: Pointer and size of source block to compress.
526 // flags: The max match finder probes (default is 128) logically OR'd against the above flags. Higher probes are slower but improve compression.
528 // Function returns a pointer to the compressed data, or NULL on failure.
529 // *pOut_len will be set to the compressed data's size, which could be larger than src_buf_len on uncompressible data.
530 // The caller must free() the returned block when it's no longer needed.
531 void *tdefl_compress_mem_to_heap(const void *pSrc_buf
, size_t src_buf_len
, size_t *pOut_len
, int flags
);
533 // tdefl_compress_mem_to_mem() compresses a block in memory to another block in memory.
534 // Returns 0 on failure.
535 size_t tdefl_compress_mem_to_mem(void *pOut_buf
, size_t out_buf_len
, const void *pSrc_buf
, size_t src_buf_len
, int flags
);
537 // Compresses an image to a compressed PNG file in memory.
539 // pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4.
541 // Function returns a pointer to the compressed data, or NULL on failure.
542 // *pLen_out will be set to the size of the PNG image file.
543 // The caller must free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed.
544 void *tdefl_write_image_to_png_file_in_memory(const void *pImage
, int w
, int h
, int num_chans
, size_t *pLen_out
);
546 // Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time.
547 typedef mz_bool (*tdefl_put_buf_func_ptr
)(const void* pBuf
, int len
, void *pUser
);
549 // tdefl_compress_mem_to_output() compresses a block to an output stream. The above helpers use this function internally.
550 mz_bool
tdefl_compress_mem_to_output(const void *pBuf
, size_t buf_len
, tdefl_put_buf_func_ptr pPut_buf_func
, void *pPut_buf_user
, int flags
);
552 enum { TDEFL_MAX_HUFF_TABLES
= 3, TDEFL_MAX_HUFF_SYMBOLS_0
= 288, TDEFL_MAX_HUFF_SYMBOLS_1
= 32, TDEFL_MAX_HUFF_SYMBOLS_2
= 19, TDEFL_LZ_DICT_SIZE
= 32768, TDEFL_LZ_DICT_SIZE_MASK
= TDEFL_LZ_DICT_SIZE
- 1, TDEFL_MIN_MATCH_LEN
= 3, TDEFL_MAX_MATCH_LEN
= 258 };
554 // TDEFL_OUT_BUF_SIZE MUST be large enough to hold a single entire compressed output block (using static/fixed Huffman codes).
555 #if TDEFL_LESS_MEMORY
556 enum { TDEFL_LZ_CODE_BUF_SIZE
= 24 * 1024, TDEFL_OUT_BUF_SIZE
= (TDEFL_LZ_CODE_BUF_SIZE
* 13 ) / 10, TDEFL_MAX_HUFF_SYMBOLS
= 288, TDEFL_LZ_HASH_BITS
= 12, TDEFL_LEVEL1_HASH_SIZE_MASK
= 4095, TDEFL_LZ_HASH_SHIFT
= (TDEFL_LZ_HASH_BITS
+ 2) / 3, TDEFL_LZ_HASH_SIZE
= 1 << TDEFL_LZ_HASH_BITS
};
558 enum { TDEFL_LZ_CODE_BUF_SIZE
= 64 * 1024, TDEFL_OUT_BUF_SIZE
= (TDEFL_LZ_CODE_BUF_SIZE
* 13 ) / 10, TDEFL_MAX_HUFF_SYMBOLS
= 288, TDEFL_LZ_HASH_BITS
= 15, TDEFL_LEVEL1_HASH_SIZE_MASK
= 4095, TDEFL_LZ_HASH_SHIFT
= (TDEFL_LZ_HASH_BITS
+ 2) / 3, TDEFL_LZ_HASH_SIZE
= 1 << TDEFL_LZ_HASH_BITS
};
561 // 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.
564 TDEFL_STATUS_BAD_PARAM
= -2,
565 TDEFL_STATUS_PUT_BUF_FAILED
= -1,
566 TDEFL_STATUS_OKAY
= 0,
567 TDEFL_STATUS_DONE
= 1,
570 // Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums
574 TDEFL_SYNC_FLUSH
= 2,
575 TDEFL_FULL_FLUSH
= 3,
579 // tdefl's compression state structure.
582 tdefl_put_buf_func_ptr m_pPut_buf_func
;
583 void *m_pPut_buf_user
;
584 mz_uint m_flags
, m_max_probes
[2];
585 int m_greedy_parsing
;
586 mz_uint m_adler32
, m_crc32
, m_lookahead_pos
, m_lookahead_size
, m_dict_size
;
587 mz_uint8
*m_pLZ_code_buf
, *m_pLZ_flags
, *m_pOutput_buf
, *m_pOutput_buf_end
;
588 mz_uint m_num_flags_left
, m_total_lz_bytes
, m_lz_code_buf_dict_pos
, m_bits_in
, m_bit_buffer
;
589 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
;
590 tdefl_status m_prev_return_status
;
591 const void *m_pIn_buf
;
593 size_t *m_pIn_buf_size
, *m_pOut_buf_size
;
595 const mz_uint8
*m_pSrc
;
596 size_t m_src_buf_left
, m_out_buf_ofs
;
597 mz_uint8 m_dict
[TDEFL_LZ_DICT_SIZE
+ TDEFL_MAX_MATCH_LEN
- 1];
598 mz_uint16 m_huff_count
[TDEFL_MAX_HUFF_TABLES
][TDEFL_MAX_HUFF_SYMBOLS
];
599 mz_uint16 m_huff_codes
[TDEFL_MAX_HUFF_TABLES
][TDEFL_MAX_HUFF_SYMBOLS
];
600 mz_uint8 m_huff_code_sizes
[TDEFL_MAX_HUFF_TABLES
][TDEFL_MAX_HUFF_SYMBOLS
];
601 mz_uint8 m_lz_code_buf
[TDEFL_LZ_CODE_BUF_SIZE
];
602 mz_uint16 m_next
[TDEFL_LZ_DICT_SIZE
];
603 mz_uint16 m_hash
[TDEFL_LZ_HASH_SIZE
];
604 mz_uint8 m_output_buf
[TDEFL_OUT_BUF_SIZE
];
607 // Initializes the compressor.
608 // There is no corresponding deinit() function because the tdefl API's do not dynamically allocate memory.
609 // 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.
610 // If pBut_buf_func is NULL the user should always call the tdefl_compress() API.
611 // flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, etc.)
612 tdefl_status
tdefl_init(tdefl_compressor
*d
, tdefl_put_buf_func_ptr pPut_buf_func
, void *pPut_buf_user
, int flags
);
614 // 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.
615 tdefl_status
tdefl_compress(tdefl_compressor
*d
, const void *pIn_buf
, size_t *pIn_buf_size
, void *pOut_buf
, size_t *pOut_buf_size
, tdefl_flush flush
);
617 // tdefl_compress_buffer() is only usable when the tdefl_init() is called with a non-NULL tdefl_put_buf_func_ptr.
618 // tdefl_compress_buffer() always consumes the entire input buffer.
619 tdefl_status
tdefl_compress_buffer(tdefl_compressor
*d
, const void *pIn_buf
, size_t in_buf_size
, tdefl_flush flush
);
621 tdefl_status
tdefl_get_prev_return_status(tdefl_compressor
*d
);
622 mz_uint32
tdefl_get_adler32(tdefl_compressor
*d
);
623 mz_uint32
tdefl_get_crc32(tdefl_compressor
*d
);
625 // Create tdefl_compress() flags given zlib-style compression parameters.
626 // level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files)
627 // window_bits may be -15 (raw deflate) or 15 (zlib)
628 // strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED
629 mz_uint
tdefl_create_comp_flags_from_zip_params(int level
, int window_bits
, int strategy
);
631 #endif // MINIZ_HEADER_INCLUDED
633 // ------------------- End of Header: Implementation follows. (If you only want the header, define MINIZ_HEADER_FILE_ONLY.)
635 #ifndef MINIZ_HEADER_FILE_ONLY
637 typedef unsigned char mz_validate_uint16
[sizeof(mz_uint16
)==2 ? 1 : -1];
638 typedef unsigned char mz_validate_uint32
[sizeof(mz_uint32
)==4 ? 1 : -1];
639 typedef unsigned char mz_validate_uint64
[sizeof(mz_uint64
)==8 ? 1 : -1];
641 #define MZ_ASSERT(x) assert(x)
643 #ifdef MINIZ_NO_MALLOC
644 #define MZ_MALLOC(x) NULL
645 #define MZ_FREE(x) x, ((void)0)
646 #define MZ_REALLOC(p, x) NULL
648 #define MZ_MALLOC(x) grub_malloc(x)
649 #define MZ_FREE(x) grub_free(x)
650 #define MZ_REALLOC(p, x) grub_realloc(p, x)
653 #define MZ_MAX(a,b) (((a)>(b))?(a):(b))
654 #define MZ_MIN(a,b) (((a)<(b))?(a):(b))
655 #define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
657 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
658 #define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
659 #define MZ_READ_LE32(p) *((const mz_uint32 *)(p))
661 #define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U))
662 #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))
665 #if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__MINGW64__) && !defined(__forceinline)
666 #define __forceinline
669 // ------------------- zlib-style API's
671 static void *def_alloc_func(void *opaque
, size_t items
, size_t size
) { (void)opaque
; return MZ_MALLOC(items
* size
); }
672 static void def_free_func(void *opaque
, void *address
) { (void)opaque
, MZ_FREE(address
); }
674 mz_ulong
mz_adler32(mz_ulong adler
, const unsigned char *ptr
, size_t buf_len
)
676 mz_uint32 i
, s1
= (mz_uint32
)(adler
& 0xffff), s2
= (mz_uint32
)(adler
>> 16); size_t block_len
= buf_len
% 5552;
677 if (!ptr
) return MZ_ADLER32_INIT
;
679 for (i
= 0; i
+ 7 < block_len
; i
+= 8, ptr
+= 8) {
680 s1
+= ptr
[0], s2
+= s1
; s1
+= ptr
[1], s2
+= s1
; s1
+= ptr
[2], s2
+= s1
; s1
+= ptr
[3], s2
+= s1
;
681 s1
+= ptr
[4], s2
+= s1
; s1
+= ptr
[5], s2
+= s1
; s1
+= ptr
[6], s2
+= s1
; s1
+= ptr
[7], s2
+= s1
;
683 for ( ; i
< block_len
; ++i
) s1
+= *ptr
++, s2
+= s1
;
684 s1
%= 65521U, s2
%= 65521U; buf_len
-= block_len
; block_len
= 5552;
686 return (s2
<< 16) + s1
;
689 // 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/
690 mz_ulong
mz_crc32(mz_ulong crc
, const mz_uint8
*ptr
, size_t buf_len
)
692 static const mz_uint32 s_crc32
[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
693 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c };
694 if (!ptr
) return MZ_CRC32_INIT
;
695 crc
= ~crc
; while (buf_len
--) { mz_uint8 b
= *ptr
++; crc
= (crc
>> 4) ^ s_crc32
[(crc
& 0xF) ^ (b
& 0xF)]; crc
= (crc
>> 4) ^ s_crc32
[(crc
& 0xF) ^ (b
>> 4)]; } return ~crc
;
698 #ifndef MINIZ_NO_ZLIB_APIS
700 const char *mz_version(void)
705 int mz_deflateInit(mz_streamp pStream
, int level
)
707 return mz_deflateInit2(pStream
, level
, MZ_DEFLATED
, MZ_DEFAULT_WINDOW_BITS
, 9, MZ_DEFAULT_STRATEGY
);
710 int mz_deflateInit2(mz_streamp pStream
, int level
, int method
, int window_bits
, int mem_level
, int strategy
)
712 tdefl_compressor
*pComp
;
713 mz_uint comp_flags
= TDEFL_COMPUTE_ADLER32
| TDEFL_COMPUTE_CRC32
| tdefl_create_comp_flags_from_zip_params(level
, window_bits
, strategy
);
715 if (!pStream
) return MZ_STREAM_ERROR
;
716 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
;
718 pStream
->data_type
= 0;
719 pStream
->adler
= MZ_ADLER32_INIT
;
720 pStream
->crc32
= MZ_CRC32_INIT
;
722 pStream
->reserved
= 0;
723 pStream
->total_in
= 0;
724 pStream
->total_out
= 0;
725 if (!pStream
->zalloc
) pStream
->zalloc
= def_alloc_func
;
726 if (!pStream
->zfree
) pStream
->zfree
= def_free_func
;
728 pComp
= (tdefl_compressor
*)pStream
->zalloc(pStream
->opaque
, 1, sizeof(tdefl_compressor
));
732 pStream
->state
= (struct mz_internal_state
*)pComp
;
734 if (tdefl_init(pComp
, NULL
, NULL
, comp_flags
) != TDEFL_STATUS_OKAY
)
736 mz_deflateEnd(pStream
);
737 return MZ_PARAM_ERROR
;
743 int mz_deflateReset(mz_streamp pStream
)
745 if ((!pStream
) || (!pStream
->state
) || (!pStream
->zalloc
) || (!pStream
->zfree
)) return MZ_STREAM_ERROR
;
746 pStream
->total_in
= pStream
->total_out
= 0;
747 tdefl_init((tdefl_compressor
*)pStream
->state
, NULL
, NULL
, ((tdefl_compressor
*)pStream
->state
)->m_flags
);
751 int mz_deflate(mz_streamp pStream
, int flush
)
753 size_t in_bytes
, out_bytes
;
754 mz_ulong orig_total_in
, orig_total_out
;
755 int mz_status
= MZ_OK
;
757 if ((!pStream
) || (!pStream
->state
) || (flush
< 0) || (flush
> MZ_FINISH
) || (!pStream
->next_out
)) return MZ_STREAM_ERROR
;
758 if (!pStream
->avail_out
) return MZ_BUF_ERROR
;
760 if (flush
== MZ_PARTIAL_FLUSH
) flush
= MZ_SYNC_FLUSH
;
762 if (((tdefl_compressor
*)pStream
->state
)->m_prev_return_status
== TDEFL_STATUS_DONE
)
763 return (flush
== MZ_FINISH
) ? MZ_STREAM_END
: MZ_BUF_ERROR
;
765 orig_total_in
= pStream
->total_in
; orig_total_out
= pStream
->total_out
;
768 tdefl_status defl_status
;
769 in_bytes
= pStream
->avail_in
; out_bytes
= pStream
->avail_out
;
771 defl_status
= tdefl_compress((tdefl_compressor
*)pStream
->state
, pStream
->next_in
, &in_bytes
, pStream
->next_out
, &out_bytes
, (tdefl_flush
)flush
);
772 pStream
->next_in
+= (mz_uint
)in_bytes
; pStream
->avail_in
-= (mz_uint
)in_bytes
;
773 pStream
->total_in
+= (mz_uint
)in_bytes
; pStream
->adler
= tdefl_get_adler32((tdefl_compressor
*)pStream
->state
); pStream
->crc32
= tdefl_get_crc32((tdefl_compressor
*)pStream
->state
);
775 pStream
->next_out
+= (mz_uint
)out_bytes
; pStream
->avail_out
-= (mz_uint
)out_bytes
;
776 pStream
->total_out
+= (mz_uint
)out_bytes
;
780 mz_status
= MZ_STREAM_ERROR
;
783 else if (defl_status
== TDEFL_STATUS_DONE
)
785 mz_status
= MZ_STREAM_END
;
788 else if (!pStream
->avail_out
)
790 else if ((!pStream
->avail_in
) && (flush
!= MZ_FINISH
))
792 if ((flush
) || (pStream
->total_in
!= orig_total_in
) || (pStream
->total_out
!= orig_total_out
))
794 return MZ_BUF_ERROR
; // Can't make forward progress without some input.
800 int mz_deflateEnd(mz_streamp pStream
)
802 if (!pStream
) return MZ_STREAM_ERROR
;
805 pStream
->zfree(pStream
->opaque
, pStream
->state
);
806 pStream
->state
= NULL
;
811 mz_ulong
mz_deflateBound(mz_streamp pStream
, mz_ulong source_len
)
814 // 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.)
815 return MZ_MAX(128 + (source_len
* 110) / 100, 128 + source_len
+ ((source_len
/ (31 * 1024)) + 1) * 5);
818 int mz_compress2(unsigned char *pDest
, mz_ulong
*pDest_len
, const unsigned char *pSource
, mz_ulong source_len
, int level
)
822 memset(&stream
, 0, sizeof(stream
));
824 // In case mz_ulong is 64-bits (argh I hate longs).
825 if ((source_len
| *pDest_len
) > 0xFFFFFFFFU
) return MZ_PARAM_ERROR
;
827 stream
.next_in
= pSource
;
828 stream
.avail_in
= (mz_uint32
)source_len
;
829 stream
.next_out
= pDest
;
830 stream
.avail_out
= (mz_uint32
)*pDest_len
;
832 status
= mz_deflateInit(&stream
, level
);
833 if (status
!= MZ_OK
) return status
;
835 status
= mz_deflate(&stream
, MZ_FINISH
);
836 if (status
!= MZ_STREAM_END
)
838 mz_deflateEnd(&stream
);
839 return (status
== MZ_OK
) ? MZ_BUF_ERROR
: status
;
842 *pDest_len
= stream
.total_out
;
843 return mz_deflateEnd(&stream
);
846 int mz_compress(unsigned char *pDest
, mz_ulong
*pDest_len
, const unsigned char *pSource
, mz_ulong source_len
)
848 return mz_compress2(pDest
, pDest_len
, pSource
, source_len
, MZ_DEFAULT_COMPRESSION
);
851 mz_ulong
mz_compressBound(mz_ulong source_len
)
853 return mz_deflateBound(NULL
, source_len
);
858 tinfl_decompressor m_decomp
;
859 mz_uint m_dict_ofs
, m_dict_avail
, m_first_call
, m_has_flushed
; int m_window_bits
;
860 mz_uint8 m_dict
[TINFL_LZ_DICT_SIZE
];
861 tinfl_status m_last_status
;
864 int mz_inflateInit2(mz_streamp pStream
, int window_bits
)
866 inflate_state
*pDecomp
;
867 if (!pStream
) return MZ_STREAM_ERROR
;
868 if ((window_bits
!= MZ_DEFAULT_WINDOW_BITS
) && (-window_bits
!= MZ_DEFAULT_WINDOW_BITS
)) return MZ_PARAM_ERROR
;
870 pStream
->data_type
= 0;
874 pStream
->total_in
= 0;
875 pStream
->total_out
= 0;
876 pStream
->reserved
= 0;
877 if (!pStream
->zalloc
) pStream
->zalloc
= def_alloc_func
;
878 if (!pStream
->zfree
) pStream
->zfree
= def_free_func
;
880 pDecomp
= (inflate_state
*)pStream
->zalloc(pStream
->opaque
, 1, sizeof(inflate_state
));
881 if (!pDecomp
) return MZ_MEM_ERROR
;
883 pStream
->state
= (struct mz_internal_state
*)pDecomp
;
885 tinfl_init(&pDecomp
->m_decomp
);
886 pDecomp
->m_dict_ofs
= 0;
887 pDecomp
->m_dict_avail
= 0;
888 pDecomp
->m_last_status
= TINFL_STATUS_NEEDS_MORE_INPUT
;
889 pDecomp
->m_first_call
= 1;
890 pDecomp
->m_has_flushed
= 0;
891 pDecomp
->m_window_bits
= window_bits
;
896 int mz_inflateInit(mz_streamp pStream
)
898 return mz_inflateInit2(pStream
, MZ_DEFAULT_WINDOW_BITS
);
901 int mz_inflate(mz_streamp pStream
, int flush
)
903 inflate_state
* pState
;
904 mz_uint n
, first_call
, decomp_flags
= TINFL_FLAG_COMPUTE_ADLER32
;
905 size_t in_bytes
, out_bytes
, orig_avail_in
;
908 if ((!pStream
) || (!pStream
->state
)) return MZ_STREAM_ERROR
;
909 if (flush
== MZ_PARTIAL_FLUSH
) flush
= MZ_SYNC_FLUSH
;
910 if ((flush
) && (flush
!= MZ_SYNC_FLUSH
) && (flush
!= MZ_FINISH
)) return MZ_STREAM_ERROR
;
912 pState
= (inflate_state
*)pStream
->state
;
913 if (pState
->m_window_bits
> 0) decomp_flags
|= TINFL_FLAG_PARSE_ZLIB_HEADER
;
914 orig_avail_in
= pStream
->avail_in
;
916 first_call
= pState
->m_first_call
; pState
->m_first_call
= 0;
917 if (pState
->m_last_status
< 0) return MZ_DATA_ERROR
;
919 if (pState
->m_has_flushed
&& (flush
!= MZ_FINISH
)) return MZ_STREAM_ERROR
;
920 pState
->m_has_flushed
|= (flush
== MZ_FINISH
);
922 if ((flush
== MZ_FINISH
) && (first_call
))
924 // MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file.
925 decomp_flags
|= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF
;
926 in_bytes
= pStream
->avail_in
; out_bytes
= pStream
->avail_out
;
927 status
= tinfl_decompress(&pState
->m_decomp
, pStream
->next_in
, &in_bytes
, pStream
->next_out
, pStream
->next_out
, &out_bytes
, decomp_flags
);
928 pState
->m_last_status
= status
;
929 pStream
->next_in
+= (mz_uint
)in_bytes
; pStream
->avail_in
-= (mz_uint
)in_bytes
; pStream
->total_in
+= (mz_uint
)in_bytes
;
930 pStream
->adler
= tinfl_get_adler32(&pState
->m_decomp
);
931 pStream
->crc32
= tinfl_get_crc32(&pState
->m_decomp
);
932 pStream
->next_out
+= (mz_uint
)out_bytes
; pStream
->avail_out
-= (mz_uint
)out_bytes
; pStream
->total_out
+= (mz_uint
)out_bytes
;
935 return MZ_DATA_ERROR
;
936 else if (status
!= TINFL_STATUS_DONE
)
938 pState
->m_last_status
= TINFL_STATUS_FAILED
;
941 return MZ_STREAM_END
;
943 // flush != MZ_FINISH then we must assume there's more input.
944 if (flush
!= MZ_FINISH
) decomp_flags
|= TINFL_FLAG_HAS_MORE_INPUT
;
946 if (pState
->m_dict_avail
)
948 n
= MZ_MIN(pState
->m_dict_avail
, pStream
->avail_out
);
949 memcpy(pStream
->next_out
, pState
->m_dict
+ pState
->m_dict_ofs
, n
);
950 pStream
->next_out
+= n
; pStream
->avail_out
-= n
; pStream
->total_out
+= n
;
951 pState
->m_dict_avail
-= n
; pState
->m_dict_ofs
= (pState
->m_dict_ofs
+ n
) & (TINFL_LZ_DICT_SIZE
- 1);
952 return ((pState
->m_last_status
== TINFL_STATUS_DONE
) && (!pState
->m_dict_avail
)) ? MZ_STREAM_END
: MZ_OK
;
957 in_bytes
= pStream
->avail_in
;
958 out_bytes
= TINFL_LZ_DICT_SIZE
- pState
->m_dict_ofs
;
960 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
);
961 pState
->m_last_status
= status
;
963 pStream
->next_in
+= (mz_uint
)in_bytes
; pStream
->avail_in
-= (mz_uint
)in_bytes
;
964 pStream
->total_in
+= (mz_uint
)in_bytes
; pStream
->adler
= tinfl_get_adler32(&pState
->m_decomp
); pStream
->crc32
= tinfl_get_crc32(&pState
->m_decomp
);
966 pState
->m_dict_avail
= (mz_uint
)out_bytes
;
968 n
= MZ_MIN(pState
->m_dict_avail
, pStream
->avail_out
);
969 memcpy(pStream
->next_out
, pState
->m_dict
+ pState
->m_dict_ofs
, n
);
970 pStream
->next_out
+= n
; pStream
->avail_out
-= n
; pStream
->total_out
+= n
;
971 pState
->m_dict_avail
-= n
; pState
->m_dict_ofs
= (pState
->m_dict_ofs
+ n
) & (TINFL_LZ_DICT_SIZE
- 1);
974 return MZ_DATA_ERROR
; // Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well).
975 else if ((status
== TINFL_STATUS_NEEDS_MORE_INPUT
) && (!orig_avail_in
))
976 return MZ_BUF_ERROR
; // Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH.
977 else if (flush
== MZ_FINISH
)
979 // The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH.
980 if (status
== TINFL_STATUS_DONE
)
981 return pState
->m_dict_avail
? MZ_BUF_ERROR
: MZ_STREAM_END
;
982 // 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.
983 else if (!pStream
->avail_out
)
986 else if ((status
== TINFL_STATUS_DONE
) || (!pStream
->avail_in
) || (!pStream
->avail_out
) || (pState
->m_dict_avail
))
990 return ((status
== TINFL_STATUS_DONE
) && (!pState
->m_dict_avail
)) ? MZ_STREAM_END
: MZ_OK
;
993 int mz_inflateEnd(mz_streamp pStream
)
996 return MZ_STREAM_ERROR
;
999 pStream
->zfree(pStream
->opaque
, pStream
->state
);
1000 pStream
->state
= NULL
;
1005 int mz_uncompress(unsigned char *pDest
, mz_ulong
*pDest_len
, const unsigned char *pSource
, mz_ulong source_len
)
1009 memset(&stream
, 0, sizeof(stream
));
1011 // In case mz_ulong is 64-bits (argh I hate longs).
1012 if ((source_len
| *pDest_len
) > 0xFFFFFFFFU
) return MZ_PARAM_ERROR
;
1014 stream
.next_in
= pSource
;
1015 stream
.avail_in
= (mz_uint32
)source_len
;
1016 stream
.next_out
= pDest
;
1017 stream
.avail_out
= (mz_uint32
)*pDest_len
;
1019 status
= mz_inflateInit(&stream
);
1020 if (status
!= MZ_OK
)
1023 status
= mz_inflate(&stream
, MZ_FINISH
);
1024 if (status
!= MZ_STREAM_END
)
1026 mz_inflateEnd(&stream
);
1027 return ((status
== MZ_BUF_ERROR
) && (!stream
.avail_in
)) ? MZ_DATA_ERROR
: status
;
1029 *pDest_len
= stream
.total_out
;
1031 return mz_inflateEnd(&stream
);
1034 const char *mz_error(int err
)
1036 static struct { int m_err
; const char *m_pDesc
; } s_error_descs
[] =
1038 { MZ_OK
, "" }, { MZ_STREAM_END
, "stream end" }, { MZ_NEED_DICT
, "need dictionary" }, { MZ_ERRNO
, "file error" }, { MZ_STREAM_ERROR
, "stream error" },
1039 { 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" }
1041 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
;
1045 #endif //MINIZ_NO_ZLIB_APIS
1047 // ------------------- Low-level Decompression (completely independent from all compression API's)
1049 #define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
1050 #define TINFL_MEMSET(p, c, l) memset(p, c, l)
1052 #define TINFL_CR_BEGIN switch(r->m_state) { case 0:
1053 #define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END
1054 #define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END
1055 #define TINFL_CR_FINISH }
1057 // 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
1058 // reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of the stream with 0's in this scenario.
1059 #define TINFL_GET_BYTE(state_index, c) do { \
1060 if (pIn_buf_cur >= pIn_buf_end) { \
1062 if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \
1063 TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \
1064 if (pIn_buf_cur < pIn_buf_end) { \
1065 c = *pIn_buf_cur++; \
1073 } else c = *pIn_buf_cur++; } MZ_MACRO_END
1075 #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))
1076 #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
1077 #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
1079 // TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2.
1080 // 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
1081 // 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
1082 // bit buffer contains >=15 bits (deflate's max. Huffman code size).
1083 #define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \
1085 temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
1087 code_len = temp >> 9; \
1088 if ((code_len) && (num_bits >= code_len)) \
1090 } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \
1091 code_len = TINFL_FAST_LOOKUP_BITS; \
1093 temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
1094 } while ((temp < 0) && (num_bits >= (code_len + 1))); if (temp >= 0) break; \
1095 } TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; \
1096 } while (num_bits < 15);
1098 // 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
1099 // 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
1100 // 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.
1101 // The slow path is only executed at the very end of the input buffer.
1102 #define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \
1103 int temp; mz_uint code_len, c; \
1104 if (num_bits < 15) { \
1105 if ((pIn_buf_end - pIn_buf_cur) < 2) { \
1106 TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
1108 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; \
1111 if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
1112 code_len = temp >> 9, temp &= 511; \
1114 code_len = TINFL_FAST_LOOKUP_BITS; do { temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; } while (temp < 0); \
1115 } sym = temp; bit_buf >>= code_len; num_bits -= code_len; } MZ_MACRO_END
1117 #if defined(__aarch64__) || defined(__arm__)
1118 #pragma GCC diagnostic push
1119 #pragma GCC diagnostic ignored "-Wmisleading-indentation"
1122 tinfl_status
tinfl_decompress(tinfl_decompressor
*r
, const mz_uint8
*pIn_buf_next
, size_t *pIn_buf_size
, mz_uint8
*pOut_buf_start
, mz_uint8
*pOut_buf_next
, size_t *pOut_buf_size
, const mz_uint32 decomp_flags
)
1124 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 };
1125 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 };
1126 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};
1127 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};
1128 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 };
1129 static const int s_min_table_sizes
[3] = { 257, 1, 4 };
1131 tinfl_status status
= TINFL_STATUS_FAILED
; mz_uint32 num_bits
, dist
, counter
, num_extra
; tinfl_bit_buf_t bit_buf
;
1132 const mz_uint8
*pIn_buf_cur
= pIn_buf_next
, *const pIn_buf_end
= pIn_buf_next
+ *pIn_buf_size
;
1133 mz_uint8
*pOut_buf_cur
= pOut_buf_next
, *const pOut_buf_end
= pOut_buf_next
+ *pOut_buf_size
;
1134 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
;
1136 // 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).
1137 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
; }
1139 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
;
1142 bit_buf
= num_bits
= dist
= counter
= num_extra
= r
->m_zhdr0
= r
->m_zhdr1
= 0; r
->m_z_adler32
= r
->m_check_adler32
= 1;
1143 if (decomp_flags
& TINFL_FLAG_PARSE_ZLIB_HEADER
)
1145 TINFL_GET_BYTE(1, r
->m_zhdr0
); TINFL_GET_BYTE(2, r
->m_zhdr1
);
1146 counter
= (((r
->m_zhdr0
* 256 + r
->m_zhdr1
) % 31 != 0) || (r
->m_zhdr1
& 32) || ((r
->m_zhdr0
& 15) != 8));
1147 if (!(decomp_flags
& TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF
)) counter
|= (((1U << (8U + (r
->m_zhdr0
>> 4))) > 32768U) || ((out_buf_size_mask
+ 1) < (size_t)(1U << (8U + (r
->m_zhdr0
>> 4)))));
1148 if (counter
) { TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED
); }
1153 TINFL_GET_BITS(3, r
->m_final
, 3); r
->m_type
= r
->m_final
>> 1;
1156 TINFL_SKIP_BITS(5, num_bits
& 7);
1157 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
]); }
1158 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
); }
1159 while ((counter
) && (num_bits
))
1161 TINFL_GET_BITS(51, dist
, 8);
1162 while (pOut_buf_cur
>= pOut_buf_end
) { TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT
); }
1163 *pOut_buf_cur
++ = (mz_uint8
)dist
;
1168 size_t n
; while (pOut_buf_cur
>= pOut_buf_end
) { TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT
); }
1169 while (pIn_buf_cur
>= pIn_buf_end
)
1171 if (decomp_flags
& TINFL_FLAG_HAS_MORE_INPUT
)
1173 TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT
);
1177 TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED
);
1180 n
= MZ_MIN(MZ_MIN((size_t)(pOut_buf_end
- pOut_buf_cur
), (size_t)(pIn_buf_end
- pIn_buf_cur
)), counter
);
1181 TINFL_MEMCPY(pOut_buf_cur
, pIn_buf_cur
, n
); pIn_buf_cur
+= n
; pOut_buf_cur
+= n
; counter
-= (mz_uint
)n
;
1184 else if (r
->m_type
== 3)
1186 TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED
);
1192 mz_uint8
*p
= r
->m_tables
[0].m_code_size
; mz_uint i
;
1193 r
->m_table_sizes
[0] = 288; r
->m_table_sizes
[1] = 32; TINFL_MEMSET(r
->m_tables
[1].m_code_size
, 5, 32);
1194 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;
1198 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
]; }
1199 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
; }
1200 r
->m_table_sizes
[2] = 19;
1202 for ( ; (int)r
->m_type
>= 0; r
->m_type
--)
1204 int tree_next
, tree_cur
; tinfl_huff_table
*pTable
;
1205 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
);
1206 for (i
= 0; i
< r
->m_table_sizes
[r
->m_type
]; ++i
) total_syms
[pTable
->m_code_size
[i
]]++;
1207 used_syms
= 0, total
= 0; next_code
[0] = next_code
[1] = 0;
1208 for (i
= 1; i
<= 15; ++i
) { used_syms
+= total_syms
[i
]; next_code
[i
+ 1] = (total
= ((total
+ total_syms
[i
]) << 1)); }
1209 if ((65536 != total
) && (used_syms
> 1))
1211 TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED
);
1213 for (tree_next
= -1, sym_index
= 0; sym_index
< r
->m_table_sizes
[r
->m_type
]; ++sym_index
)
1215 mz_uint rev_code
= 0, l
, cur_code
, code_size
= pTable
->m_code_size
[sym_index
]; if (!code_size
) continue;
1216 cur_code
= next_code
[code_size
]++; for (l
= code_size
; l
> 0; l
--, cur_code
>>= 1) rev_code
= (rev_code
<< 1) | (cur_code
& 1);
1217 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; }
1218 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; }
1219 rev_code
>>= (TINFL_FAST_LOOKUP_BITS
- 1);
1220 for (j
= code_size
; j
> (TINFL_FAST_LOOKUP_BITS
+ 1); j
--)
1222 tree_cur
-= ((rev_code
>>= 1) & 1);
1223 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];
1225 tree_cur
-= ((rev_code
>>= 1) & 1); pTable
->m_tree
[-tree_cur
- 1] = (mz_int16
)sym_index
;
1229 for (counter
= 0; counter
< (r
->m_table_sizes
[0] + r
->m_table_sizes
[1]); )
1231 mz_uint s
; TINFL_HUFF_DECODE(16, dist
, &r
->m_tables
[2]); if (dist
< 16) { r
->m_len_codes
[counter
++] = (mz_uint8
)dist
; continue; }
1232 if ((dist
== 16) && (!counter
))
1234 TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED
);
1236 num_extra
= "\02\03\07"[dist
- 16]; TINFL_GET_BITS(18, s
, num_extra
); s
+= "\03\03\013"[dist
- 16];
1237 TINFL_MEMSET(r
->m_len_codes
+ counter
, (dist
== 16) ? r
->m_len_codes
[counter
- 1] : 0, s
); counter
+= s
;
1239 if ((r
->m_table_sizes
[0] + r
->m_table_sizes
[1]) != counter
)
1241 TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED
);
1243 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]);
1251 if (((pIn_buf_end
- pIn_buf_cur
) < 4) || ((pOut_buf_end
- pOut_buf_cur
) < 2))
1253 TINFL_HUFF_DECODE(23, counter
, &r
->m_tables
[0]);
1256 while (pOut_buf_cur
>= pOut_buf_end
) { TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT
); }
1257 *pOut_buf_cur
++ = (mz_uint8
)counter
;
1261 int sym2
; mz_uint code_len
;
1262 #if TINFL_USE_64BIT_BITBUF
1263 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; }
1265 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; }
1267 if ((sym2
= r
->m_tables
[0].m_look_up
[bit_buf
& (TINFL_FAST_LOOKUP_SIZE
- 1)]) >= 0)
1268 code_len
= sym2
>> 9;
1271 code_len
= TINFL_FAST_LOOKUP_BITS
; do { sym2
= r
->m_tables
[0].m_tree
[~sym2
+ ((bit_buf
>> code_len
++) & 1)]; } while (sym2
< 0);
1273 counter
= sym2
; bit_buf
>>= code_len
; num_bits
-= code_len
;
1277 #if !TINFL_USE_64BIT_BITBUF
1278 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; }
1280 if ((sym2
= r
->m_tables
[0].m_look_up
[bit_buf
& (TINFL_FAST_LOOKUP_SIZE
- 1)]) >= 0)
1281 code_len
= sym2
>> 9;
1284 code_len
= TINFL_FAST_LOOKUP_BITS
; do { sym2
= r
->m_tables
[0].m_tree
[~sym2
+ ((bit_buf
>> code_len
++) & 1)]; } while (sym2
< 0);
1286 bit_buf
>>= code_len
; num_bits
-= code_len
;
1288 pOut_buf_cur
[0] = (mz_uint8
)counter
;
1295 pOut_buf_cur
[1] = (mz_uint8
)sym2
;
1299 if ((counter
&= 511) == 256) break;
1301 num_extra
= s_length_extra
[counter
- 257]; counter
= s_length_base
[counter
- 257];
1302 if (num_extra
) { mz_uint extra_bits
; TINFL_GET_BITS(25, extra_bits
, num_extra
); counter
+= extra_bits
; }
1304 TINFL_HUFF_DECODE(26, dist
, &r
->m_tables
[1]);
1305 num_extra
= s_dist_extra
[dist
]; dist
= s_dist_base
[dist
];
1306 if (num_extra
) { mz_uint extra_bits
; TINFL_GET_BITS(27, extra_bits
, num_extra
); dist
+= extra_bits
; }
1308 dist_from_out_buf_start
= pOut_buf_cur
- pOut_buf_start
;
1309 if ((dist
> dist_from_out_buf_start
) && (decomp_flags
& TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF
))
1311 TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED
);
1314 pSrc
= pOut_buf_start
+ ((dist_from_out_buf_start
- dist
) & out_buf_size_mask
);
1316 if ((MZ_MAX(pOut_buf_cur
, pSrc
) + counter
) > pOut_buf_end
)
1320 while (pOut_buf_cur
>= pOut_buf_end
) { TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT
); }
1321 *pOut_buf_cur
++ = pOut_buf_start
[(dist_from_out_buf_start
++ - dist
) & out_buf_size_mask
];
1325 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
1326 else if ((counter
>= 9) && (counter
<= dist
))
1328 const mz_uint8
*pSrc_end
= pSrc
+ (counter
& ~7);
1331 ((mz_uint32
*)pOut_buf_cur
)[0] = ((const mz_uint32
*)pSrc
)[0];
1332 ((mz_uint32
*)pOut_buf_cur
)[1] = ((const mz_uint32
*)pSrc
)[1];
1334 } while ((pSrc
+= 8) < pSrc_end
);
1335 if ((counter
&= 7) < 3)
1339 pOut_buf_cur
[0] = pSrc
[0];
1341 pOut_buf_cur
[1] = pSrc
[1];
1342 pOut_buf_cur
+= counter
;
1350 pOut_buf_cur
[0] = pSrc
[0];
1351 pOut_buf_cur
[1] = pSrc
[1];
1352 pOut_buf_cur
[2] = pSrc
[2];
1353 pOut_buf_cur
+= 3; pSrc
+= 3;
1354 } while ((int)(counter
-= 3) > 2);
1355 if ((int)counter
> 0)
1357 pOut_buf_cur
[0] = pSrc
[0];
1358 if ((int)counter
> 1)
1359 pOut_buf_cur
[1] = pSrc
[1];
1360 pOut_buf_cur
+= counter
;
1364 } while (!(r
->m_final
& 1));
1365 if (decomp_flags
& TINFL_FLAG_PARSE_ZLIB_HEADER
)
1367 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
; }
1369 TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE
);
1373 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
;
1374 *pIn_buf_size
= pIn_buf_cur
- pIn_buf_next
; *pOut_buf_size
= pOut_buf_cur
- pOut_buf_next
;
1375 if ((decomp_flags
& (TINFL_FLAG_PARSE_ZLIB_HEADER
| TINFL_FLAG_COMPUTE_ADLER32
)) && (status
>= 0))
1377 const mz_uint8
*ptr
= pOut_buf_next
; size_t buf_len
= *pOut_buf_size
;
1378 mz_uint32 i
, s1
= r
->m_check_adler32
& 0xffff, s2
= r
->m_check_adler32
>> 16; size_t block_len
= buf_len
% 5552;
1381 for (i
= 0; i
+ 7 < block_len
; i
+= 8, ptr
+= 8)
1383 s1
+= ptr
[0], s2
+= s1
; s1
+= ptr
[1], s2
+= s1
; s1
+= ptr
[2], s2
+= s1
; s1
+= ptr
[3], s2
+= s1
;
1384 s1
+= ptr
[4], s2
+= s1
; s1
+= ptr
[5], s2
+= s1
; s1
+= ptr
[6], s2
+= s1
; s1
+= ptr
[7], s2
+= s1
;
1386 for ( ; i
< block_len
; ++i
) s1
+= *ptr
++, s2
+= s1
;
1387 s1
%= 65521U, s2
%= 65521U; buf_len
-= block_len
; block_len
= 5552;
1389 r
->m_check_adler32
= (s2
<< 16) + s1
; if ((status
== TINFL_STATUS_DONE
) && (decomp_flags
& TINFL_FLAG_PARSE_ZLIB_HEADER
) && (r
->m_check_adler32
!= r
->m_z_adler32
)) status
= TINFL_STATUS_ADLER32_MISMATCH
;
1394 #if defined(__aarch64__) || defined(__arm__)
1395 #pragma GCC diagnostic pop
1398 // Higher level helper functions.
1399 void *tinfl_decompress_mem_to_heap(const void *pSrc_buf
, size_t src_buf_len
, size_t *pOut_len
, int flags
)
1401 tinfl_decompressor decomp
; void *pBuf
= NULL
, *pNew_buf
; size_t src_buf_ofs
= 0, out_buf_capacity
= 0;
1403 tinfl_init(&decomp
);
1406 size_t src_buf_size
= src_buf_len
- src_buf_ofs
, dst_buf_size
= out_buf_capacity
- *pOut_len
, new_out_buf_capacity
;
1407 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
,
1408 (flags
& ~TINFL_FLAG_HAS_MORE_INPUT
) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF
);
1409 if ((status
< 0) || (status
== TINFL_STATUS_NEEDS_MORE_INPUT
))
1411 MZ_FREE(pBuf
); *pOut_len
= 0; return NULL
;
1413 src_buf_ofs
+= src_buf_size
;
1414 *pOut_len
+= dst_buf_size
;
1415 if (status
== TINFL_STATUS_DONE
) break;
1416 new_out_buf_capacity
= out_buf_capacity
* 2; if (new_out_buf_capacity
< 128) new_out_buf_capacity
= 128;
1417 pNew_buf
= MZ_REALLOC(pBuf
, new_out_buf_capacity
);
1420 MZ_FREE(pBuf
); *pOut_len
= 0; return NULL
;
1422 pBuf
= pNew_buf
; out_buf_capacity
= new_out_buf_capacity
;
1427 size_t tinfl_decompress_mem_to_mem(void *pOut_buf
, size_t out_buf_len
, const void *pSrc_buf
, size_t src_buf_len
, int flags
)
1429 tinfl_decompressor decomp
; tinfl_status status
; tinfl_init(&decomp
);
1430 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
);
1431 return (status
!= TINFL_STATUS_DONE
) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED
: out_buf_len
;
1434 int tinfl_decompress_mem_to_callback(const void *pIn_buf
, size_t *pIn_buf_size
, tinfl_put_buf_func_ptr pPut_buf_func
, void *pPut_buf_user
, int flags
)
1437 tinfl_decompressor decomp
;
1438 mz_uint8
*pDict
= (mz_uint8
*)MZ_MALLOC(TINFL_LZ_DICT_SIZE
); size_t in_buf_ofs
= 0, dict_ofs
= 0;
1440 return TINFL_STATUS_FAILED
;
1441 tinfl_init(&decomp
);
1444 size_t in_buf_size
= *pIn_buf_size
- in_buf_ofs
, dst_buf_size
= TINFL_LZ_DICT_SIZE
- dict_ofs
;
1445 tinfl_status status
= tinfl_decompress(&decomp
, (const mz_uint8
*)pIn_buf
+ in_buf_ofs
, &in_buf_size
, pDict
, pDict
+ dict_ofs
, &dst_buf_size
,
1446 (flags
& ~(TINFL_FLAG_HAS_MORE_INPUT
| TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF
)));
1447 in_buf_ofs
+= in_buf_size
;
1448 if ((dst_buf_size
) && (!(*pPut_buf_func
)(pDict
+ dict_ofs
, (int)dst_buf_size
, pPut_buf_user
)))
1450 if (status
!= TINFL_STATUS_HAS_MORE_OUTPUT
)
1452 result
= (status
== TINFL_STATUS_DONE
);
1455 dict_ofs
= (dict_ofs
+ dst_buf_size
) & (TINFL_LZ_DICT_SIZE
- 1);
1458 *pIn_buf_size
= in_buf_ofs
;
1462 // ------------------- Low-level Compression (independent from all decompression API's)
1464 // Purposely making these tables static for faster init and thread safety.
1465 static const mz_uint16 s_tdefl_len_sym
[256] = {
1466 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,
1467 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,
1468 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,
1469 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,
1470 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,
1471 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,
1472 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,
1473 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 };
1475 static const mz_uint8 s_tdefl_len_extra
[256] = {
1476 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,
1477 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,
1478 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
1479 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,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 };
1481 static const mz_uint8 s_tdefl_small_dist_sym
[512] = {
1482 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,
1483 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,
1484 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,
1485 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,
1486 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,
1487 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,
1488 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,
1489 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,
1490 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,
1491 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,
1492 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,
1493 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 };
1495 static const mz_uint8 s_tdefl_small_dist_extra
[512] = {
1496 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,
1497 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,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,
1498 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
1499 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,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,
1500 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1501 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1502 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
1505 static const mz_uint8 s_tdefl_large_dist_sym
[128] = {
1506 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,
1507 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,
1508 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 };
1510 static const mz_uint8 s_tdefl_large_dist_extra
[128] = {
1511 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,
1512 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,
1513 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 };
1515 // Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted values.
1516 typedef struct { mz_uint16 m_key
, m_sym_index
; } tdefl_sym_freq
;
1517 static tdefl_sym_freq
* tdefl_radix_sort_syms(mz_uint num_syms
, tdefl_sym_freq
* pSyms0
, tdefl_sym_freq
* pSyms1
)
1519 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
);
1520 for (i
= 0; i
< num_syms
; i
++) { mz_uint freq
= pSyms0
[i
].m_key
; hist
[freq
& 0xFF]++; hist
[256 + ((freq
>> 8) & 0xFF)]++; }
1521 while ((total_passes
> 1) && (num_syms
== hist
[(total_passes
- 1) * 256])) total_passes
--;
1522 for (pass_shift
= 0, pass
= 0; pass
< total_passes
; pass
++, pass_shift
+= 8)
1524 const mz_uint32
* pHist
= &hist
[pass
<< 8];
1525 mz_uint offsets
[256], cur_ofs
= 0;
1526 for (i
= 0; i
< 256; i
++) { offsets
[i
] = cur_ofs
; cur_ofs
+= pHist
[i
]; }
1527 for (i
= 0; i
< num_syms
; i
++) pNew_syms
[offsets
[(pCur_syms
[i
].m_key
>> pass_shift
) & 0xFF]++] = pCur_syms
[i
];
1528 { tdefl_sym_freq
* t
= pCur_syms
; pCur_syms
= pNew_syms
; pNew_syms
= t
; }
1533 // tdefl_calculate_minimum_redundancy() originally written by: Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996.
1534 static void tdefl_calculate_minimum_redundancy(tdefl_sym_freq
*A
, int n
)
1536 int root
, leaf
, next
, avbl
, used
, dpth
;
1537 if (n
==0) return; else if (n
==1) { A
[0].m_key
= 1; return; }
1538 A
[0].m_key
+= A
[1].m_key
; root
= 0; leaf
= 2;
1539 for (next
=1; next
< n
-1; next
++)
1541 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
;
1542 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
);
1544 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;
1545 avbl
= 1; used
= dpth
= 0; root
= n
-2; next
= n
-1;
1548 while (root
>=0 && (int)A
[root
].m_key
==dpth
) { used
++; root
--; }
1549 while (avbl
>used
) { A
[next
--].m_key
= (mz_uint16
)(dpth
); avbl
--; }
1550 avbl
= 2*used
; dpth
++; used
= 0;
1554 // Limits canonical Huffman code table's max code size.
1555 enum { TDEFL_MAX_SUPPORTED_HUFF_CODESIZE
= 32 };
1556 static void tdefl_huffman_enforce_max_code_size(int *pNum_codes
, int code_list_len
, int max_code_size
)
1558 int i
; mz_uint32 total
= 0; if (code_list_len
<= 1) return;
1559 for (i
= max_code_size
+ 1; i
<= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE
; i
++) pNum_codes
[max_code_size
] += pNum_codes
[i
];
1560 for (i
= max_code_size
; i
> 0; i
--) total
+= (((mz_uint32
)pNum_codes
[i
]) << (max_code_size
- i
));
1561 while (total
!= (1UL << max_code_size
))
1563 pNum_codes
[max_code_size
]--;
1564 for (i
= max_code_size
- 1; i
> 0; i
--) if (pNum_codes
[i
]) { pNum_codes
[i
]--; pNum_codes
[i
+ 1] += 2; break; }
1569 static void tdefl_optimize_huffman_table(tdefl_compressor
*d
, int table_num
, int table_len
, int code_size_limit
, int static_table
)
1571 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
);
1574 for (i
= 0; i
< table_len
; i
++) num_codes
[d
->m_huff_code_sizes
[table_num
][i
]]++;
1578 tdefl_sym_freq syms0
[TDEFL_MAX_HUFF_SYMBOLS
], syms1
[TDEFL_MAX_HUFF_SYMBOLS
], *pSyms
;
1579 int num_used_syms
= 0;
1580 const mz_uint16
*pSym_count
= &d
->m_huff_count
[table_num
][0];
1581 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
; }
1583 pSyms
= tdefl_radix_sort_syms(num_used_syms
, syms0
, syms1
); tdefl_calculate_minimum_redundancy(pSyms
, num_used_syms
);
1585 for (i
= 0; i
< num_used_syms
; i
++) num_codes
[pSyms
[i
].m_key
]++;
1587 tdefl_huffman_enforce_max_code_size(num_codes
, num_used_syms
, code_size_limit
);
1589 MZ_CLEAR_OBJ(d
->m_huff_code_sizes
[table_num
]); MZ_CLEAR_OBJ(d
->m_huff_codes
[table_num
]);
1590 for (i
= 1, j
= num_used_syms
; i
<= code_size_limit
; i
++)
1591 for (l
= num_codes
[i
]; l
> 0; l
--) d
->m_huff_code_sizes
[table_num
][pSyms
[--j
].m_sym_index
] = (mz_uint8
)(i
);
1594 next_code
[1] = 0; for (j
= 0, i
= 2; i
<= code_size_limit
; i
++) next_code
[i
] = j
= ((j
+ num_codes
[i
- 1]) << 1);
1596 for (i
= 0; i
< table_len
; i
++)
1598 mz_uint rev_code
= 0, code
, code_size
; if ((code_size
= d
->m_huff_code_sizes
[table_num
][i
]) == 0) continue;
1599 code
= next_code
[code_size
]++; for (l
= code_size
; l
> 0; l
--, code
>>= 1) rev_code
= (rev_code
<< 1) | (code
& 1);
1600 d
->m_huff_codes
[table_num
][i
] = (mz_uint16
)rev_code
;
1604 #define TDEFL_PUT_BITS(b, l) do { \
1605 mz_uint bits = b; mz_uint len = l; MZ_ASSERT(bits <= ((1U << len) - 1U)); \
1606 d->m_bit_buffer |= (bits << d->m_bits_in); d->m_bits_in += len; \
1607 while (d->m_bits_in >= 8) { \
1608 if (d->m_pOutput_buf < d->m_pOutput_buf_end) \
1609 *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \
1610 d->m_bit_buffer >>= 8; \
1611 d->m_bits_in -= 8; \
1615 #define TDEFL_RLE_PREV_CODE_SIZE() { if (rle_repeat_count) { \
1616 if (rle_repeat_count < 3) { \
1617 d->m_huff_count[2][prev_code_size] = (mz_uint16)(d->m_huff_count[2][prev_code_size] + rle_repeat_count); \
1618 while (rle_repeat_count--) packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \
1620 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); \
1621 } rle_repeat_count = 0; } }
1623 #define TDEFL_RLE_ZERO_CODE_SIZE() { if (rle_z_count) { \
1624 if (rle_z_count < 3) { \
1625 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; \
1626 } else if (rle_z_count <= 10) { \
1627 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); \
1629 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); \
1630 } rle_z_count = 0; } }
1632 static mz_uint8 s_tdefl_packed_code_size_syms_swizzle
[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
1634 static void tdefl_start_dynamic_block(tdefl_compressor
*d
)
1636 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
;
1637 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;
1639 d
->m_huff_count
[0][256] = 1;
1641 tdefl_optimize_huffman_table(d
, 0, TDEFL_MAX_HUFF_SYMBOLS_0
, 15, MZ_FALSE
);
1642 tdefl_optimize_huffman_table(d
, 1, TDEFL_MAX_HUFF_SYMBOLS_1
, 15, MZ_FALSE
);
1644 for (num_lit_codes
= 286; num_lit_codes
> 257; num_lit_codes
--) if (d
->m_huff_code_sizes
[0][num_lit_codes
- 1]) break;
1645 for (num_dist_codes
= 30; num_dist_codes
> 1; num_dist_codes
--) if (d
->m_huff_code_sizes
[1][num_dist_codes
- 1]) break;
1647 memcpy(code_sizes_to_pack
, &d
->m_huff_code_sizes
[0][0], num_lit_codes
);
1648 memcpy(code_sizes_to_pack
+ num_lit_codes
, &d
->m_huff_code_sizes
[1][0], num_dist_codes
);
1649 total_code_sizes_to_pack
= num_lit_codes
+ num_dist_codes
; num_packed_code_sizes
= 0; rle_z_count
= 0; rle_repeat_count
= 0;
1651 memset(&d
->m_huff_count
[2][0], 0, sizeof(d
->m_huff_count
[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2
);
1652 for (i
= 0; i
< total_code_sizes_to_pack
; i
++)
1654 mz_uint8 code_size
= code_sizes_to_pack
[i
];
1657 TDEFL_RLE_PREV_CODE_SIZE();
1658 if (++rle_z_count
== 138) { TDEFL_RLE_ZERO_CODE_SIZE(); }
1662 TDEFL_RLE_ZERO_CODE_SIZE();
1663 if (code_size
!= prev_code_size
)
1665 TDEFL_RLE_PREV_CODE_SIZE();
1666 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
;
1668 else if (++rle_repeat_count
== 6)
1670 TDEFL_RLE_PREV_CODE_SIZE();
1673 prev_code_size
= code_size
;
1675 if (rle_repeat_count
) { TDEFL_RLE_PREV_CODE_SIZE(); } else { TDEFL_RLE_ZERO_CODE_SIZE(); }
1677 tdefl_optimize_huffman_table(d
, 2, TDEFL_MAX_HUFF_SYMBOLS_2
, 7, MZ_FALSE
);
1679 TDEFL_PUT_BITS(2, 2);
1681 TDEFL_PUT_BITS(num_lit_codes
- 257, 5);
1682 TDEFL_PUT_BITS(num_dist_codes
- 1, 5);
1684 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;
1685 num_bit_lengths
= MZ_MAX(4, (num_bit_lengths
+ 1)); TDEFL_PUT_BITS(num_bit_lengths
- 4, 4);
1686 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);
1688 for (packed_code_sizes_index
= 0; packed_code_sizes_index
< num_packed_code_sizes
; )
1690 mz_uint code
= packed_code_sizes
[packed_code_sizes_index
++]; MZ_ASSERT(code
< TDEFL_MAX_HUFF_SYMBOLS_2
);
1691 TDEFL_PUT_BITS(d
->m_huff_codes
[2][code
], d
->m_huff_code_sizes
[2][code
]);
1692 if (code
>= 16) TDEFL_PUT_BITS(packed_code_sizes
[packed_code_sizes_index
++], "\02\03\07"[code
- 16]);
1696 static void tdefl_start_static_block(tdefl_compressor
*d
)
1699 mz_uint8
*p
= &d
->m_huff_code_sizes
[0][0];
1701 for (i
= 0; i
<= 143; ++i
) *p
++ = 8;
1702 for ( ; i
<= 255; ++i
) *p
++ = 9;
1703 for ( ; i
<= 279; ++i
) *p
++ = 7;
1704 for ( ; i
<= 287; ++i
) *p
++ = 8;
1706 memset(d
->m_huff_code_sizes
[1], 5, 32);
1708 tdefl_optimize_huffman_table(d
, 0, 288, 15, MZ_TRUE
);
1709 tdefl_optimize_huffman_table(d
, 1, 32, 15, MZ_TRUE
);
1711 TDEFL_PUT_BITS(1, 2);
1714 static const mz_uint mz_bitmasks
[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF };
1716 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS
1717 static mz_bool
tdefl_compress_lz_codes(tdefl_compressor
*d
)
1720 mz_uint8
*pLZ_codes
;
1721 mz_uint8
*pOutput_buf
= d
->m_pOutput_buf
;
1722 mz_uint8
*pLZ_code_buf_end
= d
->m_pLZ_code_buf
;
1723 mz_uint64 bit_buffer
= d
->m_bit_buffer
;
1724 mz_uint bits_in
= d
->m_bits_in
;
1726 #define TDEFL_PUT_BITS_FAST(b, l) { bit_buffer |= (((mz_uint64)(b)) << bits_in); bits_in += (l); }
1729 for (pLZ_codes
= d
->m_lz_code_buf
; pLZ_codes
< pLZ_code_buf_end
; flags
>>= 1)
1732 flags
= *pLZ_codes
++ | 0x100;
1736 mz_uint s0
, s1
, n0
, n1
, sym
, num_extra_bits
;
1737 mz_uint match_len
= pLZ_codes
[0], match_dist
= *(const mz_uint16
*)(pLZ_codes
+ 1); pLZ_codes
+= 3;
1739 MZ_ASSERT(d
->m_huff_code_sizes
[0][s_tdefl_len_sym
[match_len
]]);
1740 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
]]);
1741 TDEFL_PUT_BITS_FAST(match_len
& mz_bitmasks
[s_tdefl_len_extra
[match_len
]], s_tdefl_len_extra
[match_len
]);
1743 // This sequence coaxes MSVC into using cmov's vs. jmp's.
1744 s0
= s_tdefl_small_dist_sym
[match_dist
& 511];
1745 n0
= s_tdefl_small_dist_extra
[match_dist
& 511];
1746 s1
= s_tdefl_large_dist_sym
[match_dist
>> 8];
1747 n1
= s_tdefl_large_dist_extra
[match_dist
>> 8];
1748 sym
= (match_dist
< 512) ? s0
: s1
;
1749 num_extra_bits
= (match_dist
< 512) ? n0
: n1
;
1751 MZ_ASSERT(d
->m_huff_code_sizes
[1][sym
]);
1752 TDEFL_PUT_BITS_FAST(d
->m_huff_codes
[1][sym
], d
->m_huff_code_sizes
[1][sym
]);
1753 TDEFL_PUT_BITS_FAST(match_dist
& mz_bitmasks
[num_extra_bits
], num_extra_bits
);
1757 mz_uint lit
= *pLZ_codes
++;
1758 MZ_ASSERT(d
->m_huff_code_sizes
[0][lit
]);
1759 TDEFL_PUT_BITS_FAST(d
->m_huff_codes
[0][lit
], d
->m_huff_code_sizes
[0][lit
]);
1761 if (((flags
& 2) == 0) && (pLZ_codes
< pLZ_code_buf_end
))
1765 MZ_ASSERT(d
->m_huff_code_sizes
[0][lit
]);
1766 TDEFL_PUT_BITS_FAST(d
->m_huff_codes
[0][lit
], d
->m_huff_code_sizes
[0][lit
]);
1768 if (((flags
& 2) == 0) && (pLZ_codes
< pLZ_code_buf_end
))
1772 MZ_ASSERT(d
->m_huff_code_sizes
[0][lit
]);
1773 TDEFL_PUT_BITS_FAST(d
->m_huff_codes
[0][lit
], d
->m_huff_code_sizes
[0][lit
]);
1778 if (pOutput_buf
>= d
->m_pOutput_buf_end
)
1781 *(mz_uint64
*)pOutput_buf
= bit_buffer
;
1782 pOutput_buf
+= (bits_in
>> 3);
1783 bit_buffer
>>= (bits_in
& ~7);
1787 #undef TDEFL_PUT_BITS_FAST
1789 d
->m_pOutput_buf
= pOutput_buf
;
1791 d
->m_bit_buffer
= 0;
1795 mz_uint32 n
= MZ_MIN(bits_in
, 16);
1796 TDEFL_PUT_BITS((mz_uint
)bit_buffer
& mz_bitmasks
[n
], n
);
1801 TDEFL_PUT_BITS(d
->m_huff_codes
[0][256], d
->m_huff_code_sizes
[0][256]);
1803 return (d
->m_pOutput_buf
< d
->m_pOutput_buf_end
);
1806 static mz_bool
tdefl_compress_lz_codes(tdefl_compressor
*d
)
1809 mz_uint8
*pLZ_codes
;
1812 for (pLZ_codes
= d
->m_lz_code_buf
; pLZ_codes
< d
->m_pLZ_code_buf
; flags
>>= 1)
1815 flags
= *pLZ_codes
++ | 0x100;
1818 mz_uint sym
, num_extra_bits
;
1819 mz_uint match_len
= pLZ_codes
[0], match_dist
= (pLZ_codes
[1] | (pLZ_codes
[2] << 8)); pLZ_codes
+= 3;
1821 MZ_ASSERT(d
->m_huff_code_sizes
[0][s_tdefl_len_sym
[match_len
]]);
1822 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
]]);
1823 TDEFL_PUT_BITS(match_len
& mz_bitmasks
[s_tdefl_len_extra
[match_len
]], s_tdefl_len_extra
[match_len
]);
1825 if (match_dist
< 512)
1827 sym
= s_tdefl_small_dist_sym
[match_dist
]; num_extra_bits
= s_tdefl_small_dist_extra
[match_dist
];
1831 sym
= s_tdefl_large_dist_sym
[match_dist
>> 8]; num_extra_bits
= s_tdefl_large_dist_extra
[match_dist
>> 8];
1833 MZ_ASSERT(d
->m_huff_code_sizes
[1][sym
]);
1834 TDEFL_PUT_BITS(d
->m_huff_codes
[1][sym
], d
->m_huff_code_sizes
[1][sym
]);
1835 TDEFL_PUT_BITS(match_dist
& mz_bitmasks
[num_extra_bits
], num_extra_bits
);
1839 mz_uint lit
= *pLZ_codes
++;
1840 MZ_ASSERT(d
->m_huff_code_sizes
[0][lit
]);
1841 TDEFL_PUT_BITS(d
->m_huff_codes
[0][lit
], d
->m_huff_code_sizes
[0][lit
]);
1845 TDEFL_PUT_BITS(d
->m_huff_codes
[0][256], d
->m_huff_code_sizes
[0][256]);
1847 return (d
->m_pOutput_buf
< d
->m_pOutput_buf_end
);
1849 #endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS
1851 static mz_bool
tdefl_compress_block(tdefl_compressor
*d
, mz_bool static_block
)
1854 tdefl_start_static_block(d
);
1856 tdefl_start_dynamic_block(d
);
1857 return tdefl_compress_lz_codes(d
);
1860 static int tdefl_flush_block(tdefl_compressor
*d
, int flush
)
1862 mz_uint saved_bit_buf
, saved_bits_in
;
1863 mz_uint8
*pSaved_output_buf
;
1864 mz_bool comp_block_succeeded
= MZ_FALSE
;
1865 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
;
1866 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
;
1868 d
->m_pOutput_buf
= pOutput_buf_start
;
1869 d
->m_pOutput_buf_end
= d
->m_pOutput_buf
+ TDEFL_OUT_BUF_SIZE
- 16;
1871 MZ_ASSERT(!d
->m_output_flush_remaining
);
1872 d
->m_output_flush_ofs
= 0;
1873 d
->m_output_flush_remaining
= 0;
1875 *d
->m_pLZ_flags
= (mz_uint8
)(*d
->m_pLZ_flags
>> d
->m_num_flags_left
);
1876 d
->m_pLZ_code_buf
-= (d
->m_num_flags_left
== 8);
1878 if ((d
->m_flags
& TDEFL_WRITE_ZLIB_HEADER
) && (!d
->m_block_index
))
1880 TDEFL_PUT_BITS(0x78, 8); TDEFL_PUT_BITS(0x01, 8);
1883 TDEFL_PUT_BITS(flush
== TDEFL_FINISH
, 1);
1885 pSaved_output_buf
= d
->m_pOutput_buf
; saved_bit_buf
= d
->m_bit_buffer
; saved_bits_in
= d
->m_bits_in
;
1888 comp_block_succeeded
= tdefl_compress_block(d
, (d
->m_flags
& TDEFL_FORCE_ALL_STATIC_BLOCKS
) || (d
->m_total_lz_bytes
< 48));
1890 // If the block gets expanded, forget the current contents of the output buffer and send a raw block instead.
1891 if ( ((use_raw_block
) || ((d
->m_total_lz_bytes
) && ((d
->m_pOutput_buf
- pSaved_output_buf
+ 1U) >= d
->m_total_lz_bytes
))) &&
1892 ((d
->m_lookahead_pos
- d
->m_lz_code_buf_dict_pos
) <= d
->m_dict_size
) )
1894 mz_uint i
; d
->m_pOutput_buf
= pSaved_output_buf
; d
->m_bit_buffer
= saved_bit_buf
, d
->m_bits_in
= saved_bits_in
;
1895 TDEFL_PUT_BITS(0, 2);
1896 if (d
->m_bits_in
) { TDEFL_PUT_BITS(0, 8 - d
->m_bits_in
); }
1897 for (i
= 2; i
; --i
, d
->m_total_lz_bytes
^= 0xFFFF)
1899 TDEFL_PUT_BITS(d
->m_total_lz_bytes
& 0xFFFF, 16);
1901 for (i
= 0; i
< d
->m_total_lz_bytes
; ++i
)
1903 TDEFL_PUT_BITS(d
->m_dict
[(d
->m_lz_code_buf_dict_pos
+ i
) & TDEFL_LZ_DICT_SIZE_MASK
], 8);
1906 // Check for the extremely unlikely (if not impossible) case of the compressed block not fitting into the output buffer when using dynamic codes.
1907 else if (!comp_block_succeeded
)
1909 d
->m_pOutput_buf
= pSaved_output_buf
; d
->m_bit_buffer
= saved_bit_buf
, d
->m_bits_in
= saved_bits_in
;
1910 tdefl_compress_block(d
, MZ_TRUE
);
1915 if (flush
== TDEFL_FINISH
)
1917 if (d
->m_bits_in
) { TDEFL_PUT_BITS(0, 8 - d
->m_bits_in
); }
1918 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; } }
1922 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); }
1926 MZ_ASSERT(d
->m_pOutput_buf
< d
->m_pOutput_buf_end
);
1928 memset(&d
->m_huff_count
[0][0], 0, sizeof(d
->m_huff_count
[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0
);
1929 memset(&d
->m_huff_count
[1][0], 0, sizeof(d
->m_huff_count
[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1
);
1931 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
++;
1933 if ((n
= (int)(d
->m_pOutput_buf
- pOutput_buf_start
)) != 0)
1935 if (d
->m_pPut_buf_func
)
1937 *d
->m_pIn_buf_size
= d
->m_pSrc
- (const mz_uint8
*)d
->m_pIn_buf
;
1938 if (!(*d
->m_pPut_buf_func
)(d
->m_output_buf
, n
, d
->m_pPut_buf_user
))
1939 return (d
->m_prev_return_status
= TDEFL_STATUS_PUT_BUF_FAILED
);
1941 else if (pOutput_buf_start
== d
->m_output_buf
)
1943 int bytes_to_copy
= (int)MZ_MIN((size_t)n
, (size_t)(*d
->m_pOut_buf_size
- d
->m_out_buf_ofs
));
1944 memcpy((mz_uint8
*)d
->m_pOut_buf
+ d
->m_out_buf_ofs
, d
->m_output_buf
, bytes_to_copy
);
1945 d
->m_out_buf_ofs
+= bytes_to_copy
;
1946 if ((n
-= bytes_to_copy
) != 0)
1948 d
->m_output_flush_ofs
= bytes_to_copy
;
1949 d
->m_output_flush_remaining
= n
;
1954 d
->m_out_buf_ofs
+= n
;
1958 return d
->m_output_flush_remaining
;
1961 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
1963 #pragma GCC diagnostic push
1964 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
1966 #define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16*)(p)
1967 static __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
)
1970 mz_uint dist
, pos
= lookahead_pos
& TDEFL_LZ_DICT_SIZE_MASK
, match_len
= *pMatch_len
, probe_pos
= pos
, next_probe_pos
, probe_len
;
1971 mz_uint num_probes_left
= d
->m_max_probes
[match_len
>= 32];
1972 const mz_uint16
*s
= (const mz_uint16
*)(d
->m_dict
+ pos
), *p
, *q
;
1973 mz_uint16 c01
= TDEFL_READ_UNALIGNED_WORD(&d
->m_dict
[pos
+ match_len
- 1]), s01
= TDEFL_READ_UNALIGNED_WORD(s
);
1974 MZ_ASSERT(max_match_len
<= TDEFL_MAX_MATCH_LEN
); if (max_match_len
<= match_len
) return;
1979 if (--num_probes_left
== 0) return;
1980 #define TDEFL_PROBE \
1981 next_probe_pos = d->m_next[probe_pos]; \
1982 if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \
1983 probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
1984 if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) break;
1985 TDEFL_PROBE
; TDEFL_PROBE
; TDEFL_PROBE
;
1987 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;
1988 do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p
) == TDEFL_READ_UNALIGNED_WORD(++q
)) && (TDEFL_READ_UNALIGNED_WORD(++p
) == TDEFL_READ_UNALIGNED_WORD(++q
)) &&
1989 (TDEFL_READ_UNALIGNED_WORD(++p
) == TDEFL_READ_UNALIGNED_WORD(++q
)) && (TDEFL_READ_UNALIGNED_WORD(++p
) == TDEFL_READ_UNALIGNED_WORD(++q
)) && (--probe_len
> 0) );
1992 *pMatch_dist
= dist
; *pMatch_len
= MZ_MIN(max_match_len
, TDEFL_MAX_MATCH_LEN
); break;
1994 else if ((probe_len
= ((mz_uint
)(p
- s
) * 2) + (mz_uint
)(*(const mz_uint8
*)p
== *(const mz_uint8
*)q
)) > match_len
)
1996 *pMatch_dist
= dist
; if ((*pMatch_len
= match_len
= MZ_MIN(max_match_len
, probe_len
)) == max_match_len
) break;
1997 c01
= TDEFL_READ_UNALIGNED_WORD(&d
->m_dict
[pos
+ match_len
- 1]);
2002 #pragma GCC diagnostic pop
2006 #if defined(__aarch64__) || defined(__arm__)
2007 #pragma GCC diagnostic push
2008 #pragma GCC diagnostic ignored "-Wmisleading-indentation"
2011 static __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
)
2013 mz_uint dist
, pos
= lookahead_pos
& TDEFL_LZ_DICT_SIZE_MASK
, match_len
= *pMatch_len
, probe_pos
= pos
, next_probe_pos
, probe_len
;
2014 mz_uint num_probes_left
= d
->m_max_probes
[match_len
>= 32];
2015 const mz_uint8
*s
= d
->m_dict
+ pos
, *p
, *q
;
2016 mz_uint8 c0
= d
->m_dict
[pos
+ match_len
], c1
= d
->m_dict
[pos
+ match_len
- 1];
2017 MZ_ASSERT(max_match_len
<= TDEFL_MAX_MATCH_LEN
); if (max_match_len
<= match_len
) return;
2022 if (--num_probes_left
== 0) return;
2023 #define TDEFL_PROBE \
2024 next_probe_pos = d->m_next[probe_pos]; \
2025 if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \
2026 probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
2027 if ((d->m_dict[probe_pos + match_len] == c0) && (d->m_dict[probe_pos + match_len - 1] == c1)) break;
2028 TDEFL_PROBE
; TDEFL_PROBE
; TDEFL_PROBE
;
2030 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;
2031 if (probe_len
> match_len
)
2033 *pMatch_dist
= dist
; if ((*pMatch_len
= match_len
= probe_len
) == max_match_len
) return;
2034 c0
= d
->m_dict
[pos
+ match_len
]; c1
= d
->m_dict
[pos
+ match_len
- 1];
2039 #if defined(__aarch64__) || defined(__arm__)
2040 #pragma GCC diagnostic pop
2043 #endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
2045 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
2046 #pragma GCC diagnostic push
2047 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
2048 static mz_bool
tdefl_compress_fast(tdefl_compressor
*d
)
2050 // Faster, minimally featured LZRW1-style match+parse loop with better register utilization. Intended for applications where raw throughput is valued more highly than ratio.
2051 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
;
2052 mz_uint8
*pLZ_code_buf
= d
->m_pLZ_code_buf
, *pLZ_flags
= d
->m_pLZ_flags
;
2053 mz_uint cur_pos
= lookahead_pos
& TDEFL_LZ_DICT_SIZE_MASK
;
2055 while ((d
->m_src_buf_left
) || ((d
->m_flush
) && (lookahead_size
)))
2057 const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE
= 4096;
2058 mz_uint dst_pos
= (lookahead_pos
+ lookahead_size
) & TDEFL_LZ_DICT_SIZE_MASK
;
2059 mz_uint num_bytes_to_process
= (mz_uint
)MZ_MIN(d
->m_src_buf_left
, TDEFL_COMP_FAST_LOOKAHEAD_SIZE
- lookahead_size
);
2060 d
->m_src_buf_left
-= num_bytes_to_process
;
2061 lookahead_size
+= num_bytes_to_process
;
2063 while (num_bytes_to_process
)
2065 mz_uint32 n
= MZ_MIN(TDEFL_LZ_DICT_SIZE
- dst_pos
, num_bytes_to_process
);
2066 memcpy(d
->m_dict
+ dst_pos
, d
->m_pSrc
, n
);
2067 if (dst_pos
< (TDEFL_MAX_MATCH_LEN
- 1))
2068 memcpy(d
->m_dict
+ TDEFL_LZ_DICT_SIZE
+ dst_pos
, d
->m_pSrc
, MZ_MIN(n
, (TDEFL_MAX_MATCH_LEN
- 1) - dst_pos
));
2070 dst_pos
= (dst_pos
+ n
) & TDEFL_LZ_DICT_SIZE_MASK
;
2071 num_bytes_to_process
-= n
;
2074 dict_size
= MZ_MIN(TDEFL_LZ_DICT_SIZE
- lookahead_size
, dict_size
);
2075 if ((!d
->m_flush
) && (lookahead_size
< TDEFL_COMP_FAST_LOOKAHEAD_SIZE
)) break;
2077 while (lookahead_size
>= 4)
2079 mz_uint cur_match_dist
, cur_match_len
= 1;
2080 mz_uint8
*pCur_dict
= d
->m_dict
+ cur_pos
;
2081 mz_uint first_trigram
= (*(const mz_uint32
*)pCur_dict
) & 0xFFFFFF;
2082 mz_uint hash
= (first_trigram
^ (first_trigram
>> (24 - (TDEFL_LZ_HASH_BITS
- 8)))) & TDEFL_LEVEL1_HASH_SIZE_MASK
;
2083 mz_uint probe_pos
= d
->m_hash
[hash
];
2084 d
->m_hash
[hash
] = (mz_uint16
)lookahead_pos
;
2086 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
))
2088 const mz_uint16
*p
= (const mz_uint16
*)pCur_dict
;
2089 const mz_uint16
*q
= (const mz_uint16
*)(d
->m_dict
+ probe_pos
);
2090 mz_uint32 probe_len
= 32;
2091 do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p
) == TDEFL_READ_UNALIGNED_WORD(++q
)) && (TDEFL_READ_UNALIGNED_WORD(++p
) == TDEFL_READ_UNALIGNED_WORD(++q
)) &&
2092 (TDEFL_READ_UNALIGNED_WORD(++p
) == TDEFL_READ_UNALIGNED_WORD(++q
)) && (TDEFL_READ_UNALIGNED_WORD(++p
) == TDEFL_READ_UNALIGNED_WORD(++q
)) && (--probe_len
> 0) );
2093 cur_match_len
= ((mz_uint
)(p
- (const mz_uint16
*)pCur_dict
) * 2) + (mz_uint
)(*(const mz_uint8
*)p
== *(const mz_uint8
*)q
);
2095 cur_match_len
= cur_match_dist
? TDEFL_MAX_MATCH_LEN
: 0;
2097 if ((cur_match_len
< TDEFL_MIN_MATCH_LEN
) || ((cur_match_len
== TDEFL_MIN_MATCH_LEN
) && (cur_match_dist
>= 8U*1024U)))
2100 *pLZ_code_buf
++ = (mz_uint8
)first_trigram
;
2101 *pLZ_flags
= (mz_uint8
)(*pLZ_flags
>> 1);
2102 d
->m_huff_count
[0][(mz_uint8
)first_trigram
]++;
2107 cur_match_len
= MZ_MIN(cur_match_len
, lookahead_size
);
2109 MZ_ASSERT((cur_match_len
>= TDEFL_MIN_MATCH_LEN
) && (cur_match_dist
>= 1) && (cur_match_dist
<= TDEFL_LZ_DICT_SIZE
));
2113 pLZ_code_buf
[0] = (mz_uint8
)(cur_match_len
- TDEFL_MIN_MATCH_LEN
);
2114 *(mz_uint16
*)(&pLZ_code_buf
[1]) = (mz_uint16
)cur_match_dist
;
2116 *pLZ_flags
= (mz_uint8
)((*pLZ_flags
>> 1) | 0x80);
2118 s0
= s_tdefl_small_dist_sym
[cur_match_dist
& 511];
2119 s1
= s_tdefl_large_dist_sym
[cur_match_dist
>> 8];
2120 d
->m_huff_count
[1][(cur_match_dist
< 512) ? s0
: s1
]++;
2122 d
->m_huff_count
[0][s_tdefl_len_sym
[cur_match_len
- TDEFL_MIN_MATCH_LEN
]]++;
2127 *pLZ_code_buf
++ = (mz_uint8
)first_trigram
;
2128 *pLZ_flags
= (mz_uint8
)(*pLZ_flags
>> 1);
2129 d
->m_huff_count
[0][(mz_uint8
)first_trigram
]++;
2132 if (--num_flags_left
== 0) { num_flags_left
= 8; pLZ_flags
= pLZ_code_buf
++; }
2134 total_lz_bytes
+= cur_match_len
;
2135 lookahead_pos
+= cur_match_len
;
2136 dict_size
= MZ_MIN(dict_size
+ cur_match_len
, TDEFL_LZ_DICT_SIZE
);
2137 cur_pos
= (cur_pos
+ cur_match_len
) & TDEFL_LZ_DICT_SIZE_MASK
;
2138 MZ_ASSERT(lookahead_size
>= cur_match_len
);
2139 lookahead_size
-= cur_match_len
;
2141 if (pLZ_code_buf
> &d
->m_lz_code_buf
[TDEFL_LZ_CODE_BUF_SIZE
- 8])
2144 d
->m_lookahead_pos
= lookahead_pos
; d
->m_lookahead_size
= lookahead_size
; d
->m_dict_size
= dict_size
;
2145 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
;
2146 if ((n
= tdefl_flush_block(d
, 0)) != 0)
2147 return (n
< 0) ? MZ_FALSE
: MZ_TRUE
;
2148 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
;
2152 while (lookahead_size
)
2154 mz_uint8 lit
= d
->m_dict
[cur_pos
];
2157 *pLZ_code_buf
++ = lit
;
2158 *pLZ_flags
= (mz_uint8
)(*pLZ_flags
>> 1);
2159 if (--num_flags_left
== 0) { num_flags_left
= 8; pLZ_flags
= pLZ_code_buf
++; }
2161 d
->m_huff_count
[0][lit
]++;
2164 dict_size
= MZ_MIN(dict_size
+ 1, TDEFL_LZ_DICT_SIZE
);
2165 cur_pos
= (cur_pos
+ 1) & TDEFL_LZ_DICT_SIZE_MASK
;
2168 if (pLZ_code_buf
> &d
->m_lz_code_buf
[TDEFL_LZ_CODE_BUF_SIZE
- 8])
2171 d
->m_lookahead_pos
= lookahead_pos
; d
->m_lookahead_size
= lookahead_size
; d
->m_dict_size
= dict_size
;
2172 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
;
2173 if ((n
= tdefl_flush_block(d
, 0)) != 0)
2174 return (n
< 0) ? MZ_FALSE
: MZ_TRUE
;
2175 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
;
2180 d
->m_lookahead_pos
= lookahead_pos
; d
->m_lookahead_size
= lookahead_size
; d
->m_dict_size
= dict_size
;
2181 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
;
2184 #pragma GCC diagnostic pop
2185 #endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
2187 static __forceinline
void tdefl_record_literal(tdefl_compressor
*d
, mz_uint8 lit
)
2189 d
->m_total_lz_bytes
++;
2190 *d
->m_pLZ_code_buf
++ = lit
;
2191 *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
++; }
2192 d
->m_huff_count
[0][lit
]++;
2195 static __forceinline
void tdefl_record_match(tdefl_compressor
*d
, mz_uint match_len
, mz_uint match_dist
)
2199 MZ_ASSERT((match_len
>= TDEFL_MIN_MATCH_LEN
) && (match_dist
>= 1) && (match_dist
<= TDEFL_LZ_DICT_SIZE
));
2201 d
->m_total_lz_bytes
+= match_len
;
2203 d
->m_pLZ_code_buf
[0] = (mz_uint8
)(match_len
- TDEFL_MIN_MATCH_LEN
);
2206 d
->m_pLZ_code_buf
[1] = (mz_uint8
)(match_dist
& 0xFF);
2207 d
->m_pLZ_code_buf
[2] = (mz_uint8
)(match_dist
>> 8); d
->m_pLZ_code_buf
+= 3;
2209 *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
++; }
2211 s0
= s_tdefl_small_dist_sym
[match_dist
& 511]; s1
= s_tdefl_large_dist_sym
[match_dist
>> 8];
2212 d
->m_huff_count
[1][(match_dist
< 512) ? s0
: s1
]++;
2214 d
->m_huff_count
[0][s_tdefl_len_sym
[match_len
- TDEFL_MIN_MATCH_LEN
]]++;
2217 static mz_bool
tdefl_compress_normal(tdefl_compressor
*d
)
2219 const mz_uint8
*pSrc
= d
->m_pSrc
; size_t src_buf_left
= d
->m_src_buf_left
;
2220 tdefl_flush flush
= d
->m_flush
;
2222 while ((src_buf_left
) || ((flush
) && (d
->m_lookahead_size
)))
2224 mz_uint len_to_move
, cur_match_dist
, cur_match_len
, cur_pos
;
2225 // Update dictionary and hash chains. Keeps the lookahead size equal to TDEFL_MAX_MATCH_LEN.
2226 if ((d
->m_lookahead_size
+ d
->m_dict_size
) >= (TDEFL_MIN_MATCH_LEN
- 1))
2228 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;
2229 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
];
2230 mz_uint num_bytes_to_process
= (mz_uint
)MZ_MIN(src_buf_left
, TDEFL_MAX_MATCH_LEN
- d
->m_lookahead_size
);
2231 const mz_uint8
*pSrc_end
= pSrc
+ num_bytes_to_process
;
2232 src_buf_left
-= num_bytes_to_process
;
2233 d
->m_lookahead_size
+= num_bytes_to_process
;
2234 while (pSrc
!= pSrc_end
)
2236 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
;
2237 hash
= ((hash
<< TDEFL_LZ_HASH_SHIFT
) ^ c
) & (TDEFL_LZ_HASH_SIZE
- 1);
2238 d
->m_next
[ins_pos
& TDEFL_LZ_DICT_SIZE_MASK
] = d
->m_hash
[hash
]; d
->m_hash
[hash
] = (mz_uint16
)(ins_pos
);
2239 dst_pos
= (dst_pos
+ 1) & TDEFL_LZ_DICT_SIZE_MASK
; ins_pos
++;
2244 while ((src_buf_left
) && (d
->m_lookahead_size
< TDEFL_MAX_MATCH_LEN
))
2246 mz_uint8 c
= *pSrc
++;
2247 mz_uint dst_pos
= (d
->m_lookahead_pos
+ d
->m_lookahead_size
) & TDEFL_LZ_DICT_SIZE_MASK
;
2249 d
->m_dict
[dst_pos
] = c
;
2250 if (dst_pos
< (TDEFL_MAX_MATCH_LEN
- 1))
2251 d
->m_dict
[TDEFL_LZ_DICT_SIZE
+ dst_pos
] = c
;
2252 if ((++d
->m_lookahead_size
+ d
->m_dict_size
) >= TDEFL_MIN_MATCH_LEN
)
2254 mz_uint ins_pos
= d
->m_lookahead_pos
+ (d
->m_lookahead_size
- 1) - 2;
2255 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);
2256 d
->m_next
[ins_pos
& TDEFL_LZ_DICT_SIZE_MASK
] = d
->m_hash
[hash
]; d
->m_hash
[hash
] = (mz_uint16
)(ins_pos
);
2260 d
->m_dict_size
= MZ_MIN(TDEFL_LZ_DICT_SIZE
- d
->m_lookahead_size
, d
->m_dict_size
);
2261 if ((!flush
) && (d
->m_lookahead_size
< TDEFL_MAX_MATCH_LEN
))
2264 // Simple lazy/greedy parsing state machine.
2265 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
;
2266 if (d
->m_flags
& (TDEFL_RLE_MATCHES
| TDEFL_FORCE_ALL_RAW_BLOCKS
))
2268 if ((d
->m_dict_size
) && (!(d
->m_flags
& TDEFL_FORCE_ALL_RAW_BLOCKS
)))
2270 mz_uint8 c
= d
->m_dict
[(cur_pos
- 1) & TDEFL_LZ_DICT_SIZE_MASK
];
2271 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
++; }
2272 if (cur_match_len
< TDEFL_MIN_MATCH_LEN
) cur_match_len
= 0; else cur_match_dist
= 1;
2277 tdefl_find_match(d
, d
->m_lookahead_pos
, d
->m_dict_size
, d
->m_lookahead_size
, &cur_match_dist
, &cur_match_len
);
2279 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)))
2281 cur_match_dist
= cur_match_len
= 0;
2283 if (d
->m_saved_match_len
)
2285 if (cur_match_len
> d
->m_saved_match_len
)
2287 tdefl_record_literal(d
, (mz_uint8
)d
->m_saved_lit
);
2288 if (cur_match_len
>= 128)
2290 tdefl_record_match(d
, cur_match_len
, cur_match_dist
);
2291 d
->m_saved_match_len
= 0; len_to_move
= cur_match_len
;
2295 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
;
2300 tdefl_record_match(d
, d
->m_saved_match_len
, d
->m_saved_match_dist
);
2301 len_to_move
= d
->m_saved_match_len
- 1; d
->m_saved_match_len
= 0;
2304 else if (!cur_match_dist
)
2305 tdefl_record_literal(d
, d
->m_dict
[cur_pos
]);
2306 else if ((d
->m_greedy_parsing
) || (d
->m_flags
& TDEFL_RLE_MATCHES
) || (cur_match_len
>= 128))
2308 tdefl_record_match(d
, cur_match_len
, cur_match_dist
);
2309 len_to_move
= cur_match_len
;
2313 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
;
2315 // Move the lookahead forward by len_to_move bytes.
2316 d
->m_lookahead_pos
+= len_to_move
;
2317 MZ_ASSERT(d
->m_lookahead_size
>= len_to_move
);
2318 d
->m_lookahead_size
-= len_to_move
;
2319 d
->m_dict_size
= MZ_MIN(d
->m_dict_size
+ len_to_move
, TDEFL_LZ_DICT_SIZE
);
2320 // Check if it's time to flush the current LZ codes to the internal output buffer.
2321 if ( (d
->m_pLZ_code_buf
> &d
->m_lz_code_buf
[TDEFL_LZ_CODE_BUF_SIZE
- 8]) ||
2322 ( (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
))) )
2325 d
->m_pSrc
= pSrc
; d
->m_src_buf_left
= src_buf_left
;
2326 if ((n
= tdefl_flush_block(d
, 0)) != 0)
2327 return (n
< 0) ? MZ_FALSE
: MZ_TRUE
;
2331 d
->m_pSrc
= pSrc
; d
->m_src_buf_left
= src_buf_left
;
2335 static tdefl_status
tdefl_flush_output_buffer(tdefl_compressor
*d
)
2337 if (d
->m_pIn_buf_size
)
2339 *d
->m_pIn_buf_size
= d
->m_pSrc
- (const mz_uint8
*)d
->m_pIn_buf
;
2342 if (d
->m_pOut_buf_size
)
2344 size_t n
= MZ_MIN(*d
->m_pOut_buf_size
- d
->m_out_buf_ofs
, d
->m_output_flush_remaining
);
2345 memcpy((mz_uint8
*)d
->m_pOut_buf
+ d
->m_out_buf_ofs
, d
->m_output_buf
+ d
->m_output_flush_ofs
, n
);
2346 d
->m_output_flush_ofs
+= (mz_uint
)n
;
2347 d
->m_output_flush_remaining
-= (mz_uint
)n
;
2348 d
->m_out_buf_ofs
+= n
;
2350 *d
->m_pOut_buf_size
= d
->m_out_buf_ofs
;
2353 return (d
->m_finished
&& !d
->m_output_flush_remaining
) ? TDEFL_STATUS_DONE
: TDEFL_STATUS_OKAY
;
2356 tdefl_status
tdefl_compress(tdefl_compressor
*d
, const void *pIn_buf
, size_t *pIn_buf_size
, void *pOut_buf
, size_t *pOut_buf_size
, tdefl_flush flush
)
2360 if (pIn_buf_size
) *pIn_buf_size
= 0;
2361 if (pOut_buf_size
) *pOut_buf_size
= 0;
2362 return TDEFL_STATUS_BAD_PARAM
;
2365 d
->m_pIn_buf
= pIn_buf
; d
->m_pIn_buf_size
= pIn_buf_size
;
2366 d
->m_pOut_buf
= pOut_buf
; d
->m_pOut_buf_size
= pOut_buf_size
;
2367 d
->m_pSrc
= (const mz_uint8
*)(pIn_buf
); d
->m_src_buf_left
= pIn_buf_size
? *pIn_buf_size
: 0;
2368 d
->m_out_buf_ofs
= 0;
2371 if ( ((d
->m_pPut_buf_func
!= NULL
) == ((pOut_buf
!= NULL
) || (pOut_buf_size
!= NULL
))) || (d
->m_prev_return_status
!= TDEFL_STATUS_OKAY
) ||
2372 (d
->m_wants_to_finish
&& (flush
!= TDEFL_FINISH
)) || (pIn_buf_size
&& *pIn_buf_size
&& !pIn_buf
) || (pOut_buf_size
&& *pOut_buf_size
&& !pOut_buf
) )
2374 if (pIn_buf_size
) *pIn_buf_size
= 0;
2375 if (pOut_buf_size
) *pOut_buf_size
= 0;
2376 return (d
->m_prev_return_status
= TDEFL_STATUS_BAD_PARAM
);
2378 d
->m_wants_to_finish
|= (flush
== TDEFL_FINISH
);
2380 if ((d
->m_output_flush_remaining
) || (d
->m_finished
))
2381 return (d
->m_prev_return_status
= tdefl_flush_output_buffer(d
));
2383 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
2384 if (((d
->m_flags
& TDEFL_MAX_PROBES_MASK
) == 1) &&
2385 ((d
->m_flags
& TDEFL_GREEDY_PARSING_FLAG
) != 0) &&
2386 ((d
->m_flags
& (TDEFL_FILTER_MATCHES
| TDEFL_FORCE_ALL_RAW_BLOCKS
| TDEFL_RLE_MATCHES
)) == 0))
2388 if (!tdefl_compress_fast(d
))
2389 return d
->m_prev_return_status
;
2392 #endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
2394 if (!tdefl_compress_normal(d
))
2395 return d
->m_prev_return_status
;
2398 if ((d
->m_flags
& (TDEFL_WRITE_ZLIB_HEADER
| TDEFL_COMPUTE_ADLER32
)) && (pIn_buf
))
2399 d
->m_adler32
= (mz_uint32
)mz_adler32(d
->m_adler32
, (const mz_uint8
*)pIn_buf
, d
->m_pSrc
- (const mz_uint8
*)pIn_buf
);
2401 if (d
->m_flags
& TDEFL_COMPUTE_CRC32
)
2402 d
->m_crc32
= (mz_uint32
)mz_crc32(d
->m_crc32
, (const mz_uint8
*)pIn_buf
, d
->m_pSrc
- (const mz_uint8
*)pIn_buf
);
2404 if ((flush
) && (!d
->m_lookahead_size
) && (!d
->m_src_buf_left
) && (!d
->m_output_flush_remaining
))
2406 if (tdefl_flush_block(d
, flush
) < 0)
2407 return d
->m_prev_return_status
;
2408 d
->m_finished
= (flush
== TDEFL_FINISH
);
2409 if (flush
== TDEFL_FULL_FLUSH
) { MZ_CLEAR_OBJ(d
->m_hash
); MZ_CLEAR_OBJ(d
->m_next
); d
->m_dict_size
= 0; }
2412 return (d
->m_prev_return_status
= tdefl_flush_output_buffer(d
));
2415 tdefl_status
tdefl_compress_buffer(tdefl_compressor
*d
, const void *pIn_buf
, size_t in_buf_size
, tdefl_flush flush
)
2417 MZ_ASSERT(d
->m_pPut_buf_func
); return tdefl_compress(d
, pIn_buf
, &in_buf_size
, NULL
, NULL
, flush
);
2420 tdefl_status
tdefl_init(tdefl_compressor
*d
, tdefl_put_buf_func_ptr pPut_buf_func
, void *pPut_buf_user
, int flags
)
2422 d
->m_pPut_buf_func
= pPut_buf_func
; d
->m_pPut_buf_user
= pPut_buf_user
;
2423 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;
2424 d
->m_max_probes
[1] = 1 + (((flags
& 0xFFF) >> 2) + 2) / 3;
2425 if (!(flags
& TDEFL_NONDETERMINISTIC_PARSING_FLAG
)) MZ_CLEAR_OBJ(d
->m_hash
);
2426 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;
2427 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;
2428 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;
2429 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
;
2430 d
->m_saved_match_dist
= d
->m_saved_match_len
= d
->m_saved_lit
= 0; d
->m_adler32
= 1; d
->m_crc32
= 1;
2431 d
->m_pIn_buf
= NULL
; d
->m_pOut_buf
= NULL
;
2432 d
->m_pIn_buf_size
= NULL
; d
->m_pOut_buf_size
= NULL
;
2433 d
->m_flush
= TDEFL_NO_FLUSH
; d
->m_pSrc
= NULL
; d
->m_src_buf_left
= 0; d
->m_out_buf_ofs
= 0;
2434 memset(&d
->m_huff_count
[0][0], 0, sizeof(d
->m_huff_count
[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0
);
2435 memset(&d
->m_huff_count
[1][0], 0, sizeof(d
->m_huff_count
[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1
);
2436 return TDEFL_STATUS_OKAY
;
2439 tdefl_status
tdefl_get_prev_return_status(tdefl_compressor
*d
)
2441 return d
->m_prev_return_status
;
2444 mz_uint32
tdefl_get_adler32(tdefl_compressor
*d
)
2446 return d
->m_adler32
;
2449 mz_uint32
tdefl_get_crc32(tdefl_compressor
*d
)
2454 mz_bool
tdefl_compress_mem_to_output(const void *pBuf
, size_t buf_len
, tdefl_put_buf_func_ptr pPut_buf_func
, void *pPut_buf_user
, int flags
)
2456 tdefl_compressor
*pComp
; mz_bool succeeded
; if (((buf_len
) && (!pBuf
)) || (!pPut_buf_func
)) return MZ_FALSE
;
2457 pComp
= (tdefl_compressor
*)MZ_MALLOC(sizeof(tdefl_compressor
)); if (!pComp
) return MZ_FALSE
;
2458 succeeded
= (tdefl_init(pComp
, pPut_buf_func
, pPut_buf_user
, flags
) == TDEFL_STATUS_OKAY
);
2459 succeeded
= succeeded
&& (tdefl_compress_buffer(pComp
, pBuf
, buf_len
, TDEFL_FINISH
) == TDEFL_STATUS_DONE
);
2460 MZ_FREE(pComp
); return succeeded
;
2465 size_t m_size
, m_capacity
;
2467 mz_bool m_expandable
;
2468 } tdefl_output_buffer
;
2470 static mz_bool
tdefl_output_buffer_putter(const void *pBuf
, int len
, void *pUser
)
2472 tdefl_output_buffer
*p
= (tdefl_output_buffer
*)pUser
;
2473 size_t new_size
= p
->m_size
+ len
;
2474 if (new_size
> p
->m_capacity
)
2476 size_t new_capacity
= p
->m_capacity
; mz_uint8
*pNew_buf
; if (!p
->m_expandable
) return MZ_FALSE
;
2477 do { new_capacity
= MZ_MAX(128U, new_capacity
<< 1U); } while (new_size
> new_capacity
);
2478 pNew_buf
= (mz_uint8
*)MZ_REALLOC(p
->m_pBuf
, new_capacity
); if (!pNew_buf
) return MZ_FALSE
;
2479 p
->m_pBuf
= pNew_buf
; p
->m_capacity
= new_capacity
;
2481 memcpy((mz_uint8
*)p
->m_pBuf
+ p
->m_size
, pBuf
, len
); p
->m_size
= new_size
;
2485 void *tdefl_compress_mem_to_heap(const void *pSrc_buf
, size_t src_buf_len
, size_t *pOut_len
, int flags
)
2487 tdefl_output_buffer out_buf
; MZ_CLEAR_OBJ(out_buf
);
2488 if (!pOut_len
) return MZ_FALSE
; else *pOut_len
= 0;
2489 out_buf
.m_expandable
= MZ_TRUE
;
2490 if (!tdefl_compress_mem_to_output(pSrc_buf
, src_buf_len
, tdefl_output_buffer_putter
, &out_buf
, flags
)) return NULL
;
2491 *pOut_len
= out_buf
.m_size
; return out_buf
.m_pBuf
;
2494 size_t tdefl_compress_mem_to_mem(void *pOut_buf
, size_t out_buf_len
, const void *pSrc_buf
, size_t src_buf_len
, int flags
)
2496 tdefl_output_buffer out_buf
; MZ_CLEAR_OBJ(out_buf
);
2497 if (!pOut_buf
) return 0;
2498 out_buf
.m_pBuf
= (mz_uint8
*)pOut_buf
; out_buf
.m_capacity
= out_buf_len
;
2499 if (!tdefl_compress_mem_to_output(pSrc_buf
, src_buf_len
, tdefl_output_buffer_putter
, &out_buf
, flags
)) return 0;
2500 return out_buf
.m_size
;
2503 static const mz_uint s_tdefl_num_probes
[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
2505 // 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).
2506 mz_uint
tdefl_create_comp_flags_from_zip_params(int level
, int window_bits
, int strategy
)
2508 mz_uint comp_flags
= s_tdefl_num_probes
[(level
>= 0) ? MZ_MIN(10, level
) : MZ_DEFAULT_LEVEL
] | ((level
<= 3) ? TDEFL_GREEDY_PARSING_FLAG
: 0);
2509 if (window_bits
> 0) comp_flags
|= TDEFL_WRITE_ZLIB_HEADER
;
2511 if (!level
) comp_flags
|= TDEFL_FORCE_ALL_RAW_BLOCKS
;
2512 else if (strategy
== MZ_FILTERED
) comp_flags
|= TDEFL_FILTER_MATCHES
;
2513 else if (strategy
== MZ_HUFFMAN_ONLY
) comp_flags
&= ~TDEFL_MAX_PROBES_MASK
;
2514 else if (strategy
== MZ_FIXED
) comp_flags
|= TDEFL_FORCE_ALL_STATIC_BLOCKS
;
2515 else if (strategy
== MZ_RLE
) comp_flags
|= TDEFL_RLE_MATCHES
;
2521 #pragma warning (push)
2522 #pragma warning (disable:4204) // nonstandard extension used : non-constant aggregate initializer (also supported by GNU C and C99, so no big deal)
2525 // Simple PNG writer function by Alex Evans, 2011. Released into the public domain: https://gist.github.com/908299, more context at
2526 // http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/.
2527 void *tdefl_write_image_to_png_file_in_memory(const void *pImage
, int w
, int h
, int num_chans
, size_t *pLen_out
)
2529 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;
2530 if (!pComp
) return NULL
;
2531 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
; }
2532 // write dummy header
2533 for (z
= 41; z
; --z
) tdefl_output_buffer_putter(&z
, 1, &out_buf
);
2534 // compress image data
2535 tdefl_init(pComp
, tdefl_output_buffer_putter
, &out_buf
, TDEFL_DEFAULT_MAX_PROBES
| TDEFL_WRITE_ZLIB_HEADER
);
2536 for (y
= 0; y
< h
; ++y
) { tdefl_compress_buffer(pComp
, &z
, 1, TDEFL_NO_FLUSH
); tdefl_compress_buffer(pComp
, (mz_uint8
*)pImage
+ y
* bpl
, bpl
, TDEFL_NO_FLUSH
); }
2537 if (tdefl_compress_buffer(pComp
, NULL
, 0, TDEFL_FINISH
) != TDEFL_STATUS_DONE
) { MZ_FREE(pComp
); MZ_FREE(out_buf
.m_pBuf
); return NULL
; }
2538 // write real header
2539 *pLen_out
= out_buf
.m_size
-41;
2541 mz_uint8 pnghdr
[41]={0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52,
2542 0,0,(mz_uint8
)(w
>>8),(mz_uint8
)w
,0,0,(mz_uint8
)(h
>>8),(mz_uint8
)h
,8,"\0\0\04\02\06"[num_chans
],0,0,0,0,0,0,0,
2543 (mz_uint8
)(*pLen_out
>>24),(mz_uint8
)(*pLen_out
>>16),(mz_uint8
)(*pLen_out
>>8),(mz_uint8
)*pLen_out
,0x49,0x44,0x41,0x54};
2544 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);
2545 memcpy(out_buf
.m_pBuf
, pnghdr
, 41);
2547 // write footer (IDAT CRC-32, followed by IEND chunk)
2548 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
; }
2549 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);
2550 // compute final size of file, grab compressed data buffer and return
2551 *pLen_out
+= 57; MZ_FREE(pComp
); return out_buf
.m_pBuf
;
2555 #pragma warning (pop)
2558 #pragma GCC diagnostic pop
2560 #endif // MINIZ_HEADER_FILE_ONLY
2563 This is free and unencumbered software released into the public domain.
2565 Anyone is free to copy, modify, publish, use, compile, sell, or
2566 distribute this software, either in source code form or as a compiled
2567 binary, for any purpose, commercial or non-commercial, and by any
2570 In jurisdictions that recognize copyright laws, the author or authors
2571 of this software dedicate any and all copyright interest in the
2572 software to the public domain. We make this dedication for the benefit
2573 of the public at large and to the detriment of our heirs and
2574 successors. We intend this dedication to be an overt act of
2575 relinquishment in perpetuity of all present and future rights to this
2576 software under copyright law.
2578 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2579 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2580 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
2581 IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
2582 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2583 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2584 OTHER DEALINGS IN THE SOFTWARE.
2586 For more information, please refer to <http://unlicense.org/>