mirror of
https://github.com/zlib-ng/minizip-ng
synced 2025-03-28 21:13:18 +00:00
Added support for ZSTD. #498
Co-authored-by: Force Charlie <fcharlie@users.noreply.github.com>
This commit is contained in:
parent
9b0901b858
commit
1f4758bd7f
@ -13,6 +13,7 @@ option(MZ_COMPAT "Enables compatibility layer" ON)
|
|||||||
option(MZ_ZLIB "Enables ZLIB compression" ON)
|
option(MZ_ZLIB "Enables ZLIB compression" ON)
|
||||||
option(MZ_BZIP2 "Enables BZIP2 compression" ON)
|
option(MZ_BZIP2 "Enables BZIP2 compression" ON)
|
||||||
option(MZ_LZMA "Enables LZMA compression" ON)
|
option(MZ_LZMA "Enables LZMA compression" ON)
|
||||||
|
option(MZ_ZSTD "Enables ZSTD compression" ON)
|
||||||
option(MZ_PKCRYPT "Enables PKWARE traditional encryption" ON)
|
option(MZ_PKCRYPT "Enables PKWARE traditional encryption" ON)
|
||||||
option(MZ_WZAES "Enables WinZIP AES encryption" ON)
|
option(MZ_WZAES "Enables WinZIP AES encryption" ON)
|
||||||
option(MZ_LIBCOMP "Enables Apple compression" OFF)
|
option(MZ_LIBCOMP "Enables Apple compression" OFF)
|
||||||
@ -107,6 +108,44 @@ if(MZ_ZLIB AND NOT MZ_LIBCOMP)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Check if zstd installation is present
|
||||||
|
if(MZ_ZSTD)
|
||||||
|
find_package(ZSTD)
|
||||||
|
if(ZSTD_FOUND)
|
||||||
|
message(STATUS "Using ZSTD")
|
||||||
|
list(APPEND MINIZIP_INC ${ZSTD_INCLUDE_DIRS})
|
||||||
|
set(PC_PRIVATE_LIBS "${PC_PRIVATE_LIBS} -lzstd")
|
||||||
|
else()
|
||||||
|
if(NOT ZSTD_REPOSITORY)
|
||||||
|
set(ZSTD_REPOSITORY https://github.com/facebook/zstd)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "Fetching ZSTD ${ZSTD_REPOSITORY} ${ZSTD_TAG}")
|
||||||
|
|
||||||
|
if(${CMAKE_VERSION} VERSION_LESS "3.11")
|
||||||
|
message(FATAL_ERROR "CMake 3.11 required to fetch zlib")
|
||||||
|
else()
|
||||||
|
include(FetchContent)
|
||||||
|
|
||||||
|
set(ZSTD_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/lib/zstd)
|
||||||
|
|
||||||
|
FetchContent_Declare(zstd
|
||||||
|
GIT_REPOSITORY ${ZSTD_REPOSITORY}
|
||||||
|
SOURCE_DIR ${ZSTD_SOURCE_DIR}
|
||||||
|
BINARY_DIR ${ZSTD_SOURCE_DIR})
|
||||||
|
|
||||||
|
FetchContent_GetProperties(zstd
|
||||||
|
POPULATED ZSTD_POPULATED)
|
||||||
|
if(NOT ZSTD_POPULATED)
|
||||||
|
FetchContent_Populate(zstd)
|
||||||
|
add_subdirectory(${ZSTD_SOURCE_DIR}/build/cmake EXCLUDE_FROM_ALL)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
list(APPEND MINIZIP_INC ${ZSTD_SOURCE_DIR}/lib)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
# Check if bzip2 installation is present
|
# Check if bzip2 installation is present
|
||||||
if(MZ_BZIP2)
|
if(MZ_BZIP2)
|
||||||
find_package(BZip2)
|
find_package(BZip2)
|
||||||
@ -437,6 +476,13 @@ if(MZ_ZLIB)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Include ZSTD
|
||||||
|
if(MZ_ZSTD)
|
||||||
|
list(APPEND MINIZIP_DEF -DHAVE_ZSTD)
|
||||||
|
list(APPEND MINIZIP_SRC "mz_strm_zstd.c")
|
||||||
|
list(APPEND MINIZIP_PUBLIC_HEADERS "mz_strm_zstd.h")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Include BZIP2
|
# Include BZIP2
|
||||||
if(MZ_BZIP2)
|
if(MZ_BZIP2)
|
||||||
list(APPEND MINIZIP_DEF -DHAVE_BZIP2)
|
list(APPEND MINIZIP_DEF -DHAVE_BZIP2)
|
||||||
@ -660,7 +706,7 @@ target_compile_definitions(${PROJECT_NAME} PRIVATE ${MINIZIP_DEF})
|
|||||||
# Link with external libraries
|
# Link with external libraries
|
||||||
if(MZ_ZLIB AND NOT MZ_LIBCOMP)
|
if(MZ_ZLIB AND NOT MZ_LIBCOMP)
|
||||||
if(ZLIB_FOUND)
|
if(ZLIB_FOUND)
|
||||||
target_link_libraries(${PROJECT_NAME} ${ZLIB_LIBRARIES})
|
target_link_libraries(${PROJECT_NAME} PRIVATE ${ZLIB_LIBRARIES})
|
||||||
else()
|
else()
|
||||||
# Have to add zlib to install targets
|
# Have to add zlib to install targets
|
||||||
if(NOT DEFINED BUILD_SHARED_LIBS OR NOT ${BUILD_SHARED_LIBS})
|
if(NOT DEFINED BUILD_SHARED_LIBS OR NOT ${BUILD_SHARED_LIBS})
|
||||||
@ -670,8 +716,24 @@ if(MZ_ZLIB AND NOT MZ_LIBCOMP)
|
|||||||
endif()
|
endif()
|
||||||
add_dependencies(${PROJECT_NAME} ${ZLIB_TARGET})
|
add_dependencies(${PROJECT_NAME} ${ZLIB_TARGET})
|
||||||
target_link_libraries(${PROJECT_NAME} PRIVATE ${ZLIB_TARGET})
|
target_link_libraries(${PROJECT_NAME} PRIVATE ${ZLIB_TARGET})
|
||||||
# Can't disable zlib testing so ctest tries to run zlib example app
|
if(MZ_BUILD_UNIT_TEST)
|
||||||
add_dependencies(${PROJECT_NAME} example)
|
# Can't disable zlib testing so ctest tries to run zlib example app
|
||||||
|
add_dependencies(${PROJECT_NAME} example)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
if(MZ_ZSTD)
|
||||||
|
if(ZSTD_FOUND)
|
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE ${ZSTD_LIBRARIES})
|
||||||
|
else()
|
||||||
|
# Have to add zlib to install targets
|
||||||
|
if(NOT DEFINED BUILD_SHARED_LIBS OR NOT ${BUILD_SHARED_LIBS})
|
||||||
|
set(ZSTD_TARGET libzstd_static)
|
||||||
|
else()
|
||||||
|
set(ZSTD_TARGET libzstd_shared)
|
||||||
|
endif()
|
||||||
|
add_dependencies(${PROJECT_NAME} ${ZSTD_TARGET})
|
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE ${ZSTD_TARGET})
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
if(MZ_BZIP2 AND BZIP2_FOUND)
|
if(MZ_BZIP2 AND BZIP2_FOUND)
|
||||||
|
@ -36,7 +36,7 @@ the library as version 2 because it had become difficult to maintain and code re
|
|||||||
+ Adding and removing entries from zip archives.
|
+ Adding and removing entries from zip archives.
|
||||||
+ Read and write raw zip entry data.
|
+ Read and write raw zip entry data.
|
||||||
+ Reading and writing zip archives from memory.
|
+ Reading and writing zip archives from memory.
|
||||||
+ Zlib, BZIP2, and LZMA compression methods.
|
+ Zlib, BZIP2, LZMA, and ZSTD compression methods.
|
||||||
+ Password protection through Traditional PKWARE and [WinZIP AES](https://www.winzip.com/aes_info.htm) encryption.
|
+ Password protection through Traditional PKWARE and [WinZIP AES](https://www.winzip.com/aes_info.htm) encryption.
|
||||||
+ Buffered streaming for improved I/O performance.
|
+ Buffered streaming for improved I/O performance.
|
||||||
+ NTFS timestamp support for UTC last modified, last accessed, and creation dates.
|
+ NTFS timestamp support for UTC last modified, last accessed, and creation dates.
|
||||||
@ -75,6 +75,7 @@ cmake --build .
|
|||||||
| MZ_ZLIB | Enables ZLIB compression | ON |
|
| MZ_ZLIB | Enables ZLIB compression | ON |
|
||||||
| MZ_BZIP2 | Enables BZIP2 compression | ON |
|
| MZ_BZIP2 | Enables BZIP2 compression | ON |
|
||||||
| MZ_LZMA | Enables LZMA compression | ON |
|
| MZ_LZMA | Enables LZMA compression | ON |
|
||||||
|
| MZ_ZSTD | Enables ZSTD compression | ON |
|
||||||
| MZ_PKCRYPT | Enables PKWARE traditional encryption | ON |
|
| MZ_PKCRYPT | Enables PKWARE traditional encryption | ON |
|
||||||
| MZ_WZAES | Enables WinZIP AES encryption | ON |
|
| MZ_WZAES | Enables WinZIP AES encryption | ON |
|
||||||
| MZ_LIBCOMP | Enables Apple compression | OFF |
|
| MZ_LIBCOMP | Enables Apple compression | OFF |
|
||||||
@ -111,6 +112,7 @@ cmake --build .
|
|||||||
| mz_strm_os\* | Platform specific file stream |
|
| mz_strm_os\* | Platform specific file stream |
|
||||||
| mz_strm_wzaes.\* | WinZIP AES stream |
|
| mz_strm_wzaes.\* | WinZIP AES stream |
|
||||||
| mz_strm_zlib.\* | Deflate stream using zlib |
|
| mz_strm_zlib.\* | Deflate stream using zlib |
|
||||||
|
| mz_strm_zstd.\* | ZSTD stream |
|
||||||
| mz_zip.\* | Zip format |
|
| mz_zip.\* | Zip format |
|
||||||
| mz_zip_rw.\* | Zip reader/writer |
|
| mz_zip_rw.\* | Zip reader/writer |
|
||||||
|
|
||||||
@ -122,6 +124,7 @@ cmake --build .
|
|||||||
+ [BZIP2](https://www.sourceware.org/bzip2/) written by Julian Seward.
|
+ [BZIP2](https://www.sourceware.org/bzip2/) written by Julian Seward.
|
||||||
+ [liblzma](https://tukaani.org/xz/) written by Lasse Collin.
|
+ [liblzma](https://tukaani.org/xz/) written by Lasse Collin.
|
||||||
+ Modifications were made to support the ZIP file format specification
|
+ Modifications were made to support the ZIP file format specification
|
||||||
|
+ [ZSTD](https://github.com/facebook/zstd) from Facebook
|
||||||
+ [AES](https://github.com/BrianGladman/aes) and [SHA](https://github.com/BrianGladman/sha) libraries of Brian Gladman.
|
+ [AES](https://github.com/BrianGladman/aes) and [SHA](https://github.com/BrianGladman/sha) libraries of Brian Gladman.
|
||||||
|
|
||||||
## Acknowledgments
|
## Acknowledgments
|
||||||
|
@ -8,5 +8,6 @@ Minizip compression method enumeration.
|
|||||||
|MZ_COMPRESS_METHOD_DEFLATE|8|Deflate compression|
|
|MZ_COMPRESS_METHOD_DEFLATE|8|Deflate compression|
|
||||||
|MZ_COMPRESS_METHOD_BZIP2|12|Bzip2 compression|
|
|MZ_COMPRESS_METHOD_BZIP2|12|Bzip2 compression|
|
||||||
|MZ_COMPRESS_METHOD_LZMA|14|LZMA1 compression|
|
|MZ_COMPRESS_METHOD_LZMA|14|LZMA1 compression|
|
||||||
|
|MZ_COMPRESS_METHOD_ZSTD|20|ZSTD compression|
|
||||||
|
|
||||||
_MZ_COMPRESS_METHOD_AES_ is only for internal use.
|
_MZ_COMPRESS_METHOD_AES_ is only for internal use.
|
||||||
|
11
minizip.c
11
minizip.c
@ -69,7 +69,7 @@ int32_t minizip_banner(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t minizip_help(void) {
|
int32_t minizip_help(void) {
|
||||||
printf("Usage: minizip [-x][-d dir|-l|-e][-o][-f][-y][-c cp][-a][-0 to -9][-b|-m][-k 512][-p pwd][-s] file.zip [files]\n\n" \
|
printf("Usage: minizip [-x][-d dir|-l|-e][-o][-f][-y][-c cp][-a][-0 to -9][-b|-m|-t][-k 512][-p pwd][-s] file.zip [files]\n\n" \
|
||||||
" -x Extract files\n" \
|
" -x Extract files\n" \
|
||||||
" -l List files\n" \
|
" -l List files\n" \
|
||||||
" -d Destination directory\n" \
|
" -d Destination directory\n" \
|
||||||
@ -91,7 +91,8 @@ int32_t minizip_help(void) {
|
|||||||
" -h PKCS12 certificate path\n" \
|
" -h PKCS12 certificate path\n" \
|
||||||
" -w PKCS12 certificate password\n" \
|
" -w PKCS12 certificate password\n" \
|
||||||
" -b BZIP2 compression\n" \
|
" -b BZIP2 compression\n" \
|
||||||
" -m LZMA compression\n\n");
|
" -m LZMA compression\n" \
|
||||||
|
" -t ZSTD compression\n\n");
|
||||||
return MZ_OK;
|
return MZ_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -600,6 +601,12 @@ int main(int argc, const char *argv[]) {
|
|||||||
options.compress_method = MZ_COMPRESS_METHOD_LZMA;
|
options.compress_method = MZ_COMPRESS_METHOD_LZMA;
|
||||||
#else
|
#else
|
||||||
err = MZ_SUPPORT_ERROR;
|
err = MZ_SUPPORT_ERROR;
|
||||||
|
#endif
|
||||||
|
else if ((c == 't') || (c == 'T'))
|
||||||
|
#ifdef HAVE_ZSTD
|
||||||
|
options.compress_method = MZ_COMPRESS_METHOD_ZSTD;
|
||||||
|
#else
|
||||||
|
err = MZ_SUPPORT_ERROR;
|
||||||
#endif
|
#endif
|
||||||
else if ((c == 's') || (c == 'S'))
|
else if ((c == 's') || (c == 'S'))
|
||||||
#ifdef HAVE_WZAES
|
#ifdef HAVE_WZAES
|
||||||
|
2
mz.h
2
mz.h
@ -64,6 +64,8 @@
|
|||||||
#define MZ_COMPRESS_METHOD_DEFLATE (8)
|
#define MZ_COMPRESS_METHOD_DEFLATE (8)
|
||||||
#define MZ_COMPRESS_METHOD_BZIP2 (12)
|
#define MZ_COMPRESS_METHOD_BZIP2 (12)
|
||||||
#define MZ_COMPRESS_METHOD_LZMA (14)
|
#define MZ_COMPRESS_METHOD_LZMA (14)
|
||||||
|
#define MZ_COMPRESS_METHOD_ZSTD (20)
|
||||||
|
#define MZ_COMPRESS_METHOD_WZZSTD (93)
|
||||||
#define MZ_COMPRESS_METHOD_AES (99)
|
#define MZ_COMPRESS_METHOD_AES (99)
|
||||||
|
|
||||||
#define MZ_COMPRESS_LEVEL_DEFAULT (-1)
|
#define MZ_COMPRESS_LEVEL_DEFAULT (-1)
|
||||||
|
344
mz_strm_zstd.c
Normal file
344
mz_strm_zstd.c
Normal file
@ -0,0 +1,344 @@
|
|||||||
|
/* mz_strm_zstd.c -- Stream for ztd compress/decompress
|
||||||
|
Version 2.9.3, May 21, 2020
|
||||||
|
part of the MiniZip project
|
||||||
|
|
||||||
|
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||||
|
https://github.com/nmoinvaz/minizip
|
||||||
|
Authors: Force Charlie
|
||||||
|
https://github.com/fcharlie
|
||||||
|
|
||||||
|
This program is distributed under the terms of the same license as zlib.
|
||||||
|
See the accompanying LICENSE file for the full text of the license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mz.h"
|
||||||
|
#include "mz_strm.h"
|
||||||
|
#include "mz_strm_zstd.h"
|
||||||
|
|
||||||
|
#include <zstd.h>
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
static mz_stream_vtbl mz_stream_zstd_vtbl = {
|
||||||
|
mz_stream_zstd_open,
|
||||||
|
mz_stream_zstd_is_open,
|
||||||
|
mz_stream_zstd_read,
|
||||||
|
mz_stream_zstd_write,
|
||||||
|
mz_stream_zstd_tell,
|
||||||
|
mz_stream_zstd_seek,
|
||||||
|
mz_stream_zstd_close,
|
||||||
|
mz_stream_zstd_error,
|
||||||
|
mz_stream_zstd_create,
|
||||||
|
mz_stream_zstd_delete,
|
||||||
|
mz_stream_zstd_get_prop_int64,
|
||||||
|
mz_stream_zstd_set_prop_int64
|
||||||
|
};
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
typedef struct mz_stream_zstd_s {
|
||||||
|
mz_stream stream;
|
||||||
|
ZSTD_CStream *zcstream;
|
||||||
|
ZSTD_DStream *zdstream;
|
||||||
|
ZSTD_outBuffer out;
|
||||||
|
ZSTD_inBuffer in;
|
||||||
|
int32_t mode;
|
||||||
|
int32_t error;
|
||||||
|
uint8_t buffer[INT16_MAX];
|
||||||
|
int32_t buffer_len;
|
||||||
|
int64_t total_in;
|
||||||
|
int64_t total_out;
|
||||||
|
int64_t max_total_in;
|
||||||
|
int64_t max_total_out;
|
||||||
|
int8_t initialized;
|
||||||
|
uint32_t preset;
|
||||||
|
} mz_stream_zstd;
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
int32_t mz_stream_zstd_open(void *stream, const char *path, int32_t mode) {
|
||||||
|
mz_stream_zstd *zstd = (mz_stream_zstd *)stream;
|
||||||
|
|
||||||
|
MZ_UNUSED(path);
|
||||||
|
|
||||||
|
if (mode & MZ_OPEN_MODE_WRITE) {
|
||||||
|
#ifdef MZ_ZIP_NO_COMPRESSION
|
||||||
|
return MZ_SUPPORT_ERROR;
|
||||||
|
#else
|
||||||
|
zstd->zcstream = ZSTD_createCStream();
|
||||||
|
zstd->out.dst = zstd->buffer;
|
||||||
|
zstd->out.size = sizeof(zstd->buffer);
|
||||||
|
zstd->out.pos = 0;
|
||||||
|
#endif
|
||||||
|
} else if (mode & MZ_OPEN_MODE_READ) {
|
||||||
|
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
||||||
|
return MZ_SUPPORT_ERROR;
|
||||||
|
#else
|
||||||
|
zstd->zdstream = ZSTD_createDStream();
|
||||||
|
memset(&zstd->out, 0, sizeof(ZSTD_outBuffer));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&zstd->in, 0, sizeof(ZSTD_inBuffer));
|
||||||
|
|
||||||
|
zstd->initialized = 1;
|
||||||
|
zstd->mode = mode;
|
||||||
|
zstd->error = MZ_OK;
|
||||||
|
|
||||||
|
return MZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mz_stream_zstd_is_open(void *stream) {
|
||||||
|
mz_stream_zstd *zstd = (mz_stream_zstd *)stream;
|
||||||
|
if (zstd->initialized != 1)
|
||||||
|
return MZ_OPEN_ERROR;
|
||||||
|
return MZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mz_stream_zstd_read(void *stream, void *buf, int32_t size) {
|
||||||
|
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
||||||
|
MZ_UNUSED(stream);
|
||||||
|
MZ_UNUSED(buf);
|
||||||
|
MZ_UNUSED(size);
|
||||||
|
return MZ_SUPPORT_ERROR;
|
||||||
|
#else
|
||||||
|
mz_stream_zstd *zstd = (mz_stream_zstd *)stream;
|
||||||
|
uint64_t total_in_before = 0;
|
||||||
|
uint64_t total_in_after = 0;
|
||||||
|
uint64_t total_out_before = 0;
|
||||||
|
uint64_t total_out_after = 0;
|
||||||
|
uint32_t total_in = 0;
|
||||||
|
uint32_t total_out = 0;
|
||||||
|
uint32_t in_bytes = 0;
|
||||||
|
uint32_t out_bytes = 0;
|
||||||
|
int32_t bytes_to_read = sizeof(zstd->buffer);
|
||||||
|
int32_t read = 0;
|
||||||
|
size_t result = 0;
|
||||||
|
|
||||||
|
zstd->out.pos = 0;
|
||||||
|
zstd->out.dst = buf;
|
||||||
|
zstd->out.size = size;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (zstd->in.pos == zstd->in.size) {
|
||||||
|
if (zstd->max_total_in > 0) {
|
||||||
|
if ((int64_t)bytes_to_read > (zstd->max_total_in - zstd->total_in))
|
||||||
|
bytes_to_read = (int32_t)(zstd->max_total_in - zstd->total_in);
|
||||||
|
}
|
||||||
|
read = mz_stream_read(zstd->stream.base, zstd->buffer, bytes_to_read);
|
||||||
|
if (read < 0)
|
||||||
|
return read;
|
||||||
|
|
||||||
|
zstd->in.src = zstd->buffer;
|
||||||
|
zstd->in.size = read;
|
||||||
|
zstd->in.pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
total_out_before = zstd->out.pos;
|
||||||
|
total_in_before = zstd->in.pos;
|
||||||
|
|
||||||
|
result = ZSTD_decompressStream(zstd->zdstream, &zstd->out, &zstd->in);
|
||||||
|
|
||||||
|
if (ZSTD_isError(result)) {
|
||||||
|
zstd->error = (int32_t)result;
|
||||||
|
return MZ_DATA_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
total_in_after = zstd->in.pos;
|
||||||
|
total_out_after = zstd->out.pos;
|
||||||
|
|
||||||
|
in_bytes += (uint32_t)(total_in_after - total_in_before);
|
||||||
|
out_bytes += (uint32_t)(total_out_after - total_out_before);
|
||||||
|
|
||||||
|
total_in += in_bytes;
|
||||||
|
total_out += out_bytes;
|
||||||
|
|
||||||
|
zstd->total_in += in_bytes;
|
||||||
|
zstd->total_out += out_bytes;
|
||||||
|
|
||||||
|
} while (zstd->out.pos < zstd->out.size && result > 0);
|
||||||
|
|
||||||
|
return total_out;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef MZ_ZIP_NO_COMPRESSION
|
||||||
|
static int32_t mz_stream_zstd_flush(void *stream) {
|
||||||
|
mz_stream_zstd *zstd = (mz_stream_zstd *)stream;
|
||||||
|
if (mz_stream_write(zstd->stream.base, zstd->buffer, zstd->buffer_len) != zstd->buffer_len)
|
||||||
|
return MZ_WRITE_ERROR;
|
||||||
|
return MZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mz_stream_zstd_compress(void *stream, ZSTD_EndDirective flush) {
|
||||||
|
mz_stream_zstd *zstd = (mz_stream_zstd *)stream;
|
||||||
|
uint64_t total_out_before = 0;
|
||||||
|
uint64_t total_out_after = 0;
|
||||||
|
int32_t out_bytes = 0;
|
||||||
|
size_t result = 0;
|
||||||
|
int32_t err = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (zstd->out.pos == zstd->out.size) {
|
||||||
|
err = mz_stream_zstd_flush(zstd);
|
||||||
|
if (err != MZ_OK)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
zstd->out.dst = zstd->buffer;
|
||||||
|
zstd->out.size = sizeof(zstd->buffer);
|
||||||
|
zstd->out.pos = 0;
|
||||||
|
|
||||||
|
zstd->buffer_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
total_out_before = zstd->out.pos;
|
||||||
|
|
||||||
|
result = ZSTD_compressStream2(zstd->zcstream, &zstd->out, &zstd->in, flush);
|
||||||
|
|
||||||
|
total_out_after = zstd->out.pos;
|
||||||
|
|
||||||
|
out_bytes = (uint32_t)(total_out_after - total_out_before);
|
||||||
|
|
||||||
|
zstd->buffer_len += out_bytes;
|
||||||
|
zstd->total_out += out_bytes;
|
||||||
|
|
||||||
|
if (ZSTD_isError(result)) {
|
||||||
|
zstd->error = (int32_t)result;
|
||||||
|
return MZ_DATA_ERROR;
|
||||||
|
}
|
||||||
|
} while ((zstd->in.pos < zstd->in.size) || (flush == ZSTD_e_end && result != 0));
|
||||||
|
|
||||||
|
return MZ_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int32_t mz_stream_zstd_write(void *stream, const void *buf, int32_t size) {
|
||||||
|
mz_stream_zstd *zstd = (mz_stream_zstd *)stream;
|
||||||
|
|
||||||
|
#ifdef MZ_ZIP_NO_COMPRESSION
|
||||||
|
MZ_UNUSED(zlib);
|
||||||
|
MZ_UNUSED(buf);
|
||||||
|
err = MZ_SUPPORT_ERROR;
|
||||||
|
#else
|
||||||
|
size_t result = 0;
|
||||||
|
|
||||||
|
zstd->in.src = buf;
|
||||||
|
zstd->in.pos = 0;
|
||||||
|
zstd->in.size = size;
|
||||||
|
|
||||||
|
mz_stream_zstd_compress(stream, ZSTD_e_continue);
|
||||||
|
|
||||||
|
zstd->total_in += size;
|
||||||
|
#endif
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t mz_stream_zstd_tell(void *stream) {
|
||||||
|
MZ_UNUSED(stream);
|
||||||
|
|
||||||
|
return MZ_TELL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mz_stream_zstd_seek(void *stream, int64_t offset, int32_t origin) {
|
||||||
|
MZ_UNUSED(stream);
|
||||||
|
MZ_UNUSED(offset);
|
||||||
|
MZ_UNUSED(origin);
|
||||||
|
|
||||||
|
return MZ_SEEK_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mz_stream_zstd_close(void *stream) {
|
||||||
|
mz_stream_zstd *zstd = (mz_stream_zstd *)stream;
|
||||||
|
|
||||||
|
if (zstd->mode & MZ_OPEN_MODE_WRITE) {
|
||||||
|
#ifdef MZ_ZIP_NO_COMPRESSION
|
||||||
|
return MZ_SUPPORT_ERROR;
|
||||||
|
#else
|
||||||
|
mz_stream_zstd_compress(stream, ZSTD_e_end);
|
||||||
|
mz_stream_zstd_flush(stream);
|
||||||
|
|
||||||
|
ZSTD_freeCStream(zstd->zcstream);
|
||||||
|
zstd->zcstream = NULL;
|
||||||
|
#endif
|
||||||
|
} else if (zstd->mode & MZ_OPEN_MODE_READ) {
|
||||||
|
#ifdef MZ_ZIP_NO_DECOMPRESSION
|
||||||
|
return MZ_SUPPORT_ERROR;
|
||||||
|
#else
|
||||||
|
ZSTD_freeDStream(zstd->zdstream);
|
||||||
|
zstd->zdstream = NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
zstd->initialized = 0;
|
||||||
|
return MZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mz_stream_zstd_error(void *stream) {
|
||||||
|
mz_stream_zstd *zstd = (mz_stream_zstd *)stream;
|
||||||
|
return zstd->error;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mz_stream_zstd_get_prop_int64(void *stream, int32_t prop, int64_t *value) {
|
||||||
|
mz_stream_zstd *zstd = (mz_stream_zstd *)stream;
|
||||||
|
switch (prop) {
|
||||||
|
case MZ_STREAM_PROP_TOTAL_IN:
|
||||||
|
*value = zstd->total_in;
|
||||||
|
break;
|
||||||
|
case MZ_STREAM_PROP_TOTAL_IN_MAX:
|
||||||
|
*value = zstd->max_total_in;
|
||||||
|
break;
|
||||||
|
case MZ_STREAM_PROP_TOTAL_OUT:
|
||||||
|
*value = zstd->total_out;
|
||||||
|
break;
|
||||||
|
case MZ_STREAM_PROP_TOTAL_OUT_MAX:
|
||||||
|
*value = zstd->max_total_out;
|
||||||
|
break;
|
||||||
|
case MZ_STREAM_PROP_HEADER_SIZE:
|
||||||
|
*value = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return MZ_EXIST_ERROR;
|
||||||
|
}
|
||||||
|
return MZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t mz_stream_zstd_set_prop_int64(void *stream, int32_t prop, int64_t value) {
|
||||||
|
mz_stream_zstd *zstd = (mz_stream_zstd *)stream;
|
||||||
|
switch (prop) {
|
||||||
|
case MZ_STREAM_PROP_COMPRESS_LEVEL:
|
||||||
|
if (value < 0)
|
||||||
|
zstd->preset = 6;
|
||||||
|
else
|
||||||
|
zstd->preset = (int16_t)value;
|
||||||
|
return MZ_OK;
|
||||||
|
case MZ_STREAM_PROP_TOTAL_IN_MAX:
|
||||||
|
zstd->max_total_in = value;
|
||||||
|
return MZ_OK;
|
||||||
|
}
|
||||||
|
return MZ_EXIST_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *mz_stream_zstd_create(void **stream) {
|
||||||
|
mz_stream_zstd *zstd = NULL;
|
||||||
|
zstd = (mz_stream_zstd *)MZ_ALLOC(sizeof(mz_stream_zstd));
|
||||||
|
if (zstd != NULL) {
|
||||||
|
memset(zstd, 0, sizeof(mz_stream_zstd));
|
||||||
|
zstd->stream.vtbl = &mz_stream_zstd_vtbl;
|
||||||
|
}
|
||||||
|
if (stream != NULL)
|
||||||
|
*stream = zstd;
|
||||||
|
return zstd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mz_stream_zstd_delete(void **stream) {
|
||||||
|
mz_stream_zstd *zstd = NULL;
|
||||||
|
if (stream == NULL)
|
||||||
|
return;
|
||||||
|
zstd = (mz_stream_zstd *)*stream;
|
||||||
|
if (zstd != NULL)
|
||||||
|
MZ_FREE(zstd);
|
||||||
|
*stream = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *mz_stream_zstd_get_interface(void) {
|
||||||
|
return (void *)&mz_stream_zstd_vtbl;
|
||||||
|
}
|
44
mz_strm_zstd.h
Normal file
44
mz_strm_zstd.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/* mz_strm_zlib.h -- Stream for zlib inflate/deflate
|
||||||
|
Version 2.9.2, February 12, 2020
|
||||||
|
part of the MiniZip project
|
||||||
|
|
||||||
|
Copyright (C) 2010-2020 Nathan Moinvaziri
|
||||||
|
https://github.com/nmoinvaz/minizip
|
||||||
|
|
||||||
|
This program is distributed under the terms of the same license as zlib.
|
||||||
|
See the accompanying LICENSE file for the full text of the license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MZ_STREAM_ZSTD_H
|
||||||
|
#define MZ_STREAM_ZSTD_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
int32_t mz_stream_zstd_open(void *stream, const char *filename, int32_t mode);
|
||||||
|
int32_t mz_stream_zstd_is_open(void *stream);
|
||||||
|
int32_t mz_stream_zstd_read(void *stream, void *buf, int32_t size);
|
||||||
|
int32_t mz_stream_zstd_write(void *stream, const void *buf, int32_t size);
|
||||||
|
int64_t mz_stream_zstd_tell(void *stream);
|
||||||
|
int32_t mz_stream_zstd_seek(void *stream, int64_t offset, int32_t origin);
|
||||||
|
int32_t mz_stream_zstd_close(void *stream);
|
||||||
|
int32_t mz_stream_zstd_error(void *stream);
|
||||||
|
|
||||||
|
int32_t mz_stream_zstd_get_prop_int64(void *stream, int32_t prop, int64_t *value);
|
||||||
|
int32_t mz_stream_zstd_set_prop_int64(void *stream, int32_t prop, int64_t value);
|
||||||
|
|
||||||
|
void* mz_stream_zstd_create(void **stream);
|
||||||
|
void mz_stream_zstd_delete(void **stream);
|
||||||
|
|
||||||
|
void* mz_stream_zstd_get_interface(void);
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
12
mz_zip.c
12
mz_zip.c
@ -39,6 +39,9 @@
|
|||||||
#ifdef HAVE_ZLIB
|
#ifdef HAVE_ZLIB
|
||||||
# include "mz_strm_zlib.h"
|
# include "mz_strm_zlib.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_ZSTD
|
||||||
|
# include "mz_strm_zstd.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "mz_zip.h"
|
#include "mz_zip.h"
|
||||||
|
|
||||||
@ -1616,6 +1619,10 @@ static int32_t mz_zip_entry_open_int(void *handle, uint8_t raw, int16_t compress
|
|||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_LZMA
|
#ifdef HAVE_LZMA
|
||||||
case MZ_COMPRESS_METHOD_LZMA:
|
case MZ_COMPRESS_METHOD_LZMA:
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ZSTD
|
||||||
|
case MZ_COMPRESS_METHOD_ZSTD:
|
||||||
|
case MZ_COMPRESS_METHOD_WZZSTD:
|
||||||
#endif
|
#endif
|
||||||
err = MZ_OK;
|
err = MZ_OK;
|
||||||
break;
|
break;
|
||||||
@ -1700,6 +1707,11 @@ static int32_t mz_zip_entry_open_int(void *handle, uint8_t raw, int16_t compress
|
|||||||
#ifdef HAVE_LZMA
|
#ifdef HAVE_LZMA
|
||||||
else if (zip->file_info.compression_method == MZ_COMPRESS_METHOD_LZMA)
|
else if (zip->file_info.compression_method == MZ_COMPRESS_METHOD_LZMA)
|
||||||
mz_stream_lzma_create(&zip->compress_stream);
|
mz_stream_lzma_create(&zip->compress_stream);
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ZSTD
|
||||||
|
else if ((zip->file_info.compression_method == MZ_COMPRESS_METHOD_ZSTD) ||
|
||||||
|
(zip->file_info.compression_method == MZ_COMPRESS_METHOD_WZZSTD))
|
||||||
|
mz_stream_zstd_create(&zip->compress_stream);
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
err = MZ_PARAM_ERROR;
|
err = MZ_PARAM_ERROR;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user