221 Commits

Author SHA1 Message Date
Martin Raiber
5a38f5564a Increment version in cmake 2022-02-27 20:09:11 +01:00
Martin Raiber
9eedb97176 Clear whole tree to prevent uninitialized value 2022-02-27 20:08:22 +01:00
Martin Raiber
8a7cf60c7a Merge pull request #226 from sezero/w1
replace use of stdint.h types with mz_ variants
2022-02-09 21:36:23 +01:00
Martin Raiber
d9bd65a843 Merge pull request #227 from sezero/u0
tdefl_compress_normal: Avoid NULL ptr arithmetic UB
2022-02-09 21:35:06 +01:00
Andrius Mitkus
71ba5d12d6 Avoid NULL ptr arithmetic UB 2022-02-09 09:48:30 +03:00
Ozkan Sezer
e285002431 replace use of stdint.h types with mz_ variants 2022-02-09 09:36:50 +03:00
Martin
842a20e586 Update ChangeLog 2022-02-06 14:58:49 +01:00
Martin
edc251cfa9 Add padding to structures so it continues to work if features differ 2022-02-06 14:57:58 +01:00
Martin
9ffbe56a73 Update ChangeLog 2022-02-06 14:39:43 +01:00
Martin
f2b59b344d Increment major version 2022-02-06 14:39:27 +01:00
Martin
0ce345c44a Disable building shared lib by default 2022-02-06 14:30:35 +01:00
Martin
0796bdbee6 Disable treating warnings as error with MSVC 2022-02-06 14:29:22 +01:00
Martin Raiber
056cc8db14 Merge pull request #159 from christiansandberg/reduced-inflate-memory-usage
Reduce memory usage for inflate
2022-02-06 14:16:40 +01:00
Christian Sandberg
60942b0f04 Initialize tree and code size tables separately 2022-01-24 09:55:56 +01:00
Christian Sandberg
8997650f5c Remove m_tables 2022-01-23 20:24:58 +01:00
Christian Sandberg
698faddd95 Minor formatting fix 2022-01-23 14:14:27 +01:00
Christian Sandberg
ff862d4596 Fix -Wshadow 2022-01-23 14:12:48 +01:00
Christian Sandberg
740049e643 Merge branch 'master' into reduced-inflate-memory-usage 2022-01-23 13:32:56 +01:00
Martin Raiber
2cd06e3f32 Merge pull request #217 from sezero/ub-fix
tinfl_decompress: avoid NULL ptr arithmetic UB:
2022-01-22 22:16:45 +01:00
Martin Raiber
f3d9e2293b Fix return value 2022-01-22 22:14:31 +01:00
Martin Raiber
1541a11e9b Merge pull request #220 from sezero/z64
miniz_zip: fix mz_zip_reader_extract_to_heap to read correct sizes
2022-01-22 20:12:07 +01:00
Ozkan Sezer
501a761549 miniz_zip: fix mz_zip_reader_extract_to_heap to read correct sizes
Fixes: https://github.com/richgel999/miniz/issues/218
2022-01-02 20:56:56 +03:00
Ozkan Sezer
aa70ef1644 tinfl_decompress: avoid NULL ptr arithmetic UB:
Fixes: https://github.com/richgel999/miniz/issues/216

Also see:
6b8c30e4a9
2021-12-27 10:50:32 +03:00
Martin
13b21dddc7 Remove total files check (its 32-bit uint)
This fixes a compiler warning. The check didn't do
anything since m_total_files is a 32-bit uint and
MZ_UINT32_MAX is actually a valid value.
2021-12-11 12:59:21 +01:00
Martin
a956b4c753 Fix MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8 not being set 2021-12-11 12:51:50 +01:00
Martin
ecbbbe0138 Fix function declaration if MINIZ_NO_STDIO is used 2021-11-28 18:38:56 +01:00
Martin
72e7267054 Fix unaligned pointer access 2021-11-28 18:37:55 +01:00
Martin
12b78b6d5a Fix function definitions
Fix function definitions tdefl_compressor_alloc(void) and
tinfl_decompressor_alloc(void) to not accept any amount of arguments.
2021-11-28 18:36:40 +01:00
Martin
2beb69d0a5 Don't use unaligned stores and loads per default 2021-11-28 18:35:46 +01:00
Martin
0a88083589 Improve endianess detection 2021-11-28 18:35:19 +01:00
Martin
3e5e488ba9 Use level_and_flags after MZ_DEFAULT_COMPRESSION has been handled 2021-11-28 18:08:27 +01:00
Martin
75c948a1dd Only define MINIZ_EXPORT if not already defined 2021-11-28 17:35:49 +01:00
Martin
b4108c6fcf Adjust usage text
Miniz has a history of being a single header library. Nowadays this
might be less important. So clarify that the library can be used
via other ways.
2021-11-28 17:26:16 +01:00
Martin Raiber
e6a7c5daed Merge pull request #204 from DimitriPapadopoulos/codespell
Fix a couple typos found by codespell
2021-11-11 21:42:04 +01:00
Martin Raiber
66c7313326 Merge pull request #197 from ccawley2011/patch-3
Fix use of uninitialized memory in tinfl_decompress_mem_to_callback()
2021-11-11 21:39:08 +01:00
Martin Raiber
82d6810a38 Merge pull request #193 from ccawley2011/no-inflate-deflate
Add MINIZ_NO_DEFLATE_APIS and MINIZ_NO_INFLATE_APIS
2021-11-11 21:36:53 +01:00
Martin
ee4deb08fa Merge remote-tracking branch 'ccawley2011/mingw-watcom'
# Conflicts:
#	examples/example6.c
2021-11-11 21:36:15 +01:00
Martin Raiber
cb2b132b86 Merge pull request #196 from ccawley2011/patch-2
Set MINIZ_LITTLE_ENDIAN only if not set
2021-11-11 21:26:54 +01:00
Martin Raiber
591faa9574 Merge pull request #207 from SamuelMarks/c89
C89 support
2021-11-11 21:25:11 +01:00
Martin Raiber
3a387ec369 Merge pull request #208 from ell1e/fix_mingw_cross
Fix MinGW cross compilation by removing unneeded capitalization
2021-11-11 21:24:08 +01:00
Ellie
cda0b3e7f0 Fix MinGW cross compilation by removing unneeded capitalization 2021-11-11 13:38:57 +01:00
Samuel Marks
e841503cad [CMakeLists.txt] Enforce C89; [examples/example6.c] Conform to C89; [miniz_zip.c] Use lowercase <windows.h> 2021-11-10 21:59:32 -05:00
Dimitri Papadopoulos
a7961f5b4c Fix a couple typos found by codespell 2021-11-03 14:04:11 +01:00
Martin Raiber
ca1a779ee1 Merge pull request #195 from ccawley2011/patch-1
Avoid using unaligned memory access in UBSan builds
2021-10-03 13:13:13 +02:00
Martin Raiber
18da352921 Merge pull request #203 from prezi/prezi-patch-2
Support for unicode characters in paths and filenames on windows
2021-10-03 13:12:31 +02:00
Zsombor Fazekas
d9c899cea4 Use _wstat64 instead _stat64 on windows 2021-09-16 12:12:07 +02:00
Zsombor Fazekas
70c79cc9d5 Use wfopen on windows 2021-09-16 12:00:44 +02:00
Cameron Cawley
583f4f27c2 Fix use of uninitialized memory in tinfl_decompress_mem_to_callback()
Co-authored-by: sezero <sezero@users.noreply.github.com>
2021-07-25 15:36:22 +01:00
Cameron Cawley
9b89689723 Add MINIZ_NO_DEFLATE_APIS and MINIZ_NO_INFLATE_APIS 2021-07-20 20:19:32 +01:00
Cameron Cawley
f99eae6e04 Set MINIZ_LITTLE_ENDIAN only if not set 2021-07-20 20:17:06 +01:00
Cameron Cawley
fc0c0f585e Avoid using unaligned memory access in UBSan builds 2021-07-20 18:22:34 +01:00
Cameron Cawley
78ae375016 Fix "'&array' may not produce intended result" warnings with OpenWatcom
Co-authored-by: sezero <sezero@users.noreply.github.com>
2021-07-20 18:08:11 +01:00
Cameron Cawley
f542e6df73 Fix "Comparison result always 0" warnings with OpenWatcom 2021-07-20 18:05:16 +01:00
Cameron Cawley
46347635c8 Fix building example6 with C89 compilers 2021-07-20 18:05:16 +01:00
Cameron Cawley
c0aad72d46 Use _ftelli64, _fseeki64 and stat with MinGW32 and OpenWatcom 2021-07-20 18:04:52 +01:00
Martin
08f2c2d7e3 Fix test 2021-06-27 23:22:31 +02:00
Martin
cb97387d20 Add release workflow 2021-06-27 22:44:34 +02:00
Martin
d301afc498 Add release workflow 2021-06-27 22:41:31 +02:00
Martin
8ac52a6cae Increment version 2021-06-27 22:39:44 +02:00
Martin
2281a42c77 Add release workflow 2021-06-27 22:38:35 +02:00
Martin
17b4f33dde Update changelog 2021-06-27 22:25:12 +02:00
Martin
f2df122f6f Create release zip via cmake 2021-06-27 22:25:00 +02:00
Martin
6e1754595a Merge branch 'master' of github.com:richgel999/miniz 2021-06-27 21:32:08 +02:00
Martin Raiber
0c905aec41 Merge pull request #169 from ashtul/patch-1
remove redundant condition
2021-06-27 21:28:00 +02:00
Martin Raiber
ee598099cb Merge pull request #186 from auzkok/master
Make cmake recognize FetchContent subproject
2021-06-27 21:26:10 +02:00
Martin Raiber
61b202f26a Merge pull request #189 from maroneze/master
avoid use of uninitialized value in tdefl_record_literal
2021-06-27 21:25:23 +02:00
Martin Raiber
a145b53b6a Merge pull request #191 from deining/broken-links
readme.md: fix broken links
2021-06-27 21:24:54 +02:00
Andreas Deininger
58254a3241 readme.md: fix broken links
ChangeLog.md: fix typo
2021-06-02 22:48:50 +02:00
Andre Maroneze
cf2833fdc1 avoid use of uninitialized value in tdefl_record_literal
In tdefl_record_literal, the following expression may read an uninitialized
value in the m_pLZ_flags field:

*d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1);

By explicitly initializing it, we avoid possible undefined behaviors.
Issue found with Frama-C.
2021-05-25 15:23:39 +02:00
Vojtěch Šamla
57176046b5 Make cmake recognize FetchContent subproject 2021-05-19 10:37:15 +02:00
Martin Raiber
9edb278d22 Merge pull request #184 from phprus/cmake-subproject
Improved cmake subproject support
2021-03-06 13:48:16 +01:00
Владислав Щапов
b7f04b700b Improved cmake subproject support
- Added code to determine whether this is a standalone project or included by other projects.
- Added option INSTALL_PROJECT to enable/disable install project.
- Replaced CMAKE_BINARY_DIR to CMAKE_CURRENT_BINARY_DIR.
2021-02-26 20:08:39 +05:00
Martin
75744d32d4 Add flag to set (compressed) size in local file header 2021-02-08 13:49:57 +01:00
Martin Raiber
b43f8a0c22 Merge pull request #147 from andiwand/write-with-dynamic-size
write with dynamic size
2021-02-07 22:03:46 +01:00
Martin Raiber
17d6763721 Merge pull request #154 from wdconinc/patch-1
Fix unused parameter ‘pArray’ in mz_zip_array_range_check
2021-02-07 21:41:07 +01:00
Martin Raiber
31b389ac61 Merge pull request #178 from randy408/patch-1
Update meson.build
2021-02-07 21:29:59 +01:00
Martin Raiber
fe03be2c51 Merge pull request #183 from nmoinvaz/master
Fixed MSAN use-of-uninitialized in tinfl_decompress when invalid dist.
2021-02-07 21:29:33 +01:00
Nathan Moinvaziri
60bbf6c808 Fixed MSAN use-of-uninitialized in tinfl_decompress when invalid dist is decoded. In this instance dist was 31 which s_dist_base translates as 0.
https://oss-fuzz.com/testcase-detail/4863557237473280
2021-01-30 17:05:42 -08:00
Randy
b99e5c3de3 Update meson.build 2020-12-20 22:11:45 +01:00
Martin Raiber
d6566206ce Merge pull request #176 from timgates42/bugfix_typo_purposely
docs: fix simple typo, purpsosely -> purposely
2020-12-14 20:06:48 +01:00
Tim Gates
6241bc718c docs: fix simple typo, purpsosely -> purposely
There is a small typo in miniz.h.

Should read `purposely` rather than `purpsosely`.
2020-12-08 07:06:18 +11:00
Martin Raiber
6b6b27aff2 Merge pull request #174 from randy408/bugfix
mz_zip_validate_file(): fix memory leaks
2020-11-28 10:03:15 +01:00
Martin Raiber
3a43b8c4bb Merge pull request #175 from randy408/zip_fuzzer
zip_fuzzer: omit file validation
2020-11-28 10:02:52 +01:00
Randy
864ecc8d14 zip_fuzzer: omit file validation
this is an unbounded operation
2020-11-27 02:28:21 +01:00
Randy
f52e09a208 mz_zip_validate_file(): fix memory leak on errors
https://oss-fuzz.com/testcase?key=5744008051294208
2020-11-26 02:21:57 +01:00
Martin Raiber
95795bb996 Merge pull request #173 from randy408/cifuzz
Integrate with CIFuzz (OSS-Fuzz)
2020-11-25 17:54:43 +01:00
Martin Raiber
0bac8947c5 Merge pull request #172 from leezu/patch-1
Correct zip64 ZIP archive support limitations entry
2020-11-25 00:47:40 +01:00
Leonard Lausen
90ff5d51e4 Correct zip64 ZIP archive support limitations entry
According to ChangeLog.md Zip64 format is supported since 2.0 release
2020-11-24 15:38:08 -08:00
Martin Raiber
fe4a8b78f3 Merge pull request #171 from randy408/fuzzer_updates
OSS-Fuzz integration updates
2020-11-24 19:43:19 +01:00
Randy
225354290d revert uncompress_fuzzer changes 2020-11-24 17:00:05 +01:00
Randy
b485d01faf updates to OSS-Fuzz integration
adapt more fuzz targets from zlib,
add zip fuzzer, zip dictionary.
update uncompress_fuzzer to seed the buffer length separately.
2020-11-24 16:51:30 +01:00
Randy
1cdb9afad0 Integrate with CIFuzz 2020-11-24 15:03:16 +01:00
Martin Raiber
cd65995953 Remove travis build status 2020-11-08 23:30:45 +01:00
Martin Raiber
1721df91bb Add gh actions CI 2020-11-08 23:29:35 +01:00
Martin Raiber
d1640e7c4f Merge pull request #170 from nmoinvaz/fixes/msan-error-dist
Fixed use-of-uninitialized value msan error when copying dist bytes
2020-11-08 23:23:59 +01:00
Nathan Moinvaziri
9457abb670 Fixed use-of-uninitialized value msan error when copying dist bytes with no output bytes written. 2020-11-02 17:18:01 -08:00
ariel shtul
8410f3c640 remove redundant condition
L#1067 asserts that (match_len >= TDEFL_MIN_MATCH_LEN)
2020-11-01 12:02:06 +02:00
Martin Raiber
209ba6540c Merge pull request #168 from nmoinvaz/master
Use variable size input buffer in uncompress fuzzer.
2020-10-26 23:56:49 +01:00
Nathan Moinvaziri
1e7621d96c Use variable size input buffer in uncompress fuzzer. 2020-10-17 16:10:59 -07:00
Martin Raiber
5ebed82882 Merge pull request #164 from otreblan/master
Add pkg-config file and remove hardcoded install dirs
2020-09-16 14:20:35 +02:00
otreblan
e6faac9881 Use MINIZ_VERSION for the pkg-config version 2020-09-14 12:00:26 -05:00
otreblan
65ad3cdf66 Remove hardcoded install dirs 2020-09-14 11:56:38 -05:00
otreblan
320764e3ca Add pkg-config file 2020-09-14 11:46:49 -05:00
Martin Raiber
d34ae4a14f Merge pull request #161 from randy408/ossfuzz
Add fuzz targets for OSS-Fuzz integration
2020-07-07 15:44:54 +02:00
Randy
aa3c99a7b4 fuzz_main: fix warning 2020-07-07 15:34:08 +02:00
Randy
f33da29f61 cmake: add fuzzers to build 2020-07-07 13:56:04 +02:00
Randy
b36e55e48d ossfuzz: update build file 2020-07-07 13:45:05 +02:00
Randy
797c58be3c ossfuzz: fix typo 2020-07-07 13:14:58 +02:00
Randy
d2d7d090fa ossfuzz: fix build for uncompress_fuzzer 2020-07-07 13:12:09 +02:00
Randy
436d915546 ossfuzz: add fuzzers 2020-07-07 13:08:22 +02:00
Christian Sandberg
49860a15fa Eliminate 64-bit operations on 32-bit machines 2020-07-03 13:22:18 +02:00
Christian Sandberg
524906517d Cache pointers to tables for speed 2020-06-23 11:51:26 +02:00
Christian Sandberg
3d000933a7 Reduce size of const data 2020-06-23 11:42:03 +02:00
Christian Sandberg
40b0612004 Skip unnecessary pointer usage 2020-06-22 19:39:52 +02:00
Christian Sandberg
8da3cbb64e Reduce memory usage for inflate
Use Huffman tables with correct sizes instead of always 288
2020-06-20 17:31:32 +02:00
Martin Raiber
164c81c7d7 Merge pull request #158 from dimkr/meson
Add support for building as a Meson subproject
2020-06-20 16:39:01 +02:00
Dima Krasner
a8e9424b16 Add support for building as a Meson subproject 2020-06-19 20:58:20 +03:00
Wouter Deconinck
fa09b1f3d4 Fix unused parameter ‘pArray’ in mz_zip_array_range_check
When NDEBUG, the assert in mz_zip_array_range_check does nothing and an unused variable warning is generated at 4159f8c8c3/miniz_zip.c (L280)

This commit removes the `|| define (NDEBUG)` so when debugging is turned off, no range check is performed.
2020-04-20 11:19:09 -05:00
Martin Raiber
4159f8c8c3 Merge pull request #149 from vladtepesch/master
added uncompress2
2020-03-09 13:44:23 +01:00
vlad
ccff20b76d added uncompress2 2020-02-20 19:36:13 +01:00
Andreas Stefl
1e8c7ce810 write with dynamic size 2020-01-23 17:15:04 +01:00
Martin Raiber
e48d8bab88 Merge pull request #144 from syoyo/gcc-ansi-build-fix
ansi mode does not support double-slash comment.
2019-12-26 10:15:01 +01:00
Syoyo Fujita
a828cc329c ansi mode does not support double-slash comment. Replaced // with /* */ 2019-12-26 14:53:37 +09:00
Martin Raiber
1567c8d06c Merge pull request #143 from driazati/fixcrc
Fix missing crc guard
2019-12-14 18:26:13 +01:00
Your Name
a88d1571c1 Fix missing crc guard
This fixes a warning for an unused variable if `MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS` is on.
2019-12-13 11:22:05 -08:00
Martin Raiber
f66b3e1901 Merge pull request #142 from arabine/master
Fix warning (added cast)
2019-10-28 13:55:47 +01:00
Anthony Rabine
5108f95f58 Fix warning (added cast) 2019-10-28 13:50:42 +01:00
Martin Raiber
3a00ea8b73 Merge pull request #141 from jjlilley/jjlilley
Add #elif to enable an external mz_crc32() to be linked in.
2019-10-11 16:11:13 +02:00
jeremyl
a0dd5179db Add #elif to enable an external mz_crc32() to be linked in.
Adds '#elif defined(USE_EXTERNAL_MZCRC)' by the mz_crc32() definition
to enable the option of a user linking in an alternate crc implementation.

The main reason why this might be desired would be to use an SSE-accelerated
crc implementaiton, which would be faster, but not be reasonable to include
in this file.
2019-10-09 11:30:50 -07:00
Martin Raiber
107def8e36 Merge pull request #140 from dandrader/fixLfsCheck
Fix LFS check
2019-10-06 18:02:54 +02:00
Daniel d'Andrada
334e0d64ce Fix LFS check
Code should check for__USE_LARGEFILE64, not _LARGEFILE64_SOURCE

_LARGEFILE64_SOURCE should be used only for setting a preference
when compiling code (either explicitly or by the compiler itself).
Then, according to its value, features.h will take care define things
like __USE_LARGEFILE64 appropriately.

