Compare commits
164 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c30a001bc | ||
|
|
8980137de6 | ||
|
|
4d99a8f7c2 | ||
|
|
13c4e52c91 | ||
|
|
d9be48fbe6 | ||
|
|
3a404922aa | ||
|
|
e680017bae | ||
|
|
2fa13ca8a3 | ||
|
|
0f4cbb8c27 | ||
|
|
efbf3935b1 | ||
|
|
35528ad769 | ||
|
|
189f56edaa | ||
|
|
11e7c39508 | ||
|
|
1ff82be7d6 | ||
|
|
8e8e609e02 | ||
|
|
bf7a1f0a5a | ||
|
|
4000bc3a87 | ||
|
|
200c9053d0 | ||
|
|
8573fd7cd6 | ||
|
|
961de84cbb | ||
|
|
0283a1796e | ||
|
|
3c46a05141 | ||
|
|
43bc679d05 | ||
|
|
8714fd3cd8 | ||
|
|
60ec4a72b9 | ||
|
|
3cc84f4f0c | ||
|
|
2552e6d45a | ||
|
|
622aea128a | ||
|
|
16413c213d | ||
|
|
a77af68d92 | ||
|
|
e5700656b3 | ||
|
|
4d6f89cb0a | ||
|
|
f8a09fe199 | ||
|
|
6cfbb0d1d8 | ||
|
|
fa8ef4584b | ||
|
|
039b1d2962 | ||
|
|
32bb60d989 | ||
|
|
05ab4dc05c | ||
|
|
697f010d70 | ||
|
|
bd9e22f577 | ||
|
|
9aef68479f | ||
|
|
69763e8811 | ||
|
|
18795fa61e | ||
|
|
96b0c0fc64 | ||
|
|
acfba6a21d | ||
|
|
93ded54847 | ||
|
|
a23a38bf53 | ||
|
|
d0190e5cdf | ||
|
|
90a5b2f89b | ||
|
|
6f09a0f0b5 | ||
|
|
fd55960854 | ||
|
|
b0af33a61b | ||
|
|
9ae305f6e1 | ||
|
|
d9d197c926 | ||
|
|
654bf8bdeb | ||
|
|
fe6330e1d8 | ||
|
|
f259216256 | ||
|
|
f0709ed3f5 | ||
|
|
293d4db1b7 | ||
|
|
12680974d1 | ||
|
|
ad8dedc1b3 | ||
|
|
08c03ff478 | ||
|
|
2ec92b4852 | ||
|
|
78e9404362 | ||
|
|
963a27a112 | ||
|
|
2363190ebf | ||
|
|
7265019066 | ||
|
|
83341a5605 | ||
|
|
39622ead92 | ||
|
|
ab052e6e58 | ||
|
|
39f65158c7 | ||
|
|
ca0cdfc52d | ||
|
|
7b9bcf7f94 | ||
|
|
92ab73ac32 | ||
|
|
78ef92043c | ||
|
|
11f77193b7 | ||
|
|
4a8dc21d9d | ||
|
|
725b8df44c | ||
|
|
8cdf426109 | ||
|
|
680454c21e | ||
|
|
a203b9a0d4 | ||
|
|
d4ad2bf51e | ||
|
|
be92575500 | ||
|
|
a2b5326d86 | ||
|
|
de0a4d2444 | ||
|
|
482c77e661 | ||
|
|
37ea28133d | ||
|
|
9cd715b3b1 | ||
|
|
a9d7f80cc6 | ||
|
|
8db69b6b59 | ||
|
|
c610f58a57 | ||
|
|
e1e7f70e59 | ||
|
|
76b3a87285 | ||
|
|
5c9c89509c | ||
|
|
719967dc82 | ||
|
|
18bc504331 | ||
|
|
144c351f34 | ||
|
|
bc77ea1017 | ||
|
|
7c459c8a05 | ||
|
|
118b2e3d34 | ||
|
|
e7d0e216d5 | ||
|
|
5a38f5564a | ||
|
|
9eedb97176 | ||
|
|
8a7cf60c7a | ||
|
|
d9bd65a843 | ||
|
|
71ba5d12d6 | ||
|
|
e285002431 | ||
|
|
cd1dc96d27 | ||
|
|
5245b1c52f | ||
|
|
842a20e586 | ||
|
|
edc251cfa9 | ||
|
|
9ffbe56a73 | ||
|
|
f2b59b344d | ||
|
|
0ce345c44a | ||
|
|
0796bdbee6 | ||
|
|
056cc8db14 | ||
|
|
60942b0f04 | ||
|
|
8997650f5c | ||
|
|
698faddd95 | ||
|
|
ff862d4596 | ||
|
|
740049e643 | ||
|
|
2cd06e3f32 | ||
|
|
f3d9e2293b | ||
|
|
1541a11e9b | ||
|
|
501a761549 | ||
|
|
aa70ef1644 | ||
|
|
13b21dddc7 | ||
|
|
a956b4c753 | ||
|
|
ecbbbe0138 | ||
|
|
72e7267054 | ||
|
|
12b78b6d5a | ||
|
|
2beb69d0a5 | ||
|
|
0a88083589 | ||
|
|
3e5e488ba9 | ||
|
|
75c948a1dd | ||
|
|
b4108c6fcf | ||
|
|
e6a7c5daed | ||
|
|
66c7313326 | ||
|
|
82d6810a38 | ||
|
|
ee4deb08fa | ||
|
|
cb2b132b86 | ||
|
|
591faa9574 | ||
|
|
3a387ec369 | ||
|
|
cda0b3e7f0 | ||
|
|
e841503cad | ||
|
|
a7961f5b4c | ||
|
|
ca1a779ee1 | ||
|
|
18da352921 | ||
|
|
d9c899cea4 | ||
|
|
70c79cc9d5 | ||
|
|
583f4f27c2 | ||
|
|
9b89689723 | ||
|
|
f99eae6e04 | ||
|
|
fc0c0f585e | ||
|
|
78ae375016 | ||
|
|
f542e6df73 | ||
|
|
46347635c8 | ||
|
|
c0aad72d46 | ||
|
|
08f2c2d7e3 | ||
|
|
49860a15fa | ||
|
|
524906517d | ||
|
|
3d000933a7 | ||
|
|
40b0612004 | ||
|
|
8da3cbb64e |
@ -44,3 +44,4 @@ SpacesInCStyleCastParentheses: false
|
||||
SpaceAfterControlStatementKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
ContinuationIndentWidth: 4
|
||||
SortIncludes: false
|
||||
24
.github/workflows/c-cpp.yml
vendored
24
.github/workflows/c-cpp.yml
vendored
@ -15,3 +15,27 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
- name: amalgamate
|
||||
run: bash amalgamate.sh
|
||||
- name: Run CMake consuming CMakePreset.json and run tests
|
||||
uses: lukka/run-cmake@v10
|
||||
with:
|
||||
# This is the name of the CMakePresets.json's configuration to use to generate
|
||||
# the project files. This configuration leverages the vcpkg.cmake toolchain file to
|
||||
# run vcpkg and install all dependencies specified in vcpkg.json.
|
||||
configurePreset: 'gcc'
|
||||
# Additional arguments can be appended to the cmake command.
|
||||
# This is useful to reduce the number of CMake's Presets since you can reuse
|
||||
# an existing preset with different variables.
|
||||
configurePresetAdditionalArgs: "['-DENABLE_YOUR_FEATURE=1']"
|
||||
# This is the name of the CMakePresets.json's configuration to build the project.
|
||||
buildPreset: 'gcc'
|
||||
# Additional arguments can be appended when building, for example to specify the
|
||||
# configuration to build.
|
||||
# This is useful to reduce the number of CMake's Presets you need in CMakePresets.json.
|
||||
buildPresetAdditionalArgs: "['--config Release']"
|
||||
|
||||
# This is the name of the CMakePresets.json's configuration to test the project with.
|
||||
testPreset: 'gcc'
|
||||
# Additional arguments can be appended when testing, for example to specify the config
|
||||
# to test.
|
||||
# This is useful to reduce the number of CMake's Presets you need in CMakePresets.json.
|
||||
testPresetAdditionalArgs: "[]"
|
||||
|
||||
2
.github/workflows/ci-fuzz.yml
vendored
2
.github/workflows/ci-fuzz.yml
vendored
@ -16,7 +16,7 @@ jobs:
|
||||
fuzz-seconds: 900
|
||||
dry-run: false
|
||||
- name: Upload Crash
|
||||
uses: actions/upload-artifact@v1
|
||||
uses: actions/upload-artifact@v4
|
||||
if: failure()
|
||||
with:
|
||||
name: artifacts
|
||||
|
||||
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/_build
|
||||
/amalgamation
|
||||
/bin
|
||||
@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
# determine whether this is a standalone project or included by other projects
|
||||
set (MINIZ_STANDALONE_PROJECT ON)
|
||||
@ -10,12 +10,22 @@ if(CMAKE_MINOR_VERSION LESS 12)
|
||||
project(miniz)
|
||||
# see issue https://gitlab.kitware.com/cmake/cmake/merge_requests/1799
|
||||
else()
|
||||
project(miniz C)
|
||||
project(miniz)
|
||||
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 2)
|
||||
set(MINIZ_MINOR_VERSION 2)
|
||||
set(MINIZ_PATCH_VERSION 0)
|
||||
set(MINIZ_API_VERSION 3)
|
||||
set(MINIZ_MINOR_VERSION 0)
|
||||
set(MINIZ_PATCH_VERSION 2)
|
||||
set(MINIZ_VERSION
|
||||
${MINIZ_API_VERSION}.${MINIZ_MINOR_VERSION}.${MINIZ_PATCH_VERSION})
|
||||
|
||||
@ -31,7 +41,9 @@ 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" ON)
|
||||
option(BUILD_SHARED_LIBS "Build shared library instead of static" OFF)
|
||||
option(BUILD_NO_STDIO" Build a without stdio version" OFF)
|
||||
option(BUILD_TESTS "Build tests" ${MINIZ_STANDALONE_PROJECT})
|
||||
option(INSTALL_PROJECT "Install project" ${MINIZ_STANDALONE_PROJECT})
|
||||
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin)
|
||||
@ -68,7 +80,7 @@ if(AMALGAMATE_SOURCES)
|
||||
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 "#define MINIZ_EXPORT\n" "${AMAL_MINIZ_H}")
|
||||
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")
|
||||
@ -163,10 +175,14 @@ if(NOT BUILD_HEADER_ONLY)
|
||||
if(INSTALL_PROJECT)
|
||||
install(FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/miniz.pc
|
||||
DESTINATION ${CMAKE_INSTALL_DATADIR}/pkgconfig)
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(BUILD_NO_STDIO)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE MINIZ_NO_STDIO)
|
||||
endif()
|
||||
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY
|
||||
INTERFACE_${PROJECT_NAME}_MAJOR_VERSION ${MINIZ_API_VERSION})
|
||||
set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY
|
||||
@ -231,8 +247,10 @@ if(BUILD_EXAMPLES)
|
||||
|
||||
add_executable(example1 ${EXAMPLE1_SRC_LIST})
|
||||
target_link_libraries(example1 miniz)
|
||||
if(NOT BUILD_NO_STDIO)
|
||||
add_executable(example2 ${EXAMPLE2_SRC_LIST})
|
||||
target_link_libraries(example2 miniz)
|
||||
endif()
|
||||
add_executable(example3 ${EXAMPLE3_SRC_LIST})
|
||||
target_link_libraries(example3 miniz)
|
||||
add_executable(example4 ${EXAMPLE4_SRC_LIST})
|
||||
@ -260,6 +278,7 @@ if(BUILD_FUZZERS)
|
||||
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")
|
||||
set(ADD_IN_PLACE_FUZZER_SRC_LIST "${FUZZ_MAIN_SRC}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/add_in_place_fuzzer.c")
|
||||
|
||||
add_executable(checksum_fuzzer ${CHECKSUM_FUZZER_SRC_LIST})
|
||||
target_link_libraries(checksum_fuzzer miniz)
|
||||
@ -284,6 +303,24 @@ if(BUILD_FUZZERS)
|
||||
|
||||
add_executable(zip_fuzzer ${ZIP_FUZZER_SRC_LIST})
|
||||
target_link_libraries(zip_fuzzer miniz)
|
||||
|
||||
add_executable(add_in_place_fuzzer ${ADD_IN_PLACE_FUZZER_SRC_LIST})
|
||||
target_link_libraries(add_in_place_fuzzer miniz)
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTS)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED YES)
|
||||
|
||||
add_executable(catch_tests tests/main.cpp tests/catch_amalgamated.cpp)
|
||||
if(BUILD_NO_STDIO)
|
||||
target_compile_definitions(catch_tests PRIVATE -DMINIZ_NO_STDIO)
|
||||
endif()
|
||||
target_link_libraries(catch_tests miniz)
|
||||
|
||||
enable_testing()
|
||||
|
||||
add_test(NAME catch_tests COMMAND $<TARGET_FILE:catch_tests>)
|
||||
endif()
|
||||
|
||||
set(INCLUDE_INSTALL_DIR "include")
|
||||
|
||||
31
CMakePresets.json
Normal file
31
CMakePresets.json
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
"version": 6,
|
||||
"cmakeMinimumRequired": {
|
||||
"major": 3,
|
||||
"minor": 5,
|
||||
"patch": 0
|
||||
},
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "gcc",
|
||||
"displayName": "GCC",
|
||||
"description": "Default build options for GCC",
|
||||
"generator": "Unix Makefiles",
|
||||
"binaryDir": "${sourceDir}/build"
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
{
|
||||
"name": "gcc",
|
||||
"configurePreset": "gcc"
|
||||
}
|
||||
],
|
||||
"testPresets": [
|
||||
{
|
||||
"name": "gcc",
|
||||
"configurePreset": "gcc",
|
||||
"output": {"outputOnFailure": true},
|
||||
"execution": {"noTestsAction": "error", "stopOnFailure": true}
|
||||
}
|
||||
]
|
||||
}
|
||||
45
ChangeLog.md
45
ChangeLog.md
@ -1,5 +1,48 @@
|
||||
## Changelog
|
||||
|
||||
### 3.0.2
|
||||
|
||||
- Fix buffer overrun in mz_utf8z_to_widechar on Windows
|
||||
|
||||
### 3.0.1
|
||||
|
||||
- Fix compilation error with MINIZ_USE_UNALIGNED_LOADS_AND_STORES=1
|
||||
|
||||
### 3.0.0
|
||||
|
||||
- Reduce memory usage for inflate. This changes `struct tinfl_decompressor_tag` and therefore requires a major version bump (breaks ABI compatibility)
|
||||
- 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
|
||||
- Fixed alignment problems on MacOS
|
||||
- Fixed get error string for MZ_ZIP_TOTAL_ERRORS
|
||||
- Write correct FLEVEL 2-bit value in zlib header
|
||||
- miniz.pc.in: fix include path not containing the "miniz" suffix
|
||||
- Fix compatibility with FreeBSD
|
||||
- pkg-config tweaks
|
||||
- Fix integer overflow in header corruption check
|
||||
- Fix some warnings
|
||||
- tdefl_compress_normal: Avoid NULL ptr arithmetic UB
|
||||
- replace use of stdint.h types with mz_ variants
|
||||
|
||||
|
||||
### 2.2.0
|
||||
|
||||
- Fix examples with amalgamation
|
||||
@ -123,7 +166,7 @@ Merged over a few very minor bug fixes that I fixed in the zip64 branch. This is
|
||||
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 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()
|
||||
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.
|
||||
|
||||
@ -18,11 +18,13 @@ then
|
||||
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_ARCHIVE_APIS MINIZ_NO_ARCHIVE_WRITING_APIS MINIZ_NO_ZLIB_APIS MINIZ_NO_ZLIB_COMPATIBLE_NAMES MINIZ_NO_MALLOC
|
||||
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
|
||||
echo "Test compile with GCC and MINIZ_USE_UNALIGNED_LOADS_AND_STORES=1..."
|
||||
gcc -ansi -pedantic -Wall -I$OUTPUT_PREFIX main.c $OUTPUT_PREFIX/miniz.c -o test.out -DMINIZ_USE_UNALIGNED_LOADS_AND_STORES=1
|
||||
rm test.out
|
||||
rm main.c
|
||||
|
||||
|
||||
@ -7,12 +7,12 @@ typedef unsigned short uint16;
|
||||
typedef unsigned int uint;
|
||||
|
||||
// The string to compress.
|
||||
static const char *s_pStr = "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
|
||||
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
|
||||
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
|
||||
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
|
||||
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
|
||||
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson." \
|
||||
static const char *s_pStr = "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson."
|
||||
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson."
|
||||
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson."
|
||||
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson."
|
||||
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson."
|
||||
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson."
|
||||
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson.";
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
||||
@ -21,12 +21,12 @@ typedef unsigned int uint;
|
||||
|
||||
// The string to compress.
|
||||
static const char *s_pTest_str =
|
||||
"MISSION CONTROL I wouldn't worry too much about the computer. First of all, there is still a chance that he is right, despite your tests, and" \
|
||||
"if it should happen again, we suggest eliminating this possibility by allowing the unit to remain in place and seeing whether or not it" \
|
||||
"actually fails. If the computer should turn out to be wrong, the situation is still not alarming. The type of obsessional error he may be" \
|
||||
"guilty of is not unknown among the latest generation of HAL 9000 computers. It has almost always revolved around a single detail, such as" \
|
||||
"the one you have described, and it has never interfered with the integrity or reliability of the computer's performance in other areas." \
|
||||
"No one is certain of the cause of this kind of malfunctioning. It may be over-programming, but it could also be any number of reasons. In any" \
|
||||
"MISSION CONTROL I wouldn't worry too much about the computer. First of all, there is still a chance that he is right, despite your tests, and"
|
||||
"if it should happen again, we suggest eliminating this possibility by allowing the unit to remain in place and seeing whether or not it"
|
||||
"actually fails. If the computer should turn out to be wrong, the situation is still not alarming. The type of obsessional error he may be"
|
||||
"guilty of is not unknown among the latest generation of HAL 9000 computers. It has almost always revolved around a single detail, such as"
|
||||
"the one you have described, and it has never interfered with the integrity or reliability of the computer's performance in other areas."
|
||||
"No one is certain of the cause of this kind of malfunctioning. It may be over-programming, but it could also be any number of reasons. In any"
|
||||
"event, it is somewhat analogous to human neurotic behavior. Does this answer your query? Zero-five-three-Zero, MC, transmission concluded.";
|
||||
|
||||
static const char *s_pComment = "This is a comment";
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -29,32 +29,57 @@ static void hsv_to_rgb(int hue, int min, int max, rgb_t *p)
|
||||
const int saturation = 1;
|
||||
const int color_rotate = 0;
|
||||
|
||||
if (min == max) max = min + 1;
|
||||
if (invert) hue = max - (hue - min);
|
||||
if (!saturation) {
|
||||
if (min == max)
|
||||
max = min + 1;
|
||||
if (invert)
|
||||
hue = max - (hue - min);
|
||||
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) {
|
||||
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;
|
||||
case 3: p->g = X; p->b = c; return;
|
||||
case 4: p->r = X; p->b = c; return;
|
||||
default:p->r = c; p->b = X;
|
||||
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;
|
||||
case 3:
|
||||
p->g = X;
|
||||
p->b = c;
|
||||
return;
|
||||
case 4:
|
||||
p->r = X;
|
||||
p->b = c;
|
||||
return;
|
||||
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 +114,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 +161,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
miniz.c
21
miniz.c
@ -31,7 +31,8 @@ typedef unsigned char mz_validate_uint32[sizeof(mz_uint32) == 4 ? 1 : -1];
|
||||
typedef unsigned char mz_validate_uint64[sizeof(mz_uint64) == 8 ? 1 : -1];
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* ------------------- zlib-style API's */
|
||||
@ -93,8 +94,7 @@ mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len);
|
||||
*/
|
||||
mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
|
||||
{
|
||||
static const mz_uint32 s_crc_table[256] =
|
||||
{
|
||||
static const mz_uint32 s_crc_table[256] = {
|
||||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535,
|
||||
0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
|
||||
0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D,
|
||||
@ -186,6 +186,8 @@ const char *mz_version(void)
|
||||
|
||||
#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);
|
||||
@ -320,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;
|
||||
@ -353,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;
|
||||
@ -559,7 +565,7 @@ int mz_uncompress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned cha
|
||||
memset(&stream, 0, sizeof(stream));
|
||||
|
||||
/* In case mz_ulong is 64-bits (argh I hate longs). */
|
||||
if ((*pSource_len | *pDest_len) > 0xFFFFFFFFU)
|
||||
if ((mz_uint64)(*pSource_len | *pDest_len) > 0xFFFFFFFFU)
|
||||
return MZ_PARAM_ERROR;
|
||||
|
||||
stream.next_in = pSource;
|
||||
@ -588,14 +594,15 @@ int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char
|
||||
return mz_uncompress2(pDest, pDest_len, pSource, &source_len);
|
||||
}
|
||||
|
||||
#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/
|
||||
|
||||
const char *mz_error(int err)
|
||||
{
|
||||
static struct
|
||||
{
|
||||
int m_err;
|
||||
const char *m_pDesc;
|
||||
} s_error_descs[] =
|
||||
{
|
||||
} 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_uint i;
|
||||
|
||||
181
miniz.h
181
miniz.h
@ -1,4 +1,4 @@
|
||||
/* miniz.c 2.2.0 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
|
||||
/* miniz.c 3.0.2 - 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
|
||||
@ -115,7 +115,7 @@
|
||||
#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 */
|
||||
@ -125,6 +125,12 @@
|
||||
/* 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 */
|
||||
|
||||
@ -143,6 +149,14 @@
|
||||
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
|
||||
@ -161,18 +175,40 @@
|
||||
#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
|
||||
@ -187,7 +223,8 @@
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* ------------------- zlib-style API Definitions. */
|
||||
@ -236,9 +273,9 @@ enum
|
||||
MZ_DEFAULT_COMPRESSION = -1
|
||||
};
|
||||
|
||||
#define MZ_VERSION "10.2.0"
|
||||
#define MZ_VERNUM 0xA100
|
||||
#define MZ_VER_MAJOR 10
|
||||
#define MZ_VERSION "11.0.2"
|
||||
#define MZ_VERNUM 0xB002
|
||||
#define MZ_VER_MAJOR 11
|
||||
#define MZ_VER_MINOR 2
|
||||
#define MZ_VER_REVISION 0
|
||||
#define MZ_VER_SUBREVISION 0
|
||||
@ -304,6 +341,8 @@ typedef mz_stream *mz_streamp;
|
||||
/* Returns the version string of miniz.c. */
|
||||
MINIZ_EXPORT const char *mz_version(void);
|
||||
|
||||
#ifndef MINIZ_NO_DEFLATE_APIS
|
||||
|
||||
/* mz_deflateInit() initializes a compressor with default options: */
|
||||
/* Parameters: */
|
||||
/* pStream must point to an initialized mz_stream struct. */
|
||||
@ -356,6 +395,10 @@ MINIZ_EXPORT int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const u
|
||||
/* mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress(). */
|
||||
MINIZ_EXPORT mz_ulong mz_compressBound(mz_ulong source_len);
|
||||
|
||||
#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/
|
||||
|
||||
#ifndef MINIZ_NO_INFLATE_APIS
|
||||
|
||||
/* Initializes a decompressor. */
|
||||
MINIZ_EXPORT int mz_inflateInit(mz_streamp pStream);
|
||||
|
||||
@ -389,6 +432,7 @@ MINIZ_EXPORT int mz_inflateEnd(mz_streamp pStream);
|
||||
/* Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure. */
|
||||
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. */
|
||||
MINIZ_EXPORT const char *mz_error(int err);
|
||||
@ -435,37 +479,116 @@ typedef void *const voidpc;
|
||||
#define Z_FIXED MZ_FIXED
|
||||
#define Z_DEFLATED MZ_DEFLATED
|
||||
#define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS
|
||||
#define alloc_func mz_alloc_func
|
||||
#define free_func mz_free_func
|
||||
/* See mz_alloc_func */
|
||||
typedef void *(*alloc_func)(void *opaque, size_t items, size_t size);
|
||||
/* See mz_free_func */
|
||||
typedef void (*free_func)(void *opaque, void *address);
|
||||
|
||||
#define internal_state mz_internal_state
|
||||
#define z_stream mz_stream
|
||||
#define deflateInit mz_deflateInit
|
||||
#define deflateInit2 mz_deflateInit2
|
||||
#define deflateReset mz_deflateReset
|
||||
#define deflate mz_deflate
|
||||
#define deflateEnd mz_deflateEnd
|
||||
#define deflateBound mz_deflateBound
|
||||
#define compress mz_compress
|
||||
#define compress2 mz_compress2
|
||||
#define compressBound mz_compressBound
|
||||
#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
|
||||
#define crc32 mz_crc32
|
||||
#define adler32 mz_adler32
|
||||
|
||||
#ifndef MINIZ_NO_DEFLATE_APIS
|
||||
/* Compatiblity with zlib API. See called functions for documentation */
|
||||
static int deflateInit(mz_streamp pStream, int level)
|
||||
{
|
||||
return mz_deflateInit(pStream, level);
|
||||
}
|
||||
static int deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy)
|
||||
{
|
||||
return mz_deflateInit2(pStream, level, method, window_bits, mem_level, strategy);
|
||||
}
|
||||
static int deflateReset(mz_streamp pStream)
|
||||
{
|
||||
return mz_deflateReset(pStream);
|
||||
}
|
||||
static int deflate(mz_streamp pStream, int flush)
|
||||
{
|
||||
return mz_deflate(pStream, flush);
|
||||
}
|
||||
static int deflateEnd(mz_streamp pStream)
|
||||
{
|
||||
return mz_deflateEnd(pStream);
|
||||
}
|
||||
static mz_ulong deflateBound(mz_streamp pStream, mz_ulong source_len)
|
||||
{
|
||||
return mz_deflateBound(pStream, source_len);
|
||||
}
|
||||
static int compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
|
||||
{
|
||||
return mz_compress(pDest, pDest_len, pSource, source_len);
|
||||
}
|
||||
static int compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level)
|
||||
{
|
||||
return mz_compress2(pDest, pDest_len, pSource, source_len, level);
|
||||
}
|
||||
static mz_ulong compressBound(mz_ulong source_len)
|
||||
{
|
||||
return mz_compressBound(source_len);
|
||||
}
|
||||
#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/
|
||||
|
||||
#ifndef MINIZ_NO_INFLATE_APIS
|
||||
/* Compatiblity with zlib API. See called functions for documentation */
|
||||
static int inflateInit(mz_streamp pStream)
|
||||
{
|
||||
return mz_inflateInit(pStream);
|
||||
}
|
||||
|
||||
static int inflateInit2(mz_streamp pStream, int window_bits)
|
||||
{
|
||||
return mz_inflateInit2(pStream, window_bits);
|
||||
}
|
||||
|
||||
static int inflateReset(mz_streamp pStream)
|
||||
{
|
||||
return mz_inflateReset(pStream);
|
||||
}
|
||||
|
||||
static int inflate(mz_streamp pStream, int flush)
|
||||
{
|
||||
return mz_inflate(pStream, flush);
|
||||
}
|
||||
|
||||
static int inflateEnd(mz_streamp pStream)
|
||||
{
|
||||
return mz_inflateEnd(pStream);
|
||||
}
|
||||
|
||||
static int uncompress(unsigned char* pDest, mz_ulong* pDest_len, const unsigned char* pSource, mz_ulong source_len)
|
||||
{
|
||||
return mz_uncompress(pDest, pDest_len, pSource, source_len);
|
||||
}
|
||||
|
||||
static int uncompress2(unsigned char* pDest, mz_ulong* pDest_len, const unsigned char* pSource, mz_ulong* pSource_len)
|
||||
{
|
||||
return mz_uncompress2(pDest, pDest_len, pSource, pSource_len);
|
||||
}
|
||||
#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/
|
||||
|
||||
static mz_ulong crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len)
|
||||
{
|
||||
return mz_crc32(crc, ptr, buf_len);
|
||||
}
|
||||
|
||||
static mz_ulong adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len)
|
||||
{
|
||||
return mz_adler32(adler, ptr, buf_len);
|
||||
}
|
||||
|
||||
#define MAX_WBITS 15
|
||||
#define MAX_MEM_LEVEL 9
|
||||
#define zError mz_error
|
||||
|
||||
static const char* zError(int err)
|
||||
{
|
||||
return mz_error(err);
|
||||
}
|
||||
#define ZLIB_VERSION MZ_VERSION
|
||||
#define ZLIB_VERNUM MZ_VERNUM
|
||||
#define ZLIB_VER_MAJOR MZ_VER_MAJOR
|
||||
#define ZLIB_VER_MINOR MZ_VER_MINOR
|
||||
#define ZLIB_VER_REVISION MZ_VER_REVISION
|
||||
#define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION
|
||||
|
||||
#define zlibVersion mz_version
|
||||
#define zlib_version mz_version()
|
||||
#endif /* #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES */
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/@CMAKE_INSTALL_LIBDIR@
|
||||
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@
|
||||
includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@/@PROJECT_NAME@
|
||||
|
||||
Name: @PROJECT_NAME@
|
||||
Description: @PROJECT_DESCRIPTION@
|
||||
|
||||
@ -8,10 +8,10 @@
|
||||
|
||||
/* ------------------- Types and macros */
|
||||
typedef unsigned char mz_uint8;
|
||||
typedef signed short mz_int16;
|
||||
typedef unsigned short mz_uint16;
|
||||
typedef unsigned int mz_uint32;
|
||||
typedef unsigned int mz_uint;
|
||||
typedef int16_t mz_int16;
|
||||
typedef uint16_t mz_uint16;
|
||||
typedef uint32_t mz_uint32;
|
||||
typedef uint32_t mz_uint;
|
||||
typedef int64_t mz_int64;
|
||||
typedef uint64_t mz_uint64;
|
||||
typedef int mz_bool;
|
||||
@ -36,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
|
||||
@ -58,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))
|
||||
@ -78,7 +81,8 @@ typedef struct mz_dummy_time_t_tag
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
extern MINIZ_EXPORT void *miniz_def_alloc_func(void *opaque, size_t items, size_t size);
|
||||
|
||||
80
miniz_tdef.c
80
miniz_tdef.c
@ -26,15 +26,17 @@
|
||||
|
||||
#include "miniz.h"
|
||||
|
||||
#ifndef MINIZ_NO_DEFLATE_APIS
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* ------------------- Low-level Compression (independent from all decompression API's) */
|
||||
|
||||
/* Purposely making these tables static for faster init and thread safety. */
|
||||
static const mz_uint16 s_tdefl_len_sym[256] =
|
||||
{
|
||||
static const mz_uint16 s_tdefl_len_sym[256] = {
|
||||
257, 258, 259, 260, 261, 262, 263, 264, 265, 265, 266, 266, 267, 267, 268, 268, 269, 269, 269, 269, 270, 270, 270, 270, 271, 271, 271, 271, 272, 272, 272, 272,
|
||||
273, 273, 273, 273, 273, 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, 274, 275, 275, 275, 275, 275, 275, 275, 275, 276, 276, 276, 276, 276, 276, 276, 276,
|
||||
277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
|
||||
@ -45,16 +47,14 @@ static const mz_uint16 s_tdefl_len_sym[256] =
|
||||
284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 285
|
||||
};
|
||||
|
||||
static const mz_uint8 s_tdefl_len_extra[256] =
|
||||
{
|
||||
static const mz_uint8 s_tdefl_len_extra[256] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0
|
||||
};
|
||||
|
||||
static const mz_uint8 s_tdefl_small_dist_sym[512] =
|
||||
{
|
||||
static const mz_uint8 s_tdefl_small_dist_sym[512] = {
|
||||
0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11,
|
||||
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
|
||||
@ -69,8 +69,7 @@ static const mz_uint8 s_tdefl_small_dist_sym[512] =
|
||||
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17
|
||||
};
|
||||
|
||||
static const mz_uint8 s_tdefl_small_dist_extra[512] =
|
||||
{
|
||||
static const mz_uint8 s_tdefl_small_dist_extra[512] = {
|
||||
0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
@ -81,15 +80,13 @@ static const mz_uint8 s_tdefl_small_dist_extra[512] =
|
||||
7, 7, 7, 7, 7, 7, 7, 7
|
||||
};
|
||||
|
||||
static const mz_uint8 s_tdefl_large_dist_sym[128] =
|
||||
{
|
||||
static const mz_uint8 s_tdefl_large_dist_sym[128] = {
|
||||
0, 0, 18, 19, 20, 20, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
|
||||
26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
|
||||
28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
|
||||
};
|
||||
|
||||
static const mz_uint8 s_tdefl_large_dist_extra[128] =
|
||||
{
|
||||
static const mz_uint8 s_tdefl_large_dist_extra[128] = {
|
||||
0, 0, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
|
||||
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
|
||||
13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13
|
||||
@ -104,7 +101,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;
|
||||
@ -222,7 +219,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++)
|
||||
@ -248,8 +245,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);
|
||||
@ -335,7 +332,7 @@ static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int
|
||||
} \
|
||||
}
|
||||
|
||||
static mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
|
||||
static const mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
|
||||
|
||||
static void tdefl_start_dynamic_block(tdefl_compressor *d)
|
||||
{
|
||||
@ -473,7 +470,8 @@ static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d)
|
||||
if (flags & 1)
|
||||
{
|
||||
mz_uint s0, s1, n0, n1, sym, num_extra_bits;
|
||||
mz_uint match_len = pLZ_codes[0], match_dist = *(const mz_uint16 *)(pLZ_codes + 1);
|
||||
mz_uint match_len = pLZ_codes[0];
|
||||
mz_uint match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8));
|
||||
pLZ_codes += 3;
|
||||
|
||||
MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
|
||||
@ -518,7 +516,7 @@ static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d)
|
||||
if (pOutput_buf >= d->m_pOutput_buf_end)
|
||||
return MZ_FALSE;
|
||||
|
||||
*(mz_uint64 *)pOutput_buf = bit_buffer;
|
||||
memcpy(pOutput_buf, &bit_buffer, sizeof(mz_uint64));
|
||||
pOutput_buf += (bits_in >> 3);
|
||||
bit_buffer >>= (bits_in & ~7);
|
||||
bits_in &= 7;
|
||||
@ -600,6 +598,8 @@ static mz_bool tdefl_compress_block(tdefl_compressor *d, mz_bool static_block)
|
||||
return tdefl_compress_lz_codes(d);
|
||||
}
|
||||
|
||||
static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 };
|
||||
|
||||
static int tdefl_flush_block(tdefl_compressor *d, int flush)
|
||||
{
|
||||
mz_uint saved_bit_buf, saved_bits_in;
|
||||
@ -620,8 +620,28 @@ static int tdefl_flush_block(tdefl_compressor *d, int flush)
|
||||
|
||||
if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index))
|
||||
{
|
||||
TDEFL_PUT_BITS(0x78, 8);
|
||||
TDEFL_PUT_BITS(0x01, 8);
|
||||
const mz_uint8 cmf = 0x78;
|
||||
mz_uint8 flg, flevel = 3;
|
||||
mz_uint header, i, mz_un = sizeof(s_tdefl_num_probes) / sizeof(mz_uint);
|
||||
|
||||
/* Determine compression level by reversing the process in tdefl_create_comp_flags_from_zip_params() */
|
||||
for (i = 0; i < mz_un; i++)
|
||||
if (s_tdefl_num_probes[i] == (d->m_flags & 0xFFF))
|
||||
break;
|
||||
|
||||
if (i < 2)
|
||||
flevel = 0;
|
||||
else if (i < 6)
|
||||
flevel = 1;
|
||||
else if (i == 6)
|
||||
flevel = 2;
|
||||
|
||||
header = cmf << 8 | (flevel << 6);
|
||||
header += 31 - (header % 31);
|
||||
flg = header & 0xFF;
|
||||
|
||||
TDEFL_PUT_BITS(cmf, 8);
|
||||
TDEFL_PUT_BITS(flg, 8);
|
||||
}
|
||||
|
||||
TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1);
|
||||
@ -1092,7 +1112,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)
|
||||
@ -1302,8 +1322,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;
|
||||
}
|
||||
}
|
||||
@ -1326,7 +1346,7 @@ 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;
|
||||
@ -1347,7 +1367,7 @@ tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_fun
|
||||
d->m_src_buf_left = 0;
|
||||
d->m_out_buf_ofs = 0;
|
||||
if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG))
|
||||
MZ_CLEAR_OBJ(d->m_dict);
|
||||
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;
|
||||
@ -1438,8 +1458,6 @@ size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void
|
||||
return out_buf.m_size;
|
||||
}
|
||||
|
||||
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). */
|
||||
mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy)
|
||||
{
|
||||
@ -1557,7 +1575,7 @@ void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h,
|
||||
/* 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));
|
||||
}
|
||||
@ -1575,3 +1593,5 @@ void tdefl_compressor_free(tdefl_compressor *pComp)
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/
|
||||
|
||||
17
miniz_tdef.h
17
miniz_tdef.h
@ -1,13 +1,18 @@
|
||||
#pragma once
|
||||
#include "miniz_common.h"
|
||||
|
||||
#ifndef MINIZ_NO_DEFLATE_APIS
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
/* ------------------- Low-level Compression API Definitions */
|
||||
|
||||
/* Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly slower, and raw/dynamic blocks will be output more frequently). */
|
||||
#ifndef TDEFL_LESS_MEMORY
|
||||
#define TDEFL_LESS_MEMORY 0
|
||||
#endif
|
||||
|
||||
/* tdefl_init() compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search): */
|
||||
/* TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap compression), 4095=Huffman+LZ (slowest/best compression). */
|
||||
@ -101,7 +106,7 @@ enum
|
||||
enum
|
||||
{
|
||||
TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024,
|
||||
TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10,
|
||||
TDEFL_OUT_BUF_SIZE = (mz_uint)((TDEFL_LZ_CODE_BUF_SIZE * 13) / 10),
|
||||
TDEFL_MAX_HUFF_SYMBOLS = 288,
|
||||
TDEFL_LZ_HASH_BITS = 15,
|
||||
TDEFL_LEVEL1_HASH_SIZE_MASK = 4095,
|
||||
@ -111,7 +116,8 @@ 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,
|
||||
@ -119,7 +125,8 @@ 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,
|
||||
@ -188,3 +195,5 @@ MINIZ_EXPORT void tdefl_compressor_free(tdefl_compressor *pComp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/
|
||||
|
||||
126
miniz_tinfl.c
126
miniz_tinfl.c
@ -26,8 +26,11 @@
|
||||
|
||||
#include "miniz.h"
|
||||
|
||||
#ifndef MINIZ_NO_INFLATE_APIS
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* ------------------- Low-level Decompression (completely independent from all compression API's) */
|
||||
@ -106,10 +109,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; \
|
||||
@ -121,7 +124,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; \
|
||||
@ -137,7 +140,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; \
|
||||
@ -146,7 +149,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 \
|
||||
{ \
|
||||
@ -155,14 +158,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; \
|
||||
@ -171,20 +174,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). */
|
||||
@ -194,6 +210,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;
|
||||
@ -210,7 +233,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
|
||||
TINFL_GET_BYTE(2, r->m_zhdr1);
|
||||
counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8));
|
||||
if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
|
||||
counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1U << (8U + (r->m_zhdr0 >> 4)))));
|
||||
counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)((size_t)1 << (8U + (r->m_zhdr0 >> 4)))));
|
||||
if (counter)
|
||||
{
|
||||
TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED);
|
||||
@ -271,11 +294,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)
|
||||
@ -292,26 +315,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)
|
||||
@ -325,7 +352,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]++;
|
||||
@ -336,14 +363,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;
|
||||
}
|
||||
@ -351,24 +378,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;
|
||||
@ -388,8 +415,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 (;;)
|
||||
@ -399,7 +426,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)
|
||||
@ -427,14 +454,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;
|
||||
@ -451,19 +478,25 @@ 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;
|
||||
num_bits -= code_len;
|
||||
|
||||
/* assert(sym2 != 0 && counter != 0); */
|
||||
if (sym2 == 0 && counter == 0)
|
||||
{
|
||||
TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED);
|
||||
}
|
||||
|
||||
pOut_buf_cur[0] = (mz_uint8)counter;
|
||||
if (sym2 & 256)
|
||||
{
|
||||
@ -487,7 +520,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)
|
||||
@ -572,7 +605,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)
|
||||
@ -604,7 +637,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;
|
||||
@ -699,6 +732,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 (;;)
|
||||
{
|
||||
@ -721,7 +755,7 @@ int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size,
|
||||
}
|
||||
|
||||
#ifndef MINIZ_NO_MALLOC
|
||||
tinfl_decompressor *tinfl_decompressor_alloc()
|
||||
tinfl_decompressor *tinfl_decompressor_alloc(void)
|
||||
{
|
||||
tinfl_decompressor *pDecomp = (tinfl_decompressor *)MZ_MALLOC(sizeof(tinfl_decompressor));
|
||||
if (pDecomp)
|
||||
@ -738,3 +772,5 @@ void tinfl_decompressor_free(tinfl_decompressor *pDecomp)
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/
|
||||
|
||||
@ -2,8 +2,11 @@
|
||||
#include "miniz_common.h"
|
||||
/* ------------------- Low-level Decompression API Definitions */
|
||||
|
||||
#ifndef MINIZ_NO_INFLATE_APIS
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
/* Decompression flags used by tinfl_decompress(). */
|
||||
/* TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream. */
|
||||
@ -53,7 +56,8 @@ MINIZ_EXPORT void tinfl_decompressor_free(tinfl_decompressor *pDecomp);
|
||||
#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. */
|
||||
@ -110,12 +114,6 @@ 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
|
||||
@ -135,10 +133,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*/
|
||||
|
||||
283
miniz_zip.c
283
miniz_zip.c
@ -29,7 +29,8 @@
|
||||
#ifndef MINIZ_NO_ARCHIVE_APIS
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* ------------------- .ZIP archive reading */
|
||||
@ -39,20 +40,67 @@ extern "C" {
|
||||
#else
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW64__)
|
||||
#if defined(_MSC_VER) || defined(__MINGW64__) || defined(__MINGW32__)
|
||||
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#ifndef __cplusplus
|
||||
#define MICROSOFT_WINDOWS_WINBASE_H_DEFINE_INTERLOCKED_CPLUSPLUS_OVERLOADS 0
|
||||
#endif
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
static WCHAR *mz_utf8z_to_widechar(const char *str)
|
||||
{
|
||||
int reqChars = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
|
||||
WCHAR *wStr = (WCHAR *)malloc(reqChars * sizeof(WCHAR));
|
||||
MultiByteToWideChar(CP_UTF8, 0, str, -1, wStr, reqChars);
|
||||
return wStr;
|
||||
}
|
||||
|
||||
static FILE *mz_fopen(const char *pFilename, const char *pMode)
|
||||
{
|
||||
WCHAR *wFilename = mz_utf8z_to_widechar(pFilename);
|
||||
WCHAR *wMode = mz_utf8z_to_widechar(pMode);
|
||||
FILE *pFile = NULL;
|
||||
fopen_s(&pFile, pFilename, pMode);
|
||||
return pFile;
|
||||
errno_t err = _wfopen_s(&pFile, wFilename, wMode);
|
||||
free(wFilename);
|
||||
free(wMode);
|
||||
return err ? NULL : pFile;
|
||||
}
|
||||
|
||||
static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream)
|
||||
{
|
||||
WCHAR *wPath = mz_utf8z_to_widechar(pPath);
|
||||
WCHAR *wMode = mz_utf8z_to_widechar(pMode);
|
||||
FILE *pFile = NULL;
|
||||
if (freopen_s(&pFile, pPath, pMode, pStream))
|
||||
return NULL;
|
||||
return pFile;
|
||||
errno_t err = _wfreopen_s(&pFile, wPath, wMode, pStream);
|
||||
free(wPath);
|
||||
free(wMode);
|
||||
return err ? NULL : pFile;
|
||||
}
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
static int mz_stat(const char *path, struct _stat *buffer)
|
||||
{
|
||||
WCHAR *wPath = mz_utf8z_to_widechar(path);
|
||||
int res = _wstat(wPath, buffer);
|
||||
free(wPath);
|
||||
return res;
|
||||
}
|
||||
#else
|
||||
static int mz_stat64(const char *path, struct __stat64 *buffer)
|
||||
{
|
||||
WCHAR *wPath = mz_utf8z_to_widechar(path);
|
||||
int res = _wstat64(wPath, buffer);
|
||||
free(wPath);
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef MINIZ_NO_TIME
|
||||
#include <sys/utime.h>
|
||||
#endif
|
||||
@ -62,12 +110,18 @@ static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream)
|
||||
#define MZ_FWRITE fwrite
|
||||
#define MZ_FTELL64 _ftelli64
|
||||
#define MZ_FSEEK64 _fseeki64
|
||||
#if defined(__MINGW32__)
|
||||
#define MZ_FILE_STAT_STRUCT _stat
|
||||
#define MZ_FILE_STAT mz_stat
|
||||
#else
|
||||
#define MZ_FILE_STAT_STRUCT _stat64
|
||||
#define MZ_FILE_STAT _stat64
|
||||
#define MZ_FILE_STAT mz_stat64
|
||||
#endif
|
||||
#define MZ_FFLUSH fflush
|
||||
#define MZ_FREOPEN mz_freopen
|
||||
#define MZ_DELETE_FILE remove
|
||||
#elif defined(__MINGW32__)
|
||||
|
||||
#elif defined(__WATCOMC__)
|
||||
#ifndef MINIZ_NO_TIME
|
||||
#include <sys/utime.h>
|
||||
#endif
|
||||
@ -75,13 +129,14 @@ static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream)
|
||||
#define MZ_FCLOSE fclose
|
||||
#define MZ_FREAD fread
|
||||
#define MZ_FWRITE fwrite
|
||||
#define MZ_FTELL64 ftello64
|
||||
#define MZ_FSEEK64 fseeko64
|
||||
#define MZ_FILE_STAT_STRUCT _stat
|
||||
#define MZ_FILE_STAT _stat
|
||||
#define MZ_FTELL64 _ftelli64
|
||||
#define MZ_FSEEK64 _fseeki64
|
||||
#define MZ_FILE_STAT_STRUCT stat
|
||||
#define MZ_FILE_STAT stat
|
||||
#define MZ_FFLUSH fflush
|
||||
#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
|
||||
#define MZ_DELETE_FILE remove
|
||||
|
||||
#elif defined(__TINYC__)
|
||||
#ifndef MINIZ_NO_TIME
|
||||
#include <sys/utime.h>
|
||||
@ -97,6 +152,7 @@ static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream)
|
||||
#define MZ_FFLUSH fflush
|
||||
#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
|
||||
#define MZ_DELETE_FILE remove
|
||||
|
||||
#elif defined(__USE_LARGEFILE64) /* gcc, clang */
|
||||
#ifndef MINIZ_NO_TIME
|
||||
#include <utime.h>
|
||||
@ -112,7 +168,8 @@ static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream)
|
||||
#define MZ_FFLUSH fflush
|
||||
#define MZ_FREOPEN(p, m, s) freopen64(p, m, s)
|
||||
#define MZ_DELETE_FILE remove
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
#elif defined(__APPLE__) || defined(__FreeBSD__) || (defined(__linux__) && defined(__x86_64__))
|
||||
#ifndef MINIZ_NO_TIME
|
||||
#include <utime.h>
|
||||
#endif
|
||||
@ -258,7 +315,7 @@ struct mz_zip_internal_state_tag
|
||||
mz_zip_array m_sorted_central_dir_offsets;
|
||||
|
||||
/* The flags passed in when the archive is initially opened. */
|
||||
uint32_t m_init_flags;
|
||||
mz_uint32 m_init_flags;
|
||||
|
||||
/* MZ_TRUE if the archive has a zip64 end of central directory headers, etc. */
|
||||
mz_bool m_zip64;
|
||||
@ -580,7 +637,7 @@ static mz_bool mz_zip_reader_locate_header_sig(mz_zip_archive *pZip, mz_uint32 r
|
||||
}
|
||||
|
||||
/* Give up if we've searched the entire file, or we've gone back "too far" (~64kb) */
|
||||
if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >= (MZ_UINT16_MAX + record_size)))
|
||||
if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >= ((mz_uint64)(MZ_UINT16_MAX) + record_size)))
|
||||
return MZ_FALSE;
|
||||
|
||||
cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0);
|
||||
@ -590,10 +647,23 @@ static mz_bool mz_zip_reader_locate_header_sig(mz_zip_archive *pZip, mz_uint32 r
|
||||
return MZ_TRUE;
|
||||
}
|
||||
|
||||
static mz_bool mz_zip_reader_eocd64_valid(mz_zip_archive *pZip, uint64_t offset, uint8_t *buf)
|
||||
{
|
||||
if (pZip->m_pRead(pZip->m_pIO_opaque, offset, buf, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) == MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)
|
||||
{
|
||||
if (MZ_READ_LE32(buf + MZ_ZIP64_ECDH_SIG_OFS) == MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG)
|
||||
{
|
||||
return MZ_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return MZ_FALSE;
|
||||
}
|
||||
|
||||
static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flags)
|
||||
{
|
||||
mz_uint cdir_size = 0, cdir_entries_on_this_disk = 0, num_this_disk = 0, cdir_disk_index = 0;
|
||||
mz_uint64 cdir_ofs = 0;
|
||||
mz_uint64 cdir_ofs = 0, eocd_ofs = 0, archive_ofs = 0;
|
||||
mz_int64 cur_file_ofs = 0;
|
||||
const mz_uint8 *p;
|
||||
|
||||
@ -615,6 +685,7 @@ static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flag
|
||||
if (!mz_zip_reader_locate_header_sig(pZip, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE, &cur_file_ofs))
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_FAILED_FINDING_CENTRAL_DIR);
|
||||
|
||||
eocd_ofs = cur_file_ofs;
|
||||
/* Read and verify the end of central directory record. */
|
||||
if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
|
||||
@ -627,19 +698,38 @@ static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flag
|
||||
if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs - MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE, pZip64_locator, MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) == MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE)
|
||||
{
|
||||
if (MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_SIG_OFS) == MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG)
|
||||
{
|
||||
zip64_end_of_central_dir_ofs = MZ_READ_LE64(pZip64_locator + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS);
|
||||
if (zip64_end_of_central_dir_ofs > (pZip->m_archive_size - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE))
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
|
||||
|
||||
if (pZip->m_pRead(pZip->m_pIO_opaque, zip64_end_of_central_dir_ofs, pZip64_end_of_central_dir, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) == MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)
|
||||
{
|
||||
if (MZ_READ_LE32(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_SIG_OFS) == MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG)
|
||||
{
|
||||
pZip->m_pState->m_zip64 = MZ_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pZip->m_pState->m_zip64)
|
||||
{
|
||||
/* Try locating the EOCD64 right before the EOCD64 locator. This works even
|
||||
* when the effective start of the zip header is not yet known. */
|
||||
if (cur_file_ofs < MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE +
|
||||
MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
|
||||
|
||||
zip64_end_of_central_dir_ofs = cur_file_ofs -
|
||||
MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE -
|
||||
MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE;
|
||||
|
||||
if (!mz_zip_reader_eocd64_valid(pZip, zip64_end_of_central_dir_ofs,
|
||||
pZip64_end_of_central_dir))
|
||||
{
|
||||
/* That failed, try reading where the locator tells us to. */
|
||||
zip64_end_of_central_dir_ofs = MZ_READ_LE64(
|
||||
pZip64_locator + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS);
|
||||
|
||||
if (zip64_end_of_central_dir_ofs >
|
||||
(pZip->m_archive_size - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE))
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
|
||||
|
||||
if (!mz_zip_reader_eocd64_valid(pZip, zip64_end_of_central_dir_ofs,
|
||||
pZip64_end_of_central_dir))
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -694,12 +784,36 @@ static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flag
|
||||
if (((num_this_disk | cdir_disk_index) != 0) && ((num_this_disk != 1) || (cdir_disk_index != 1)))
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK);
|
||||
|
||||
if (cdir_size < pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)
|
||||
if (cdir_size < (mz_uint64)pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
|
||||
|
||||
if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size)
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
|
||||
|
||||
if (eocd_ofs < cdir_ofs + cdir_size)
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
|
||||
|
||||
/* The end of central dir follows the central dir, unless the zip file has
|
||||
* some trailing data (e.g. it is appended to an executable file). */
|
||||
archive_ofs = eocd_ofs - (cdir_ofs + cdir_size);
|
||||
if (pZip->m_pState->m_zip64)
|
||||
{
|
||||
if (archive_ofs < MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE +
|
||||
MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE)
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
|
||||
|
||||
archive_ofs -= MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE +
|
||||
MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE;
|
||||
}
|
||||
|
||||
/* Update the archive start position, but only if not specified. */
|
||||
if ((pZip->m_zip_type == MZ_ZIP_TYPE_FILE || pZip->m_zip_type == MZ_ZIP_TYPE_CFILE ||
|
||||
pZip->m_zip_type == MZ_ZIP_TYPE_USER) && pZip->m_pState->m_file_archive_start_ofs == 0)
|
||||
{
|
||||
pZip->m_pState->m_file_archive_start_ofs = archive_ofs;
|
||||
pZip->m_archive_size -= archive_ofs;
|
||||
}
|
||||
|
||||
pZip->m_central_directory_file_ofs = cdir_ofs;
|
||||
|
||||
if (pZip->m_total_files)
|
||||
@ -845,7 +959,7 @@ static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flag
|
||||
void mz_zip_zero_struct(mz_zip_archive *pZip)
|
||||
{
|
||||
if (pZip)
|
||||
MZ_CLEAR_OBJ(*pZip);
|
||||
MZ_CLEAR_PTR(pZip);
|
||||
}
|
||||
|
||||
static mz_bool mz_zip_reader_end_internal(mz_zip_archive *pZip, mz_bool set_last_error)
|
||||
@ -988,7 +1102,7 @@ mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, const char *pFilename,
|
||||
if ((!pZip) || (!pFilename) || ((archive_size) && (archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)))
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
|
||||
|
||||
pFile = MZ_FOPEN(pFilename, "rb");
|
||||
pFile = MZ_FOPEN(pFilename, (flags & MZ_ZIP_FLAG_READ_ALLOW_WRITING ) ? "r+b" : "rb");
|
||||
if (!pFile)
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);
|
||||
|
||||
@ -1319,7 +1433,7 @@ static mz_bool mz_zip_locate_file_binary_search(mz_zip_archive *pZip, const char
|
||||
const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
|
||||
const mz_zip_array *pCentral_dir = &pState->m_central_dir;
|
||||
mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0);
|
||||
const uint32_t size = pZip->m_total_files;
|
||||
const mz_uint32 size = pZip->m_total_files;
|
||||
const mz_uint filename_len = (mz_uint)strlen(pFilename);
|
||||
|
||||
if (pIndex)
|
||||
@ -1334,7 +1448,7 @@ static mz_bool mz_zip_locate_file_binary_search(mz_zip_archive *pZip, const char
|
||||
while (l <= h)
|
||||
{
|
||||
mz_int64 m = l + ((h - l) >> 1);
|
||||
uint32_t file_index = pIndices[(uint32_t)m];
|
||||
mz_uint32 file_index = pIndices[(mz_uint32)m];
|
||||
|
||||
int comp = mz_zip_filename_compare(pCentral_dir, pCentral_dir_offsets, file_index, pFilename, filename_len);
|
||||
if (!comp)
|
||||
@ -1427,7 +1541,7 @@ mz_bool mz_zip_reader_locate_file_v2(mz_zip_archive *pZip, const char *pName, co
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_FILE_NOT_FOUND);
|
||||
}
|
||||
|
||||
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)
|
||||
static mz_bool mz_zip_reader_extract_to_mem_no_alloc1(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, const mz_zip_archive_file_stat *st)
|
||||
{
|
||||
int status = TINFL_STATUS_DONE;
|
||||
mz_uint64 needed_size, cur_file_ofs, comp_remaining, out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail;
|
||||
@ -1440,7 +1554,11 @@ mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file
|
||||
if ((!pZip) || (!pZip->m_pState) || ((buf_size) && (!pBuf)) || ((user_read_buf_size) && (!pUser_read_buf)) || (!pZip->m_pRead))
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
|
||||
|
||||
if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
|
||||
if (st)
|
||||
{
|
||||
file_stat = *st;
|
||||
}
|
||||
else if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
|
||||
return MZ_FALSE;
|
||||
|
||||
/* A directory or zero length file */
|
||||
@ -1468,7 +1586,7 @@ mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file
|
||||
if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
|
||||
|
||||
cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
|
||||
cur_file_ofs += (mz_uint64)(MZ_ZIP_LOCAL_DIR_HEADER_SIZE) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
|
||||
if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
|
||||
|
||||
@ -1570,17 +1688,22 @@ mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file
|
||||
return status == TINFL_STATUS_DONE;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return mz_zip_reader_extract_to_mem_no_alloc1(pZip, file_index, pBuf, buf_size, flags, pUser_read_buf, user_read_buf_size, NULL);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
mz_uint32 file_index;
|
||||
if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index))
|
||||
return MZ_FALSE;
|
||||
return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, pUser_read_buf, user_read_buf_size);
|
||||
return mz_zip_reader_extract_to_mem_no_alloc1(pZip, file_index, pBuf, buf_size, flags, pUser_read_buf, user_read_buf_size, NULL);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, NULL, 0);
|
||||
return mz_zip_reader_extract_to_mem_no_alloc1(pZip, file_index, pBuf, buf_size, flags, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
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)
|
||||
@ -1590,23 +1713,17 @@ mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFil
|
||||
|
||||
void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags)
|
||||
{
|
||||
mz_uint64 comp_size, uncomp_size, alloc_size;
|
||||
const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
|
||||
mz_zip_archive_file_stat file_stat;
|
||||
mz_uint64 alloc_size;
|
||||
void *pBuf;
|
||||
|
||||
if (pSize)
|
||||
*pSize = 0;
|
||||
|
||||
if (!p)
|
||||
{
|
||||
mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
|
||||
if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
|
||||
uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
|
||||
|
||||
alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size;
|
||||
alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size : file_stat.m_uncomp_size;
|
||||
if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
|
||||
{
|
||||
mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
|
||||
@ -1619,7 +1736,7 @@ void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, si
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!mz_zip_reader_extract_to_mem(pZip, file_index, pBuf, (size_t)alloc_size, flags))
|
||||
if (!mz_zip_reader_extract_to_mem_no_alloc1(pZip, file_index, pBuf, (size_t)alloc_size, flags, NULL, 0, &file_stat))
|
||||
{
|
||||
pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
|
||||
return NULL;
|
||||
@ -1681,7 +1798,7 @@ mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_ind
|
||||
if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
|
||||
|
||||
cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
|
||||
cur_file_ofs += (mz_uint64)(MZ_ZIP_LOCAL_DIR_HEADER_SIZE) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
|
||||
if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
|
||||
|
||||
@ -1923,7 +2040,7 @@ mz_zip_reader_extract_iter_state* mz_zip_reader_extract_iter_new(mz_zip_archive
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pState->cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
|
||||
pState->cur_file_ofs += (mz_uint64)(MZ_ZIP_LOCAL_DIR_HEADER_SIZE) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
|
||||
if ((pState->cur_file_ofs + pState->file_stat.m_comp_size) > pZip->m_archive_size)
|
||||
{
|
||||
mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
|
||||
@ -2080,7 +2197,7 @@ size_t mz_zip_reader_extract_iter_read(mz_zip_reader_extract_iter_state* pState,
|
||||
size_t to_copy = MZ_MIN((buf_size - copied_to_caller), pState->out_blk_remain);
|
||||
|
||||
/* Copy data to caller's buffer */
|
||||
memcpy( (uint8_t*)pvBuf + copied_to_caller, pWrite_buf_cur, to_copy );
|
||||
memcpy((mz_uint8 *)pvBuf + copied_to_caller, pWrite_buf_cur, to_copy);
|
||||
|
||||
#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
|
||||
/* Perform CRC */
|
||||
@ -2449,7 +2566,7 @@ handle_failure:
|
||||
mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags)
|
||||
{
|
||||
mz_zip_internal_state *pState;
|
||||
uint32_t i;
|
||||
mz_uint32 i;
|
||||
|
||||
if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (!pZip->m_pRead))
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
|
||||
@ -2467,9 +2584,6 @@ mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pZip->m_total_files >= MZ_UINT32_MAX)
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
|
||||
|
||||
if (pState->m_central_dir.m_size >= MZ_UINT32_MAX)
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
|
||||
}
|
||||
@ -2831,7 +2945,7 @@ mz_bool mz_zip_writer_init_file_v2(mz_zip_archive *pZip, const char *pFilename,
|
||||
mz_uint64 cur_ofs = 0;
|
||||
char buf[4096];
|
||||
|
||||
MZ_CLEAR_OBJ(buf);
|
||||
MZ_CLEAR_ARR(buf);
|
||||
|
||||
do
|
||||
{
|
||||
@ -2910,7 +3024,8 @@ mz_bool mz_zip_writer_init_from_reader_v2(mz_zip_archive *pZip, const char *pFil
|
||||
if (pZip->m_pIO_opaque != pZip)
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
|
||||
|
||||
if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE)
|
||||
if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE &&
|
||||
!(flags & MZ_ZIP_FLAG_READ_ALLOW_WRITING) )
|
||||
{
|
||||
if (!pFilename)
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
|
||||
@ -3194,7 +3309,7 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n
|
||||
pState->m_zip64 = MZ_TRUE;
|
||||
/*return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES); */
|
||||
}
|
||||
if ((buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF))
|
||||
if (((mz_uint64)buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF))
|
||||
{
|
||||
pState->m_zip64 = MZ_TRUE;
|
||||
/*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
|
||||
@ -3218,6 +3333,8 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n
|
||||
time(&cur_time);
|
||||
mz_zip_time_t_to_dos_time(cur_time, &dos_time, &dos_date);
|
||||
}
|
||||
#else
|
||||
(void)last_modified;
|
||||
#endif /* #ifndef MINIZ_NO_TIME */
|
||||
|
||||
if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
|
||||
@ -3244,10 +3361,8 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n
|
||||
if (!pState->m_zip64)
|
||||
{
|
||||
/* Bail early if the archive would obviously become too large */
|
||||
if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size
|
||||
+ MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + user_extra_data_len +
|
||||
pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + user_extra_data_central_len
|
||||
+ MZ_ZIP_DATA_DESCRIPTER_SIZE32) > 0xFFFFFFFF)
|
||||
if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + user_extra_data_len +
|
||||
pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + user_extra_data_central_len + MZ_ZIP_DATA_DESCRIPTER_SIZE32) > 0xFFFFFFFF)
|
||||
{
|
||||
pState->m_zip64 = MZ_TRUE;
|
||||
/*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
|
||||
@ -3287,7 +3402,7 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n
|
||||
}
|
||||
cur_archive_file_ofs += num_alignment_padding_bytes;
|
||||
|
||||
MZ_CLEAR_OBJ(local_dir_header);
|
||||
MZ_CLEAR_ARR(local_dir_header);
|
||||
|
||||
if (!store_data_uncompressed || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
|
||||
{
|
||||
@ -3437,7 +3552,7 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n
|
||||
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, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len)
|
||||
{
|
||||
mz_uint16 gen_flags = (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE) ? 0 : MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR;
|
||||
mz_uint16 gen_flags;
|
||||
mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes;
|
||||
mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0;
|
||||
mz_uint64 local_dir_header_ofs, cur_archive_file_ofs = pZip->m_archive_size, uncomp_size = 0, comp_size = 0;
|
||||
@ -3449,13 +3564,15 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA
|
||||
mz_zip_internal_state *pState;
|
||||
mz_uint64 file_ofs = 0, cur_archive_header_file_ofs;
|
||||
|
||||
if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME))
|
||||
gen_flags |= MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8;
|
||||
|
||||
if ((int)level_and_flags < 0)
|
||||
level_and_flags = MZ_DEFAULT_LEVEL;
|
||||
level = level_and_flags & 0xF;
|
||||
|
||||
gen_flags = (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE) ? 0 : MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR;
|
||||
|
||||
if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME))
|
||||
gen_flags |= MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8;
|
||||
|
||||
/* Sanity checks */
|
||||
if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION))
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
|
||||
@ -3503,9 +3620,7 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA
|
||||
if (!pState->m_zip64)
|
||||
{
|
||||
/* Bail early if the archive would obviously become too large */
|
||||
if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE
|
||||
+ archive_name_size + comment_size + user_extra_data_len + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 1024
|
||||
+ MZ_ZIP_DATA_DESCRIPTER_SIZE32 + user_extra_data_central_len) > 0xFFFFFFFF)
|
||||
if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + user_extra_data_len + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 1024 + MZ_ZIP_DATA_DESCRIPTER_SIZE32 + user_extra_data_central_len) > 0xFFFFFFFF)
|
||||
{
|
||||
pState->m_zip64 = MZ_TRUE;
|
||||
/*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
|
||||
@ -3517,6 +3632,8 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA
|
||||
{
|
||||
mz_zip_time_t_to_dos_time(*pFile_time, &dos_time, &dos_date);
|
||||
}
|
||||
#else
|
||||
(void)pFile_time;
|
||||
#endif
|
||||
|
||||
if (max_size <= 3)
|
||||
@ -3540,7 +3657,7 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA
|
||||
method = MZ_DEFLATED;
|
||||
}
|
||||
|
||||
MZ_CLEAR_OBJ(local_dir_header);
|
||||
MZ_CLEAR_ARR(local_dir_header);
|
||||
if (pState->m_zip64)
|
||||
{
|
||||
if (max_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX)
|
||||
@ -3844,7 +3961,7 @@ mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name,
|
||||
}
|
||||
#endif /* #ifndef MINIZ_NO_STDIO */
|
||||
|
||||
static mz_bool mz_zip_writer_update_zip64_extension_block(mz_zip_array *pNew_ext, mz_zip_archive *pZip, const mz_uint8 *pExt, uint32_t ext_len, mz_uint64 *pComp_size, mz_uint64 *pUncomp_size, mz_uint64 *pLocal_header_ofs, mz_uint32 *pDisk_start)
|
||||
static mz_bool mz_zip_writer_update_zip64_extension_block(mz_zip_array *pNew_ext, mz_zip_archive *pZip, const mz_uint8 *pExt, mz_uint32 ext_len, mz_uint64 *pComp_size, mz_uint64 *pUncomp_size, mz_uint64 *pLocal_header_ofs, mz_uint32 *pDisk_start)
|
||||
{
|
||||
/* + 64 should be enough for any new zip64 data */
|
||||
if (!mz_zip_array_reserve(pZip, pNew_ext, ext_len + 64, MZ_FALSE))
|
||||
@ -4002,7 +4119,7 @@ mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *
|
||||
local_header_extra_len = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
|
||||
local_header_comp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS);
|
||||
local_header_uncomp_size = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS);
|
||||
src_archive_bytes_remaining = local_header_filename_size + local_header_extra_len + src_file_stat.m_comp_size;
|
||||
src_archive_bytes_remaining = src_file_stat.m_comp_size + local_header_filename_size + local_header_extra_len;
|
||||
|
||||
/* Try to find a zip64 extended information field */
|
||||
if ((local_header_extra_len) && ((local_header_comp_size == MZ_UINT32_MAX) || (local_header_uncomp_size == MZ_UINT32_MAX)))
|
||||
@ -4160,10 +4277,10 @@ mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *
|
||||
if (pZip->m_pState->m_zip64)
|
||||
{
|
||||
/* dest is zip64, so upgrade the data descriptor */
|
||||
const mz_uint32 *pSrc_descriptor = (const mz_uint32 *)((const mz_uint8 *)pBuf + (has_id ? sizeof(mz_uint32) : 0));
|
||||
const mz_uint32 src_crc32 = pSrc_descriptor[0];
|
||||
const mz_uint64 src_comp_size = pSrc_descriptor[1];
|
||||
const mz_uint64 src_uncomp_size = pSrc_descriptor[2];
|
||||
const mz_uint8 *pSrc_descriptor = (const mz_uint8 *)pBuf + (has_id ? sizeof(mz_uint32) : 0);
|
||||
const mz_uint32 src_crc32 = MZ_READ_LE32(pSrc_descriptor);
|
||||
const mz_uint64 src_comp_size = MZ_READ_LE32(pSrc_descriptor + sizeof(mz_uint32));
|
||||
const mz_uint64 src_uncomp_size = MZ_READ_LE32(pSrc_descriptor + 2 * sizeof(mz_uint32));
|
||||
|
||||
mz_write_le32((mz_uint8 *)pBuf, MZ_ZIP_DATA_DESCRIPTOR_ID);
|
||||
mz_write_le32((mz_uint8 *)pBuf + sizeof(mz_uint32) * 1, src_crc32);
|
||||
@ -4299,7 +4416,7 @@ mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip)
|
||||
|
||||
if (pState->m_zip64)
|
||||
{
|
||||
if ((pZip->m_total_files > MZ_UINT32_MAX) || (pState->m_central_dir.m_size >= MZ_UINT32_MAX))
|
||||
if ((mz_uint64)pState->m_central_dir.m_size >= MZ_UINT32_MAX)
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
|
||||
}
|
||||
else
|
||||
@ -4327,7 +4444,7 @@ mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip)
|
||||
/* Write zip64 end of central directory header */
|
||||
mz_uint64 rel_ofs_to_zip64_ecdr = pZip->m_archive_size;
|
||||
|
||||
MZ_CLEAR_OBJ(hdr);
|
||||
MZ_CLEAR_ARR(hdr);
|
||||
MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDH_SIG_OFS, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG);
|
||||
MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS, MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE - sizeof(mz_uint32) - sizeof(mz_uint64));
|
||||
MZ_WRITE_LE16(hdr + MZ_ZIP64_ECDH_VERSION_MADE_BY_OFS, 0x031E); /* TODO: always Unix */
|
||||
@ -4342,7 +4459,7 @@ mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip)
|
||||
pZip->m_archive_size += MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE;
|
||||
|
||||
/* Write zip64 end of central directory locator */
|
||||
MZ_CLEAR_OBJ(hdr);
|
||||
MZ_CLEAR_ARR(hdr);
|
||||
MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDL_SIG_OFS, MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG);
|
||||
MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS, rel_ofs_to_zip64_ecdr);
|
||||
MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS, 1);
|
||||
@ -4353,7 +4470,7 @@ mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip)
|
||||
}
|
||||
|
||||
/* Write end of central directory record */
|
||||
MZ_CLEAR_OBJ(hdr);
|
||||
MZ_CLEAR_ARR(hdr);
|
||||
MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_SIG_OFS, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG);
|
||||
MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS, MZ_MIN(MZ_UINT16_MAX, pZip->m_total_files));
|
||||
MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS, MZ_MIN(MZ_UINT16_MAX, pZip->m_total_files));
|
||||
@ -4452,14 +4569,14 @@ mz_bool mz_zip_add_mem_to_archive_file_in_place_v2(const char *pZip_filename, co
|
||||
else
|
||||
{
|
||||
/* Append to an existing archive. */
|
||||
if (!mz_zip_reader_init_file_v2(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY, 0, 0))
|
||||
if (!mz_zip_reader_init_file_v2(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY | MZ_ZIP_FLAG_READ_ALLOW_WRITING, 0, 0))
|
||||
{
|
||||
if (pErr)
|
||||
*pErr = zip_archive.m_last_error;
|
||||
return MZ_FALSE;
|
||||
}
|
||||
|
||||
if (!mz_zip_writer_init_from_reader_v2(&zip_archive, pZip_filename, level_and_flags))
|
||||
if (!mz_zip_writer_init_from_reader_v2(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_READ_ALLOW_WRITING))
|
||||
{
|
||||
if (pErr)
|
||||
*pErr = zip_archive.m_last_error;
|
||||
@ -4669,7 +4786,9 @@ const char *mz_zip_get_error_string(mz_zip_error mz_err)
|
||||
case MZ_ZIP_VALIDATION_FAILED:
|
||||
return "validation failed";
|
||||
case MZ_ZIP_WRITE_CALLBACK_FAILED:
|
||||
return "write calledback failed";
|
||||
return "write callback failed";
|
||||
case MZ_ZIP_TOTAL_ERRORS:
|
||||
return "total errors";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
50
miniz_zip.h
50
miniz_zip.h
@ -7,7 +7,8 @@
|
||||
#ifndef MINIZ_NO_ARCHIVE_APIS
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
enum
|
||||
@ -32,10 +33,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;
|
||||
|
||||
@ -72,6 +69,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);
|
||||
@ -81,14 +83,16 @@ 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,
|
||||
@ -100,10 +104,12 @@ typedef enum {
|
||||
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_FLAG_WRITE_HEADER_SET_SIZE = 0x20000,
|
||||
MZ_ZIP_FLAG_READ_ALLOW_WRITING = 0x40000
|
||||
} mz_zip_flags;
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
MZ_ZIP_TYPE_INVALID = 0,
|
||||
MZ_ZIP_TYPE_USER,
|
||||
MZ_ZIP_TYPE_MEMORY,
|
||||
@ -114,7 +120,8 @@ 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,
|
||||
@ -183,9 +190,7 @@ typedef struct
|
||||
mz_uint flags;
|
||||
|
||||
int status;
|
||||
#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
|
||||
mz_uint file_crc32;
|
||||
#endif
|
||||
|
||||
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;
|
||||
@ -195,6 +200,12 @@ typedef struct
|
||||
|
||||
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 */
|
||||
@ -318,9 +329,9 @@ MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_cfile(mz_zip_archive *pZip, c
|
||||
/* 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
|
||||
@ -334,7 +345,9 @@ MINIZ_EXPORT mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags
|
||||
|
||||
/* Misc utils/helpers, valid for ZIP reading or writing */
|
||||
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(). */
|
||||
MINIZ_EXPORT mz_bool mz_zip_end(mz_zip_archive *pZip);
|
||||
@ -387,7 +400,6 @@ MINIZ_EXPORT mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, c
|
||||
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. */
|
||||
@ -408,7 +420,7 @@ MINIZ_EXPORT mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_
|
||||
/* An archive must be manually finalized by calling this function for it to be valid. */
|
||||
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. */
|
||||
MINIZ_EXPORT mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **ppBuf, size_t *pSize);
|
||||
|
||||
@ -425,11 +437,13 @@ MINIZ_EXPORT mz_bool mz_zip_writer_end(mz_zip_archive *pZip);
|
||||
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. */
|
||||
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 */
|
||||
|
||||
|
||||
14
readme.md
14
readme.md
@ -4,7 +4,7 @@ Miniz is a lossless, high performance data compression library in a single sourc
|
||||
|
||||
## Usage
|
||||
|
||||
Please use the files from the [releases page](https://github.com/richgel999/miniz/releases) in your projects. Do not use the git checkout directly! The different source and header files are [amalgamated](https://www.sqlite.org/amalgamation.html) into one `miniz.c`/`miniz.h` pair in a build step (`amalgamate.sh`). Include `miniz.c` and `miniz.h` in your project to use Miniz.
|
||||
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).
|
||||
|
||||
## Features
|
||||
|
||||
@ -18,6 +18,18 @@ Please use the files from the [releases page](https://github.com/richgel999/mini
|
||||
* 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.)
|
||||
|
||||
## Building miniz - Using vcpkg
|
||||
|
||||
You can download and install miniz using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
|
||||
|
||||
git clone https://github.com/Microsoft/vcpkg.git
|
||||
cd vcpkg
|
||||
./bootstrap-vcpkg.sh
|
||||
./vcpkg integrate install
|
||||
./vcpkg install miniz
|
||||
|
||||
The miniz port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
|
||||
|
||||
## Known Problems
|
||||
|
||||
* No support for encrypted archives. Not sure how useful this stuff is in practice.
|
||||
|
||||
5
test.sh
5
test.sh
@ -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
|
||||
|
||||
87
tests/add_in_place_fuzzer.c
Normal file
87
tests/add_in_place_fuzzer.c
Normal file
@ -0,0 +1,87 @@
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include "miniz.h"
|
||||
|
||||
static const mz_uint files_count = 5;
|
||||
static const mz_uint max_file_size = 1024 * 1024;
|
||||
static const char *zip_file_name = "/tmp/miniz-fuzzer-test.zip";
|
||||
|
||||
/* Read 32-bit integer from the fuzzer input with range [0, max] */
|
||||
static mz_uint read_uint32(const mz_uint8 **data, size_t *size, mz_uint max)
|
||||
{
|
||||
mz_uint value = 0;
|
||||
|
||||
if (*size >= sizeof(mz_uint))
|
||||
{
|
||||
memcpy(&value, *data, sizeof(mz_uint));
|
||||
*data += sizeof(mz_uint);
|
||||
*size -= sizeof(mz_uint);
|
||||
value = MZ_MIN(max == UINT_MAX ? value : value % (max + 1), *size);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Read random-length null terminated string from the fuzzer input */
|
||||
static mz_bool read_string(const mz_uint8 **data, size_t *size, char *destination, mz_uint max_len)
|
||||
{
|
||||
mz_uint filename_len = read_uint32(data, size, max_len - 1);
|
||||
memcpy(destination, *data, filename_len);
|
||||
destination[filename_len] = 0;
|
||||
*data += filename_len;
|
||||
*size -= filename_len;
|
||||
return filename_len > 0;
|
||||
}
|
||||
|
||||
/* Get random-length buffer from the fuzzer input */
|
||||
static mz_bool read_buffer(const mz_uint8 **data, size_t *size, const mz_uint8 **destination, mz_uint *len)
|
||||
{
|
||||
*len = read_uint32(data, size, max_file_size);
|
||||
*destination = *data;
|
||||
*data += *len;
|
||||
*size -= *len;
|
||||
return *len > 0;
|
||||
}
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
mz_uint i;
|
||||
char archive_file_name[FILENAME_MAX];
|
||||
const mz_uint8 *file_data;
|
||||
mz_uint file_length, flags;
|
||||
size_t extracted_size;
|
||||
mz_uint8 *extracted_data;
|
||||
const char *comment = mz_version();
|
||||
|
||||
/* Remove the temporary file for better reproducibility */
|
||||
remove(zip_file_name);
|
||||
|
||||
for (i = 0; i < files_count; ++i)
|
||||
{
|
||||
/* Fill archive file name */
|
||||
if (!read_string(&data, &size, archive_file_name, sizeof(archive_file_name)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* Prepare file's content */
|
||||
if (!read_buffer(&data, &size, &file_data, &file_length))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/* Prepare flags for adding file */
|
||||
flags = read_uint32(&data, &size, UINT_MAX);
|
||||
|
||||
mz_zip_add_mem_to_archive_file_in_place(zip_file_name, archive_file_name, file_data, file_length, comment,
|
||||
(mz_uint16)strlen(comment), flags);
|
||||
|
||||
/* Prepare flags for extracting file */
|
||||
flags = read_uint32(&data, &size, UINT_MAX);
|
||||
extracted_data = mz_zip_extract_archive_file_to_heap(zip_file_name, archive_file_name, &extracted_size, flags);
|
||||
free(extracted_data);
|
||||
}
|
||||
|
||||
remove(zip_file_name);
|
||||
return 0;
|
||||
}
|
||||
10795
tests/catch_amalgamated.cpp
Normal file
10795
tests/catch_amalgamated.cpp
Normal file
File diff suppressed because it is too large
Load Diff
13143
tests/catch_amalgamated.hpp
Normal file
13143
tests/catch_amalgamated.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -13,7 +13,8 @@ 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;
|
||||
if (dataLen < 1 || dataLen > kMaxSize)
|
||||
return 0;
|
||||
|
||||
uint32_t crc = crc32(0L, NULL, 0);
|
||||
uint32_t adler = adler32(0L, NULL, 0);
|
||||
|
||||
@ -26,7 +26,10 @@ static void check_compress_level(uint8_t *compr, size_t comprLen,
|
||||
assert(0 == memcmp(data, uncompr, dataLen));
|
||||
}
|
||||
|
||||
#define put_byte(s, i, c) {s[i] = (unsigned char)(c);}
|
||||
#define put_byte(s, i, c) \
|
||||
{ \
|
||||
s[i] = (unsigned char)(c); \
|
||||
}
|
||||
|
||||
static void write_zlib_header(uint8_t *s)
|
||||
{
|
||||
|
||||
@ -11,8 +11,10 @@
|
||||
|
||||
#include "miniz.h"
|
||||
|
||||
#define CHECK_ERR(err, msg) { \
|
||||
if (err != Z_OK) { \
|
||||
#define CHECK_ERR(err, msg) \
|
||||
{ \
|
||||
if (err != Z_OK) \
|
||||
{ \
|
||||
fprintf(stderr, "%s error: %d\n", msg, err); \
|
||||
exit(1); \
|
||||
} \
|
||||
@ -23,7 +25,6 @@ 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 */
|
||||
|
||||
@ -30,7 +30,8 @@ int main(int argc, char **argv)
|
||||
siz_buf = ftell(f);
|
||||
rewind(f);
|
||||
|
||||
if(siz_buf < 1) goto err;
|
||||
if (siz_buf < 1)
|
||||
goto err;
|
||||
|
||||
buf = (char *)malloc(siz_buf);
|
||||
if (buf == NULL)
|
||||
|
||||
@ -11,8 +11,10 @@
|
||||
|
||||
#include "miniz.h"
|
||||
|
||||
#define CHECK_ERR(err, msg) { \
|
||||
if (err != Z_OK) { \
|
||||
#define CHECK_ERR(err, msg) \
|
||||
{ \
|
||||
if (err != Z_OK) \
|
||||
{ \
|
||||
fprintf(stderr, "%s error: %d\n", msg, err); \
|
||||
exit(1); \
|
||||
} \
|
||||
@ -94,7 +96,8 @@ void test_large_inflate(unsigned char *compr, size_t comprLen,
|
||||
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;
|
||||
if (err == Z_STREAM_END)
|
||||
break;
|
||||
|
||||
CHECK_ERR(err, "large inflate");
|
||||
}
|
||||
|
||||
131
tests/main.cpp
Normal file
131
tests/main.cpp
Normal file
@ -0,0 +1,131 @@
|
||||
#include "catch_amalgamated.hpp"
|
||||
#include "../miniz.h"
|
||||
#include <assert.h>
|
||||
#include <string>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define unlink _unlink
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifndef MINIZ_NO_STDIO
|
||||
bool create_test_zip()
|
||||
{
|
||||
unlink("test.zip");
|
||||
mz_zip_archive zip_archive = {};
|
||||
auto b = mz_zip_writer_init_file(&zip_archive, "test.zip", 0);
|
||||
if (!b)
|
||||
return false;
|
||||
|
||||
b = mz_zip_writer_add_mem(&zip_archive, "test.txt", "foo", 3, MZ_DEFAULT_COMPRESSION);
|
||||
if (!b)
|
||||
return false;
|
||||
|
||||
b = mz_zip_writer_finalize_archive(&zip_archive);
|
||||
if (!b)
|
||||
return false;
|
||||
|
||||
b = mz_zip_writer_end(&zip_archive);
|
||||
if (!b)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST_CASE("Zip writer tests")
|
||||
{
|
||||
auto b = create_test_zip();
|
||||
REQUIRE(b);
|
||||
|
||||
SECTION("Test test.txt content correct")
|
||||
{
|
||||
mz_zip_archive zip_archive = {};
|
||||
|
||||
auto b = mz_zip_reader_init_file(&zip_archive, "test.zip", 0);
|
||||
REQUIRE(b);
|
||||
|
||||
size_t content_size;
|
||||
auto content = mz_zip_reader_extract_file_to_heap(&zip_archive, "test.txt", &content_size, 0);
|
||||
|
||||
std::string_view content_view(reinterpret_cast<char *>(content), content_size);
|
||||
|
||||
REQUIRE(content_view == "foo");
|
||||
REQUIRE(content_view.size() == 3);
|
||||
|
||||
free(content);
|
||||
|
||||
mz_zip_reader_end(&zip_archive);
|
||||
}
|
||||
|
||||
SECTION("Test repeated file addition to zip")
|
||||
{
|
||||
mz_zip_archive zip_archive = {};
|
||||
auto b = mz_zip_writer_init_file(&zip_archive, "test2.zip", 0);
|
||||
REQUIRE(b);
|
||||
|
||||
b = mz_zip_writer_finalize_archive(&zip_archive);
|
||||
REQUIRE(b);
|
||||
|
||||
b = mz_zip_writer_end(&zip_archive);
|
||||
REQUIRE(b);
|
||||
|
||||
for (int i = 0; i < 50; i++)
|
||||
{
|
||||
const char *str = "hello world";
|
||||
b = mz_zip_add_mem_to_archive_file_in_place(
|
||||
std::string("test2.zip").c_str(), ("file1.txt" + std::to_string(i)).c_str(),
|
||||
str, (mz_uint16)strlen(str),
|
||||
NULL, 0,
|
||||
MZ_BEST_COMPRESSION);
|
||||
REQUIRE(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_CASE("Tinfl / tdefl tests")
|
||||
{
|
||||
SECTION("simple_test1")
|
||||
{
|
||||
size_t cmp_len = 0;
|
||||
|
||||
const char *p = "This is a test.This is a test.This is a test.1234567This is a test.This is a test.123456";
|
||||
size_t uncomp_len = strlen(p);
|
||||
|
||||
void *pComp_data = tdefl_compress_mem_to_heap(p, uncomp_len, &cmp_len, TDEFL_WRITE_ZLIB_HEADER);
|
||||
REQUIRE(pComp_data);
|
||||
|
||||
size_t decomp_len = 0;
|
||||
void *pDecomp_data = tinfl_decompress_mem_to_heap(pComp_data, cmp_len, &decomp_len, TINFL_FLAG_PARSE_ZLIB_HEADER);
|
||||
|
||||
REQUIRE(pDecomp_data);
|
||||
REQUIRE(decomp_len == uncomp_len);
|
||||
REQUIRE(memcmp(pDecomp_data, p, uncomp_len) == 0);
|
||||
|
||||
free(pComp_data);
|
||||
free(pDecomp_data);
|
||||
}
|
||||
|
||||
SECTION("simple_test2")
|
||||
{
|
||||
uint8_t cmp_buf[1024], decomp_buf[1024];
|
||||
uLong cmp_len = sizeof(cmp_buf);
|
||||
|
||||
const char *p = "This is a test.This is a test.This is a test.1234567This is a test.This is a test.123456";
|
||||
uLong uncomp_len = (uLong)strlen(p);
|
||||
|
||||
int status = compress(cmp_buf, &cmp_len, (const uint8_t *)p, uncomp_len);
|
||||
REQUIRE(status == Z_OK);
|
||||
|
||||
REQUIRE(cmp_len <= compressBound(uncomp_len));
|
||||
|
||||
uLong decomp_len = sizeof(decomp_buf);
|
||||
status = uncompress(decomp_buf, &decomp_len, cmp_buf, cmp_len);
|
||||
;
|
||||
|
||||
REQUIRE(status == Z_OK);
|
||||
REQUIRE(decomp_len == uncomp_len);
|
||||
REQUIRE(memcmp(decomp_buf, p, uncomp_len) == 0);
|
||||
}
|
||||
}
|
||||
@ -18,9 +18,15 @@
|
||||
# This script is meant to be run by
|
||||
# https://github.com/google/oss-fuzz/blob/master/projects/miniz/Dockerfile
|
||||
|
||||
cat << "EOF" > miniz_export.h
|
||||
#ifndef MINIZ_EXPORT
|
||||
#define MINIZ_EXPORT
|
||||
#endif
|
||||
EOF
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DAMALGAMATE_SOURCES=ON -DBUILD_SHARED_LIBS=OFF -DBUILD_FUZZERS=ON
|
||||
cmake .. -DAMALGAMATE_SOURCES=ON -DBUILD_SHARED_LIBS=OFF -DBUILD_FUZZERS=ON -DBUILD_TESTS=OFF
|
||||
make -j$(nproc)
|
||||
cd ..
|
||||
|
||||
|
||||
@ -11,8 +11,10 @@
|
||||
|
||||
#include "miniz.h"
|
||||
|
||||
#define CHECK_ERR(err, msg) { \
|
||||
if (err != Z_OK) { \
|
||||
#define CHECK_ERR(err, msg) \
|
||||
{ \
|
||||
if (err != Z_OK) \
|
||||
{ \
|
||||
fprintf(stderr, "%s error: %d\n", msg, err); \
|
||||
exit(1); \
|
||||
} \
|
||||
|
||||
@ -14,7 +14,8 @@ 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;
|
||||
if (Z_OK != uncompress2(buffer, &buffer_length, data, &size))
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -12,7 +12,8 @@ static const size_t data_max = 1024 * 256;
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
if(size > data_max) return 0;
|
||||
if (size > data_max)
|
||||
return 0;
|
||||
|
||||
int ret = 0;
|
||||
mz_zip_archive zip;
|
||||
@ -20,7 +21,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
|
||||
mz_uint flags = 0;
|
||||
|
||||
if(!mz_zip_reader_init_mem(&zip, data, size, flags)) return 0;
|
||||
if (!mz_zip_reader_init_mem(&zip, data, size, flags))
|
||||
return 0;
|
||||
|
||||
mz_uint i, files;
|
||||
|
||||
@ -30,22 +32,26 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
mz_zip_clear_last_error(&zip);
|
||||
|
||||
if(mz_zip_reader_is_file_a_directory(&zip, i)) continue;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user