Fossil SCM

updated to miniz-1.16 beta r1

stephan 2016-02-02 15:58 UTC trunk
Commit 0cd368f1bfde792e1827994d02a5b4f7fa86fa9e
1 file changed +100 -30
+100 -30
--- src/miniz.c
+++ src/miniz.c
@@ -1,14 +1,29 @@
1
-/* miniz.c v1.15 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
1
+/* miniz.c v1.16 beta r1 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
22
See "unlicense" statement at the end of this file.
33
Rich Geldreich <[email protected]>, last updated Oct. 13, 2013
44
Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
55
66
Most API's defined in miniz.c are optional. For example, to disable the archive related functions just define
77
MINIZ_NO_ARCHIVE_APIS, or to get rid of all stdio usage define MINIZ_NO_STDIO (see the list below for more macros).
88
99
* Change History
10
+ 10/19/13 v1.16 beta r1 - Two key inflator-only robustness and streaming related changes. Also merged in tdefl_compressor_alloc(), tdefl_compressor_free() helpers to make script bindings easier for rustyzip.
11
+ - The inflator coroutine func. is subtle and complex so I'm being cautious about this release. I would greatly appreciate any help with testing or any feedback.
12
+ I feel good about these changes, and they've been through several hours of automated testing, but they will probably not fix anything for the majority of prev. users so I'm
13
+ going to mark this release as beta for a few weeks and continue testing it at work/home on various things.
14
+ - The inflator in raw (non-zlib) mode is now usable on gzip or similiar data streams that have a bunch of bytes following the raw deflate data (problem discovered by rustyzip author williamw520).
15
+ This version should *never* read beyond the last byte of the raw deflate data independent of how many bytes you pass into the input buffer. This issue was caused by the various Huffman bitbuffer lookahead optimizations, and
16
+ would not be an issue if the caller knew and enforced the precise size of the raw compressed data *or* if the compressed data was in zlib format (i.e. always followed by the byte aligned zlib adler32).
17
+ So in other words, you can now call the inflator on deflate streams that are followed by arbitrary amounts of data and it's guaranteed that decompression will stop exactly on the last byte.
18
+ - The inflator now has a new failure status: TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS (-4). Previously, if the inflator was starved of bytes and could not make progress (because the input buffer was empty and the
19
+ caller did not set the TINFL_FLAG_HAS_MORE_INPUT flag - say on truncated or corrupted compressed data stream) it would append all 0's to the input and try to soldier on.
20
+ This is scary, because in the worst case, I believe it was possible for the prev. inflator to start outputting large amounts of literal data. If the caller didn't know when to stop accepting output
21
+ (because it didn't know how much uncompressed data was expected, or didn't enforce a sane maximum) it could continue forever. v1.16 cannot fall into this failure mode, instead it'll return
22
+ TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS immediately if it needs 1 or more bytes to make progress, the input buf is empty, and the caller has indicated that no more input is available. This is a "soft"
23
+ failure, so you can call the inflator again with more input and it will try to continue, or you can give up and fail. This could be very useful in network streaming scenarios.
24
+ - Added documentation to all the tinfl return status codes, fixed miniz_tester so it accepts double minus params for Linux, tweaked example1.c, added a simple "follower bytes" test to miniz_tester.cpp.
1025
10/13/13 v1.15 r4 - Interim bugfix release while I work on the next major release with Zip64 support (almost there!):
1126
- Critical fix for the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY bug (thanks [email protected]) which could cause locate files to not find files. This bug
1227
would only have occured in earlier versions if you explicitly used this flag, OR if you used mz_zip_extract_archive_file_to_heap() or mz_zip_add_mem_to_archive_file_in_place()
1328
(which used this flag). If you can't switch to v1.15 but want to fix this bug, just remove the uses of this flag from both helper funcs (and of course don't use the flag).
1429
- Bugfix in mz_zip_reader_extract_to_mem_no_alloc() from kymoon when pUser_read_buf is not NULL and compressed size is > uncompressed size
@@ -25,11 +40,11 @@
2540
- Merged in some compiler fixes from paulharris's github repro.
2641
- Retested this build under Windows (VS 2010, including static analysis), tcc 0.9.26, gcc v4.6 and clang v3.3.
2742
- Added example6.c, which dumps an image of the mandelbrot set to a PNG file.
2843
- Modified example2 to help test the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY flag more.
2944
- In r3: Bugfix to mz_zip_writer_add_file() found during merge: Fix possible src file fclose() leak if alignment bytes+local header file write faiiled
30
- - In r4: Minor bugfix to mz_zip_writer_add_from_zip_reader(): Was pushing the wrong central dir header offset, appears harmless in this release, but it became a problem in the zip64 branch
45
+ - In r4: Minor bugfix to mz_zip_writer_add_from_zip_reader(): Was pushing the wrong central dir header offset, appears harmless in this release, but it became a problem in the zip64 branch
3146
5/20/12 v1.14 - MinGW32/64 GCC 4.6.1 compiler fixes: added MZ_FORCEINLINE, #include <time.h> (thanks fermtect).
3247
5/19/12 v1.13 - From [email protected] and [email protected] - Fix mz_crc32() so it doesn't compute the wrong CRC-32's when mz_ulong is 64-bit.
3348
- Temporarily/locally slammed in "typedef unsigned long mz_ulong" and re-ran a randomized regression test on ~500k files.
3449
- Eliminated a bunch of warnings when compiling with GCC 32-bit/64.
3550
- Ran all examples, miniz.c, and tinfl.c through MSVC 2008's /analyze (static analysis) option and fixed all warnings (except for the silly
@@ -251,10 +266,11 @@
251266
// Note that mz_alloc_func parameter types purpsosely differ from zlib's: items/size is size_t, not unsigned long.
252267
typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size);
253268
typedef void (*mz_free_func)(void *opaque, void *address);
254269
typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size);
255270
271
+// TODO: I can't encode "1.16" here, argh
256272
#define MZ_VERSION "9.1.15"
257273
#define MZ_VERNUM 0x91F0
258274
#define MZ_VER_MAJOR 9
259275
#define MZ_VER_MINOR 1
260276
#define MZ_VER_REVISION 15
@@ -719,16 +735,41 @@
719735
#define TINFL_LZ_DICT_SIZE 32768
720736
721737
// Return status.
722738
typedef enum
723739
{
740
+ // This flags indicates the inflator needs 1 or more input bytes to make forward progress, but the caller is indicating that no more are available. The compressed data
741
+ // is probably corrupted. If you call the inflator again with more bytes it'll try to continue processing the input but this is a BAD sign (either the data is corrupted or you called it incorrectly).
742
+ // If you call it again with no input you'll just get TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS again.
743
+ TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS = -4,
744
+
745
+ // This flag indicates that one or more of the input parameters was obviously bogus. (You can try calling it again, but if you get this error the calling code is wrong.)
724746
TINFL_STATUS_BAD_PARAM = -3,
747
+
748
+ // This flags indicate the inflator is finished but the adler32 check of the uncompressed data didn't match. If you call it again it'll return TINFL_STATUS_DONE.
725749
TINFL_STATUS_ADLER32_MISMATCH = -2,
750
+
751
+ // This flags indicate the inflator has somehow failed (bad code, corrupted input, etc.). If you call it again without resetting via tinfl_init() it it'll just keep on returning the same status failure code.
726752
TINFL_STATUS_FAILED = -1,
753
+
754
+ // Any status code less than TINFL_STATUS_DONE must indicate a failure.
755
+
756
+ // This flag indicates the inflator has returned every byte of uncompressed data that it can, has consumed every byte that it needed, has successfully reached the end of the deflate stream, and
757
+ // if zlib headers and adler32 checking enabled that it has successfully checked the uncompressed data's adler32. If you call it again you'll just get TINFL_STATUS_DONE over and over again.
727758
TINFL_STATUS_DONE = 0,
759
+
760
+ // This flag indicates the inflator MUST have more input data (even 1 byte) before it can make any more forward progress, or you need to clear the TINFL_FLAG_HAS_MORE_INPUT
761
+ // flag on the next call if you don't have any more source data. If the source data was somehow corrupted it's also possible (but unlikely) for the inflator to keep on demanding input to
762
+ // proceed, so be sure to properly set the TINFL_FLAG_HAS_MORE_INPUT flag.
728763
TINFL_STATUS_NEEDS_MORE_INPUT = 1,
764
+
765
+ // This flag indicates the inflator definitely has 1 or more bytes of uncompressed data available, but it cannot write this data into the output buffer.
766
+ // Note if the source compressed data was corrupted it's possible for the inflator to return a lot of uncompressed data to the caller. I've been assuming you know how much uncompressed data to expect
767
+ // (either exact or worst case) and will stop calling the inflator and fail after receiving too much. In pure streaming scenarios where you have no idea how many bytes to expect this may not be possible
768
+ // so I may need to add some code to address this.
729769
TINFL_STATUS_HAS_MORE_OUTPUT = 2
770
+
730771
} tinfl_status;
731772
732773
// Initializes the decompressor to its initial state.
733774
#define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END
734775
#define tinfl_get_adler32(r) (r)->m_check_adler32
@@ -819,11 +860,11 @@
819860
// Returns 0 on failure.
820861
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);
821862
822863
// Compresses an image to a compressed PNG file in memory.
823864
// On entry:
824
-// pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4.
865
+// pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4.
825866
// The image pitch in bytes per scanline will be w*num_chans. The leftmost pixel on the top scanline is stored first in memory.
826867
// level may range from [0,10], use MZ_NO_COMPRESSION, MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc. or a decent default is MZ_DEFAULT_LEVEL
827868
// If flip is true, the image will be flipped on the Y axis (useful for OpenGL apps).
828869
// On return:
829870
// Function returns a pointer to the compressed data, or NULL on failure.
@@ -916,10 +957,18 @@
916957
// level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files)
917958
// window_bits may be -15 (raw deflate) or 15 (zlib)
918959
// strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED
919960
mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy);
920961
#endif // #ifndef MINIZ_NO_ZLIB_APIS
962
+
963
+// Allocate the tdefl_compressor and tinfl_decompressor structures in C so that
964
+// non-C language bindings to tdefl_ and tinfl_ API don't need to worry about
965
+// structure size and allocation mechanism.
966
+tdefl_compressor *tdefl_compressor_alloc();
967
+void tdefl_compressor_free(tdefl_compressor *pComp);
968
+tinfl_decompressor *tinfl_decompressor_alloc();
969
+void tinfl_decompressor_free(tinfl_decompressor *pDecomp);
921970
922971
#ifdef __cplusplus
923972
}
924973
#endif
925974
@@ -1363,27 +1412,14 @@
13631412
#define TINFL_CR_BEGIN switch(r->m_state) { case 0:
13641413
#define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END
13651414
#define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END
13661415
#define TINFL_CR_FINISH }
13671416
1368
-// 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
1369
-// reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of the stream with 0's in this scenario.
13701417
#define TINFL_GET_BYTE(state_index, c) do { \
1371
- if (pIn_buf_cur >= pIn_buf_end) { \
1372
- for ( ; ; ) { \
1373
- if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \
1374
- TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \
1375
- if (pIn_buf_cur < pIn_buf_end) { \
1376
- c = *pIn_buf_cur++; \
1377
- break; \
1378
- } \
1379
- } else { \
1380
- c = 0; \
1381
- break; \
1382
- } \
1383
- } \
1384
- } else c = *pIn_buf_cur++; } MZ_MACRO_END
1418
+ while (pIn_buf_cur >= pIn_buf_end) { \
1419
+ TINFL_CR_RETURN(state_index, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS); \
1420
+ } c = *pIn_buf_cur++; } MZ_MACRO_END
13851421
13861422
#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))
13871423
#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
13881424
#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
13891425
@@ -1408,10 +1444,12 @@
14081444
14091445
// 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
14101446
// 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
14111447
// 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.
14121448
// The slow path is only executed at the very end of the input buffer.
1449
+// v1.16: The original macro handled the case at the very end of the passed-in input buffer, but we also need to handle the case where the user passes in 1+zillion bytes
1450
+// following the deflate data and our non-conservative read-ahead path won't kick in here on this code. This is much trickier.
14131451
#define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \
14141452
int temp; mz_uint code_len, c; \
14151453
if (num_bits < 15) { \
14161454
if ((pIn_buf_end - pIn_buf_cur) < 2) { \
14171455
TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
@@ -1472,18 +1510,11 @@
14721510
while (counter)
14731511
{
14741512
size_t n; while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); }
14751513
while (pIn_buf_cur >= pIn_buf_end)
14761514
{
1477
- if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT)
1478
- {
1479
- TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT);
1480
- }
1481
- else
1482
- {
1483
- TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED);
1484
- }
1515
+ TINFL_CR_RETURN(38, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS);
14851516
}
14861517
n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter);
14871518
TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); pIn_buf_cur += n; pOut_buf_cur += n; counter -= (mz_uint)n;
14881519
}
14891520
}
@@ -1666,19 +1697,31 @@
16661697
pOut_buf_cur += counter;
16671698
}
16681699
}
16691700
}
16701701
} while (!(r->m_final & 1));
1702
+
1703
+ // Ensure byte alignment and put back any bytes from the bitbuf if we've looked ahead too far on gzip, or other Deflate streams followed by arbitrary data.
1704
+ // I'm being super conservative here. A number of simplifications can be made to the byte alignment part, and the Adler32 check shouldn't ever need to worry about reading from the bitbuf now.
1705
+ TINFL_SKIP_BITS(32, num_bits & 7);
1706
+ while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8)) { --pIn_buf_cur; num_bits -= 8; } bit_buf &= (tinfl_bit_buf_t)((1ULL << num_bits) - 1ULL);
1707
+ MZ_ASSERT(!num_bits); // if this assert fires then we've read beyond the end of non-deflate/zlib streams with following data (such as gzip streams).
1708
+
16711709
if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
16721710
{
1673
- 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; }
1711
+ 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; }
16741712
}
16751713
TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE);
1714
+
16761715
TINFL_CR_FINISH
16771716
16781717
common_exit:
1679
- 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;
1718
+ // As long as we aren't telling the caller that we NEED more input to make forward progress:
1719
+ // Put back any bytes from the bitbuf in case we've looked ahead too far on gzip, or other Deflate streams followed by arbitrary data.
1720
+ // We need to be very careful here to NOT push back any bytes we definitely know we need to make forward progress, though, or we'll lock the caller up into an inf loop.
1721
+ if ((status != TINFL_STATUS_NEEDS_MORE_INPUT) && (status != TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS)) { while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8)) { --pIn_buf_cur; num_bits -= 8; } }
1722
+ r->m_num_bits = num_bits; r->m_bit_buf = bit_buf & (tinfl_bit_buf_t)((1ULL << num_bits) - 1ULL); 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;
16801723
*pIn_buf_size = pIn_buf_cur - pIn_buf_next; *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
16811724
if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0))
16821725
{
16831726
const mz_uint8 *ptr = pOut_buf_next; size_t buf_len = *pOut_buf_size;
16841727
mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16; size_t block_len = buf_len % 5552;
@@ -2826,15 +2869,42 @@
28262869
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; }
28272870
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);
28282871
// compute final size of file, grab compressed data buffer and return
28292872
*pLen_out += 57; MZ_FREE(pComp); return out_buf.m_pBuf;
28302873
}
2874
+
28312875
void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out)
28322876
{
28332877
// Level 6 corresponds to TDEFL_DEFAULT_MAX_PROBES or MZ_DEFAULT_LEVEL (but we can't depend on MZ_DEFAULT_LEVEL being available in case the zlib API's where #defined out)
28342878
return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans, pLen_out, 6, MZ_FALSE);
28352879
}
2880
+
2881
+// Allocate the tdefl_compressor and tinfl_decompressor structures in C so that
2882
+// non-C language bindings to tdefL_ and tinfl_ API don't need to worry about
2883
+// structure size and allocation mechanism.
2884
+tdefl_compressor *tdefl_compressor_alloc()
2885
+{
2886
+ return (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor));
2887
+}
2888
+
2889
+void tdefl_compressor_free(tdefl_compressor* pComp)
2890
+{
2891
+ MZ_FREE(pComp);
2892
+}
2893
+
2894
+tinfl_decompressor *tinfl_decompressor_alloc()
2895
+{
2896
+ tinfl_decompressor *pDecomp = (tinfl_decompressor *)MZ_MALLOC(sizeof(tinfl_decompressor));
2897
+ if (pDecomp)
2898
+ tinfl_init(pDecomp);
2899
+ return pDecomp;
2900
+}
2901
+
2902
+void tinfl_decompressor_free(tinfl_decompressor *pDecomp)
2903
+{
2904
+ MZ_FREE(pDecomp);
2905
+}
28362906
28372907
#ifdef _MSC_VER
28382908
#pragma warning (pop)
28392909
#endif
28402910
@@ -4439,11 +4509,11 @@
44394509
if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + comment_size + archive_name_size) > 0xFFFFFFFF))
44404510
return MZ_FALSE;
44414511
44424512
if (!mz_zip_get_file_modified_time(pSrc_filename, &dos_time, &dos_date))
44434513
return MZ_FALSE;
4444
-
4514
+
44454515
pSrc_file = MZ_FOPEN(pSrc_filename, "rb");
44464516
if (!pSrc_file)
44474517
return MZ_FALSE;
44484518
MZ_FSEEK64(pSrc_file, 0, SEEK_END);
44494519
uncomp_size = MZ_FTELL64(pSrc_file);
44504520
--- src/miniz.c
+++ src/miniz.c
@@ -1,14 +1,29 @@
1 /* miniz.c v1.15 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
2 See "unlicense" statement at the end of this file.
3 Rich Geldreich <[email protected]>, last updated Oct. 13, 2013
4 Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
5
6 Most API's defined in miniz.c are optional. For example, to disable the archive related functions just define
7 MINIZ_NO_ARCHIVE_APIS, or to get rid of all stdio usage define MINIZ_NO_STDIO (see the list below for more macros).
8
9 * Change History
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10 10/13/13 v1.15 r4 - Interim bugfix release while I work on the next major release with Zip64 support (almost there!):
11 - Critical fix for the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY bug (thanks [email protected]) which could cause locate files to not find files. This bug
12 would only have occured in earlier versions if you explicitly used this flag, OR if you used mz_zip_extract_archive_file_to_heap() or mz_zip_add_mem_to_archive_file_in_place()
13 (which used this flag). If you can't switch to v1.15 but want to fix this bug, just remove the uses of this flag from both helper funcs (and of course don't use the flag).
14 - Bugfix in mz_zip_reader_extract_to_mem_no_alloc() from kymoon when pUser_read_buf is not NULL and compressed size is > uncompressed size
@@ -25,11 +40,11 @@
25 - Merged in some compiler fixes from paulharris's github repro.
26 - Retested this build under Windows (VS 2010, including static analysis), tcc 0.9.26, gcc v4.6 and clang v3.3.
27 - Added example6.c, which dumps an image of the mandelbrot set to a PNG file.
28 - Modified example2 to help test the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY flag more.
29 - In r3: Bugfix to mz_zip_writer_add_file() found during merge: Fix possible src file fclose() leak if alignment bytes+local header file write faiiled
30 - In r4: Minor bugfix to mz_zip_writer_add_from_zip_reader(): Was pushing the wrong central dir header offset, appears harmless in this release, but it became a problem in the zip64 branch
31 5/20/12 v1.14 - MinGW32/64 GCC 4.6.1 compiler fixes: added MZ_FORCEINLINE, #include <time.h> (thanks fermtect).
32 5/19/12 v1.13 - From [email protected] and [email protected] - Fix mz_crc32() so it doesn't compute the wrong CRC-32's when mz_ulong is 64-bit.
33 - Temporarily/locally slammed in "typedef unsigned long mz_ulong" and re-ran a randomized regression test on ~500k files.
34 - Eliminated a bunch of warnings when compiling with GCC 32-bit/64.
35 - Ran all examples, miniz.c, and tinfl.c through MSVC 2008's /analyze (static analysis) option and fixed all warnings (except for the silly
@@ -251,10 +266,11 @@
251 // Note that mz_alloc_func parameter types purpsosely differ from zlib's: items/size is size_t, not unsigned long.
252 typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size);
253 typedef void (*mz_free_func)(void *opaque, void *address);
254 typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size);
255
 
256 #define MZ_VERSION "9.1.15"
257 #define MZ_VERNUM 0x91F0
258 #define MZ_VER_MAJOR 9
259 #define MZ_VER_MINOR 1
260 #define MZ_VER_REVISION 15
@@ -719,16 +735,41 @@
719 #define TINFL_LZ_DICT_SIZE 32768
720
721 // Return status.
722 typedef enum
723 {
 
 
 
 
 
 
724 TINFL_STATUS_BAD_PARAM = -3,
 
 
725 TINFL_STATUS_ADLER32_MISMATCH = -2,
 
 
726 TINFL_STATUS_FAILED = -1,
 
 
 
 
 
727 TINFL_STATUS_DONE = 0,
 
 
 
 
728 TINFL_STATUS_NEEDS_MORE_INPUT = 1,
 
 
 
 
 
729 TINFL_STATUS_HAS_MORE_OUTPUT = 2
 
730 } tinfl_status;
731
732 // Initializes the decompressor to its initial state.
733 #define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END
734 #define tinfl_get_adler32(r) (r)->m_check_adler32
@@ -819,11 +860,11 @@
819 // Returns 0 on failure.
820 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);
821
822 // Compresses an image to a compressed PNG file in memory.
823 // On entry:
824 // pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4.
825 // The image pitch in bytes per scanline will be w*num_chans. The leftmost pixel on the top scanline is stored first in memory.
826 // level may range from [0,10], use MZ_NO_COMPRESSION, MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc. or a decent default is MZ_DEFAULT_LEVEL
827 // If flip is true, the image will be flipped on the Y axis (useful for OpenGL apps).
828 // On return:
829 // Function returns a pointer to the compressed data, or NULL on failure.
@@ -916,10 +957,18 @@
916 // level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files)
917 // window_bits may be -15 (raw deflate) or 15 (zlib)
918 // strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED
919 mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy);
920 #endif // #ifndef MINIZ_NO_ZLIB_APIS
 
 
 
 
 
 
 
 
921
922 #ifdef __cplusplus
923 }
924 #endif
925
@@ -1363,27 +1412,14 @@
1363 #define TINFL_CR_BEGIN switch(r->m_state) { case 0:
1364 #define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END
1365 #define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END
1366 #define TINFL_CR_FINISH }
1367
1368 // 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
1369 // reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of the stream with 0's in this scenario.
1370 #define TINFL_GET_BYTE(state_index, c) do { \
1371 if (pIn_buf_cur >= pIn_buf_end) { \
1372 for ( ; ; ) { \
1373 if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \
1374 TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \
1375 if (pIn_buf_cur < pIn_buf_end) { \
1376 c = *pIn_buf_cur++; \
1377 break; \
1378 } \
1379 } else { \
1380 c = 0; \
1381 break; \
1382 } \
1383 } \
1384 } else c = *pIn_buf_cur++; } MZ_MACRO_END
1385
1386 #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))
1387 #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
1388 #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
1389
@@ -1408,10 +1444,12 @@
1408
1409 // 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
1410 // 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
1411 // 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.
1412 // The slow path is only executed at the very end of the input buffer.
 
 
1413 #define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \
1414 int temp; mz_uint code_len, c; \
1415 if (num_bits < 15) { \
1416 if ((pIn_buf_end - pIn_buf_cur) < 2) { \
1417 TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
@@ -1472,18 +1510,11 @@
1472 while (counter)
1473 {
1474 size_t n; while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); }
1475 while (pIn_buf_cur >= pIn_buf_end)
1476 {
1477 if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT)
1478 {
1479 TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT);
1480 }
1481 else
1482 {
1483 TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED);
1484 }
1485 }
1486 n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter);
1487 TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); pIn_buf_cur += n; pOut_buf_cur += n; counter -= (mz_uint)n;
1488 }
1489 }
@@ -1666,19 +1697,31 @@
1666 pOut_buf_cur += counter;
1667 }
1668 }
1669 }
1670 } while (!(r->m_final & 1));
 
 
 
 
 
 
 
1671 if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
1672 {
1673 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; }
1674 }
1675 TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE);
 
1676 TINFL_CR_FINISH
1677
1678 common_exit:
1679 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;
 
 
 
 
1680 *pIn_buf_size = pIn_buf_cur - pIn_buf_next; *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
1681 if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0))
1682 {
1683 const mz_uint8 *ptr = pOut_buf_next; size_t buf_len = *pOut_buf_size;
1684 mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16; size_t block_len = buf_len % 5552;
@@ -2826,15 +2869,42 @@
2826 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; }
2827 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);
2828 // compute final size of file, grab compressed data buffer and return
2829 *pLen_out += 57; MZ_FREE(pComp); return out_buf.m_pBuf;
2830 }
 
2831 void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out)
2832 {
2833 // Level 6 corresponds to TDEFL_DEFAULT_MAX_PROBES or MZ_DEFAULT_LEVEL (but we can't depend on MZ_DEFAULT_LEVEL being available in case the zlib API's where #defined out)
2834 return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans, pLen_out, 6, MZ_FALSE);
2835 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2836
2837 #ifdef _MSC_VER
2838 #pragma warning (pop)
2839 #endif
2840
@@ -4439,11 +4509,11 @@
4439 if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + comment_size + archive_name_size) > 0xFFFFFFFF))
4440 return MZ_FALSE;
4441
4442 if (!mz_zip_get_file_modified_time(pSrc_filename, &dos_time, &dos_date))
4443 return MZ_FALSE;
4444
4445 pSrc_file = MZ_FOPEN(pSrc_filename, "rb");
4446 if (!pSrc_file)
4447 return MZ_FALSE;
4448 MZ_FSEEK64(pSrc_file, 0, SEEK_END);
4449 uncomp_size = MZ_FTELL64(pSrc_file);
4450
--- src/miniz.c
+++ src/miniz.c
@@ -1,14 +1,29 @@
1 /* miniz.c v1.16 beta r1 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
2 See "unlicense" statement at the end of this file.
3 Rich Geldreich <[email protected]>, last updated Oct. 13, 2013
4 Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
5
6 Most API's defined in miniz.c are optional. For example, to disable the archive related functions just define
7 MINIZ_NO_ARCHIVE_APIS, or to get rid of all stdio usage define MINIZ_NO_STDIO (see the list below for more macros).
8
9 * Change History
10 10/19/13 v1.16 beta r1 - Two key inflator-only robustness and streaming related changes. Also merged in tdefl_compressor_alloc(), tdefl_compressor_free() helpers to make script bindings easier for rustyzip.
11 - The inflator coroutine func. is subtle and complex so I'm being cautious about this release. I would greatly appreciate any help with testing or any feedback.
12 I feel good about these changes, and they've been through several hours of automated testing, but they will probably not fix anything for the majority of prev. users so I'm
13 going to mark this release as beta for a few weeks and continue testing it at work/home on various things.
14 - The inflator in raw (non-zlib) mode is now usable on gzip or similiar data streams that have a bunch of bytes following the raw deflate data (problem discovered by rustyzip author williamw520).
15 This version should *never* read beyond the last byte of the raw deflate data independent of how many bytes you pass into the input buffer. This issue was caused by the various Huffman bitbuffer lookahead optimizations, and
16 would not be an issue if the caller knew and enforced the precise size of the raw compressed data *or* if the compressed data was in zlib format (i.e. always followed by the byte aligned zlib adler32).
17 So in other words, you can now call the inflator on deflate streams that are followed by arbitrary amounts of data and it's guaranteed that decompression will stop exactly on the last byte.
18 - The inflator now has a new failure status: TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS (-4). Previously, if the inflator was starved of bytes and could not make progress (because the input buffer was empty and the
19 caller did not set the TINFL_FLAG_HAS_MORE_INPUT flag - say on truncated or corrupted compressed data stream) it would append all 0's to the input and try to soldier on.
20 This is scary, because in the worst case, I believe it was possible for the prev. inflator to start outputting large amounts of literal data. If the caller didn't know when to stop accepting output
21 (because it didn't know how much uncompressed data was expected, or didn't enforce a sane maximum) it could continue forever. v1.16 cannot fall into this failure mode, instead it'll return
22 TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS immediately if it needs 1 or more bytes to make progress, the input buf is empty, and the caller has indicated that no more input is available. This is a "soft"
23 failure, so you can call the inflator again with more input and it will try to continue, or you can give up and fail. This could be very useful in network streaming scenarios.
24 - Added documentation to all the tinfl return status codes, fixed miniz_tester so it accepts double minus params for Linux, tweaked example1.c, added a simple "follower bytes" test to miniz_tester.cpp.
25 10/13/13 v1.15 r4 - Interim bugfix release while I work on the next major release with Zip64 support (almost there!):
26 - Critical fix for the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY bug (thanks [email protected]) which could cause locate files to not find files. This bug
27 would only have occured in earlier versions if you explicitly used this flag, OR if you used mz_zip_extract_archive_file_to_heap() or mz_zip_add_mem_to_archive_file_in_place()
28 (which used this flag). If you can't switch to v1.15 but want to fix this bug, just remove the uses of this flag from both helper funcs (and of course don't use the flag).
29 - Bugfix in mz_zip_reader_extract_to_mem_no_alloc() from kymoon when pUser_read_buf is not NULL and compressed size is > uncompressed size
@@ -25,11 +40,11 @@
40 - Merged in some compiler fixes from paulharris's github repro.
41 - Retested this build under Windows (VS 2010, including static analysis), tcc 0.9.26, gcc v4.6 and clang v3.3.
42 - Added example6.c, which dumps an image of the mandelbrot set to a PNG file.
43 - Modified example2 to help test the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY flag more.
44 - In r3: Bugfix to mz_zip_writer_add_file() found during merge: Fix possible src file fclose() leak if alignment bytes+local header file write faiiled
45 - In r4: Minor bugfix to mz_zip_writer_add_from_zip_reader(): Was pushing the wrong central dir header offset, appears harmless in this release, but it became a problem in the zip64 branch
46 5/20/12 v1.14 - MinGW32/64 GCC 4.6.1 compiler fixes: added MZ_FORCEINLINE, #include <time.h> (thanks fermtect).
47 5/19/12 v1.13 - From [email protected] and [email protected] - Fix mz_crc32() so it doesn't compute the wrong CRC-32's when mz_ulong is 64-bit.
48 - Temporarily/locally slammed in "typedef unsigned long mz_ulong" and re-ran a randomized regression test on ~500k files.
49 - Eliminated a bunch of warnings when compiling with GCC 32-bit/64.
50 - Ran all examples, miniz.c, and tinfl.c through MSVC 2008's /analyze (static analysis) option and fixed all warnings (except for the silly
@@ -251,10 +266,11 @@
266 // Note that mz_alloc_func parameter types purpsosely differ from zlib's: items/size is size_t, not unsigned long.
267 typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size);
268 typedef void (*mz_free_func)(void *opaque, void *address);
269 typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size);
270
271 // TODO: I can't encode "1.16" here, argh
272 #define MZ_VERSION "9.1.15"
273 #define MZ_VERNUM 0x91F0
274 #define MZ_VER_MAJOR 9
275 #define MZ_VER_MINOR 1
276 #define MZ_VER_REVISION 15
@@ -719,16 +735,41 @@
735 #define TINFL_LZ_DICT_SIZE 32768
736
737 // Return status.
738 typedef enum
739 {
740 // This flags indicates the inflator needs 1 or more input bytes to make forward progress, but the caller is indicating that no more are available. The compressed data
741 // is probably corrupted. If you call the inflator again with more bytes it'll try to continue processing the input but this is a BAD sign (either the data is corrupted or you called it incorrectly).
742 // If you call it again with no input you'll just get TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS again.
743 TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS = -4,
744
745 // This flag indicates that one or more of the input parameters was obviously bogus. (You can try calling it again, but if you get this error the calling code is wrong.)
746 TINFL_STATUS_BAD_PARAM = -3,
747
748 // This flags indicate the inflator is finished but the adler32 check of the uncompressed data didn't match. If you call it again it'll return TINFL_STATUS_DONE.
749 TINFL_STATUS_ADLER32_MISMATCH = -2,
750
751 // This flags indicate the inflator has somehow failed (bad code, corrupted input, etc.). If you call it again without resetting via tinfl_init() it it'll just keep on returning the same status failure code.
752 TINFL_STATUS_FAILED = -1,
753
754 // Any status code less than TINFL_STATUS_DONE must indicate a failure.
755
756 // This flag indicates the inflator has returned every byte of uncompressed data that it can, has consumed every byte that it needed, has successfully reached the end of the deflate stream, and
757 // if zlib headers and adler32 checking enabled that it has successfully checked the uncompressed data's adler32. If you call it again you'll just get TINFL_STATUS_DONE over and over again.
758 TINFL_STATUS_DONE = 0,
759
760 // This flag indicates the inflator MUST have more input data (even 1 byte) before it can make any more forward progress, or you need to clear the TINFL_FLAG_HAS_MORE_INPUT
761 // flag on the next call if you don't have any more source data. If the source data was somehow corrupted it's also possible (but unlikely) for the inflator to keep on demanding input to
762 // proceed, so be sure to properly set the TINFL_FLAG_HAS_MORE_INPUT flag.
763 TINFL_STATUS_NEEDS_MORE_INPUT = 1,
764
765 // This flag indicates the inflator definitely has 1 or more bytes of uncompressed data available, but it cannot write this data into the output buffer.
766 // Note if the source compressed data was corrupted it's possible for the inflator to return a lot of uncompressed data to the caller. I've been assuming you know how much uncompressed data to expect
767 // (either exact or worst case) and will stop calling the inflator and fail after receiving too much. In pure streaming scenarios where you have no idea how many bytes to expect this may not be possible
768 // so I may need to add some code to address this.
769 TINFL_STATUS_HAS_MORE_OUTPUT = 2
770
771 } tinfl_status;
772
773 // Initializes the decompressor to its initial state.
774 #define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END
775 #define tinfl_get_adler32(r) (r)->m_check_adler32
@@ -819,11 +860,11 @@
860 // Returns 0 on failure.
861 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);
862
863 // Compresses an image to a compressed PNG file in memory.
864 // On entry:
865 // pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4.
866 // The image pitch in bytes per scanline will be w*num_chans. The leftmost pixel on the top scanline is stored first in memory.
867 // level may range from [0,10], use MZ_NO_COMPRESSION, MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc. or a decent default is MZ_DEFAULT_LEVEL
868 // If flip is true, the image will be flipped on the Y axis (useful for OpenGL apps).
869 // On return:
870 // Function returns a pointer to the compressed data, or NULL on failure.
@@ -916,10 +957,18 @@
957 // level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files)
958 // window_bits may be -15 (raw deflate) or 15 (zlib)
959 // strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED
960 mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy);
961 #endif // #ifndef MINIZ_NO_ZLIB_APIS
962
963 // Allocate the tdefl_compressor and tinfl_decompressor structures in C so that
964 // non-C language bindings to tdefl_ and tinfl_ API don't need to worry about
965 // structure size and allocation mechanism.
966 tdefl_compressor *tdefl_compressor_alloc();
967 void tdefl_compressor_free(tdefl_compressor *pComp);
968 tinfl_decompressor *tinfl_decompressor_alloc();
969 void tinfl_decompressor_free(tinfl_decompressor *pDecomp);
970
971 #ifdef __cplusplus
972 }
973 #endif
974
@@ -1363,27 +1412,14 @@
1412 #define TINFL_CR_BEGIN switch(r->m_state) { case 0:
1413 #define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END
1414 #define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END
1415 #define TINFL_CR_FINISH }
1416
 
 
1417 #define TINFL_GET_BYTE(state_index, c) do { \
1418 while (pIn_buf_cur >= pIn_buf_end) { \
1419 TINFL_CR_RETURN(state_index, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS); \
1420 } c = *pIn_buf_cur++; } MZ_MACRO_END
 
 
 
 
 
 
 
 
 
 
 
1421
1422 #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))
1423 #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
1424 #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
1425
@@ -1408,10 +1444,12 @@
1444
1445 // 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
1446 // 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
1447 // 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.
1448 // The slow path is only executed at the very end of the input buffer.
1449 // v1.16: The original macro handled the case at the very end of the passed-in input buffer, but we also need to handle the case where the user passes in 1+zillion bytes
1450 // following the deflate data and our non-conservative read-ahead path won't kick in here on this code. This is much trickier.
1451 #define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \
1452 int temp; mz_uint code_len, c; \
1453 if (num_bits < 15) { \
1454 if ((pIn_buf_end - pIn_buf_cur) < 2) { \
1455 TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
@@ -1472,18 +1510,11 @@
1510 while (counter)
1511 {
1512 size_t n; while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); }
1513 while (pIn_buf_cur >= pIn_buf_end)
1514 {
1515 TINFL_CR_RETURN(38, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS);
 
 
 
 
 
 
 
1516 }
1517 n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter);
1518 TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); pIn_buf_cur += n; pOut_buf_cur += n; counter -= (mz_uint)n;
1519 }
1520 }
@@ -1666,19 +1697,31 @@
1697 pOut_buf_cur += counter;
1698 }
1699 }
1700 }
1701 } while (!(r->m_final & 1));
1702
1703 // Ensure byte alignment and put back any bytes from the bitbuf if we've looked ahead too far on gzip, or other Deflate streams followed by arbitrary data.
1704 // I'm being super conservative here. A number of simplifications can be made to the byte alignment part, and the Adler32 check shouldn't ever need to worry about reading from the bitbuf now.
1705 TINFL_SKIP_BITS(32, num_bits & 7);
1706 while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8)) { --pIn_buf_cur; num_bits -= 8; } bit_buf &= (tinfl_bit_buf_t)((1ULL << num_bits) - 1ULL);
1707 MZ_ASSERT(!num_bits); // if this assert fires then we've read beyond the end of non-deflate/zlib streams with following data (such as gzip streams).
1708
1709 if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
1710 {
1711 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; }
1712 }
1713 TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE);
1714
1715 TINFL_CR_FINISH
1716
1717 common_exit:
1718 // As long as we aren't telling the caller that we NEED more input to make forward progress:
1719 // Put back any bytes from the bitbuf in case we've looked ahead too far on gzip, or other Deflate streams followed by arbitrary data.
1720 // We need to be very careful here to NOT push back any bytes we definitely know we need to make forward progress, though, or we'll lock the caller up into an inf loop.
1721 if ((status != TINFL_STATUS_NEEDS_MORE_INPUT) && (status != TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS)) { while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8)) { --pIn_buf_cur; num_bits -= 8; } }
1722 r->m_num_bits = num_bits; r->m_bit_buf = bit_buf & (tinfl_bit_buf_t)((1ULL << num_bits) - 1ULL); 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;
1723 *pIn_buf_size = pIn_buf_cur - pIn_buf_next; *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
1724 if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0))
1725 {
1726 const mz_uint8 *ptr = pOut_buf_next; size_t buf_len = *pOut_buf_size;
1727 mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16; size_t block_len = buf_len % 5552;
@@ -2826,15 +2869,42 @@
2869 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; }
2870 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);
2871 // compute final size of file, grab compressed data buffer and return
2872 *pLen_out += 57; MZ_FREE(pComp); return out_buf.m_pBuf;
2873 }
2874
2875 void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out)
2876 {
2877 // Level 6 corresponds to TDEFL_DEFAULT_MAX_PROBES or MZ_DEFAULT_LEVEL (but we can't depend on MZ_DEFAULT_LEVEL being available in case the zlib API's where #defined out)
2878 return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans, pLen_out, 6, MZ_FALSE);
2879 }
2880
2881 // Allocate the tdefl_compressor and tinfl_decompressor structures in C so that
2882 // non-C language bindings to tdefL_ and tinfl_ API don't need to worry about
2883 // structure size and allocation mechanism.
2884 tdefl_compressor *tdefl_compressor_alloc()
2885 {
2886 return (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor));
2887 }
2888
2889 void tdefl_compressor_free(tdefl_compressor* pComp)
2890 {
2891 MZ_FREE(pComp);
2892 }
2893
2894 tinfl_decompressor *tinfl_decompressor_alloc()
2895 {
2896 tinfl_decompressor *pDecomp = (tinfl_decompressor *)MZ_MALLOC(sizeof(tinfl_decompressor));
2897 if (pDecomp)
2898 tinfl_init(pDecomp);
2899 return pDecomp;
2900 }
2901
2902 void tinfl_decompressor_free(tinfl_decompressor *pDecomp)
2903 {
2904 MZ_FREE(pDecomp);
2905 }
2906
2907 #ifdef _MSC_VER
2908 #pragma warning (pop)
2909 #endif
2910
@@ -4439,11 +4509,11 @@
4509 if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + comment_size + archive_name_size) > 0xFFFFFFFF))
4510 return MZ_FALSE;
4511
4512 if (!mz_zip_get_file_modified_time(pSrc_filename, &dos_time, &dos_date))
4513 return MZ_FALSE;
4514
4515 pSrc_file = MZ_FOPEN(pSrc_filename, "rb");
4516 if (!pSrc_file)
4517 return MZ_FALSE;
4518 MZ_FSEEK64(pSrc_file, 0, SEEK_END);
4519 uncomp_size = MZ_FTELL64(pSrc_file);
4520

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button