As a side-effect, this patch adds support for clang. When building
with clang one has to explicitly define _LARGEFILE64_SOURCE if he
want to use the *64 api.
2019-10-04 14:11:18 +02:00
Martin Raiber
0238ce2a3b Merge pull request #139 from andiwand/cmake-use-current-directories
use CMAKE_CURRENT_* directories
2019-10-01 13:38:34 +02:00
Andreas Stefl
cd99affed0 use CMAKE_CURRENT_* directories 2019-09-26 20:03:00 +02:00
Martin Raiber
bee490c712 Merge pull request #137 from dandrader/locateFileBool
mz_zip_reader_locate_file_v2 returns an mz_bool
2019-09-24 13:13:12 +02:00
Daniel d'Andrada
6ed35304fe mz_zip_reader_locate_file_v2 returns an mz_bool 2019-09-24 10:48:48 +02:00
Martin Raiber
e0c964c4a3 Merge pull request #135 from tamasmeszaros/cmake-dynlib
Add include location tolerance and stop forcing _GNU_SOURCE
2019-06-11 20:50:10 +02:00
tamasmeszaros
416f5ea723 Add include location tolerance and stop forcing _GNU_SOURCE.
_GNU_SOURCE will still be enabled if building static or shared library, but only as a PRIVATE compile definition. It will not leak into targets using miniz.
2019-06-04 09:38:33 +02:00
tamasmeszaros
e8ab1c9a6d Fix for misleading doc comment on mz_zip_reader_init_cfile function. 2019-06-03 15:48:11 +02:00
Martin Raiber
e71344bdd7 Merge pull request #134 from tamasmeszaros/cmake-dynlib
Support installation of amalgamated sources
2019-06-03 15:11:49 +02:00
tamasmeszaros
3b9a004a4f Create export script for amalgamated sources with correct version info.
Also added _GNU_SOURCE to on GNU compilers to support large files.
2019-06-03 10:44:40 +02:00
tamasmeszaros
d57872c77a Fix for older cmake versions and build of examples. 2019-06-03 10:02:13 +02:00
Martin Raiber
b713ca2b4a Merge pull request #132 from tamasmeszaros/cmake-dynlib
Use CMake export header for exporting symbols.
2019-06-02 21:30:46 +02:00
tamasmeszaros
185bc3c683 Use CMake export header for exporting symbols.
Only in shared library mode.
2019-05-28 11:57:37 +02:00
Martin Raiber
ff06fbaafc Merge pull request #131 from tamasmeszaros/cmake-dynlib
Modified cmake script to support shared library mode and find_package.
2019-05-27 18:10:45 +02:00
tamasmeszaros
1261dfa9ad Modified cmake script to support shared library mode and find_package. 2019-05-27 14:16:27 +02:00
Martin Raiber
ea41268ac9 Merge pull request #129 from rbsheth/cmake_updates
CMake updates and CMake-based amalgamation step
2019-05-23 19:55:02 +02:00
Rahul Sheth
c3e5de6699 remove bash-specific amalgamation code 2019-05-22 19:52:19 -04:00
Rahul Sheth
a3aeeb3307 fix examples with amalgamation 2019-05-22 19:25:54 -04:00
Rahul Sheth
4ec19d6731 Initial CMake update 2019-05-22 19:17:28 -04:00
Martin
a4264837ae Fix type issue 2019-04-11 02:35:18 +02:00
Martin
b4936524bc Update ChangeLog 2019-03-31 14:40:12 +02:00
Martin Raiber
e9020723b3 Merge pull request #124 from Cgettys/add-unaligned-defined-guard
Add !defined check on MINIZ_USE_ALIGNED_LOADS_AND_STORES
2019-03-31 14:33:13 +02:00
Charlie Gettys
5ba89c135d Add !defined check on MINIZ_USE_ALIGNED_LOADS_AND_STORES
Add !defined check so that one can override MINIZ_USE_ALIGNED_LOADS_AND_STORES in case a given compiler does not support it (this issue has been seen in the wild, #assimp/assimp#2389
2019-03-27 10:46:41 -04:00
Martin
25de35faec Remove check that path of file added to archive contains ':' or '\' 2019-03-07 14:37:56 +01:00
Martin
4d1d5b6771 Merge branch 'master' of github.com:richgel999/miniz 2019-03-07 14:08:22 +01:00
Martin Raiber
034f0228eb Merge pull request #122 from FrancescAlted/fix-msvc-warning2
More fixes for warnings MSVC
2019-03-07 14:06:42 +01:00
Martin Raiber
4b8c4f432c Merge pull request #121 from FrancescAlted/fix-msvc-warning
Fix a MSVC 2013 warning
2019-03-07 14:05:31 +01:00
Martin Raiber
9d79ea2245 Merge pull request #119 from andiwand/cmake-use-target_include_directories
use target_include_directories
2019-03-07 14:04:51 +01:00
Martin
6db3c0d290 Don't warn if _LARGEFILE64_SOURCE is not defined 2019-03-07 14:04:15 +01:00
Francesc Alted
96f0da1db9 Yet another fix 2019-03-06 14:34:39 +01:00
Francesc Alted
93c6567773 More fixes for MSVC 2019-03-06 14:07:45 +01:00
Francesc Alted
2b45f89867 Fix a MSVC 2013 warning 2019-03-06 09:51:03 +01:00
Andreas Stefl
5c62e23e04 use target_include_directories 2019-03-03 19:35:13 +01:00
Martin Raiber
f3461d636a Merge pull request #109 from mcgouganp/master
Fix large file support under Windows
2019-01-23 17:44:13 +01:00
paul
45a080c050 Fix large file support under Windows
Under Windows _stat maps to _stat64i32 which only supports max int32_t file sizes.
Change to _stat64 which uses 64bit file sizes and file modification times.
2019-01-23 12:36:25 +10:00
Martin Raiber
2e15a3ff77 Merge pull request #107 from lumag/fix-alloc
Move comp/decomp alloc/free  prototypes under guarding #ifndef
2019-01-17 13:24:21 +01:00
Dmitry Eremin-Solenikov
d31e119d4d Move comp/decomp alloc/free prototypes under guarding #ifndef
Function implemenations are already guarded by #ifndef MZ_NO_MALLOC, so
let's put prototypes under the same #ifndef. Also, while we are at it,
make those prototypes standard-compliant by adding void argument.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
2019-01-17 12:52:11 +03:00
Martin Raiber
3a884afaa7 Merge pull request #106 from lumag/inflateReset
Implement inflateReset() function
2018-12-18 12:59:48 +01:00
Dmitry Eremin-Solenikov
ae423e65b4 Implement inflateReset() function
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
2018-12-18 14:26:37 +03:00
Martin Raiber
336fca3bd4 Merge pull request #105 from zdevito/master
guard memcpy when n == 0 because buffer may be NULL
2018-11-30 02:23:29 +01:00
Zach DeVito
a3ca94f833 guard memcpy when n == 0 because buffer may be NULL 2018-11-29 16:56:13 -08:00
Martin
9ce0d0ddff Fix out of bounds read while reading Zip64 extended information 2018-11-11 19:11:47 +01:00
Martin
f8600923fc Incremented version 2018-11-11 19:10:51 +01:00
Martin
306edd2022 New function to read files via callback functions when adding them 2018-11-11 19:10:35 +01:00
Martin
407d298c14 Remove inline for c90 support 2018-11-05 18:32:42 +01:00
Martin
53bfef515c More instances of memcpy instead of cast and use memcpy per default 2018-10-27 17:14:33 +02:00
Martin
91fa285a27 Fix grammar errors in ChangeLog 2018-10-27 17:12:43 +02:00
Martin
df65d5a1de Update ChangeLog 2018-09-19 12:48:59 +02:00
Martin
46cdde2ac5 Fix corrupt archive if uncompressed file smaller than 4 byte and file is added by mz_zip_writer_add_mem* 2018-07-10 22:31:13 +02:00
Martin
3616bf804b Fix heap overflow to user buffer in tinfl_status tinfl_decompress 2018-06-18 22:17:43 +02:00
Martin
76237898c0 Updated ChangeLog 2018-04-18 17:13:39 +02:00
Martin
3af5c82fd3 Add license, changelog, readme and example files to release zip 2018-04-18 17:12:44 +02:00
Martin
55f4dfe1d2 Incremented version 2018-04-18 17:09:01 +02:00
Martin
b344eaf775 Remove unimplemented functions 2018-04-18 16:50:36 +02:00
Martin
36b6c99f62 Incremented version 2018-02-20 19:03:53 +01:00
Martin
04f2169b8a Incremented version 2018-02-20 19:02:57 +01:00
Martin
14a5a1397b Merge branch 'master' of github.com:uroni/miniz 2018-02-20 19:00:19 +01:00
Martin
fef12d34f1 Remove _LARGEFILE64_SOURCE requirement from apple defines for large files 2018-02-20 18:58:32 +01:00
Martin Raiber
b01930542e Merge pull request #83 from arteniioleg/master
install library and headers
2017-11-30 12:52:09 +01:00
Martin Raiber
9c88e826a2 Merge pull request #82 from JonnyH/WIP/fix-default-level-mz_zip_writer_add_mem
Fix assert with mz_zip_writer_add_mem* w/MZ_DEFAULT_COMPRESSION
2017-11-30 12:51:58 +01:00
arteniioleg
22e4ef1b1d install library and headers 2017-11-23 14:25:55 +02:00
Jonathan Hamilton
7a7d0b423b Fix assert with mz_zip_writer_add_mem* w/MZ_DEFAULT_COMPRESSION
Issue #81

As MZ_DEFAULT_COMPRESSION is set as "-1", one of the bits is incorrectly
interpreted as the "MZ_ZIP_FLAG_COMPRESSED_DATA" flag before the check
for (flags < 0) intended to catch the MZ_DEFAULT_COMPRESION case.

This would then cause an assert() to be hit on any calls where the
uncomp_size is non-zero.

Moving the "Default" level check above any other flag checks should
solve this issue.
2017-11-23 00:22:24 -08:00
Martin Raiber
c17cc20c80 Merge pull request #3 from lockie/master
CMake improvements
2017-10-17 23:36:08 +02:00
Martin Raiber
0f6b199e5b Merge pull request #78 from coyote1357/master
Fix resource leak in mz_zip_reader_init_file_v2
2017-10-17 23:33:40 +02:00
T. Isaac Lightburn
0b7d3070b9 Fix resource leak in mz_zip_reader_init_file_v2
Was returning on error without closing file.
2017-10-12 21:29:43 -05:00
Martin Raiber
aadc405b1c Merge pull request #76 from jasonrohrer/master
Fixed loads of uninitilized value errors found with Valgrind by memse…
2017-09-02 16:17:53 +02:00
Jason Rohrer
02c51d3662 Fixed loads of uninitilized value errors found with Valgrind by memsetting m_dict to 0 in tdefl_init. 2017-08-28 18:28:14 -07:00
Andrew Kravchuk
9393a95f26 Removed need in C++ compiler in cmake build 2017-08-26 03:47:07 +03:00
Andrew Kravchuk
82e5b184e4 Fixed CMAKE_BUILD_TYPE default value 2017-08-26 00:03:50 +03:00
Martin
81df2df0f6 Document mz_zip_writer_init 2017-07-08 13:58:18 +02:00
Martin Raiber
64d92e19ad Merge pull request #66 from unsightlygod/iterative_decompression
Iterative decompression
2017-07-08 13:41:34 +02:00
Martin
404c574eba Define processor/arch macros as zero if not set to one 2017-07-08 13:37:05 +02:00
Martin
c1f791f81b Define processor/arch macros as zero if not set to one 2017-07-08 13:34:56 +02:00
Martin
c93e4d804c Increment version 2017-07-08 13:12:42 +02:00
Martin
84e8458de0 Option to use memcpy for unaligned data access 2017-05-18 18:47:09 +02:00
Phil Greenland
78cdcb0fce Include basic tests for iterative extraction method. 2017-05-14 12:04:54 +01:00
Phil Greenland
0d13890f4b Add "iterative" file extraction method based on mz_zip_reader_extract_to_callback. 2017-05-14 11:54:29 +01:00
Martin Raiber
7ecd1b3677 Merge pull request #65 from udda/fix-png-height
Fix PNG height
2017-05-05 00:14:57 +02:00
Mario Cianciolo
a0786b126d Fix PNG height
Fixed array index where to store image height.
PNG files made using `tdefl_write_image_to_png_file_in_memory_ex()` were very tall, with a huge empty area at the end.
Since `pnghdr[22]` was assigned twice, I changed indices to store height exactly in the way width is stored (two consecutive swapped bytes). Now PNG file height is correct.
2017-04-30 23:13:09 +02:00
Martin
9b1ddf6861 Add debug configuration 2017-04-24 17:28:45 +02:00
Martin
149b34c254 Remove check for cur_archive_file_ofs > UINT_MAX, because cur_archive_file_ofs is not used after this point 2017-04-24 17:28:20 +02:00
Martin
6e915ef7fc Improve MZ_ZIP_FLAG_WRITE_ZIP64 documentation 2017-04-24 17:26:55 +02:00
Martin
11f795a19c Improve readme 2017-04-24 17:26:29 +02:00
Martin Raiber
ec028ffe66 Merge pull request #60 from janisozaur/master
Fix compilation with GCC6
2017-03-24 15:11:32 +01:00
Michał Janiszewski
a6a989cc18 clang-format the sources 2017-03-23 08:50:08 +01:00
Michał Janiszewski
3d51050db5 Set amalgamate.sh as executable 2017-03-23 08:38:27 +01:00
Michał Janiszewski
3c7177c0cb Fix misleading indentation 2017-03-23 08:38:10 +01:00
Martin
35c2d67bcf Fix compilation with the various omission compile definitions 2017-03-13 19:49:01 +01:00
Martin
1c6ca868d7 Fix compilation with the various omission compile definitions 2017-03-13 19:38:42 +01:00
Martin
2337db2f7b Fix formatting 2017-03-11 19:09:33 +01:00
Martin
3b3c258b2d Update readme/changelog 2017-03-11 19:06:16 +01:00
38 changed files with 2759 additions and 722 deletions

17
.github/workflows/c-cpp.yml vendored Normal file
View File

@@ -0,0 +1,17 @@
name: C/C++ CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: amalgamate
run: bash amalgamate.sh

23
.github/workflows/ci-fuzz.yml vendored Normal file
View File

@@ -0,0 +1,23 @@
name: CIFuzz
on: [pull_request]
jobs:
Fuzzing:
runs-on: ubuntu-latest
steps:
- name: Build Fuzzers
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
with:
oss-fuzz-project-name: 'miniz'
dry-run: false
- name: Run Fuzzers
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
with:
oss-fuzz-project-name: 'miniz'
fuzz-seconds: 900
dry-run: false
- name: Upload Crash
uses: actions/upload-artifact@v1
if: failure()
with:
name: artifacts
path: ./out/artifacts

60
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,60 @@
name: Create release
# Controls when the action will run.
on:
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
build:
name: Create new release
runs-on: ubuntu-latest
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- name: Checkout code
uses: actions/checkout@v2
with:
path: source
- name: Install dependencies
run: |
sudo apt-get install -y cmake
- name: Configure
run: |
mkdir build
mkdir inst
cd build
cmake ../source -G"Unix Makefiles" -DAMALGAMATE_SOURCES=ON -DCMAKE_INSTALL_PREFIX=../inst
- name: Build
run: |
cd build
make install
- name: Get current version
id: relver
run: echo "::set-output name=relver::$(cat build/miniz.pc | grep Version | cut -d ':' -f2 | xargs)"
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.relver.outputs.relver }}
release_name: Release ${{ steps.relver.outputs.relver }}
draft: false
prerelease: false
- name: Upload Release Asset
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./build/miniz-${{ steps.relver.outputs.relver }}.zip
asset_name: miniz-${{ steps.relver.outputs.relver }}.zip
asset_content_type: application/zip

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
/_build
/amalgamation
/bin

View File

@@ -1,14 +1,234 @@
PROJECT(miniz)
cmake_minimum_required(VERSION 2.8)
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_CONFIGURATION_TYPES Release)
cmake_minimum_required(VERSION 3.0)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
# determine whether this is a standalone project or included by other projects
set (MINIZ_STANDALONE_PROJECT ON)
if(DEFINED PROJECT_NAME)
set(MINIZ_STANDALONE_PROJECT OFF)
endif()
if(CMAKE_MINOR_VERSION LESS 12)
project(miniz)
# see issue https://gitlab.kitware.com/cmake/cmake/merge_requests/1799
else()
project(miniz C)
set(CMAKE_C_STANDARD 90)
set(CMAKE_VERBOSE_MAKEFILE ON)
# set(CMAKE_C_VISIBILITY_PRESET hidden)
# set(CMAKE_VISIBILITY_INLINES_HIDDEN YES)
if (MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3 /Zi /permissive-")
else ()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wshadow -Wformat=2 -Wall -Wno-overlength-strings -pedantic")
endif ()
endif()
set(MINIZ_API_VERSION 3)
set(MINIZ_MINOR_VERSION 0)
set(MINIZ_PATCH_VERSION 0)
set(MINIZ_VERSION
${MINIZ_API_VERSION}.${MINIZ_MINOR_VERSION}.${MINIZ_PATCH_VERSION})
if(CMAKE_BUILD_TYPE STREQUAL "")
# CMake defaults to leaving CMAKE_BUILD_TYPE empty. This screws up
# differentiation between debug and release builds.
set(CMAKE_BUILD_TYPE "Release" CACHE STRING
"Choose the type of build, options are: None (CMAKE_CXX_FLAGS or \
CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel." FORCE)
endif ()
option(BUILD_EXAMPLES "Build examples" ${MINIZ_STANDALONE_PROJECT})
option(BUILD_FUZZERS "Build fuzz targets" OFF)
option(AMALGAMATE_SOURCES "Amalgamate sources into miniz.h/c" OFF)
option(BUILD_HEADER_ONLY "Build a header-only version" OFF)
option(BUILD_SHARED_LIBS "Build shared library instead of static" OFF)
option(INSTALL_PROJECT "Install project" ${MINIZ_STANDALONE_PROJECT})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin)
if(INSTALL_PROJECT)
include(GNUInstallDirs)
endif()
if(BUILD_HEADER_ONLY)
set(AMALGAMATE_SOURCES ON CACHE BOOL "Build a header-only version" FORCE)
endif(BUILD_HEADER_ONLY)
if(AMALGAMATE_SOURCES)
# Amalgamate
file(COPY miniz.h DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/amalgamation/)
file(READ miniz.h MINIZ_H)
file(READ miniz_common.h MINIZ_COMMON_H)
file(READ miniz_tdef.h MINIZ_TDEF_H)
file(READ miniz_tinfl.h MINIZ_TINFL_H)
file(READ miniz_zip.h MINIZ_ZIP_H)
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/amalgamation/miniz.h
"${MINIZ_COMMON_H} ${MINIZ_TDEF_H} ${MINIZ_TINFL_H} ${MINIZ_ZIP_H}")
file(COPY miniz.c DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/amalgamation/)
file(READ miniz_tdef.c MINIZ_TDEF_C)
file(READ miniz_tinfl.c MINIZ_TINFL_C)
file(READ miniz_zip.c MINIZ_ZIP_C)
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/amalgamation/miniz.c
"${MINIZ_TDEF_C} ${MINIZ_TINFL_C} ${MINIZ_ZIP_C}")
file(READ ${CMAKE_CURRENT_BINARY_DIR}/amalgamation/miniz.h AMAL_MINIZ_H)
file(READ ${CMAKE_CURRENT_BINARY_DIR}/amalgamation/miniz.c AMAL_MINIZ_C)
foreach(REPLACE_STRING miniz;miniz_common;miniz_tdef;miniz_tinfl;miniz_zip;miniz_export)
string(REPLACE "#include \"${REPLACE_STRING}.h\"" "" AMAL_MINIZ_H "${AMAL_MINIZ_H}")
string(REPLACE "#include \"${REPLACE_STRING}.h\"" "" AMAL_MINIZ_C "${AMAL_MINIZ_C}")
endforeach()
string(CONCAT AMAL_MINIZ_H "#ifndef MINIZ_EXPORT\n#define MINIZ_EXPORT\n#endif\n" "${AMAL_MINIZ_H}")
if(BUILD_HEADER_ONLY)
string(CONCAT AMAL_MINIZ_H "${AMAL_MINIZ_H}" "\n#ifndef MINIZ_HEADER_FILE_ONLY\n"
"${AMAL_MINIZ_C}" "\n#endif // MINIZ_HEADER_FILE_ONLY\n")
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/amalgamation/miniz.h "${AMAL_MINIZ_H}")
add_library(${PROJECT_NAME} INTERFACE)
# Might not be a good idea to force this on the library user
# as it could bloat the global namespace
# https://github.com/libevent/libevent/issues/460
# target_compile_definitions(${PROJECT_NAME}
# INTERFACE $<$<C_COMPILER_ID:GNU>:_GNU_SOURCE>)
set_property(TARGET ${PROJECT_NAME} APPEND
PROPERTY INTERFACE_INCLUDE_DIRECTORIES
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/amalgamation>
$<INSTALL_INTERFACE:include>
)
else(BUILD_HEADER_ONLY)
string(CONCAT AMAL_MINIZ_C "#include \"miniz.h\"\n" "${AMAL_MINIZ_C}")
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/amalgamation/miniz.h "${AMAL_MINIZ_H}")
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/amalgamation/miniz.c "${AMAL_MINIZ_C}")
set(miniz_SOURCE ${CMAKE_CURRENT_BINARY_DIR}/amalgamation/miniz.h
${CMAKE_CURRENT_BINARY_DIR}/amalgamation/miniz.c)
add_library(${PROJECT_NAME} STATIC ${miniz_SOURCE})
target_include_directories(${PROJECT_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/amalgamation>
$<INSTALL_INTERFACE:include>
)
endif(BUILD_HEADER_ONLY)
set(INSTALL_HEADERS ${CMAKE_CURRENT_BINARY_DIR}/amalgamation/miniz.h)
file(GLOB_RECURSE ZIP_FILES RELATIVE "${CMAKE_CURRENT_BINARY_DIR}/amalgamation" "${CMAKE_CURRENT_BINARY_DIR}/amalgamation/*")
file(GLOB_RECURSE ZIP_FILES2 RELATIVE "${CMAKE_SOURCE_DIR}" "${CMAKE_SOURCE_DIR}/examples/*")
list(APPEND ZIP_FILES ${ZIP_FILES2})
list(APPEND ZIP_FILES "ChangeLog.md")
list(APPEND ZIP_FILES "readme.md")
list(APPEND ZIP_FILES "LICENSE")
set(ZIP_OUT_FN "${CMAKE_CURRENT_BINARY_DIR}/miniz-${MINIZ_VERSION}.zip")
message(STATUS "Zip files: ${ZIP_FILES}")
add_custom_command(
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/examples ${CMAKE_CURRENT_BINARY_DIR}/amalgamation/examples
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/ChangeLog.md ${CMAKE_CURRENT_BINARY_DIR}/amalgamation/ChangeLog.md
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/readme.md ${CMAKE_CURRENT_BINARY_DIR}/amalgamation/readme.md
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/LICENSE ${CMAKE_CURRENT_BINARY_DIR}/amalgamation/LICENSE
COMMAND ${CMAKE_COMMAND} -E tar "cf" "${ZIP_OUT_FN}" --format=zip -- ${ZIP_FILES}
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/amalgamation"
OUTPUT "${ZIP_OUT_FN}"
DEPENDS ${ZIP_FILES}
COMMENT "Zipping to ${CMAKE_CURRENT_BINARY_DIR}/miniz.zip."
)
add_custom_target(
create_zip ALL
DEPENDS "${ZIP_OUT_FN}"
)
else(AMALGAMATE_SOURCES)
include(GenerateExportHeader)
set(miniz_SOURCE miniz.c miniz_zip.c miniz_tinfl.c miniz_tdef.c)
add_library(${PROJECT_NAME} ${miniz_SOURCE})
generate_export_header(${PROJECT_NAME})
add_library(miniz ${miniz_SOURCE})
if(NOT BUILD_SHARED_LIBS)
string(TOUPPER ${PROJECT_NAME} PROJECT_UPPER)
set_target_properties(${PROJECT_NAME}
PROPERTIES INTERFACE_COMPILE_DEFINITIONS ${PROJECT_UPPER}_STATIC_DEFINE)
else()
set_property(TARGET ${PROJECT_NAME} PROPERTY C_VISIBILITY_PRESET hidden)
endif()
set_property(TARGET ${PROJECT_NAME} PROPERTY VERSION ${MINIZ_VERSION})
set_property(TARGET ${PROJECT_NAME} PROPERTY SOVERSION ${MINIZ_API_VERSION})
target_include_directories(${PROJECT_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
$<INSTALL_INTERFACE:include>
)
file(GLOB INSTALL_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h)
list(APPEND
INSTALL_HEADERS ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}_export.h)
endif(AMALGAMATE_SOURCES)
if(NOT BUILD_HEADER_ONLY)
target_compile_definitions(${PROJECT_NAME}
PRIVATE $<$<C_COMPILER_ID:GNU>:_GNU_SOURCE>)
# pkg-config file
configure_file(miniz.pc.in ${CMAKE_CURRENT_BINARY_DIR}/miniz.pc @ONLY)
if(INSTALL_PROJECT)
install(FILES
${CMAKE_CURRENT_BINARY_DIR}/miniz.pc
DESTINATION ${CMAKE_INSTALL_DATADIR}/pkgconfig)
endif()
endif()
set_property(TARGET ${PROJECT_NAME} PROPERTY
INTERFACE_${PROJECT_NAME}_MAJOR_VERSION ${MINIZ_API_VERSION})
set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY
COMPATIBLE_INTERFACE_STRING ${PROJECT_NAME}_MAJOR_VERSION
)
if(INSTALL_PROJECT)
install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}Targets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
# users can use <miniz.h> or <miniz/miniz.h>
INCLUDES DESTINATION include ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}
)
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/${PROJECT_NAME}ConfigVersion.cmake"
VERSION ${MINIZ_VERSION}
COMPATIBILITY AnyNewerVersion
)
export(EXPORT ${PROJECT_NAME}Targets
FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/${PROJECT_NAME}Targets.cmake"
NAMESPACE ${PROJECT_NAME}::
)
configure_file(Config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/${PROJECT_NAME}Config.cmake"
@ONLY
)
set(ConfigPackageLocation ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
install(EXPORT ${PROJECT_NAME}Targets
FILE
${PROJECT_NAME}Targets.cmake
NAMESPACE
${PROJECT_NAME}::
DESTINATION
${ConfigPackageLocation}
)
install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/${PROJECT_NAME}Config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/${PROJECT_NAME}ConfigVersion.cmake"
DESTINATION
${ConfigPackageLocation}
COMPONENT
Devel
)
endif()
if(BUILD_EXAMPLES)
set(EXAMPLE1_SRC_LIST "${CMAKE_CURRENT_SOURCE_DIR}/examples/example1.c")
set(EXAMPLE2_SRC_LIST "${CMAKE_CURRENT_SOURCE_DIR}/examples/example2.c")
set(EXAMPLE3_SRC_LIST "${CMAKE_CURRENT_SOURCE_DIR}/examples/example3.c")
@@ -19,7 +239,6 @@ set(MINIZ_TESTER_SRC_LIST
"${CMAKE_CURRENT_SOURCE_DIR}/tests/miniz_tester.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/tests/timer.cpp")
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
add_executable(example1 ${EXAMPLE1_SRC_LIST})
target_link_libraries(example1 miniz)
add_executable(example2 ${EXAMPLE2_SRC_LIST})
@@ -38,3 +257,48 @@ endif()
# add_executable(miniz_tester ${MINIZ_TESTER_SRC_LIST})
# target_link_libraries(miniz_tester miniz)
endif(BUILD_EXAMPLES)
if(BUILD_FUZZERS)
set(FUZZ_MAIN_SRC "${CMAKE_CURRENT_SOURCE_DIR}/tests/fuzz_main.c")
set(CHECKSUM_FUZZER_SRC_LIST "${FUZZ_MAIN_SRC}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/checksum_fuzzer.c")
set(FLUSH_FUZZER_SRC_LIST "${FUZZ_MAIN_SRC}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/flush_fuzzer.c")
set(UNCOMPRESS_FUZZER_SRC_LIST "${FUZZ_MAIN_SRC}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/uncompress_fuzzer.c")
set(UNCOMPRESS2_FUZZER_SRC_LIST "${FUZZ_MAIN_SRC}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/uncompress2_fuzzer.c")
set(COMPRESS_FUZZER_SRC_LIST "${FUZZ_MAIN_SRC}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/compress_fuzzer.c")
set(SMALL_FUZZER_SRC_LIST "${FUZZ_MAIN_SRC}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/small_fuzzer.c")
set(LARGE_FUZZER_SRC_LIST "${FUZZ_MAIN_SRC}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/large_fuzzer.c")
set(ZIP_FUZZER_SRC_LIST "${FUZZ_MAIN_SRC}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/zip_fuzzer.c")
add_executable(checksum_fuzzer ${CHECKSUM_FUZZER_SRC_LIST})
target_link_libraries(checksum_fuzzer miniz)
add_executable(flush_fuzzer ${FLUSH_FUZZER_SRC_LIST})
target_link_libraries(flush_fuzzer miniz)
add_executable(uncompress_fuzzer ${UNCOMPRESS_FUZZER_SRC_LIST})
target_link_libraries(uncompress_fuzzer miniz)
add_executable(uncompress2_fuzzer ${UNCOMPRESS2_FUZZER_SRC_LIST})
target_link_libraries(uncompress2_fuzzer miniz)
add_executable(compress_fuzzer ${COMPRESS_FUZZER_SRC_LIST})
target_link_libraries(compress_fuzzer miniz)
add_executable(small_fuzzer ${SMALL_FUZZER_SRC_LIST})
target_link_libraries(small_fuzzer miniz)
add_executable(large_fuzzer ${LARGE_FUZZER_SRC_LIST})
target_link_libraries(large_fuzzer miniz)
add_executable(zip_fuzzer ${ZIP_FUZZER_SRC_LIST})
target_link_libraries(zip_fuzzer miniz)
endif()
set(INCLUDE_INSTALL_DIR "include")
if(INSTALL_PROJECT)
install(FILES ${INSTALL_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME})
endif()

220
ChangeLog.md Normal file
View File

@@ -0,0 +1,220 @@
## Changelog
### 3.0.0
- Reduce memory usage for inflate. This changes `struct tinfl_decompressor_tag` and therefore requires a major version bump
- Add padding to structures so it continues to work if features differ. This also changes some structures
- Use _ftelli64, _fseeki64 and stat with MinGW32 and OpenWatcom
- Fix varios warnings with OpenWatcom compiler
- Avoid using unaligned memory access in UBSan builds
- Set MINIZ_LITTLE_ENDIAN only if not set
- Add MINIZ_NO_DEFLATE_APIS and MINIZ_NO_INFLATE_APIS
- Fix use of uninitialized memory in tinfl_decompress_mem_to_callback()
- Use wfopen on windows
- Use _wstat64 instead _stat64 on windows
- Use level_and_flags after MZ_DEFAULT_COMPRESSION has been handled
- Improve endianess detection
- Don't use unaligned stores and loads per default
- Fix function declaration if MINIZ_NO_STDIO is used
- Fix MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8 not being set
- Remove total files check (its 32-bit uint)
- tinfl_decompress: avoid NULL ptr arithmetic UB
- miniz_zip: fix mz_zip_reader_extract_to_heap to read correct sizes
- Eliminate 64-bit operations on 32-bit machines
- Disable treating warnings as error with MSVC
- Disable building shared lib via CMake by default
### 2.2.0
- Fix examples with amalgamation
- Modified cmake script to support shared library mode and find_package
- Fix for misleading doc comment on `mz_zip_reader_init_cfile` function
- Add include location tolerance and stop forcing `_GNU_SOURCE`
- Fix: mz_zip_reader_locate_file_v2 returns an mz_bool
- Fix large file system checks
- Add #elif to enable an external mz_crc32() to be linked in
- Write with dynamic size (size of file/data to be added not known before adding)
- Added uncompress2 for zlib compatibility
- Add support for building as a Meson subproject
- Added OSSFuzz support; Integrate with CIFuzz
- Add pkg-config file
- Fixed use-of-uninitialized value msan error when copying dist bytes with no output bytes written.
- mz_zip_validate_file(): fix memory leak on errors
- Fixed MSAN use-of-uninitialized in tinfl_decompress when invalid dist is decoded. In this instance dist was 31 which s_dist_base translates as 0
- Add flag to set (compressed) size in local file header
- avoid use of uninitialized value in tdefl_record_literal
### 2.1.0
- More instances of memcpy instead of cast and use memcpy per default
- Remove inline for c90 support
- New function to read files via callback functions when adding them
- Fix out of bounds read while reading Zip64 extended information
- guard memcpy when n == 0 because buffer may be NULL
- Implement inflateReset() function
- Move comp/decomp alloc/free prototypes under guarding #ifndef MZ_NO_MALLOC
- Fix large file support under Windows
- Don't warn if _LARGEFILE64_SOURCE is not defined to 1
- Fixes for MSVC warnings
- Remove check that path of file added to archive contains ':' or '\'
- Add !defined check on MINIZ_USE_ALIGNED_LOADS_AND_STORES
### 2.0.8
- Remove unimplemented functions (mz_zip_locate_file and mz_zip_locate_file_v2)
- Add license, changelog, readme and example files to release zip
- Fix heap overflow to user buffer in tinfl_status tinfl_decompress
- Fix corrupt archive if uncompressed file smaller than 4 byte and the file is added by mz_zip_writer_add_mem*
### 2.0.7
- Removed need in C++ compiler in cmake build
- Fixed a lot of uninitialized value errors found with Valgrind by memsetting m_dict to 0 in tdefl_init
- Fix resource leak in mz_zip_reader_init_file_v2
- Fix assert with mz_zip_writer_add_mem* w/MZ_DEFAULT_COMPRESSION
- cmake build: install library and headers
- Remove _LARGEFILE64_SOURCE requirement from apple defines for large files
### 2.0.6
- Improve MZ_ZIP_FLAG_WRITE_ZIP64 documentation
- Remove check for cur_archive_file_ofs > UINT_MAX because cur_archive_file_ofs is not used after this point
- Add cmake debug configuration
- Fix PNG height when creating png files
- Add "iterative" file extraction method based on mz_zip_reader_extract_to_callback.
- Option to use memcpy for unaligned data access
- Define processor/arch macros as zero if not set to one
### 2.0.4/2.0.5
- Fix compilation with the various omission compile definitions
### 2.0.3
- Fix GCC/clang compile warnings
- Added callback for periodic flushes (for ZIP file streaming)
- Use UTF-8 for file names in ZIP files per default
### 2.0.2
- Fix source backwards compatibility with 1.x
- Fix a ZIP bit not being set correctly
### 2.0.1
- Added some tests
- Added CI
- Make source code ANSI C compatible
### 2.0.0 beta
- Matthew Sitton merged miniz 1.x to Rich Geldreich's vogl ZIP64 changes. Miniz is now licensed as MIT since the vogl code base is MIT licensed
- Miniz is now split into several files
- Miniz does now not seek backwards when creating ZIP files. That is the ZIP files can be streamed
- Miniz automatically switches to the ZIP64 format when the created ZIP files goes over ZIP file limits
- Similar to [SQLite](https://www.sqlite.org/amalgamation.html) the Miniz source code is amalgamated into one miniz.c/miniz.h pair in a build step (amalgamate.sh). Please use miniz.c/miniz.h in your projects
- Miniz 2 is only source back-compatible with miniz 1.x. It breaks binary compatibility because structures changed
### v1.16 BETA Oct 19, 2013
Still testing, this release is downloadable from [here](http://www.tenacioussoftware.com/miniz_v116_beta_r1.7z). 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. I would greatly appreciate any help with testing or any feedback.
The inflator in raw (non-zlib) mode is now usable on gzip or similar streams that have a bunch of bytes following the raw deflate data (problem discovered by rustyzip author williamw520). 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.
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 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. This is scary behavior if the caller didn't know when to stop accepting output (because it didn't know how much uncompressed data was expected, or didn't enforce a sane maximum). v1.16 will instead return 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" 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.
- 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.
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
going to mark this release as beta for a few weeks and continue testing it at work/home on various things.
- The inflator in raw (non-zlib) mode is now usable on gzip or similar data streams that have a bunch of bytes following the raw deflate data (problem discovered by rustyzip author williamw520).
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
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).
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.
- 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
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.
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
(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
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"
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.
- 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.
### v1.15 r4 STABLE - Oct 13, 2013
Merged over a few very minor bug fixes that I fixed in the zip64 branch. This is downloadable from [here](http://code.google.com/p/miniz/downloads/list) and also in SVN head (as of 10/19/13).
### v1.15 - Oct. 13, 2013
Interim bugfix release while I work on the next major release with zip64 and streaming compression/decompression support. Fixed the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY bug (thanks kahmyong.moon@hp.com), which could cause the locate files func to not find files when this flag was specified. Also fixed a bug in mz_zip_reader_extract_to_mem_no_alloc() with user provided read buffers (thanks kymoon). I also merged lots of compiler fixes from various github repo branches and Google Code issue reports. I finally added cmake support (only tested under for Linux so far), compiled and tested with clang v3.3 and gcc 4.6 (under Linux), added defl_write_image_to_png_file_in_memory_ex() (supports Y flipping for OpenGL use, real-time compression), added a new PNG example (example6.c - Mandelbrot), and I added 64-bit file I/O support (stat64(), etc.) for glibc.
- Critical fix for the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY bug (thanks kahmyong.moon@hp.com) which could cause locate files to not find files. This bug
would only have occurred 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()
(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).
- 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
- Fixing mz_zip_reader_extract_*() funcs so they don't try to extract compressed data from directory entries, to account for weird zipfiles which contain zero-size compressed data on dir entries.
Hopefully this fix won't cause any issues on weird zip archives, because it assumes the low 16-bits of zip external attributes are DOS attributes (which I believe they always are in practice).
- Fixing mz_zip_reader_is_file_a_directory() so it doesn't check the internal attributes, just the filename and external attributes
- mz_zip_reader_init_file() - missing MZ_FCLOSE() call if the seek failed
- Added cmake support for Linux builds which builds all the examples, tested with clang v3.3 and gcc v4.6.
- Clang fix for tdefl_write_image_to_png_file_in_memory() from toffaletti
- Merged MZ_FORCEINLINE fix from hdeanclark
- Fix <time.h> include before config #ifdef, thanks emil.brink
- Added tdefl_write_image_to_png_file_in_memory_ex(): supports Y flipping (super useful for OpenGL apps), and explicit control over the compression level (so you can
set it to 1 for real-time compression).
- Merged in some compiler fixes from paulharris's github repro.
- Retested this build under Windows (VS 2010, including static analysis), tcc 0.9.26, gcc v4.6 and clang v3.3.
- Added example6.c, which dumps an image of the mandelbrot set to a PNG file.
- Modified example2 to help test the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY flag more.
- 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
- 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
### v1.14 - May 20, 2012
(SVN Only) Minor tweaks to get miniz.c compiling with the Tiny C Compiler, added #ifndef MINIZ_NO_TIME guards around utime.h includes. Adding mz_free() function, so the caller can free heap blocks returned by miniz using whatever heap functions it has been configured to use, MSVC specific fixes to use "safe" variants of several functions (localtime_s, fopen_s, freopen_s).
MinGW32/64 GCC 4.6.1 compiler fixes: added MZ_FORCEINLINE, #include <time.h> (thanks fermtect).
Compiler specific fixes, some from fermtect. I upgraded to TDM GCC 4.6.1 and now static __forceinline is giving it fits, so I'm changing all usage of __forceinline to MZ_FORCEINLINE and forcing gcc to use __attribute__((__always_inline__)) (and MSVC to use __forceinline). Also various fixes from fermtect for MinGW32: added #include , 64-bit ftell/fseek fixes.
### v1.13 - May 19, 2012
From jason@cornsyrup.org and kelwert@mtu.edu - Most importantly, fixed mz_crc32() so it doesn't compute the wrong CRC-32's when mz_ulong is 64-bits. Temporarily/locally slammed in "typedef unsigned long mz_ulong" and re-ran a randomized regression test on ~500k files. Other stuff:
Eliminated a bunch of warnings when compiling with GCC 32-bit/64. Ran all examples, miniz.c, and tinfl.c through MSVC 2008's /analyze (static analysis) option and fixed all warnings (except for the silly "Use of the comma-operator in a tested expression.." analysis warning, which I purposely use to work around a MSVC compiler warning).
Created 32-bit and 64-bit Codeblocks projects/workspace. Built and tested Linux executables. The codeblocks workspace is compatible with Linux+Win32/x64. Added miniz_tester solution/project, which is a useful little app derived from LZHAM's tester app that I use as part of the regression test. Ran miniz.c and tinfl.c through another series of regression testing on ~500,000 files and archives. Modified example5.c so it purposely disables a bunch of high-level functionality (MINIZ_NO_STDIO, etc.). (Thanks to corysama for the MINIZ_NO_STDIO bug report.)
Fix ftell() usage in a few of the examples so they exit with an error on files which are too large (a limitation of the examples, not miniz itself). Fix fail logic handling in mz_zip_add_mem_to_archive_file_in_place() so it always calls mz_zip_writer_finalize_archive() and mz_zip_writer_end(), even if the file add fails.
- From jason@cornsyrup.org and kelwert@mtu.edu - Fix mz_crc32() so it doesn't compute the wrong CRC-32's when mz_ulong is 64-bit.
- Temporarily/locally slammed in "typedef unsigned long mz_ulong" and re-ran a randomized regression test on ~500k files.
- Eliminated a bunch of warnings when compiling with GCC 32-bit/64.
- Ran all examples, miniz.c, and tinfl.c through MSVC 2008's /analyze (static analysis) option and fixed all warnings (except for the silly
"Use of the comma-operator in a tested expression.." analysis warning, which I purposely use to work around a MSVC compiler warning).
- Created 32-bit and 64-bit Codeblocks projects/workspace. Built and tested Linux executables. The codeblocks workspace is compatible with Linux+Win32/x64.
- Added miniz_tester solution/project, which is a useful little app derived from LZHAM's tester app that I use as part of the regression test.
- Ran miniz.c and tinfl.c through another series of regression testing on ~500,000 files and archives.
- Modified example5.c so it purposely disables a bunch of high-level functionality (MINIZ_NO_STDIO, etc.). (Thanks to corysama for the MINIZ_NO_STDIO bug report.)
- Fix ftell() usage in examples so they exit with an error on files which are too large (a limitation of the examples, not miniz itself).
### v1.12 - 4/12/12
More comments, added low-level example5.c, fixed a couple minor level_and_flags issues in the archive API's.
level_and_flags can now be set to MZ_DEFAULT_COMPRESSION. Thanks to Bruce Dawson <bruced@valvesoftware.com> for the feedback/bug report.
### v1.11 - 5/28/11
Added statement from unlicense.org
### v1.10 - 5/27/11
- Substantial compressor optimizations:
- Level 1 is now ~4x faster than before. The L1 compressor's throughput now varies between 70-110MB/sec. on a Core i7 (actual throughput varies depending on the type of data, and x64 vs. x86).
- Improved baseline L2-L9 compression perf. Also, greatly improved compression perf. issues on some file types.
- Refactored the compression code for better readability and maintainability.
- Added level 10 compression level (L10 has slightly better ratio than level 9, but could have a potentially large drop in throughput on some files).
### v1.09 - 5/15/11
Initial stable release.

1
Config.cmake.in Normal file
View File

@@ -0,0 +1 @@
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")

55
amalgamate.sh Normal file → Executable file
View File

@@ -3,40 +3,51 @@
set -e
mkdir -p amalgamation
OUTPUT_PREFIX=amalgamation/miniz
cat miniz.h > $OUTPUT_PREFIX.h
cat miniz.c > $OUTPUT_PREFIX.c
cat miniz_common.h >> $OUTPUT_PREFIX.h
cat miniz_tdef.c >> $OUTPUT_PREFIX.c
cat miniz_tdef.h >> $OUTPUT_PREFIX.h
cat miniz_tinfl.c >> $OUTPUT_PREFIX.c
cat miniz_tinfl.h >> $OUTPUT_PREFIX.h
cat miniz_zip.c >> $OUTPUT_PREFIX.c
cat miniz_zip.h >> $OUTPUT_PREFIX.h
sed -i '0,/#include "miniz.h"/{s/#include "miniz.h"/#include "miniz.h"/}' $OUTPUT_PREFIX.c
for i in miniz miniz_common miniz_tdef miniz_tinfl miniz_zip
do
sed -i "s/#include \"$i.h\"//g" $OUTPUT_PREFIX.h
sed -i "s/#include \"$i.h\"//g" $OUTPUT_PREFIX.c
done
OUTPUT_PREFIX=_build/amalgamation
cmake -H. -B_build -DAMALGAMATE_SOURCES=ON -G"Unix Makefiles"
echo "int main() { return 0; }" > main.c
gcc -pedantic -Wall main.c $OUTPUT_PREFIX.c -o test.out
gcc -ansi -pedantic -Wall main.c $OUTPUT_PREFIX.c -o test.out
echo "Test compile with GCC..."
gcc -pedantic -Wall -I$OUTPUT_PREFIX main.c $OUTPUT_PREFIX/miniz.c -o test.out
echo "Test compile with GCC ANSI..."
gcc -ansi -pedantic -Wall -I$OUTPUT_PREFIX main.c $OUTPUT_PREFIX/miniz.c -o test.out
if command -v clang
then
clang -Wall -Wpedantic -fsanitize=unsigned-integer-overflow main.c $OUTPUT_PREFIX.c -o test.out
echo "Test compile with clang..."
clang -Wall -Wpedantic -fsanitize=unsigned-integer-overflow -I$OUTPUT_PREFIX main.c $OUTPUT_PREFIX/miniz.c -o test.out
fi
for def in MINIZ_NO_STDIO MINIZ_NO_TIME MINIZ_NO_DEFLATE_APIS MINIZ_NO_INFLATE_APIS MINIZ_NO_ARCHIVE_APIS MINIZ_NO_ARCHIVE_WRITING_APIS MINIZ_NO_ZLIB_APIS MINIZ_NO_ZLIB_COMPATIBLE_NAMES MINIZ_NO_MALLOC
do
echo "Test compile with GCC and define $def..."
gcc -ansi -pedantic -Wall -I$OUTPUT_PREFIX main.c $OUTPUT_PREFIX/miniz.c -o test.out -D${def}
done
rm test.out
rm main.c
cp $OUTPUT_PREFIX/miniz.* amalgamation/
cp ChangeLog.md amalgamation/
cp LICENSE amalgamation/
cp readme.md amalgamation/
mkdir -p amalgamation/examples
cp examples/* amalgamation/examples/
cd amalgamation
! test -e miniz.zip || rm miniz.zip
echo -e "miniz.c\nminiz.h" | zip -@ miniz
cat << EOF | zip -@ miniz
miniz.c
miniz.h
ChangeLog.md
LICENSE
readme.md
examples/example1.c
examples/example2.c
examples/example3.c
examples/example4.c
examples/example5.c
examples/example6.c
EOF
cd ..
echo "Amalgamation created."

View File

@@ -13,7 +13,7 @@
#endif
#include <stdio.h>
#include "miniz_zip.h"
#include "miniz.h"
typedef unsigned char uint8;
typedef unsigned short uint16;

View File

@@ -100,7 +100,7 @@ int main(int argc, char *argv[])
file_loc = ftell(pInfile);
fseek(pInfile, 0, SEEK_SET);
if ((file_loc < 0) || (file_loc > INT_MAX))
if ((file_loc < 0) || ((mz_uint64)file_loc > INT_MAX))
{
// This is not a limitation of miniz or tinfl, but this example.
printf("File is too large to be processed by this example.\n");

View File

@@ -1,6 +1,6 @@
// example4.c - Uses tinfl.c to decompress a zlib stream in memory to an output file
// Public domain, May 15 2011, Rich Geldreich, richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c.
#include "miniz_tinfl.h"
#include "miniz.h"
#include <stdio.h>
#include <limits.h>
@@ -47,7 +47,7 @@ int main(int argc, char *argv[])
file_loc = ftell(pInfile);
fseek(pInfile, 0, SEEK_SET);
if ((file_loc < 0) || (file_loc > INT_MAX))
if ((file_loc < 0) || ((mz_uint64)file_loc > INT_MAX))
{
// This is not a limitation of miniz or tinfl, but this example.
printf("File is too large to be processed by this example.\n");

View File

@@ -132,7 +132,7 @@ int main(int argc, char *argv[])
file_loc = ftell(pInfile);
fseek(pInfile, 0, SEEK_SET);
if ((file_loc < 0) || (file_loc > INT_MAX))
if ((file_loc < 0) || ((mz_uint64)file_loc > INT_MAX))
{
// This is not a limitation of miniz or tinfl, but this example.
printf("File is too large to be processed by this example.\n");

View File

@@ -34,14 +34,17 @@ static void hsv_to_rgb(int hue, int min, int max, rgb_t *p)
if (!saturation) {
p->r = p->g = p->b = 255 * (max - hue) / (max - min);
return;
}
double h = fmod(color_rotate + 1e-4 + 4.0 * (hue - min) / (max - min), 6);
double c = 255.0f * saturation;
double X = c * (1 - fabs(fmod(h, 2) - 1));
} else {
const double h_dbl = fmod(color_rotate + 1e-4 + 4.0 * (hue - min) / (max - min), 6);
const double c_dbl = 255 * saturation;
const double X_dbl = c_dbl * (1 - fabs(fmod(h_dbl, 2) - 1));
const int h = (int)h_dbl;
const int c = (int)c_dbl;
const int X = (int)X_dbl;
p->r = p->g = p->b = 0;
switch((int)h) {
switch(h) {
case 0: p->r = c; p->g = X; return;
case 1: p->r = X; p->g = c; return;
case 2: p->g = c; p->b = X; return;
@@ -50,11 +53,10 @@ static void hsv_to_rgb(int hue, int min, int max, rgb_t *p)
default:p->r = c; p->b = X;
}
}
}
int main(int argc, char *argv[])
{
(void)argc, (void)argv;
// Image resolution
const int iXmax = 4096;
const int iYmax = 4096;
@@ -89,6 +91,8 @@ int main(int argc, char *argv[])
int MinIter = 9999, MaxIter = 0;
(void)argc, (void)argv;
for(iY = 0; iY < iYmax; iY++)
{
Cy = CyMin + iY * PixelHeight;
@@ -134,7 +138,7 @@ int main(int argc, char *argv[])
uint Iterations = color[0] | (color[1] << 8U);
hsv_to_rgb(Iterations, MinIter, MaxIter, (rgb_t *)color);
hsv_to_rgb((int)Iterations, MinIter, MaxIter, (rgb_t *)color);
}
}

21
meson.build Normal file
View File

@@ -0,0 +1,21 @@
project('miniz', 'c')
miniz_includes = include_directories('.')
cfg = configuration_data()
cfg.set('MINIZ_EXPORT', '')
miniz_export_h = configure_file(output: 'miniz_export.h',
configuration: cfg)
libminiz = static_library('miniz',
miniz_export_h, 'miniz.c', 'miniz_zip.c', 'miniz_tinfl.c', 'miniz_tdef.c',
include_directories: miniz_includes)
miniz_dependency = declare_dependency(link_with: libminiz,
include_directories: miniz_includes)
miniz_dep = miniz_dependency # Compatibility for WrapDB users
if meson.version().version_compare('>= 0.54.0')
meson.override_dependency('miniz', miniz_dep)
endif

68
miniz.c
View File

@@ -82,6 +82,12 @@ mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len)
}
return ~crcu32;
}
#elif defined(USE_EXTERNAL_MZCRC)
/* If USE_EXTERNAL_CRC is defined, an external module will export the
* mz_crc32() symbol for us to use, e.g. an SSE-accelerated version.
* Depending on the impl, it may be necessary to ~ the input/output crc values.
*/
mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len);
#else
/* Faster, but larger CPU cache footprint.
*/
@@ -157,19 +163,17 @@ void mz_free(void *p)
MZ_FREE(p);
}
#ifndef MINIZ_NO_ZLIB_APIS
void *miniz_def_alloc_func(void *opaque, size_t items, size_t size)
MINIZ_EXPORT void *miniz_def_alloc_func(void *opaque, size_t items, size_t size)
{
(void)opaque, (void)items, (void)size;
return MZ_MALLOC(items * size);
}
void miniz_def_free_func(void *opaque, void *address)
MINIZ_EXPORT void miniz_def_free_func(void *opaque, void *address)
{
(void)opaque, (void)address;
MZ_FREE(address);
}
void *miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size)
MINIZ_EXPORT void *miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size)
{
(void)opaque, (void)address, (void)items, (void)size;
return MZ_REALLOC(address, items * size);
@@ -180,6 +184,10 @@ const char *mz_version(void)
return MZ_VERSION;
}
#ifndef MINIZ_NO_ZLIB_APIS
#ifndef MINIZ_NO_DEFLATE_APIS
int mz_deflateInit(mz_streamp pStream, int level)
{
return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY);
@@ -314,7 +322,7 @@ int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char
memset(&stream, 0, sizeof(stream));
/* In case mz_ulong is 64-bits (argh I hate longs). */
if ((source_len | *pDest_len) > 0xFFFFFFFFU)
if ((mz_uint64)(source_len | *pDest_len) > 0xFFFFFFFFU)
return MZ_PARAM_ERROR;
stream.next_in = pSource;
@@ -347,6 +355,10 @@ mz_ulong mz_compressBound(mz_ulong source_len)
return mz_deflateBound(NULL, source_len);
}
#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/
#ifndef MINIZ_NO_INFLATE_APIS
typedef struct
{
tinfl_decompressor m_decomp;
@@ -397,6 +409,32 @@ int mz_inflateInit(mz_streamp pStream)
return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS);
}
int mz_inflateReset(mz_streamp pStream)
{
inflate_state *pDecomp;
if (!pStream)
return MZ_STREAM_ERROR;
pStream->data_type = 0;
pStream->adler = 0;
pStream->msg = NULL;
pStream->total_in = 0;
pStream->total_out = 0;
pStream->reserved = 0;
pDecomp = (inflate_state *)pStream->state;
tinfl_init(&pDecomp->m_decomp);
pDecomp->m_dict_ofs = 0;
pDecomp->m_dict_avail = 0;
pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
pDecomp->m_first_call = 1;
pDecomp->m_has_flushed = 0;
/* pDecomp->m_window_bits = window_bits */;
return MZ_OK;
}
int mz_inflate(mz_streamp pStream, int flush)
{
inflate_state *pState;
@@ -520,19 +558,18 @@ int mz_inflateEnd(mz_streamp pStream)
}
return MZ_OK;
}
int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
int mz_uncompress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong *pSource_len)
{
mz_stream stream;
int status;
memset(&stream, 0, sizeof(stream));
/* In case mz_ulong is 64-bits (argh I hate longs). */
if ((source_len | *pDest_len) > 0xFFFFFFFFU)
if ((mz_uint64)(*pSource_len | *pDest_len) > 0xFFFFFFFFU)
return MZ_PARAM_ERROR;
stream.next_in = pSource;
stream.avail_in = (mz_uint32)source_len;
stream.avail_in = (mz_uint32)*pSource_len;
stream.next_out = pDest;
stream.avail_out = (mz_uint32)*pDest_len;
@@ -541,6 +578,7 @@ int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char
return status;
status = mz_inflate(&stream, MZ_FINISH);
*pSource_len = *pSource_len - stream.avail_in;
if (status != MZ_STREAM_END)
{
mz_inflateEnd(&stream);
@@ -551,6 +589,13 @@ int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char
return mz_inflateEnd(&stream);
}
int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
{
return mz_uncompress2(pDest, pDest_len, pSource, &source_len);
}
#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/
const char *mz_error(int err)
{
static struct
@@ -559,8 +604,7 @@ const char *mz_error(int err)
const char *m_pDesc;
} s_error_descs[] =
{
{ MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" },
{ 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" }
{ MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" }, { 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" }
};
mz_uint i;
for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i)

230
miniz.h
View File

@@ -1,4 +1,4 @@
/* miniz.c v1.16 beta r1 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
/* miniz.c 3.0.0 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
See "unlicense" statement at the end of this file.
Rich Geldreich <richgel99@gmail.com>, last updated Oct. 13, 2013
Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
@@ -6,66 +6,6 @@
Most API's defined in miniz.c are optional. For example, to disable the archive related functions just define
MINIZ_NO_ARCHIVE_APIS, or to get rid of all stdio usage define MINIZ_NO_STDIO (see the list below for more macros).
* Change History
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.
- 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.
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
going to mark this release as beta for a few weeks and continue testing it at work/home on various things.
- 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).
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
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).
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.
- 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
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.
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
(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
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"
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.
- 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.
10/13/13 v1.15 r4 - Interim bugfix release while I work on the next major release with Zip64 support (almost there!):
- Critical fix for the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY bug (thanks kahmyong.moon@hp.com) which could cause locate files to not find files. This bug
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()
(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).
- 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
- Fixing mz_zip_reader_extract_*() funcs so they don't try to extract compressed data from directory entries, to account for weird zipfiles which contain zero-size compressed data on dir entries.
Hopefully this fix won't cause any issues on weird zip archives, because it assumes the low 16-bits of zip external attributes are DOS attributes (which I believe they always are in practice).
- Fixing mz_zip_reader_is_file_a_directory() so it doesn't check the internal attributes, just the filename and external attributes
- mz_zip_reader_init_file() - missing MZ_FCLOSE() call if the seek failed
- Added cmake support for Linux builds which builds all the examples, tested with clang v3.3 and gcc v4.6.
- Clang fix for tdefl_write_image_to_png_file_in_memory() from toffaletti
- Merged MZ_FORCEINLINE fix from hdeanclark
- Fix <time.h> include before config #ifdef, thanks emil.brink
- Added tdefl_write_image_to_png_file_in_memory_ex(): supports Y flipping (super useful for OpenGL apps), and explicit control over the compression level (so you can
set it to 1 for real-time compression).
- Merged in some compiler fixes from paulharris's github repro.
- Retested this build under Windows (VS 2010, including static analysis), tcc 0.9.26, gcc v4.6 and clang v3.3.
- Added example6.c, which dumps an image of the mandelbrot set to a PNG file.
- Modified example2 to help test the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY flag more.
- 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
- 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
5/20/12 v1.14 - MinGW32/64 GCC 4.6.1 compiler fixes: added MZ_FORCEINLINE, #include <time.h> (thanks fermtect).
5/19/12 v1.13 - From jason@cornsyrup.org and kelwert@mtu.edu - Fix mz_crc32() so it doesn't compute the wrong CRC-32's when mz_ulong is 64-bit.
- Temporarily/locally slammed in "typedef unsigned long mz_ulong" and re-ran a randomized regression test on ~500k files.
- Eliminated a bunch of warnings when compiling with GCC 32-bit/64.
- Ran all examples, miniz.c, and tinfl.c through MSVC 2008's /analyze (static analysis) option and fixed all warnings (except for the silly
"Use of the comma-operator in a tested expression.." analysis warning, which I purposely use to work around a MSVC compiler warning).
- Created 32-bit and 64-bit Codeblocks projects/workspace. Built and tested Linux executables. The codeblocks workspace is compatible with Linux+Win32/x64.
- Added miniz_tester solution/project, which is a useful little app derived from LZHAM's tester app that I use as part of the regression test.
- Ran miniz.c and tinfl.c through another series of regression testing on ~500,000 files and archives.
- Modified example5.c so it purposely disables a bunch of high-level functionality (MINIZ_NO_STDIO, etc.). (Thanks to corysama for the MINIZ_NO_STDIO bug report.)
- Fix ftell() usage in examples so they exit with an error on files which are too large (a limitation of the examples, not miniz itself).
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.
level_and_flags can now be set to MZ_DEFAULT_COMPRESSION. Thanks to Bruce Dawson <bruced@valvesoftware.com> for the feedback/bug report.
5/28/11 v1.11 - Added statement from unlicense.org
5/27/11 v1.10 - Substantial compressor optimizations:
- Level 1 is now ~4x faster than before. The L1 compressor's throughput now varies between 70-110MB/sec. on a
- Core i7 (actual throughput varies depending on the type of data, and x64 vs. x86).
- Improved baseline L2-L9 compression perf. Also, greatly improved compression perf. issues on some file types.
- Refactored the compression code for better readability and maintainability.
- Added level 10 compression level (L10 has slightly better ratio than level 9, but could have a potentially large
drop in throughput on some files).
5/15/11 v1.09 - Initial stable release.
* Low-level Deflate/Inflate implementation notes:
Compression: Use the "tdefl" API's. The compressor supports raw, static, and dynamic blocks, lazy or
@@ -84,7 +24,7 @@
zlib replacement in many apps:
The z_stream struct, optional memory allocation callbacks
deflateInit/deflateInit2/deflate/deflateReset/deflateEnd/deflateBound
inflateInit/inflateInit2/inflate/inflateEnd
inflateInit/inflateInit2/inflate/inflateReset/inflateEnd
compress, compress2, compressBound, uncompress
CRC-32, Adler-32 - Using modern, minimal code size, CPU cache friendly routines.
Supports raw deflate streams or standard zlib streams with adler-32 checking.
@@ -155,7 +95,7 @@
possibility that the archive's central directory could be lost with this method if anything goes wrong, though.
- ZIP archive support limitations:
No zip64 or spanning support. Extraction functions can only handle unencrypted, stored or deflated files.
No spanning support. Extraction functions can only handle unencrypted, stored or deflated files.
Requires streams capable of seeking.
* This is a header file library, like stb_image.c. To get only a header file, either cut and paste the
@@ -172,12 +112,10 @@
*/
#pragma once
#include "miniz_common.h"
#include "miniz_tdef.h"
#include "miniz_tinfl.h"
#include "miniz_export.h"
/* Defines to completely disable specific portions of miniz.c:
If all macros here are defined the only functionality remaining will be CRC-32, adler-32, tinfl, and tdefl. */
If all macros here are defined the only functionality remaining will be CRC-32 and adler-32. */
/* Define MINIZ_NO_STDIO to disable all usage and any functions which rely on stdio for file I/O. */
/*#define MINIZ_NO_STDIO */
@@ -187,10 +125,16 @@
/* The current downside is the times written to your archives will be from 1979. */
/*#define MINIZ_NO_TIME */
/* Define MINIZ_NO_DEFLATE_APIS to disable all compression API's. */
/*#define MINIZ_NO_DEFLATE_APIS */
/* Define MINIZ_NO_INFLATE_APIS to disable all decompression API's. */
/*#define MINIZ_NO_INFLATE_APIS */
/* Define MINIZ_NO_ARCHIVE_APIS to disable all ZIP archive API's. */
/*#define MINIZ_NO_ARCHIVE_APIS */
/* Define MINIZ_NO_ARCHIVE_APIS to disable all writing related ZIP archive API's. */
/* Define MINIZ_NO_ARCHIVE_WRITING_APIS to disable all writing related ZIP archive API's. */
/*#define MINIZ_NO_ARCHIVE_WRITING_APIS */
/* Define MINIZ_NO_ZLIB_APIS to remove all ZLIB-style compression/decompression API's. */
@@ -205,11 +149,21 @@
functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work. */
/*#define MINIZ_NO_MALLOC */
#ifdef MINIZ_NO_INFLATE_APIS
#define MINIZ_NO_ARCHIVE_APIS
#endif
#ifdef MINIZ_NO_DEFLATE_APIS
#define MINIZ_NO_ARCHIVE_WRITING_APIS
#endif
#if defined(__TINYC__) && (defined(__linux) || defined(__linux__))
/* TODO: Work around "error: include file 'sys\utime.h' when compiling with tcc on Linux */
#define MINIZ_NO_TIME
#endif
#include <stddef.h>
#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_ARCHIVE_APIS)
#include <time.h>
#endif
@@ -217,21 +171,55 @@
#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__)
/* MINIZ_X86_OR_X64_CPU is only used to help set the below macros. */
#define MINIZ_X86_OR_X64_CPU 1
#else
#define MINIZ_X86_OR_X64_CPU 0
#endif
#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU
/* Set MINIZ_LITTLE_ENDIAN only if not set */
#if !defined(MINIZ_LITTLE_ENDIAN)
#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)
#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
/* Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. */
#define MINIZ_LITTLE_ENDIAN 1
#else
#define MINIZ_LITTLE_ENDIAN 0
#endif
#else
#if MINIZ_X86_OR_X64_CPU
#define MINIZ_LITTLE_ENDIAN 1
#else
#define MINIZ_LITTLE_ENDIAN 0
#endif
#endif
#endif
/* Using unaligned loads and stores causes errors when using UBSan */
#if defined(__has_feature)
#if __has_feature(undefined_behavior_sanitizer)
#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0
#endif
#endif
/* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES only if not set */
#if !defined(MINIZ_USE_UNALIGNED_LOADS_AND_STORES)
#if MINIZ_X86_OR_X64_CPU
/* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient integer loads and stores from unaligned addresses. */
#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0
#define MINIZ_UNALIGNED_USE_MEMCPY
#else
#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0
#endif
#endif
#if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) || defined(__ia64__) || defined(__x86_64__)
/* Set MINIZ_HAS_64BIT_REGISTERS to 1 if operations on 64-bit integers are reasonably fast (and don't involve compiler generated calls to helper functions). */
#define MINIZ_HAS_64BIT_REGISTERS 1
#else
#define MINIZ_HAS_64BIT_REGISTERS 0
#endif
#ifdef __cplusplus
@@ -244,15 +232,15 @@ extern "C" {
typedef unsigned long mz_ulong;
/* mz_free() internally uses the MZ_FREE() macro (which by default calls free() unless you've modified the MZ_MALLOC macro) to release a block allocated from the heap. */
void mz_free(void *p);
MINIZ_EXPORT void mz_free(void *p);
#define MZ_ADLER32_INIT (1)
/* mz_adler32() returns the initial adler-32 value to use when called with ptr==NULL. */
mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len);
MINIZ_EXPORT mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len);
#define MZ_CRC32_INIT (0)
/* mz_crc32() returns the initial CRC-32 value to use when called with ptr==NULL. */
mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len);
MINIZ_EXPORT mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len);
/* Compression strategies. */
enum
@@ -267,22 +255,32 @@ enum
/* Method */
#define MZ_DEFLATED 8
#ifndef MINIZ_NO_ZLIB_APIS
/* Heap allocation callbacks.
Note that mz_alloc_func parameter types purpsosely differ from zlib's: items/size is size_t, not unsigned long. */
Note that mz_alloc_func parameter types purposely differ from zlib's: items/size is size_t, not unsigned long. */
typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size);
typedef void (*mz_free_func)(void *opaque, void *address);
typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size);
/* TODO: I can't encode "1.16" here, argh */
#define MZ_VERSION "9.1.15"
#define MZ_VERNUM 0x91F0
#define MZ_VER_MAJOR 9
#define MZ_VER_MINOR 1
#define MZ_VER_REVISION 15
/* 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. */
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
};
#define MZ_VERSION "11.0.0"
#define MZ_VERNUM 0xB000
#define MZ_VER_MAJOR 11
#define MZ_VER_MINOR 0
#define MZ_VER_REVISION 0
#define MZ_VER_SUBREVISION 0
#ifndef MINIZ_NO_ZLIB_APIS
/* 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). */
enum
{
@@ -309,17 +307,6 @@ enum
MZ_PARAM_ERROR = -10000
};
/* 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. */
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
};
/* Window bits */
#define MZ_DEFAULT_WINDOW_BITS 15
@@ -351,7 +338,9 @@ typedef struct mz_stream_s
typedef mz_stream *mz_streamp;
/* Returns the version string of miniz.c. */
const char *mz_version(void);
MINIZ_EXPORT const char *mz_version(void);
#ifndef MINIZ_NO_DEFLATE_APIS
/* mz_deflateInit() initializes a compressor with default options: */
/* Parameters: */
@@ -364,17 +353,17 @@ const char *mz_version(void);
/* MZ_STREAM_ERROR if the stream is bogus. */
/* MZ_PARAM_ERROR if the input parameters are bogus. */
/* MZ_MEM_ERROR on out of memory. */
int mz_deflateInit(mz_streamp pStream, int level);
MINIZ_EXPORT int mz_deflateInit(mz_streamp pStream, int level);
/* mz_deflateInit2() is like mz_deflate(), except with more control: */
/* Additional parameters: */
/* method must be MZ_DEFLATED */
/* 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) */
/* mem_level must be between [1, 9] (it's checked but ignored by miniz.c) */
int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy);
MINIZ_EXPORT int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy);
/* Quickly resets a compressor without having to reallocate anything. Same as calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2(). */
int mz_deflateReset(mz_streamp pStream);
MINIZ_EXPORT int mz_deflateReset(mz_streamp pStream);
/* mz_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible. */
/* Parameters: */
@@ -386,31 +375,38 @@ int mz_deflateReset(mz_streamp pStream);
/* MZ_STREAM_ERROR if the stream is bogus. */
/* MZ_PARAM_ERROR if one of the parameters is invalid. */
/* 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.) */
int mz_deflate(mz_streamp pStream, int flush);
MINIZ_EXPORT int mz_deflate(mz_streamp pStream, int flush);
/* mz_deflateEnd() deinitializes a compressor: */
/* Return values: */
/* MZ_OK on success. */
/* MZ_STREAM_ERROR if the stream is bogus. */
int mz_deflateEnd(mz_streamp pStream);
MINIZ_EXPORT int mz_deflateEnd(mz_streamp pStream);
/* 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. */
mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len);
MINIZ_EXPORT mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len);
/* Single-call compression functions mz_compress() and mz_compress2(): */
/* Returns MZ_OK on success, or one of the error codes from mz_deflate() on failure. */
int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level);
MINIZ_EXPORT int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
MINIZ_EXPORT int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level);
/* mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress(). */
mz_ulong mz_compressBound(mz_ulong source_len);
MINIZ_EXPORT mz_ulong mz_compressBound(mz_ulong source_len);
#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/
#ifndef MINIZ_NO_INFLATE_APIS
/* Initializes a decompressor. */
int mz_inflateInit(mz_streamp pStream);
MINIZ_EXPORT int mz_inflateInit(mz_streamp pStream);
/* 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: */
/* window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate). */
int mz_inflateInit2(mz_streamp pStream, int window_bits);
MINIZ_EXPORT int mz_inflateInit2(mz_streamp pStream, int window_bits);
/* Quickly resets a compressor without having to reallocate anything. Same as calling mz_inflateEnd() followed by mz_inflateInit()/mz_inflateInit2(). */
MINIZ_EXPORT int mz_inflateReset(mz_streamp pStream);
/* 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. */
/* Parameters: */
@@ -426,17 +422,19 @@ int mz_inflateInit2(mz_streamp pStream, int window_bits);
/* MZ_PARAM_ERROR if one of the parameters is invalid. */
/* 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 */
/* with more input data, or with more room in the output buffer (except when using single call decompression, described above). */
int mz_inflate(mz_streamp pStream, int flush);
MINIZ_EXPORT int mz_inflate(mz_streamp pStream, int flush);
/* Deinitializes a decompressor. */
int mz_inflateEnd(mz_streamp pStream);
MINIZ_EXPORT int mz_inflateEnd(mz_streamp pStream);
/* Single-call decompression. */
/* Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure. */
int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
MINIZ_EXPORT int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
MINIZ_EXPORT int mz_uncompress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong *pSource_len);
#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/
/* Returns a string description of the specified error code, or NULL if the error code is invalid. */
const char *mz_error(int err);
MINIZ_EXPORT const char *mz_error(int err);
/* 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. */
/* Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project. */
@@ -484,6 +482,8 @@ typedef void *const voidpc;
#define free_func mz_free_func
#define internal_state mz_internal_state
#define z_stream mz_stream
#ifndef MINIZ_NO_DEFLATE_APIS
#define deflateInit mz_deflateInit
#define deflateInit2 mz_deflateInit2
#define deflateReset mz_deflateReset
@@ -493,11 +493,18 @@ typedef void *const voidpc;
#define compress mz_compress
#define compress2 mz_compress2
#define compressBound mz_compressBound
#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/
#ifndef MINIZ_NO_INFLATE_APIS
#define inflateInit mz_inflateInit
#define inflateInit2 mz_inflateInit2
#define inflateReset mz_inflateReset
#define inflate mz_inflate
#define inflateEnd mz_inflateEnd
#define uncompress mz_uncompress
#define uncompress2 mz_uncompress2
#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/
#define crc32 mz_crc32
#define adler32 mz_adler32
#define MAX_WBITS 15
@@ -518,3 +525,8 @@ typedef void *const voidpc;
#ifdef __cplusplus
}
#endif
#include "miniz_common.h"
#include "miniz_tdef.h"
#include "miniz_tinfl.h"
#include "miniz_zip.h"

13
miniz.pc.in Normal file
View File

@@ -0,0 +1,13 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix}
libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
Name: @PROJECT_NAME@
Description: @PROJECT_DESCRIPTION@
Version: @MINIZ_VERSION@
URL: @PROJECT_HOMEPAGE_URL@
Requires:
Libs: -L${libdir} -lminiz
Cflags: -I${includedir}

View File

@@ -1,8 +1,10 @@
#pragma once
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "miniz_export.h"
/* ------------------- Types and macros */
typedef unsigned char mz_uint8;
@@ -34,7 +36,8 @@ typedef int mz_bool;
#ifdef MINIZ_NO_TIME
typedef struct mz_dummy_time_t_tag
{
int m_dummy;
mz_uint32 m_dummy1;
mz_uint32 m_dummy2;
} mz_dummy_time_t;
#define MZ_TIME_T mz_dummy_time_t
#else
@@ -56,6 +59,8 @@ typedef struct mz_dummy_time_t_tag
#define MZ_MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MZ_MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
#define MZ_CLEAR_ARR(obj) memset((obj), 0, sizeof(obj))
#define MZ_CLEAR_PTR(obj) memset((obj), 0, sizeof(*obj))
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
#define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
@@ -79,9 +84,9 @@ typedef struct mz_dummy_time_t_tag
extern "C" {
#endif
extern void *miniz_def_alloc_func(void *opaque, size_t items, size_t size);
extern void miniz_def_free_func(void *opaque, void *address);
extern void *miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size);
extern MINIZ_EXPORT void *miniz_def_alloc_func(void *opaque, size_t items, size_t size);
extern MINIZ_EXPORT void miniz_def_free_func(void *opaque, void *address);
extern MINIZ_EXPORT void *miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size);
#define MZ_UINT16_MAX (0xFFFFU)
#define MZ_UINT32_MAX (0xFFFFFFFFU)

View File

@@ -24,9 +24,10 @@
*
**************************************************************************/
#include "miniz_tdef.h"
#include "miniz.h"
#ifndef MINIZ_NO_DEFLATE_APIS
#ifdef __cplusplus
extern "C" {
#endif
@@ -105,7 +106,7 @@ static tdefl_sym_freq *tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq *p
{
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);
MZ_CLEAR_ARR(hist);
for (i = 0; i < num_syms; i++)
{
mz_uint freq = pSyms0[i].m_key;
@@ -223,7 +224,7 @@ static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int
{
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);
MZ_CLEAR_ARR(num_codes);
if (static_table)
{
for (i = 0; i < table_len; i++)
@@ -249,8 +250,8 @@ static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int
tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, code_size_limit);
MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]);
MZ_CLEAR_OBJ(d->m_huff_codes[table_num]);
MZ_CLEAR_ARR(d->m_huff_code_sizes[table_num]);
MZ_CLEAR_ARR(d->m_huff_codes[table_num]);
for (i = 1, j = num_used_syms; i <= code_size_limit; i++)
for (l = num_codes[i]; l > 0; l--)
d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i);
@@ -737,13 +738,29 @@ static int tdefl_flush_block(tdefl_compressor *d, int flush)
}
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
#ifdef MINIZ_UNALIGNED_USE_MEMCPY
static mz_uint16 TDEFL_READ_UNALIGNED_WORD(const mz_uint8* p)
{
mz_uint16 ret;
memcpy(&ret, p, sizeof(mz_uint16));
return ret;
}
static mz_uint16 TDEFL_READ_UNALIGNED_WORD2(const mz_uint16* p)
{
mz_uint16 ret;
memcpy(&ret, p, sizeof(mz_uint16));
return ret;
}
#else
#define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16 *)(p)
#define TDEFL_READ_UNALIGNED_WORD2(p) *(const mz_uint16 *)(p)
#endif
static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len)
{
mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len;
mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
const mz_uint16 *s = (const mz_uint16 *)(d->m_dict + pos), *p, *q;
mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]), s01 = TDEFL_READ_UNALIGNED_WORD(s);
mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]), s01 = TDEFL_READ_UNALIGNED_WORD2(s);
MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN);
if (max_match_len <= match_len)
return;
@@ -767,14 +784,14 @@ static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahe
if (!dist)
break;
q = (const mz_uint16 *)(d->m_dict + probe_pos);
if (TDEFL_READ_UNALIGNED_WORD(q) != s01)
if (TDEFL_READ_UNALIGNED_WORD2(q) != s01)
continue;
p = s;
probe_len = 32;
do
{
} while ((TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) &&
(TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0));
} while ((TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) &&
(TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (--probe_len > 0));
if (!probe_len)
{
*pMatch_dist = dist;
@@ -837,6 +854,16 @@ static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahe
#endif /* #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES */
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
#ifdef MINIZ_UNALIGNED_USE_MEMCPY
static mz_uint32 TDEFL_READ_UNALIGNED_WORD32(const mz_uint8* p)
{
mz_uint32 ret;
memcpy(&ret, p, sizeof(mz_uint32));
return ret;
}
#else
#define TDEFL_READ_UNALIGNED_WORD32(p) *(const mz_uint32 *)(p)
#endif
static mz_bool tdefl_compress_fast(tdefl_compressor *d)
{
/* Faster, minimally featured LZRW1-style match+parse loop with better register utilization. Intended for applications where raw throughput is valued more highly than ratio. */
@@ -871,20 +898,20 @@ static mz_bool tdefl_compress_fast(tdefl_compressor *d)
{
mz_uint cur_match_dist, cur_match_len = 1;
mz_uint8 *pCur_dict = d->m_dict + cur_pos;
mz_uint first_trigram = (*(const mz_uint32 *)pCur_dict) & 0xFFFFFF;
mz_uint first_trigram = TDEFL_READ_UNALIGNED_WORD32(pCur_dict) & 0xFFFFFF;
mz_uint hash = (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) & TDEFL_LEVEL1_HASH_SIZE_MASK;
mz_uint probe_pos = d->m_hash[hash];
d->m_hash[hash] = (mz_uint16)lookahead_pos;
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))
if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <= dict_size) && ((TDEFL_READ_UNALIGNED_WORD32(d->m_dict + (probe_pos &= TDEFL_LZ_DICT_SIZE_MASK)) & 0xFFFFFF) == first_trigram))
{
const mz_uint16 *p = (const mz_uint16 *)pCur_dict;
const mz_uint16 *q = (const mz_uint16 *)(d->m_dict + probe_pos);
mz_uint32 probe_len = 32;
do
{
} while ((TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) &&
(TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0));
} while ((TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) &&
(TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) && (--probe_len > 0));
cur_match_len = ((mz_uint)(p - (const mz_uint16 *)pCur_dict) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q);
if (!probe_len)
cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0;
@@ -906,7 +933,11 @@ static mz_bool tdefl_compress_fast(tdefl_compressor *d)
cur_match_dist--;
pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN);
#ifdef MINIZ_UNALIGNED_USE_MEMCPY
memcpy(&pLZ_code_buf[1], &cur_match_dist, sizeof(cur_match_dist));
#else
*(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist;
#endif
pLZ_code_buf += 3;
*pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80);
@@ -1045,8 +1076,6 @@ static MZ_FORCEINLINE void tdefl_record_match(tdefl_compressor *d, mz_uint match
s0 = s_tdefl_small_dist_sym[match_dist & 511];
s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127];
d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++;
if (match_len >= TDEFL_MIN_MATCH_LEN)
d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++;
}
@@ -1065,7 +1094,7 @@ static mz_bool tdefl_compress_normal(tdefl_compressor *d)
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;
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];
mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size);
const mz_uint8 *pSrc_end = pSrc + num_bytes_to_process;
const mz_uint8 *pSrc_end = pSrc ? pSrc + num_bytes_to_process : NULL;
src_buf_left -= num_bytes_to_process;
d->m_lookahead_size += num_bytes_to_process;
while (pSrc != pSrc_end)
@@ -1275,8 +1304,8 @@ tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pI
d->m_finished = (flush == TDEFL_FINISH);
if (flush == TDEFL_FULL_FLUSH)
{
MZ_CLEAR_OBJ(d->m_hash);
MZ_CLEAR_OBJ(d->m_next);
MZ_CLEAR_ARR(d->m_hash);
MZ_CLEAR_ARR(d->m_next);
d->m_dict_size = 0;
}
}
@@ -1299,11 +1328,12 @@ tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_fun
d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0;
d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3;
if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG))
MZ_CLEAR_OBJ(d->m_hash);
MZ_CLEAR_ARR(d->m_hash);
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;
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;
d->m_pLZ_code_buf = d->m_lz_code_buf + 1;
d->m_pLZ_flags = d->m_lz_code_buf;
*d->m_pLZ_flags = 0;
d->m_num_flags_left = 8;
d->m_pOutput_buf = d->m_output_buf;
d->m_pOutput_buf_end = d->m_output_buf;
@@ -1318,6 +1348,8 @@ tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_fun
d->m_pSrc = NULL;
d->m_src_buf_left = 0;
d->m_out_buf_ofs = 0;
if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG))
MZ_CLEAR_ARR(d->m_dict);
memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
return TDEFL_STATUS_OKAY;
@@ -1408,7 +1440,6 @@ size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void
return out_buf.m_size;
}
#ifndef MINIZ_NO_ZLIB_APIS
static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
/* 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). */
@@ -1431,7 +1462,6 @@ mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int
return comp_flags;
}
#endif /*MINIZ_NO_ZLIB_APIS */
#ifdef _MSC_VER
#pragma warning(push)
@@ -1492,7 +1522,7 @@ void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int
pnghdr[18] = (mz_uint8)(w >> 8);
pnghdr[19] = (mz_uint8)w;
pnghdr[22] = (mz_uint8)(h >> 8);
pnghdr[22] = (mz_uint8)h;
pnghdr[23] = (mz_uint8)h;
pnghdr[25] = chans[num_chans];
pnghdr[33] = (mz_uint8)(*pLen_out >> 24);
pnghdr[34] = (mz_uint8)(*pLen_out >> 16);
@@ -1525,10 +1555,11 @@ void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h,
return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans, pLen_out, 6, MZ_FALSE);
}
#ifndef MINIZ_NO_MALLOC
/* Allocate the tdefl_compressor and tinfl_decompressor structures in C so that */
/* non-C language bindings to tdefL_ and tinfl_ API don't need to worry about */
/* structure size and allocation mechanism. */
tdefl_compressor *tdefl_compressor_alloc()
tdefl_compressor *tdefl_compressor_alloc(void)
{
return (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor));
}
@@ -1537,6 +1568,7 @@ void tdefl_compressor_free(tdefl_compressor *pComp)
{
MZ_FREE(pComp);
}
#endif
#ifdef _MSC_VER
#pragma warning(pop)
@@ -1545,3 +1577,5 @@ void tdefl_compressor_free(tdefl_compressor *pComp)
#ifdef __cplusplus
}
#endif
#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/

View File

@@ -1,6 +1,8 @@
#pragma once
#include "miniz_common.h"
#ifndef MINIZ_NO_DEFLATE_APIS
#ifdef __cplusplus
extern "C" {
#endif
@@ -48,11 +50,11 @@ enum
/* Function returns a pointer to the compressed data, or NULL on failure. */
/* *pOut_len will be set to the compressed data's size, which could be larger than src_buf_len on uncompressible data. */
/* The caller must free() the returned block when it's no longer needed. */
void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
MINIZ_EXPORT void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
/* tdefl_compress_mem_to_mem() compresses a block in memory to another block in memory. */
/* Returns 0 on failure. */
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);
MINIZ_EXPORT 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);
/* Compresses an image to a compressed PNG file in memory. */
/* On entry: */
@@ -64,14 +66,14 @@ size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void
/* Function returns a pointer to the compressed data, or NULL on failure. */
/* *pLen_out will be set to the size of the PNG image file. */
/* The caller must mz_free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed. */
void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip);
void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out);
MINIZ_EXPORT void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip);
MINIZ_EXPORT void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out);
/* Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time. */
typedef mz_bool (*tdefl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser);
/* tdefl_compress_mem_to_output() compresses a block to an output stream. The above helpers use this function internally. */
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);
MINIZ_EXPORT 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);
enum
{
@@ -111,8 +113,7 @@ enum
#endif
/* 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. */
typedef enum
{
typedef enum {
TDEFL_STATUS_BAD_PARAM = -2,
TDEFL_STATUS_PUT_BUF_FAILED = -1,
TDEFL_STATUS_OKAY = 0,
@@ -120,8 +121,7 @@ typedef enum
} tdefl_status;
/* Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums */
typedef enum
{
typedef enum {
TDEFL_NO_FLUSH = 0,
TDEFL_SYNC_FLUSH = 2,
TDEFL_FULL_FLUSH = 3,
@@ -161,33 +161,34 @@ typedef struct
/* 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. */
/* If pBut_buf_func is NULL the user should always call the tdefl_compress() API. */
/* flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, etc.) */
tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
MINIZ_EXPORT tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
/* 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. */
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);
MINIZ_EXPORT 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);
/* tdefl_compress_buffer() is only usable when the tdefl_init() is called with a non-NULL tdefl_put_buf_func_ptr. */
/* tdefl_compress_buffer() always consumes the entire input buffer. */
tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush);
MINIZ_EXPORT tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush);
tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d);
mz_uint32 tdefl_get_adler32(tdefl_compressor *d);
MINIZ_EXPORT tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d);
MINIZ_EXPORT mz_uint32 tdefl_get_adler32(tdefl_compressor *d);
/* Can't use tdefl_create_comp_flags_from_zip_params if MINIZ_NO_ZLIB_APIS isn't defined, because it uses some of its macros. */
#ifndef MINIZ_NO_ZLIB_APIS
/* Create tdefl_compress() flags given zlib-style compression parameters. */
/* level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files) */
/* window_bits may be -15 (raw deflate) or 15 (zlib) */
/* strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED */
mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy);
#endif /* #ifndef MINIZ_NO_ZLIB_APIS */
MINIZ_EXPORT mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy);
#ifndef MINIZ_NO_MALLOC
/* Allocate the tdefl_compressor structure in C so that */
/* non-C language bindings to tdefl_ API don't need to worry about */
/* structure size and allocation mechanism. */
tdefl_compressor *tdefl_compressor_alloc();
void tdefl_compressor_free(tdefl_compressor *pComp);
MINIZ_EXPORT tdefl_compressor *tdefl_compressor_alloc(void);
MINIZ_EXPORT void tdefl_compressor_free(tdefl_compressor *pComp);
#endif
#ifdef __cplusplus
}
#endif
#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/

View File

@@ -24,7 +24,9 @@
*
**************************************************************************/
#include "miniz_tinfl.h"
#include "miniz.h"
#ifndef MINIZ_NO_INFLATE_APIS
#ifdef __cplusplus
extern "C" {
@@ -45,8 +47,7 @@ extern "C" {
status = result; \
r->m_state = state_index; \
goto common_exit; \
case state_index: \
; \
case state_index:; \
} \
MZ_MACRO_END
#define TINFL_CR_RETURN_FOREVER(state_index, result) \
@@ -107,10 +108,10 @@ extern "C" {
/* 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 */
/* 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 */
/* bit buffer contains >=15 bits (deflate's max. Huffman code size). */
#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \
#define TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree) \
do \
{ \
temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
temp = pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
if (temp >= 0) \
{ \
code_len = temp >> 9; \
@@ -122,7 +123,7 @@ extern "C" {
code_len = TINFL_FAST_LOOKUP_BITS; \
do \
{ \
temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \
} while ((temp < 0) && (num_bits >= (code_len + 1))); \
if (temp >= 0) \
break; \
@@ -138,7 +139,7 @@ extern "C" {
/* The slow path is only executed at the very end of the input buffer. */
/* 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 */
/* following the deflate data and our non-conservative read-ahead path won't kick in here on this code. This is much trickier. */
#define TINFL_HUFF_DECODE(state_index, sym, pHuff) \
#define TINFL_HUFF_DECODE(state_index, sym, pLookUp, pTree) \
do \
{ \
int temp; \
@@ -147,7 +148,7 @@ extern "C" {
{ \
if ((pIn_buf_end - pIn_buf_cur) < 2) \
{ \
TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree); \
} \
else \
{ \
@@ -156,14 +157,14 @@ extern "C" {
num_bits += 16; \
} \
} \
if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
if ((temp = pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
code_len = temp >> 9, temp &= 511; \
else \
{ \
code_len = TINFL_FAST_LOOKUP_BITS; \
do \
{ \
temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \
} while (temp < 0); \
} \
sym = temp; \
@@ -172,20 +173,33 @@ extern "C" {
} \
MZ_MACRO_END
static void tinfl_clear_tree(tinfl_decompressor *r)
{
if (r->m_type == 0)
MZ_CLEAR_ARR(r->m_tree_0);
else if (r->m_type == 1)
MZ_CLEAR_ARR(r->m_tree_1);
else
MZ_CLEAR_ARR(r->m_tree_2);
}
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)
{
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 };
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 };
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 };
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 };
static const mz_uint16 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 };
static const mz_uint8 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 };
static const mz_uint16 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 };
static const mz_uint8 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 };
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 };
static const int s_min_table_sizes[3] = { 257, 1, 4 };
static const mz_uint16 s_min_table_sizes[3] = { 257, 1, 4 };
mz_int16 *pTrees[3];
mz_uint8 *pCode_sizes[3];
tinfl_status status = TINFL_STATUS_FAILED;
mz_uint32 num_bits, dist, counter, num_extra;
tinfl_bit_buf_t bit_buf;
const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size;
mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size;
mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next ? pOut_buf_next + *pOut_buf_size : NULL;
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;
/* 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). */
@@ -195,6 +209,13 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
return TINFL_STATUS_BAD_PARAM;
}
pTrees[0] = r->m_tree_0;
pTrees[1] = r->m_tree_1;
pTrees[2] = r->m_tree_2;
pCode_sizes[0] = r->m_code_size_0;
pCode_sizes[1] = r->m_code_size_1;
pCode_sizes[2] = r->m_code_size_2;
num_bits = r->m_num_bits;
bit_buf = r->m_bit_buf;
dist = r->m_dist;
@@ -272,11 +293,11 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
{
if (r->m_type == 1)
{
mz_uint8 *p = r->m_tables[0].m_code_size;
mz_uint8 *p = r->m_code_size_0;
mz_uint i;
r->m_table_sizes[0] = 288;
r->m_table_sizes[1] = 32;
TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32);
TINFL_MEMSET(r->m_code_size_1, 5, 32);
for (i = 0; i <= 143; ++i)
*p++ = 8;
for (; i <= 255; ++i)
@@ -293,26 +314,30 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]);
r->m_table_sizes[counter] += s_min_table_sizes[counter];
}
MZ_CLEAR_OBJ(r->m_tables[2].m_code_size);
MZ_CLEAR_ARR(r->m_code_size_2);
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;
r->m_code_size_2[s_length_dezigzag[counter]] = (mz_uint8)s;
}
r->m_table_sizes[2] = 19;
}
for (; (int)r->m_type >= 0; r->m_type--)
{
int tree_next, tree_cur;
tinfl_huff_table *pTable;
mz_int16 *pLookUp;
mz_int16 *pTree;
mz_uint8 *pCode_size;
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);
pLookUp = r->m_look_up[r->m_type];
pTree = pTrees[r->m_type];
pCode_size = pCode_sizes[r->m_type];
MZ_CLEAR_ARR(total_syms);
TINFL_MEMSET(pLookUp, 0, sizeof(r->m_look_up[0]));
tinfl_clear_tree(r);
for (i = 0; i < r->m_table_sizes[r->m_type]; ++i)
total_syms[pTable->m_code_size[i]]++;
total_syms[pCode_size[i]]++;
used_syms = 0, total = 0;
next_code[0] = next_code[1] = 0;
for (i = 1; i <= 15; ++i)
@@ -326,7 +351,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
}
for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index)
{
mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index];
mz_uint rev_code = 0, l, cur_code, code_size = pCode_size[sym_index];
if (!code_size)
continue;
cur_code = next_code[code_size]++;
@@ -337,14 +362,14 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
mz_int16 k = (mz_int16)((code_size << 9) | sym_index);
while (rev_code < TINFL_FAST_LOOKUP_SIZE)
{
pTable->m_look_up[rev_code] = k;
pLookUp[rev_code] = k;
rev_code += (1 << code_size);
}
continue;
}
if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)]))
if (0 == (tree_cur = pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)]))
{
pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next;
pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next;
tree_cur = tree_next;
tree_next -= 2;
}
@@ -352,24 +377,24 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--)
{
tree_cur -= ((rev_code >>= 1) & 1);
if (!pTable->m_tree[-tree_cur - 1])
if (!pTree[-tree_cur - 1])
{
pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next;
pTree[-tree_cur - 1] = (mz_int16)tree_next;
tree_cur = tree_next;
tree_next -= 2;
}
else
tree_cur = pTable->m_tree[-tree_cur - 1];
tree_cur = pTree[-tree_cur - 1];
}
tree_cur -= ((rev_code >>= 1) & 1);
pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
pTree[-tree_cur - 1] = (mz_int16)sym_index;
}
if (r->m_type == 2)
{
for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]);)
{
mz_uint s;
TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]);
TINFL_HUFF_DECODE(16, dist, r->m_look_up[2], r->m_tree_2);
if (dist < 16)
{
r->m_len_codes[counter++] = (mz_uint8)dist;
@@ -389,8 +414,8 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
{
TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED);
}
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]);
TINFL_MEMCPY(r->m_code_size_0, r->m_len_codes, r->m_table_sizes[0]);
TINFL_MEMCPY(r->m_code_size_1, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]);
}
}
for (;;)
@@ -400,7 +425,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
{
if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2))
{
TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]);
TINFL_HUFF_DECODE(23, counter, r->m_look_up[0], r->m_tree_0);
if (counter >= 256)
break;
while (pOut_buf_cur >= pOut_buf_end)
@@ -428,14 +453,14 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
num_bits += 16;
}
#endif
if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
if ((sym2 = r->m_look_up[0][bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
code_len = sym2 >> 9;
else
{
code_len = TINFL_FAST_LOOKUP_BITS;
do
{
sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)];
sym2 = r->m_tree_0[~sym2 + ((bit_buf >> code_len++) & 1)];
} while (sym2 < 0);
}
counter = sym2;
@@ -452,14 +477,14 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
num_bits += 16;
}
#endif
if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
if ((sym2 = r->m_look_up[0][bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
code_len = sym2 >> 9;
else
{
code_len = TINFL_FAST_LOOKUP_BITS;
do
{
sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)];
sym2 = r->m_tree_0[~sym2 + ((bit_buf >> code_len++) & 1)];
} while (sym2 < 0);
}
bit_buf >>= code_len;
@@ -488,7 +513,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
counter += extra_bits;
}
TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]);
TINFL_HUFF_DECODE(26, dist, r->m_look_up[1], r->m_tree_1);
num_extra = s_dist_extra[dist];
dist = s_dist_base[dist];
if (num_extra)
@@ -499,7 +524,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
}
dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
if ((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
if ((dist == 0 || dist > dist_from_out_buf_start || dist_from_out_buf_start == 0) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
{
TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED);
}
@@ -524,8 +549,12 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
do
{
#ifdef MINIZ_UNALIGNED_USE_MEMCPY
memcpy(pOut_buf_cur, pSrc, sizeof(mz_uint32)*2);
#else
((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0];
((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1];
#endif
pOut_buf_cur += 8;
} while ((pSrc += 8) < pSrc_end);
if ((counter &= 7) < 3)
@@ -541,18 +570,19 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
}
}
#endif
do
while(counter>2)
{
pOut_buf_cur[0] = pSrc[0];
pOut_buf_cur[1] = pSrc[1];
pOut_buf_cur[2] = pSrc[2];
pOut_buf_cur += 3;
pSrc += 3;
} while ((int)(counter -= 3) > 2);
if ((int)counter > 0)
counter -= 3;
}
if (counter > 0)
{
pOut_buf_cur[0] = pSrc[0];
if ((int)counter > 1)
if (counter > 1)
pOut_buf_cur[1] = pSrc[1];
pOut_buf_cur += counter;
}
@@ -568,7 +598,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
--pIn_buf_cur;
num_bits -= 8;
}
bit_buf &= (tinfl_bit_buf_t)(( ((mz_uint64)1) << num_bits) - (mz_uint64)1);
bit_buf &= ~(~(tinfl_bit_buf_t)0 << num_bits);
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). */
if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
@@ -600,7 +630,7 @@ common_exit:
}
}
r->m_num_bits = num_bits;
r->m_bit_buf = bit_buf & (tinfl_bit_buf_t)(( ((mz_uint64)1) << num_bits) - (mz_uint64)1);
r->m_bit_buf = bit_buf & ~(~(tinfl_bit_buf_t)0 << num_bits);
r->m_dist = dist;
r->m_counter = counter;
r->m_num_extra = num_extra;
@@ -695,6 +725,7 @@ int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size,
size_t in_buf_ofs = 0, dict_ofs = 0;
if (!pDict)
return TINFL_STATUS_FAILED;
memset(pDict,0,TINFL_LZ_DICT_SIZE);
tinfl_init(&decomp);
for (;;)
{
@@ -716,7 +747,8 @@ int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size,
return result;
}
tinfl_decompressor *tinfl_decompressor_alloc()
#ifndef MINIZ_NO_MALLOC
tinfl_decompressor *tinfl_decompressor_alloc(void)
{
tinfl_decompressor *pDecomp = (tinfl_decompressor *)MZ_MALLOC(sizeof(tinfl_decompressor));
if (pDecomp)
@@ -728,7 +760,10 @@ void tinfl_decompressor_free(tinfl_decompressor *pDecomp)
{
MZ_FREE(pDecomp);
}
#endif
#ifdef __cplusplus
}
#endif
#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/

View File

@@ -2,6 +2,8 @@
#include "miniz_common.h"
/* ------------------- Low-level Decompression API Definitions */
#ifndef MINIZ_NO_INFLATE_APIS
#ifdef __cplusplus
extern "C" {
#endif
@@ -26,34 +28,34 @@ enum
/* Function returns a pointer to the decompressed data, or NULL on failure. */
/* *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data. */
/* The caller must call mz_free() on the returned block when it's no longer needed. */
void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
MINIZ_EXPORT void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
/* tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory. */
/* Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success. */
#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1))
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);
MINIZ_EXPORT 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);
/* 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. */
/* Returns 1 on success or 0 on failure. */
typedef int (*tinfl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser);
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);
MINIZ_EXPORT 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);
struct tinfl_decompressor_tag;
typedef struct tinfl_decompressor_tag tinfl_decompressor;
#ifndef MINIZ_NO_MALLOC
/* Allocate the tinfl_decompressor structure in C so that */
/* non-C language bindings to tinfl_ API don't need to worry about */
/* structure size and allocation mechanism. */
tinfl_decompressor *tinfl_decompressor_alloc();
void tinfl_decompressor_free(tinfl_decompressor *pDecomp);
MINIZ_EXPORT tinfl_decompressor *tinfl_decompressor_alloc(void);
MINIZ_EXPORT void tinfl_decompressor_free(tinfl_decompressor *pDecomp);
#endif
/* Max size of LZ dictionary. */
#define TINFL_LZ_DICT_SIZE 32768
/* Return status. */
typedef enum
{
typedef enum {
/* 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 */
/* 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). */
/* If you call it again with no input you'll just get TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS again. */
@@ -97,7 +99,7 @@ typedef enum
/* 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. */
/* 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. */
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);
MINIZ_EXPORT 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);
/* Internal/private bits follow. */
enum
@@ -110,14 +112,10 @@ enum
TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS
};
typedef struct
{
mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0];
mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
} tinfl_huff_table;
#if MINIZ_HAS_64BIT_REGISTERS
#define TINFL_USE_64BIT_BITBUF 1
#else
#define TINFL_USE_64BIT_BITBUF 0
#endif
#if TINFL_USE_64BIT_BITBUF
@@ -133,10 +131,18 @@ struct tinfl_decompressor_tag
mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES];
tinfl_bit_buf_t m_bit_buf;
size_t m_dist_from_out_buf_start;
tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES];
mz_int16 m_look_up[TINFL_MAX_HUFF_TABLES][TINFL_FAST_LOOKUP_SIZE];
mz_int16 m_tree_0[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
mz_int16 m_tree_1[TINFL_MAX_HUFF_SYMBOLS_1 * 2];
mz_int16 m_tree_2[TINFL_MAX_HUFF_SYMBOLS_2 * 2];
mz_uint8 m_code_size_0[TINFL_MAX_HUFF_SYMBOLS_0];
mz_uint8 m_code_size_1[TINFL_MAX_HUFF_SYMBOLS_1];
mz_uint8 m_code_size_2[TINFL_MAX_HUFF_SYMBOLS_2];
mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137];
};
#ifdef __cplusplus
}
#endif
#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,11 @@
#pragma once
#include "miniz.h"
#include "miniz_common.h"
/* ------------------- ZIP archive reading/writing */
#ifndef MINIZ_NO_ARCHIVE_APIS
#ifdef __cplusplus
extern "C" {
#endif
@@ -30,10 +32,6 @@ typedef struct
mz_uint16 m_bit_flag;
mz_uint16 m_method;
#ifndef MINIZ_NO_TIME
MZ_TIME_T m_time;
#endif
/* CRC-32 of uncompressed data. */
mz_uint32 m_crc32;
@@ -70,6 +68,11 @@ typedef struct
/* Guaranteed to be zero terminated, may be truncated to fit. */
char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE];
#ifdef MINIZ_NO_TIME
MZ_TIME_T m_padding;
#else
MZ_TIME_T m_time;
#endif
} mz_zip_archive_file_stat;
typedef size_t (*mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n);
@@ -79,29 +82,29 @@ typedef mz_bool (*mz_file_needs_keepalive)(void *pOpaque);
struct mz_zip_internal_state_tag;
typedef struct mz_zip_internal_state_tag mz_zip_internal_state;
typedef enum
{
typedef enum {
MZ_ZIP_MODE_INVALID = 0,
MZ_ZIP_MODE_READING = 1,
MZ_ZIP_MODE_WRITING = 2,
MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3
} mz_zip_mode;
typedef enum
{
typedef enum {
MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100,
MZ_ZIP_FLAG_IGNORE_PATH = 0x0200,
MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400,
MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY = 0x0800,
MZ_ZIP_FLAG_VALIDATE_LOCATE_FILE_FLAG = 0x1000, /* if enabled, mz_zip_reader_locate_file() will be called on each file as its validated to ensure the func finds the file in the central dir (intended for testing) */
MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY = 0x2000, /* validate the local headers, but don't decompress the entire file and check the crc32 */
MZ_ZIP_FLAG_WRITE_ZIP64 = 0x4000, /* use the zip64 file format, instead of the original zip file format */
MZ_ZIP_FLAG_WRITE_ZIP64 = 0x4000, /* always use the zip64 file format, instead of the original zip file format with automatic switch to zip64. Use as flags parameter with mz_zip_writer_init*_v2 */
MZ_ZIP_FLAG_WRITE_ALLOW_READING = 0x8000,
MZ_ZIP_FLAG_ASCII_FILENAME = 0x10000
MZ_ZIP_FLAG_ASCII_FILENAME = 0x10000,
/*After adding a compressed file, seek back
to local file header and set the correct sizes*/
MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE = 0x20000
} mz_zip_flags;
typedef enum
{
typedef enum {
MZ_ZIP_TYPE_INVALID = 0,
MZ_ZIP_TYPE_USER,
MZ_ZIP_TYPE_MEMORY,
@@ -112,8 +115,7 @@ typedef enum
} mz_zip_type;
/* miniz error codes. Be sure to update mz_zip_get_error_string() if you add or modify this enum. */
typedef enum
{
typedef enum {
MZ_ZIP_NO_ERROR = 0,
MZ_ZIP_UNDEFINED_ERROR,
MZ_ZIP_TOO_MANY_FILES,
@@ -176,163 +178,191 @@ typedef struct
} mz_zip_archive;
typedef struct
{
mz_zip_archive *pZip;
mz_uint flags;
int status;
mz_uint64 read_buf_size, read_buf_ofs, read_buf_avail, comp_remaining, out_buf_ofs, cur_file_ofs;
mz_zip_archive_file_stat file_stat;
void *pRead_buf;
void *pWrite_buf;
size_t out_blk_remain;
tinfl_decompressor inflator;
#ifdef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
mz_uint padding;
#else
mz_uint file_crc32;
#endif
} mz_zip_reader_extract_iter_state;
/* -------- ZIP reading */
/* Inits a ZIP archive reader. */
/* These functions read and validate the archive's central directory. */
mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint flags);
MINIZ_EXPORT mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint flags);
mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint flags);
MINIZ_EXPORT mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint flags);
#ifndef MINIZ_NO_STDIO
/* Read a archive from a disk file. */
/* file_start_ofs is the file offset where the archive actually begins, or 0. */
/* actual_archive_size is the true total size of the archive, which may be smaller than the file's actual size on disk. If zero the entire file is treated as the archive. */
mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags);
mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags, mz_uint64 file_start_ofs, mz_uint64 archive_size);
MINIZ_EXPORT mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags);
MINIZ_EXPORT mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags, mz_uint64 file_start_ofs, mz_uint64 archive_size);
/* Read an archive from an already opened FILE, beginning at the current file position. */
/* The archive is assumed to be archive_size bytes long. If archive_size is < 0, then the entire rest of the file is assumed to contain the archive. */
/* The archive is assumed to be archive_size bytes long. If archive_size is 0, then the entire rest of the file is assumed to contain the archive. */
/* The FILE will NOT be closed when mz_zip_reader_end() is called. */
mz_bool mz_zip_reader_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint64 archive_size, mz_uint flags);
MINIZ_EXPORT mz_bool mz_zip_reader_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint64 archive_size, mz_uint flags);
#endif
/* Ends archive reading, freeing all allocations, and closing the input archive file if mz_zip_reader_init_file() was used. */
mz_bool mz_zip_reader_end(mz_zip_archive *pZip);
MINIZ_EXPORT mz_bool mz_zip_reader_end(mz_zip_archive *pZip);
/* -------- ZIP reading or writing */
/* Clears a mz_zip_archive struct to all zeros. */
/* Important: This must be done before passing the struct to any mz_zip functions. */
void mz_zip_zero_struct(mz_zip_archive *pZip);
MINIZ_EXPORT void mz_zip_zero_struct(mz_zip_archive *pZip);
mz_zip_mode mz_zip_get_mode(mz_zip_archive *pZip);
mz_zip_type mz_zip_get_type(mz_zip_archive *pZip);
MINIZ_EXPORT mz_zip_mode mz_zip_get_mode(mz_zip_archive *pZip);
MINIZ_EXPORT mz_zip_type mz_zip_get_type(mz_zip_archive *pZip);
/* Returns the total number of files in the archive. */
mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip);
MINIZ_EXPORT mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip);
mz_uint64 mz_zip_get_archive_size(mz_zip_archive *pZip);
mz_uint64 mz_zip_get_archive_file_start_offset(mz_zip_archive *pZip);
MZ_FILE *mz_zip_get_cfile(mz_zip_archive *pZip);
MINIZ_EXPORT mz_uint64 mz_zip_get_archive_size(mz_zip_archive *pZip);
MINIZ_EXPORT mz_uint64 mz_zip_get_archive_file_start_offset(mz_zip_archive *pZip);
MINIZ_EXPORT MZ_FILE *mz_zip_get_cfile(mz_zip_archive *pZip);
/* Reads n bytes of raw archive data, starting at file offset file_ofs, to pBuf. */
size_t mz_zip_read_archive_data(mz_zip_archive *pZip, mz_uint64 file_ofs, void *pBuf, size_t n);
/* Attempts to locates a file in the archive's central directory. */
/* Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH */
/* Returns -1 if the file cannot be found. */
int mz_zip_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);
/* Returns MZ_FALSE if the file cannot be found. */
mz_bool mz_zip_locate_file_v2(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags, mz_uint32 *pIndex);
MINIZ_EXPORT size_t mz_zip_read_archive_data(mz_zip_archive *pZip, mz_uint64 file_ofs, void *pBuf, size_t n);
/* All mz_zip funcs set the m_last_error field in the mz_zip_archive struct. These functions retrieve/manipulate this field. */
/* Note that the m_last_error functionality is not thread safe. */
mz_zip_error mz_zip_set_last_error(mz_zip_archive *pZip, mz_zip_error err_num);
mz_zip_error mz_zip_peek_last_error(mz_zip_archive *pZip);
mz_zip_error mz_zip_clear_last_error(mz_zip_archive *pZip);
mz_zip_error mz_zip_get_last_error(mz_zip_archive *pZip);
const char *mz_zip_get_error_string(mz_zip_error mz_err);
MINIZ_EXPORT mz_zip_error mz_zip_set_last_error(mz_zip_archive *pZip, mz_zip_error err_num);
MINIZ_EXPORT mz_zip_error mz_zip_peek_last_error(mz_zip_archive *pZip);
MINIZ_EXPORT mz_zip_error mz_zip_clear_last_error(mz_zip_archive *pZip);
MINIZ_EXPORT mz_zip_error mz_zip_get_last_error(mz_zip_archive *pZip);
MINIZ_EXPORT const char *mz_zip_get_error_string(mz_zip_error mz_err);
/* MZ_TRUE if the archive file entry is a directory entry. */
mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index);
MINIZ_EXPORT mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index);
/* MZ_TRUE if the file is encrypted/strong encrypted. */
mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index);
MINIZ_EXPORT mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index);
/* MZ_TRUE if the compression method is supported, and the file is not encrypted, and the file is not a compressed patch file. */
mz_bool mz_zip_reader_is_file_supported(mz_zip_archive *pZip, mz_uint file_index);
MINIZ_EXPORT mz_bool mz_zip_reader_is_file_supported(mz_zip_archive *pZip, mz_uint file_index);
/* Retrieves the filename of an archive file entry. */
/* Returns the number of bytes written to pFilename, or if filename_buf_size is 0 this function returns the number of bytes needed to fully store the filename. */
mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size);
MINIZ_EXPORT mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size);
/* Attempts to locates a file in the archive's central directory. */
/* Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH */
/* Returns -1 if the file cannot be found. */
int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);
int mz_zip_reader_locate_file_v2(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags, mz_uint32 *file_index);
MINIZ_EXPORT int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);
MINIZ_EXPORT mz_bool mz_zip_reader_locate_file_v2(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags, mz_uint32 *file_index);
/* Returns detailed information about an archive file entry. */
mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat);
MINIZ_EXPORT mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat);
/* MZ_TRUE if the file is in zip64 format. */
/* A file is considered zip64 if it contained a zip64 end of central directory marker, or if it contained any zip64 extended file information fields in the central directory. */
mz_bool mz_zip_is_zip64(mz_zip_archive *pZip);
MINIZ_EXPORT mz_bool mz_zip_is_zip64(mz_zip_archive *pZip);
/* Returns the total central directory size in bytes. */
/* The current max supported size is <= MZ_UINT32_MAX. */
size_t mz_zip_get_central_dir_size(mz_zip_archive *pZip);
MINIZ_EXPORT size_t mz_zip_get_central_dir_size(mz_zip_archive *pZip);
/* Extracts a archive file to a memory buffer using no memory allocation. */
/* There must be at least enough room on the stack to store the inflator's state (~34KB or so). */
mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
/* Extracts a archive file to a memory buffer. */
mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags);
mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags);
MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags);
MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags);
/* Extracts a archive file to a dynamically allocated heap buffer. */
/* The memory will be allocated via the mz_zip_archive's alloc/realloc functions. */
/* Returns NULL and sets the last error on failure. */
void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags);
void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags);
MINIZ_EXPORT void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags);
MINIZ_EXPORT void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags);
/* Extracts a archive file using a callback function to output the file's data. */
mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);
mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);
MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);
MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);
/* Extract a file iteratively */
MINIZ_EXPORT mz_zip_reader_extract_iter_state* mz_zip_reader_extract_iter_new(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags);
MINIZ_EXPORT mz_zip_reader_extract_iter_state* mz_zip_reader_extract_file_iter_new(mz_zip_archive *pZip, const char *pFilename, mz_uint flags);
MINIZ_EXPORT size_t mz_zip_reader_extract_iter_read(mz_zip_reader_extract_iter_state* pState, void* pvBuf, size_t buf_size);
MINIZ_EXPORT mz_bool mz_zip_reader_extract_iter_free(mz_zip_reader_extract_iter_state* pState);
#ifndef MINIZ_NO_STDIO
/* Extracts a archive file to a disk file and sets its last accessed and modified times. */
/* This function only extracts files, not archive directory records. */
mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags);
mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags);
MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags);
MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags);
/* Extracts a archive file starting at the current position in the destination FILE stream. */
mz_bool mz_zip_reader_extract_to_cfile(mz_zip_archive *pZip, mz_uint file_index, MZ_FILE *File, mz_uint flags);
mz_bool mz_zip_reader_extract_file_to_cfile(mz_zip_archive *pZip, const char *pArchive_filename, MZ_FILE *pFile, mz_uint flags);
MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_cfile(mz_zip_archive *pZip, mz_uint file_index, MZ_FILE *File, mz_uint flags);
MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_cfile(mz_zip_archive *pZip, const char *pArchive_filename, MZ_FILE *pFile, mz_uint flags);
#endif
#if 0
/* TODO */
typedef void *mz_zip_streaming_extract_state_ptr;
mz_zip_streaming_extract_state_ptr mz_zip_streaming_extract_begin(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags);
uint64_t mz_zip_streaming_extract_get_size(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
uint64_t mz_zip_streaming_extract_get_cur_ofs(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
mz_bool mz_zip_streaming_extract_seek(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, uint64_t new_ofs);
mz_uint64 mz_zip_streaming_extract_get_size(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
mz_uint64 mz_zip_streaming_extract_get_cur_ofs(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
mz_bool mz_zip_streaming_extract_seek(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, mz_uint64 new_ofs);
size_t mz_zip_streaming_extract_read(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, void *pBuf, size_t buf_size);
mz_bool mz_zip_streaming_extract_end(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
#endif
/* This function compares the archive's local headers, the optional local zip64 extended information block, and the optional descriptor following the compressed data vs. the data in the central directory. */
/* It also validates that each file can be successfully uncompressed unless the MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY is specified. */
mz_bool mz_zip_validate_file(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags);
MINIZ_EXPORT mz_bool mz_zip_validate_file(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags);
/* Validates an entire archive by calling mz_zip_validate_file() on each file. */
mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags);
MINIZ_EXPORT mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags);
/* Misc utils/helpers, valid for ZIP reading or writing */
mz_bool mz_zip_validate_mem_archive(const void *pMem, size_t size, mz_uint flags, mz_zip_error *pErr);
mz_bool mz_zip_validate_file_archive(const char *pFilename, mz_uint flags, mz_zip_error *pErr);
MINIZ_EXPORT mz_bool mz_zip_validate_mem_archive(const void *pMem, size_t size, mz_uint flags, mz_zip_error *pErr);
#ifndef MINIZ_NO_STDIO
MINIZ_EXPORT mz_bool mz_zip_validate_file_archive(const char *pFilename, mz_uint flags, mz_zip_error *pErr);
#endif
/* Universal end function - calls either mz_zip_reader_end() or mz_zip_writer_end(). */
mz_bool mz_zip_end(mz_zip_archive *pZip);
MINIZ_EXPORT mz_bool mz_zip_end(mz_zip_archive *pZip);
/* -------- ZIP writing */
#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
/* Inits a ZIP archive writer. */
mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size);
mz_bool mz_zip_writer_init_v2(mz_zip_archive *pZip, mz_uint64 existing_size, mz_uint flags);
mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size);
mz_bool mz_zip_writer_init_heap_v2(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size, mz_uint flags);
/*Set pZip->m_pWrite (and pZip->m_pIO_opaque) before calling mz_zip_writer_init or mz_zip_writer_init_v2*/
/*The output is streamable, i.e. file_ofs in mz_file_write_func always increases only by n*/
MINIZ_EXPORT mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size);
MINIZ_EXPORT mz_bool mz_zip_writer_init_v2(mz_zip_archive *pZip, mz_uint64 existing_size, mz_uint flags);
MINIZ_EXPORT mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size);
MINIZ_EXPORT mz_bool mz_zip_writer_init_heap_v2(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size, mz_uint flags);
#ifndef MINIZ_NO_STDIO
mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning);
mz_bool mz_zip_writer_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning, mz_uint flags);
mz_bool mz_zip_writer_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint flags);
MINIZ_EXPORT mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning);
MINIZ_EXPORT mz_bool mz_zip_writer_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning, mz_uint flags);
MINIZ_EXPORT mz_bool mz_zip_writer_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint flags);
#endif
/* Converts a ZIP archive reader object into a writer object, to allow efficient in-place file appends to occur on an existing archive. */
@@ -341,50 +371,57 @@ mz_bool mz_zip_writer_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint f
/* Finally, for archives opened using mz_zip_reader_init, the mz_zip_archive's user provided m_pWrite function cannot be NULL. */
/* Note: In-place archive modification is not recommended unless you know what you're doing, because if execution stops or something goes wrong before */
/* the archive is finalized the file's central directory will be hosed. */
mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename);
mz_bool mz_zip_writer_init_from_reader_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags);
MINIZ_EXPORT mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename);
MINIZ_EXPORT mz_bool mz_zip_writer_init_from_reader_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags);
/* Adds the contents of a memory buffer to an archive. These functions record the current local time into the archive. */
/* To add a directory entry, call this method with an archive name ending in a forwardslash with an empty buffer. */
/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */
mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags);
MINIZ_EXPORT mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags);
/* Like mz_zip_writer_add_mem(), except you can specify a file comment field, and optionally supply the function with already compressed data. */
/* uncomp_size/uncomp_crc32 are only used if the MZ_ZIP_FLAG_COMPRESSED_DATA flag is specified. */
mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
MINIZ_EXPORT mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
mz_uint64 uncomp_size, mz_uint32 uncomp_crc32);
mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
MINIZ_EXPORT mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
mz_uint64 uncomp_size, mz_uint32 uncomp_crc32, MZ_TIME_T *last_modified, const char *user_extra_data_local, mz_uint user_extra_data_local_len,
const char *user_extra_data_central, mz_uint user_extra_data_central_len);
/* Adds the contents of a file to an archive. This function also records the disk file's modified time into the archive. */
/* File data is supplied via a read callback function. User mz_zip_writer_add_(c)file to add a file directly.*/
MINIZ_EXPORT mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pArchive_name, mz_file_read_func read_callback, void* callback_opaque, mz_uint64 max_size,
const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data_local, mz_uint user_extra_data_local_len,
const char *user_extra_data_central, mz_uint user_extra_data_central_len);
#ifndef MINIZ_NO_STDIO
/* Adds the contents of a disk file to an archive. This function also records the disk file's modified time into the archive. */
/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */
mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
MINIZ_EXPORT mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
/* Like mz_zip_writer_add_file(), except the file data is read from the specified FILE stream. */
mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 size_to_add,
MINIZ_EXPORT mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 max_size,
const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data_local, mz_uint user_extra_data_local_len,
const char *user_extra_data_central, mz_uint user_extra_data_central_len);
#endif
/* Adds a file to an archive by fully cloning the data from another archive. */
/* This function fully clones the source file's compressed data (no recompression), along with its full filename, extra data (it may add or modify the zip64 local header extra data field), and the optional descriptor following the compressed data. */
mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint src_file_index);
MINIZ_EXPORT mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint src_file_index);
/* Finalizes the archive by writing the central directory records followed by the end of central directory record. */
/* After an archive is finalized, the only valid call on the mz_zip_archive struct is mz_zip_writer_end(). */
/* An archive must be manually finalized by calling this function for it to be valid. */
mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip);
MINIZ_EXPORT mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip);
/* Finalizes a heap archive, returning a poiner to the heap block and its size. */
/* Finalizes a heap archive, returning a pointer to the heap block and its size. */
/* The heap block will be allocated using the mz_zip_archive's alloc/realloc callbacks. */
mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **ppBuf, size_t *pSize);
MINIZ_EXPORT mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **ppBuf, size_t *pSize);
/* Ends archive writing, freeing all allocations, and closing the output file if mz_zip_writer_init_file() was used. */
/* Note for the archive to be valid, it *must* have been finalized before ending (this function will not do it for you). */
mz_bool mz_zip_writer_end(mz_zip_archive *pZip);
MINIZ_EXPORT mz_bool mz_zip_writer_end(mz_zip_archive *pZip);
/* -------- Misc. high-level helper functions: */
@@ -392,17 +429,21 @@ mz_bool mz_zip_writer_end(mz_zip_archive *pZip);
/* Note this is NOT a fully safe operation. If it crashes or dies in some way your archive can be left in a screwed up state (without a central directory). */
/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */
/* TODO: Perhaps add an option to leave the existing central dir in place in case the add dies? We could then truncate the file (so the old central dir would be at the end) if something goes wrong. */
mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
mz_bool mz_zip_add_mem_to_archive_file_in_place_v2(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_zip_error *pErr);
MINIZ_EXPORT mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
MINIZ_EXPORT mz_bool mz_zip_add_mem_to_archive_file_in_place_v2(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_zip_error *pErr);
#ifndef MINIZ_NO_STDIO
/* Reads a single file from an archive into a heap block. */
/* If pComment is not NULL, only the file with the specified comment will be extracted. */
/* Returns NULL on failure. */
void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags);
void *mz_zip_extract_archive_file_to_heap_v2(const char *pZip_filename, const char *pArchive_name, const char *pComment, size_t *pSize, mz_uint flags, mz_zip_error *pErr);
MINIZ_EXPORT void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags);
MINIZ_EXPORT void *mz_zip_extract_archive_file_to_heap_v2(const char *pZip_filename, const char *pArchive_name, const char *pComment, size_t *pSize, mz_uint flags, mz_zip_error *pErr);
#endif
#endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS */
#ifdef __cplusplus
}
#endif
#endif /* MINIZ_NO_ARCHIVE_APIS */

View File

@@ -1,14 +1,34 @@
## miniz
## Miniz
This is a reorganized version of miniz
https://github.com/richgel999/miniz
Miniz is a lossless, high performance data compression library in a single source file that implements the zlib (RFC 1950) and Deflate (RFC 1951) compressed data format specification standards. It supports the most commonly used functions exported by the zlib library, but is a completely independent implementation so zlib's licensing requirements do not apply. Miniz also contains simple to use functions for writing .PNG format image files and reading/writing/appending .ZIP format archives. Miniz's compression speed has been tuned to be comparable to zlib's, and it also has a specialized real-time compressor function designed to compare well against fastlz/minilzo.
Basically file since source file has been separated into a more traditional
header/source library. This is mainly based off of the organization done for the
version in the valve vogl tool. That way the changes could be merged more easily.
https://github.com/ValveSoftware/vogl/blob/master/src/voglcore/vogl_miniz.h
## Usage
I've also integrated the changes from here:
http://www.tenacioussoftware.com/miniz_v116_beta_r1.7z
Releases are available at the [releases page](https://github.com/richgel999/miniz/releases) as a pair of `miniz.c`/`miniz.h` files which can be simply added to a project. To create this file pair the different source and header files are [amalgamated](https://www.sqlite.org/amalgamation.html) during build. Alternatively use as cmake or meson module (or build system of your choice).
[![Build Status](https://travis-ci.org/uroni/miniz.svg?branch=master)](https://travis-ci.org/uroni/miniz)
## Features
* MIT licensed
* A portable, single source and header file library written in plain C. Tested with GCC, clang and Visual Studio.
* Easily tuned and trimmed down by defines
* A drop-in replacement for zlib's most used API's (tested in several open source projects that use zlib, such as libpng and libzip).
* Fills a single threaded performance vs. compression ratio gap between several popular real-time compressors and zlib. For example, at level 1, miniz.c compresses around 5-9% better than minilzo, but is approx. 35% slower. At levels 2-9, miniz.c is designed to compare favorably against zlib's ratio and speed. See the miniz performance comparison page for example timings.
* Not a block based compressor: miniz.c fully supports stream based processing using a coroutine-style implementation. The zlib-style API functions can be called a single byte at a time if that's all you've got.
* Easy to use. The low-level compressor (tdefl) and decompressor (tinfl) have simple state structs which can be saved/restored as needed with simple memcpy's. The low-level codec API's don't use the heap in any way.
* Entire inflater (including optional zlib header parsing and Adler-32 checking) is implemented in a single function as a coroutine, which is separately available in a small (~550 line) source file: miniz_tinfl.c
* A fairly complete (but totally optional) set of .ZIP archive manipulation and extraction API's. The archive functionality is intended to solve common problems encountered in embedded, mobile, or game development situations. (The archive API's are purposely just powerful enough to write an entire archiver given a bit of additional higher-level logic.)
## Known Problems
* No support for encrypted archives. Not sure how useful this stuff is in practice.
* Minimal documentation. The assumption is that the user is already familiar with the basic zlib API. I need to write an API wiki - for now I've tried to place key comments before each enum/API, and I've included 6 examples that demonstrate how to use the module's major features.
## Special Thanks
Thanks to Alex Evans for the PNG writer function. Also, thanks to Paul Holden and Thorsten Scheuermann for feedback and testing, Matt Pritchard for all his encouragement, and Sean Barrett's various public domain libraries for inspiration (and encouraging me to write miniz.c in C, which was much more enjoyable and less painful than I thought it would be considering I've been programming in C++ for so long).
Thanks to Bruce Dawson for reporting a problem with the level_and_flags archive API parameter (which is fixed in v1.12) and general feedback, and Janez Zemva for indirectly encouraging me into writing more examples.
## Patents
I was recently asked if miniz avoids patent issues. miniz purposely uses the same core algorithms as the ones used by zlib. The compressor uses vanilla hash chaining as described [here](https://datatracker.ietf.org/doc/html/rfc1951#section-4). Also see the [gzip FAQ](https://web.archive.org/web/20160308045258/http://www.gzip.org/#faq11). In my opinion, if miniz falls prey to a patent attack then zlib/gzip are likely to be at serious risk too.

View File

@@ -4,6 +4,11 @@ set -e
. amalgamate.sh
cat << "EOF" > miniz_export.h
#ifndef MINIZ_EXPORT
#define MINIZ_EXPORT
#endif
EOF
g++ tests/miniz_tester.cpp tests/timer.cpp amalgamation/miniz.c -o miniz_tester -I. -ggdb -O2
for i in 1 2 3 4 5 6

25
tests/checksum_fuzzer.c Normal file
View File

@@ -0,0 +1,25 @@
/* Derived from zlib fuzzers at http://github.com/google/oss-fuzz/tree/master/projects/zlib,
* see ossfuzz.sh for full license text.
*/
#include <stddef.h>
#include <stdint.h>
#include <inttypes.h>
#include "miniz.h"
static const size_t kMaxSize = 1024 * 1024;
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataLen)
{
/* Discard inputs larger than 1Mb. */
if (dataLen < 1 || dataLen > kMaxSize) return 0;
uint32_t crc = crc32(0L, NULL, 0);
uint32_t adler = adler32(0L, NULL, 0);
crc = crc32(crc, data, (uint32_t) dataLen);
adler = adler32(adler, data, (uint32_t) dataLen);
return 0;
}

88
tests/compress_fuzzer.c Normal file
View File

@@ -0,0 +1,88 @@
/* Derived from zlib fuzzers at http://github.com/google/oss-fuzz/tree/master/projects/zlib,
* see ossfuzz.sh for full license text.
*/
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <inttypes.h>
#include "miniz.h"
static const uint8_t *data;
static size_t dataLen;
static void check_compress_level(uint8_t *compr, size_t comprLen,
uint8_t *uncompr, size_t uncomprLen,
int level)
{
compress2(compr, &comprLen, data, dataLen, level);
uncompress(uncompr, &uncomprLen, compr, comprLen);
/* Make sure compress + uncompress gives back the input data. */
assert(dataLen == uncomprLen);
assert(0 == memcmp(data, uncompr, dataLen));
}
#define put_byte(s, i, c) {s[i] = (unsigned char)(c);}
static void write_zlib_header(uint8_t *s)
{
unsigned level_flags = 0; /* compression level (0..3) */
unsigned w_bits = 8; /* window size log2(w_size) (8..16) */
unsigned int header = (Z_DEFLATED + ((w_bits-8)<<4)) << 8;
header |= (level_flags << 6);
header += 31 - (header % 31);
/* s is guaranteed to be longer than 2 bytes. */
put_byte(s, 0, (unsigned char)(header >> 8));
put_byte(s, 1, (unsigned char)(header & 0xff));
}
static void check_decompress(uint8_t *compr, size_t comprLen)
{
/* We need to write a valid zlib header of size two bytes. Copy the input data
in a larger buffer. Do not modify the input data to avoid libFuzzer error:
fuzz target overwrites its const input. */
size_t copyLen = dataLen + 2;
uint8_t *copy = malloc(copyLen);
memcpy(copy + 2, data, dataLen);
write_zlib_header(copy);
uncompress(compr, &comprLen, copy, copyLen);
free(copy);
}
int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size)
{
/* compressBound does not provide enough space for low compression levels. */
size_t comprLen = 100 + 2 * compressBound(size);
size_t uncomprLen = size;
uint8_t *compr, *uncompr;
/* Discard inputs larger than 1Mb. */
static size_t kMaxSize = 1024 * 1024;
if (size < 1 || size > kMaxSize)
return 0;
data = d;
dataLen = size;
compr = calloc(1, comprLen);
uncompr = calloc(1, uncomprLen);
check_compress_level(compr, comprLen, uncompr, uncomprLen, 1);
check_compress_level(compr, comprLen, uncompr, uncomprLen, 3);
check_compress_level(compr, comprLen, uncompr, uncomprLen, 6);
check_compress_level(compr, comprLen, uncompr, uncomprLen, 7);
check_decompress(compr, comprLen);
free(compr);
free(uncompr);
return 0;
}

87
tests/flush_fuzzer.c Normal file
View File

@@ -0,0 +1,87 @@
/* Derived from zlib fuzzers at http://github.com/google/oss-fuzz/tree/master/projects/zlib,
* see ossfuzz.sh for full license text.
*/
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include "miniz.h"
#define CHECK_ERR(err, msg) { \
if (err != Z_OK) { \
fprintf(stderr, "%s error: %d\n", msg, err); \
exit(1); \
} \
}
static const uint8_t *data;
static size_t dataLen;
static alloc_func zalloc = NULL;
static free_func zfree = NULL;
void test_flush(unsigned char *compr, size_t *comprLen)
{
z_stream c_stream; /* compression stream */
int err;
unsigned int len = dataLen;
c_stream.zalloc = zalloc;
c_stream.zfree = zfree;
c_stream.opaque = NULL;
err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
CHECK_ERR(err, "deflateInit");
c_stream.next_in = (Bytef *)data;
c_stream.next_out = compr;
c_stream.avail_in = 3;
c_stream.avail_out = (unsigned int)*comprLen;
err = deflate(&c_stream, Z_FULL_FLUSH);
CHECK_ERR(err, "deflate flush 1");
compr[3]++; /* force an error in first compressed block */
c_stream.avail_in = len - 3;
err = deflate(&c_stream, Z_FINISH);
if (err != Z_STREAM_END)
{
CHECK_ERR(err, "deflate flush 2");
}
err = deflateEnd(&c_stream);
CHECK_ERR(err, "deflateEnd");
*comprLen = (size_t)c_stream.total_out;
}
int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size)
{
size_t comprLen = 100 + 2 * compressBound(size);
size_t uncomprLen = size;
uint8_t *compr, *uncompr;
/* Discard inputs larger than 1Mb. */
static const size_t kMaxSize = 1024 * 1024;
/* This test requires at least 3 bytes of input data. */
if (size <= 3 || size > kMaxSize)
return 0;
data = d;
dataLen = size;
compr = calloc(1, comprLen);
uncompr = calloc(1, uncomprLen);
test_flush(compr, &comprLen);
free(compr);
free(uncompr);
return 0;
}

54
tests/fuzz_main.c Normal file
View File

@@ -0,0 +1,54 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
/* Fuzz target entry point for building without libFuzzer */
int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size);
int main(int argc, char **argv)
{
FILE *f;
char *buf = NULL;
long siz_buf;
if(argc < 2)
{
fprintf(stderr, "no input file\n");
goto err;
}
f = fopen(argv[1], "rb");
if(f == NULL)
{
fprintf(stderr, "error opening input file %s\n", argv[1]);
goto err;
}
fseek(f, 0, SEEK_END);
siz_buf = ftell(f);
rewind(f);
if(siz_buf < 1) goto err;
buf = (char*)malloc(siz_buf);
if(buf == NULL)
{
fprintf(stderr, "malloc() failed\n");
goto err;
}
if(fread(buf, siz_buf, 1, f) != 1)
{
fprintf(stderr, "fread() failed\n");
goto err;
}
(void)LLVMFuzzerTestOneInput((uint8_t*)buf, siz_buf);
err:
free(buf);
return 0;
}

130
tests/large_fuzzer.c Normal file
View File

@@ -0,0 +1,130 @@
/* Derived from zlib fuzzers at http://github.com/google/oss-fuzz/tree/master/projects/zlib,
* see ossfuzz.sh for full license text.
*/
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include "miniz.h"
#define CHECK_ERR(err, msg) { \
if (err != Z_OK) { \
fprintf(stderr, "%s error: %d\n", msg, err); \
exit(1); \
} \
}
static const uint8_t *data;
static size_t dataLen;
static alloc_func zalloc = NULL;
static free_func zfree = NULL;
static unsigned int diff;
/* Test deflate() with large buffers and dynamic change of compression level */
void test_large_deflate(unsigned char *compr, size_t comprLen,
unsigned char *uncompr, size_t uncomprLen)
{
z_stream c_stream; /* compression stream */
int err;
c_stream.zalloc = zalloc;
c_stream.zfree = zfree;
c_stream.opaque = NULL;
err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
CHECK_ERR(err, "deflateInit");
c_stream.next_out = compr;
c_stream.avail_out = (unsigned int)comprLen;
/* At this point, uncompr is still mostly zeroes, so it should compress
* very well:
*/
c_stream.next_in = uncompr;
c_stream.avail_in = (unsigned int)uncomprLen;
err = deflate(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate large 1");
if (c_stream.avail_in != 0)
{
fprintf(stderr, "deflate not greedy\n");
exit(1);
}
/* Feed in already compressed data: */
c_stream.next_in = compr;
diff = (unsigned int)(c_stream.next_out - compr);
c_stream.avail_in = diff;
deflate(&c_stream, Z_NO_FLUSH);
err = deflate(&c_stream, Z_FINISH);
if (err != Z_STREAM_END)
{
fprintf(stderr, "deflate large should report Z_STREAM_END\n");
exit(1);
}
err = deflateEnd(&c_stream);
CHECK_ERR(err, "deflateEnd");
}
/* Test inflate() with large buffers */
void test_large_inflate(unsigned char *compr, size_t comprLen,
unsigned char *uncompr, size_t uncomprLen)
{
int err;
z_stream d_stream; /* decompression stream */
d_stream.zalloc = zalloc;
d_stream.zfree = zfree;
d_stream.opaque = NULL;
d_stream.next_in = compr;
d_stream.avail_in = (unsigned int)comprLen;
err = inflateInit(&d_stream);
CHECK_ERR(err, "inflateInit");
for (;;)
{
d_stream.next_out = uncompr; /* discard the output */
d_stream.avail_out = (unsigned int)uncomprLen;
err = inflate(&d_stream, Z_NO_FLUSH);
if (err == Z_STREAM_END) break;
CHECK_ERR(err, "large inflate");
}
err = inflateEnd(&d_stream);
CHECK_ERR(err, "inflateEnd");
}
int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size)
{
size_t comprLen = 100 + 3 * size;
size_t uncomprLen = comprLen;
uint8_t *compr, *uncompr;
/* Discard inputs larger than 512Kb. */
static size_t kMaxSize = 512 * 1024;
if (size < 1 || size > kMaxSize)
return 0;
data = d;
dataLen = size;
compr = calloc(1, comprLen);
uncompr = calloc(1, uncomprLen);
test_large_deflate(compr, comprLen, uncompr, uncomprLen);
test_large_inflate(compr, comprLen, uncompr, uncomprLen);
free(compr);
free(uncompr);
return 0;
}

View File

@@ -993,6 +993,71 @@ static bool zip_extract(const char *pZip_filename, const char *pDst_filename)
}
free(p);
}
if (stat.m_uncomp_size<100*1024*1024)
{
/* Use iterative reader to read onto heap in one big chunk */
mz_zip_reader_extract_iter_state *pIter = mz_zip_reader_extract_iter_new(&zip, i, 0);
void *p = malloc(stat.m_uncomp_size);
if ((!pIter) && (0 != stat.m_uncomp_size))
{
print_error("Failed testing archive -4 \"%s\" err: %s!\n", pZip_filename, mz_zip_get_error_string(mz_zip_get_last_error(&zip)));
free(p);
mz_zip_reader_end(&zip);
return false;
}
if (pIter)
{
if (stat.m_uncomp_size != mz_zip_reader_extract_iter_read(pIter, p, stat.m_uncomp_size) )
{
print_error("Failed testing archive -5 \"%s\" err: %s!\n", pZip_filename, mz_zip_get_error_string(mz_zip_get_last_error(&zip)));
free(p);
mz_zip_reader_extract_iter_free(pIter);
mz_zip_reader_end(&zip);
return false;
}
if (MZ_TRUE != mz_zip_reader_extract_iter_free(pIter))
{
print_error("Failed testing archive -6 \"%s\" err: %s!\n", pZip_filename, mz_zip_get_error_string(mz_zip_get_last_error(&zip)));
free(p);
mz_zip_reader_end(&zip);
return false;
}
}
free(p);
}
if (stat.m_uncomp_size<100*1024)
{
/* Use iterative reader to read file one byte at a time */
mz_zip_reader_extract_iter_state *pIter = mz_zip_reader_extract_iter_new(&zip, i, 0);
uint8_t byBuffer;
if ((!pIter) && (0 != stat.m_uncomp_size))
{
print_error("Failed testing archive -7 \"%s\" err: %s!\n", pZip_filename, mz_zip_get_error_string(mz_zip_get_last_error(&zip)));
mz_zip_reader_end(&zip);
return false;
}
if (pIter)
{
for ( uint64_t uiIndex = 0; uiIndex < stat.m_uncomp_size; uiIndex++ )
{
if (sizeof(byBuffer) != mz_zip_reader_extract_iter_read(pIter, &byBuffer, sizeof(byBuffer)))
{
print_error("Failed testing archive -8 \"%s\" err: %s!\n", pZip_filename, mz_zip_get_error_string(mz_zip_get_last_error(&zip)));
mz_zip_reader_extract_iter_free(pIter);
mz_zip_reader_end(&zip);
return false;
}
}
if (MZ_TRUE != mz_zip_reader_extract_iter_free(pIter))
{
print_error("Failed testing archive -9 \"%s\" err: %s!\n", pZip_filename, mz_zip_get_error_string(mz_zip_get_last_error(&zip)));
mz_zip_reader_end(&zip);
return false;
}
}
}
}
printf("Verified %u files\n", mz_zip_reader_get_num_files(&zip));
@@ -1446,6 +1511,15 @@ static bool test_archives(const char *pPath, comp_options options)
if (mz_crc32(MZ_CRC32_INIT, (const uint8*)p, extracted_size) != extracted_crc32)
status = false;
mz_zip_reader_extract_iter_state *pIter = mz_zip_reader_extract_file_iter_new(&src_archive, name, 0);
void *q = malloc(extracted_size);
mz_zip_reader_extract_iter_read(pIter, q, extracted_size);
mz_zip_reader_extract_iter_free(pIter);
if (mz_crc32(MZ_CRC32_INIT, (const uint8*)q, extracted_size) != extracted_crc32)
status = false;
free(q);
free(p);
if (options.m_write_archives)

42
tests/ossfuzz.sh Executable file
View File

@@ -0,0 +1,42 @@
#!/bin/bash -eu
# Copyright 2020 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################
# This script is meant to be run by
# https://github.com/google/oss-fuzz/blob/master/projects/miniz/Dockerfile
mkdir build
cd build
cmake .. -DAMALGAMATE_SOURCES=ON -DBUILD_SHARED_LIBS=OFF -DBUILD_FUZZERS=ON
make -j$(nproc)
cd ..
zip $OUT/seed_corpus.zip *.*
for f in $(find $SRC -name '*_fuzzer.c'); do
b=$(basename -s .c $f)
$CC $CFLAGS -Ibuild/amalgamation $f -c -o /tmp/$b.o
$CXX $CXXFLAGS -stdlib=libc++ -Ibuild/amalgamation /tmp/$b.o -o $OUT/$b $LIB_FUZZING_ENGINE ./build/libminiz.a
rm -f /tmp/$b.o
ln -sf $OUT/seed_corpus.zip $OUT/${b}_seed_corpus.zip
done
# Add .zip input file for the zip fuzzer
rm -f $OUT/zip_fuzzer_seed_corpus.zip
zip $OUT/zip_fuzzer_seed_corpus.zip $OUT/seed_corpus.zip
cp tests/zip.dict $OUT/zip_fuzzer.dict

124
tests/small_fuzzer.c Normal file
View File

@@ -0,0 +1,124 @@
/* Derived from zlib fuzzers at http://github.com/google/oss-fuzz/tree/master/projects/zlib,
* see ossfuzz.sh for full license text.
*/
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include "miniz.h"
#define CHECK_ERR(err, msg) { \
if (err != Z_OK) { \
fprintf(stderr, "%s error: %d\n", msg, err); \
exit(1); \
} \
}
static const uint8_t *data;
static size_t dataLen;
static alloc_func zalloc = NULL;
static free_func zfree = NULL;
/* Test deflate() with small buffers */
void test_deflate(unsigned char *compr, size_t comprLen)
{
z_stream c_stream; /* compression stream */
int err;
unsigned long len = dataLen;
c_stream.zalloc = zalloc;
c_stream.zfree = zfree;
c_stream.opaque = NULL;
err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
CHECK_ERR(err, "deflateInit");
c_stream.next_in = (Bytef *)data;
c_stream.next_out = compr;
while (c_stream.total_in != len && c_stream.total_out < comprLen)
{
c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
err = deflate(&c_stream, Z_NO_FLUSH);
CHECK_ERR(err, "deflate small 1");
}
/* Finish the stream, still forcing small buffers: */
for (;;)
{
c_stream.avail_out = 1;
err = deflate(&c_stream, Z_FINISH);
if (err == Z_STREAM_END)
break;
CHECK_ERR(err, "deflate small 2");
}
err = deflateEnd(&c_stream);
CHECK_ERR(err, "deflateEnd");
}
/* Test inflate() with small buffers */
void test_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen)
{
int err;
z_stream d_stream; /* decompression stream */
d_stream.zalloc = zalloc;
d_stream.zfree = zfree;
d_stream.opaque = NULL;
d_stream.next_in = compr;
d_stream.avail_in = 0;
d_stream.next_out = uncompr;
err = inflateInit(&d_stream);
CHECK_ERR(err, "inflateInit");
while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen)
{
d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
err = inflate(&d_stream, Z_NO_FLUSH);
if (err == Z_STREAM_END)
break;
CHECK_ERR(err, "inflate");
}
err = inflateEnd(&d_stream);
CHECK_ERR(err, "inflateEnd");
if (memcmp(uncompr, data, dataLen))
{
fprintf(stderr, "bad inflate\n");
exit(1);
}
}
int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size)
{
size_t comprLen = compressBound(size);
size_t uncomprLen = size;
uint8_t *compr, *uncompr;
/* Discard inputs larger than 1Mb. */
static size_t kMaxSize = 1024 * 1024;
if (size < 1 || size > kMaxSize)
return 0;
data = d;
dataLen = size;
compr = calloc(1, comprLen);
uncompr = calloc(1, uncomprLen);
test_deflate(compr, comprLen);
test_inflate(compr, comprLen, uncompr, uncomprLen);
free(compr);
free(uncompr);
return 0;
}

View File

@@ -0,0 +1,20 @@
/* Derived from zlib fuzzers at http://github.com/google/oss-fuzz/tree/master/projects/zlib,
* see ossfuzz.sh for full license text.
*/
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "miniz.h"
static unsigned char buffer[256 * 1024] = { 0 };
int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
unsigned long int buffer_length = sizeof(buffer);
if (Z_OK != uncompress2(buffer, &buffer_length, data, &size)) return 0;
return 0;
}

30
tests/uncompress_fuzzer.c Normal file
View File

@@ -0,0 +1,30 @@
/* Derived from zlib fuzzers at http://github.com/google/oss-fuzz/tree/master/projects/zlib,
* see ossfuzz.sh for full license text.
*/
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "miniz.h"
int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
unsigned long int buffer_length = 1;
unsigned char *buffer = NULL;
int z_status = 0;
if (size > 0)
buffer_length *= data[0];
if (size > 1)
buffer_length *= data[1];
buffer = (unsigned char *)malloc(buffer_length);
z_status = uncompress(buffer, &buffer_length, data, size);
free(buffer);
if (Z_OK != z_status)
return 0;
return 0;
}

9
tests/zip.dict Normal file
View File

@@ -0,0 +1,9 @@
# Fuzzing dictionary for .zip files
header_lfh="\x50\x4b\x03\x04"
header_cd="\x50\x4b\x01\x02"
header_eocd="\x50\x4b\x05\x06"
header_eocd64="\x50\x4b\x06\x06"
data_descriptor="\x50\x4b\x07\x08"
extra_data_sig="\x50\x4b\x06\x08"
digital_sig="\x50\x4b\x05\x05"

57
tests/zip_fuzzer.c Normal file
View File

@@ -0,0 +1,57 @@
#include <stdint.h>
#include <inttypes.h>
#include "miniz.h"
static char filename[260];
static unsigned char read_buf[1024 * 256];
static const size_t filename_max = sizeof(filename);
static const size_t read_buf_size = sizeof(read_buf);
static const size_t data_max = 1024 * 256;
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
if(size > data_max) return 0;
int ret = 0;
mz_zip_archive zip;
mz_zip_zero_struct(&zip);
mz_uint flags = 0;
if(!mz_zip_reader_init_mem(&zip, data, size, flags)) return 0;
mz_uint i, files;
files = mz_zip_reader_get_num_files(&zip);
for(i=0; i < files; i++)
{
mz_zip_clear_last_error(&zip);
if(mz_zip_reader_is_file_a_directory(&zip, i)) continue;
mz_zip_validate_file(&zip, i, MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY);
if(mz_zip_reader_is_file_encrypted(&zip, i)) continue;
mz_zip_clear_last_error(&zip);
mz_uint ret = mz_zip_reader_get_filename(&zip, i, filename, filename_max);
if(mz_zip_get_last_error(&zip)) continue;
mz_zip_archive_file_stat file_stat = {0};
mz_bool status = mz_zip_reader_file_stat(&zip, i, &file_stat) != 0;
if ((file_stat.m_method) && (file_stat.m_method != MZ_DEFLATED)) continue;
mz_zip_reader_extract_file_to_mem(&zip, file_stat.m_filename, read_buf, read_buf_size, 0);
}
cleanup:
mz_zip_reader_end(&zip);
return ret;
}