update miniz to 3.0.1

This commit is contained in:
BlackMATov
2023-01-08 16:31:29 +07:00
parent 02f4e3c71a
commit 95044d5ebc
10 changed files with 404 additions and 176 deletions

View File

@@ -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,6 +594,8 @@ 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

View File

@@ -1,4 +1,4 @@
/* miniz.c 2.1.0 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
/* miniz.c 3.0.0 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
See "unlicense" statement at the end of this file.
Rich Geldreich <richgel99@gmail.com>, last updated Oct. 13, 2013
Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
@@ -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
@@ -236,9 +272,9 @@ enum
MZ_DEFAULT_COMPRESSION = -1
};
#define MZ_VERSION "10.1.0"
#define MZ_VERNUM 0xA100
#define MZ_VER_MAJOR 10
#define MZ_VERSION "11.0.1"
#define MZ_VERNUM 0xB001
#define MZ_VER_MAJOR 11
#define MZ_VER_MINOR 1
#define MZ_VER_REVISION 0
#define MZ_VER_SUBREVISION 0
@@ -304,6 +340,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 +394,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 +431,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);
@@ -439,6 +482,8 @@ typedef void *const voidpc;
#define free_func mz_free_func
#define internal_state mz_internal_state
#define z_stream mz_stream
#ifndef MINIZ_NO_DEFLATE_APIS
#define deflateInit mz_deflateInit
#define deflateInit2 mz_deflateInit2
#define deflateReset mz_deflateReset
@@ -448,6 +493,9 @@ typedef void *const voidpc;
#define compress mz_compress
#define compress2 mz_compress2
#define compressBound mz_compressBound
#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/
#ifndef MINIZ_NO_INFLATE_APIS
#define inflateInit mz_inflateInit
#define inflateInit2 mz_inflateInit2
#define inflateReset mz_inflateReset
@@ -455,6 +503,8 @@ typedef void *const voidpc;
#define inflateEnd mz_inflateEnd
#define uncompress mz_uncompress
#define uncompress2 mz_uncompress2
#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/
#define crc32 mz_crc32
#define adler32 mz_adler32
#define MAX_WBITS 15

View File

@@ -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))

View File

@@ -26,6 +26,8 @@
#include "miniz.h"
#ifndef MINIZ_NO_DEFLATE_APIS
#ifdef __cplusplus
extern "C" {
#endif
@@ -104,7 +106,7 @@ static tdefl_sym_freq *tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq *p
{
mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2];
tdefl_sym_freq *pCur_syms = pSyms0, *pNew_syms = pSyms1;
MZ_CLEAR_OBJ(hist);
MZ_CLEAR_ARR(hist);
for (i = 0; i < num_syms; i++)
{
mz_uint freq = pSyms0[i].m_key;
@@ -222,7 +224,7 @@ static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int
{
int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE];
mz_uint next_code[TDEFL_MAX_SUPPORTED_HUFF_CODESIZE + 1];
MZ_CLEAR_OBJ(num_codes);
MZ_CLEAR_ARR(num_codes);
if (static_table)
{
for (i = 0; i < table_len; i++)
@@ -248,8 +250,8 @@ static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int
tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, code_size_limit);
MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]);
MZ_CLEAR_OBJ(d->m_huff_codes[table_num]);
MZ_CLEAR_ARR(d->m_huff_code_sizes[table_num]);
MZ_CLEAR_ARR(d->m_huff_codes[table_num]);
for (i = 1, j = num_used_syms; i <= code_size_limit; i++)
for (l = num_codes[i]; l > 0; l--)
d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i);
@@ -335,7 +337,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 +475,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 +521,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 +603,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];
static int tdefl_flush_block(tdefl_compressor *d, int flush)
{
mz_uint saved_bit_buf, saved_bits_in;
@@ -620,8 +625,27 @@ 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);
@@ -1074,9 +1098,7 @@ static MZ_FORCEINLINE void tdefl_record_match(tdefl_compressor *d, mz_uint match
s0 = s_tdefl_small_dist_sym[match_dist & 511];
s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127];
d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++;
if (match_len >= TDEFL_MIN_MATCH_LEN)
d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++;
d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++;
}
static mz_bool tdefl_compress_normal(tdefl_compressor *d)
@@ -1094,7 +1116,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)
@@ -1304,8 +1326,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;
}
}
@@ -1328,11 +1350,12 @@ tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_fun
d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0;
d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3;
if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG))
MZ_CLEAR_OBJ(d->m_hash);
MZ_CLEAR_ARR(d->m_hash);
d->m_lookahead_pos = d->m_lookahead_size = d->m_dict_size = d->m_total_lz_bytes = d->m_lz_code_buf_dict_pos = d->m_bits_in = 0;
d->m_output_flush_ofs = d->m_output_flush_remaining = d->m_finished = d->m_block_index = d->m_bit_buffer = d->m_wants_to_finish = 0;
d->m_pLZ_code_buf = d->m_lz_code_buf + 1;
d->m_pLZ_flags = d->m_lz_code_buf;
*d->m_pLZ_flags = 0;
d->m_num_flags_left = 8;
d->m_pOutput_buf = d->m_output_buf;
d->m_pOutput_buf_end = d->m_output_buf;
@@ -1348,7 +1371,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;
@@ -1558,7 +1581,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));
}
@@ -1576,3 +1599,5 @@ void tdefl_compressor_free(tdefl_compressor *pComp)
#ifdef __cplusplus
}
#endif
#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/

View File

@@ -1,6 +1,8 @@
#pragma once
#include "miniz_common.h"
#ifndef MINIZ_NO_DEFLATE_APIS
#ifdef __cplusplus
extern "C" {
#endif
@@ -188,3 +190,5 @@ MINIZ_EXPORT void tdefl_compressor_free(tdefl_compressor *pComp);
#ifdef __cplusplus
}
#endif
#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/

View File

@@ -26,6 +26,8 @@
#include "miniz.h"
#ifndef MINIZ_NO_INFLATE_APIS
#ifdef __cplusplus
extern "C" {
#endif
@@ -106,10 +108,10 @@ extern "C" {
/* It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a */
/* Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the */
/* bit buffer contains >=15 bits (deflate's max. Huffman code size). */
#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \
#define TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree) \
do \
{ \
temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
temp = pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
if (temp >= 0) \
{ \
code_len = temp >> 9; \
@@ -121,7 +123,7 @@ extern "C" {
code_len = TINFL_FAST_LOOKUP_BITS; \
do \
{ \
temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \
} while ((temp < 0) && (num_bits >= (code_len + 1))); \
if (temp >= 0) \
break; \
@@ -137,7 +139,7 @@ extern "C" {
/* The slow path is only executed at the very end of the input buffer. */
/* v1.16: The original macro handled the case at the very end of the passed-in input buffer, but we also need to handle the case where the user passes in 1+zillion bytes */
/* following the deflate data and our non-conservative read-ahead path won't kick in here on this code. This is much trickier. */
#define TINFL_HUFF_DECODE(state_index, sym, pHuff) \
#define TINFL_HUFF_DECODE(state_index, sym, pLookUp, pTree) \
do \
{ \
int temp; \
@@ -146,7 +148,7 @@ extern "C" {
{ \
if ((pIn_buf_end - pIn_buf_cur) < 2) \
{ \
TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree); \
} \
else \
{ \
@@ -155,14 +157,14 @@ extern "C" {
num_bits += 16; \
} \
} \
if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
if ((temp = pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
code_len = temp >> 9, temp &= 511; \
else \
{ \
code_len = TINFL_FAST_LOOKUP_BITS; \
do \
{ \
temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \
} while (temp < 0); \
} \
sym = temp; \
@@ -171,20 +173,33 @@ extern "C" {
} \
MZ_MACRO_END
static void tinfl_clear_tree(tinfl_decompressor *r)
{
if (r->m_type == 0)
MZ_CLEAR_ARR(r->m_tree_0);
else if (r->m_type == 1)
MZ_CLEAR_ARR(r->m_tree_1);
else
MZ_CLEAR_ARR(r->m_tree_2);
}
tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags)
{
static const int s_length_base[31] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 };
static const int s_length_extra[31] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0 };
static const int s_dist_base[32] = { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0 };
static const int s_dist_extra[32] = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 };
static const mz_uint16 s_length_base[31] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 };
static const mz_uint8 s_length_extra[31] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0 };
static const mz_uint16 s_dist_base[32] = { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0 };
static const mz_uint8 s_dist_extra[32] = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 };
static const mz_uint8 s_length_dezigzag[19] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
static const int s_min_table_sizes[3] = { 257, 1, 4 };
static const mz_uint16 s_min_table_sizes[3] = { 257, 1, 4 };
mz_int16 *pTrees[3];
mz_uint8 *pCode_sizes[3];
tinfl_status status = TINFL_STATUS_FAILED;
mz_uint32 num_bits, dist, counter, num_extra;
tinfl_bit_buf_t bit_buf;
const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size;
mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size;
mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next ? pOut_buf_next + *pOut_buf_size : NULL;
size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t)-1 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, dist_from_out_buf_start;
/* Ensure the output buffer's size is a power of 2, unless the output buffer is large enough to hold the entire output file (in which case it doesn't matter). */
@@ -194,6 +209,13 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
return TINFL_STATUS_BAD_PARAM;
}
pTrees[0] = r->m_tree_0;
pTrees[1] = r->m_tree_1;
pTrees[2] = r->m_tree_2;
pCode_sizes[0] = r->m_code_size_0;
pCode_sizes[1] = r->m_code_size_1;
pCode_sizes[2] = r->m_code_size_2;
num_bits = r->m_num_bits;
bit_buf = r->m_bit_buf;
dist = r->m_dist;
@@ -210,7 +232,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 +293,11 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
{
if (r->m_type == 1)
{
mz_uint8 *p = r->m_tables[0].m_code_size;
mz_uint8 *p = r->m_code_size_0;
mz_uint i;
r->m_table_sizes[0] = 288;
r->m_table_sizes[1] = 32;
TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32);
TINFL_MEMSET(r->m_code_size_1, 5, 32);
for (i = 0; i <= 143; ++i)
*p++ = 8;
for (; i <= 255; ++i)
@@ -292,26 +314,30 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]);
r->m_table_sizes[counter] += s_min_table_sizes[counter];
}
MZ_CLEAR_OBJ(r->m_tables[2].m_code_size);
MZ_CLEAR_ARR(r->m_code_size_2);
for (counter = 0; counter < r->m_table_sizes[2]; counter++)
{
mz_uint s;
TINFL_GET_BITS(14, s, 3);
r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s;
r->m_code_size_2[s_length_dezigzag[counter]] = (mz_uint8)s;
}
r->m_table_sizes[2] = 19;
}
for (; (int)r->m_type >= 0; r->m_type--)
{
int tree_next, tree_cur;
tinfl_huff_table *pTable;
mz_int16 *pLookUp;
mz_int16 *pTree;
mz_uint8 *pCode_size;
mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16];
pTable = &r->m_tables[r->m_type];
MZ_CLEAR_OBJ(total_syms);
MZ_CLEAR_OBJ(pTable->m_look_up);
MZ_CLEAR_OBJ(pTable->m_tree);
pLookUp = r->m_look_up[r->m_type];
pTree = pTrees[r->m_type];
pCode_size = pCode_sizes[r->m_type];
MZ_CLEAR_ARR(total_syms);
TINFL_MEMSET(pLookUp, 0, sizeof(r->m_look_up[0]));
tinfl_clear_tree(r);
for (i = 0; i < r->m_table_sizes[r->m_type]; ++i)
total_syms[pTable->m_code_size[i]]++;
total_syms[pCode_size[i]]++;
used_syms = 0, total = 0;
next_code[0] = next_code[1] = 0;
for (i = 1; i <= 15; ++i)
@@ -325,7 +351,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
}
for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index)
{
mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index];
mz_uint rev_code = 0, l, cur_code, code_size = pCode_size[sym_index];
if (!code_size)
continue;
cur_code = next_code[code_size]++;
@@ -336,14 +362,14 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
mz_int16 k = (mz_int16)((code_size << 9) | sym_index);
while (rev_code < TINFL_FAST_LOOKUP_SIZE)
{
pTable->m_look_up[rev_code] = k;
pLookUp[rev_code] = k;
rev_code += (1 << code_size);
}
continue;
}
if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)]))
if (0 == (tree_cur = pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)]))
{
pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next;
pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next;
tree_cur = tree_next;
tree_next -= 2;
}
@@ -351,24 +377,24 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--)
{
tree_cur -= ((rev_code >>= 1) & 1);
if (!pTable->m_tree[-tree_cur - 1])
if (!pTree[-tree_cur - 1])
{
pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next;
pTree[-tree_cur - 1] = (mz_int16)tree_next;
tree_cur = tree_next;
tree_next -= 2;
}
else
tree_cur = pTable->m_tree[-tree_cur - 1];
tree_cur = pTree[-tree_cur - 1];
}
tree_cur -= ((rev_code >>= 1) & 1);
pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
pTree[-tree_cur - 1] = (mz_int16)sym_index;
}
if (r->m_type == 2)
{
for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]);)
{
mz_uint s;
TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]);
TINFL_HUFF_DECODE(16, dist, r->m_look_up[2], r->m_tree_2);
if (dist < 16)
{
r->m_len_codes[counter++] = (mz_uint8)dist;
@@ -388,8 +414,8 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
{
TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED);
}
TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]);
TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]);
TINFL_MEMCPY(r->m_code_size_0, r->m_len_codes, r->m_table_sizes[0]);
TINFL_MEMCPY(r->m_code_size_1, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]);
}
}
for (;;)
@@ -399,7 +425,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
{
if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2))
{
TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]);
TINFL_HUFF_DECODE(23, counter, r->m_look_up[0], r->m_tree_0);
if (counter >= 256)
break;
while (pOut_buf_cur >= pOut_buf_end)
@@ -427,14 +453,14 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
num_bits += 16;
}
#endif
if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
if ((sym2 = r->m_look_up[0][bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
code_len = sym2 >> 9;
else
{
code_len = TINFL_FAST_LOOKUP_BITS;
do
{
sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)];
sym2 = r->m_tree_0[~sym2 + ((bit_buf >> code_len++) & 1)];
} while (sym2 < 0);
}
counter = sym2;
@@ -451,14 +477,14 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
num_bits += 16;
}
#endif
if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
if ((sym2 = r->m_look_up[0][bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
code_len = sym2 >> 9;
else
{
code_len = TINFL_FAST_LOOKUP_BITS;
do
{
sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)];
sym2 = r->m_tree_0[~sym2 + ((bit_buf >> code_len++) & 1)];
} while (sym2 < 0);
}
bit_buf >>= code_len;
@@ -487,7 +513,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
counter += extra_bits;
}
TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]);
TINFL_HUFF_DECODE(26, dist, r->m_look_up[1], r->m_tree_1);
num_extra = s_dist_extra[dist];
dist = s_dist_base[dist];
if (num_extra)
@@ -498,7 +524,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
}
dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
if ((dist > dist_from_out_buf_start || dist_from_out_buf_start == 0) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
if ((dist == 0 || dist > dist_from_out_buf_start || dist_from_out_buf_start == 0) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
{
TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED);
}
@@ -572,7 +598,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
--pIn_buf_cur;
num_bits -= 8;
}
bit_buf &= (tinfl_bit_buf_t)((((mz_uint64)1) << num_bits) - (mz_uint64)1);
bit_buf &= ~(~(tinfl_bit_buf_t)0 << num_bits);
MZ_ASSERT(!num_bits); /* if this assert fires then we've read beyond the end of non-deflate/zlib streams with following data (such as gzip streams). */
if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
@@ -604,7 +630,7 @@ common_exit:
}
}
r->m_num_bits = num_bits;
r->m_bit_buf = bit_buf & (tinfl_bit_buf_t)((((mz_uint64)1) << num_bits) - (mz_uint64)1);
r->m_bit_buf = bit_buf & ~(~(tinfl_bit_buf_t)0 << num_bits);
r->m_dist = dist;
r->m_counter = counter;
r->m_num_extra = num_extra;
@@ -699,6 +725,7 @@ int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size,
size_t in_buf_ofs = 0, dict_ofs = 0;
if (!pDict)
return TINFL_STATUS_FAILED;
memset(pDict,0,TINFL_LZ_DICT_SIZE);
tinfl_init(&decomp);
for (;;)
{
@@ -721,7 +748,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 +765,5 @@ void tinfl_decompressor_free(tinfl_decompressor *pDecomp)
#ifdef __cplusplus
}
#endif
#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/

View File

@@ -2,6 +2,8 @@
#include "miniz_common.h"
/* ------------------- Low-level Decompression API Definitions */
#ifndef MINIZ_NO_INFLATE_APIS
#ifdef __cplusplus
extern "C" {
#endif
@@ -110,12 +112,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 +131,18 @@ struct tinfl_decompressor_tag
mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES];
tinfl_bit_buf_t m_bit_buf;
size_t m_dist_from_out_buf_start;
tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES];
mz_int16 m_look_up[TINFL_MAX_HUFF_TABLES][TINFL_FAST_LOOKUP_SIZE];
mz_int16 m_tree_0[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
mz_int16 m_tree_1[TINFL_MAX_HUFF_SYMBOLS_1 * 2];
mz_int16 m_tree_2[TINFL_MAX_HUFF_SYMBOLS_2 * 2];
mz_uint8 m_code_size_0[TINFL_MAX_HUFF_SYMBOLS_0];
mz_uint8 m_code_size_1[TINFL_MAX_HUFF_SYMBOLS_1];
mz_uint8 m_code_size_2[TINFL_MAX_HUFF_SYMBOLS_2];
mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137];
};
#ifdef __cplusplus
}
#endif
#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/

View File

@@ -40,19 +40,48 @@ extern "C" {
#include <sys/stat.h>
#if defined(_MSC_VER) || defined(__MINGW64__)
#define WIN32_LEAN_AND_MEAN
#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, sizeof(WCHAR) * reqChars);
return wStr;
}
static FILE *mz_fopen(const char *pFilename, const char *pMode)
{
FILE *pFile = NULL;
fopen_s(&pFile, pFilename, pMode);
return pFile;
WCHAR* wFilename = mz_utf8z_to_widechar(pFilename);
WCHAR* wMode = mz_utf8z_to_widechar(pMode);
FILE* pFile = NULL;
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)
{
FILE *pFile = NULL;
if (freopen_s(&pFile, pPath, pMode, pStream))
return NULL;
return pFile;
WCHAR* wPath = mz_utf8z_to_widechar(pPath);
WCHAR* wMode = mz_utf8z_to_widechar(pMode);
FILE* pFile = NULL;
errno_t err = _wfreopen_s(&pFile, wPath, wMode, pStream);
free(wPath);
free(wMode);
return err ? NULL : pFile;
}
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;
}
#ifndef MINIZ_NO_TIME
#include <sys/utime.h>
#endif
@@ -63,11 +92,12 @@ static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream)
#define MZ_FTELL64 _ftelli64
#define MZ_FSEEK64 _fseeki64
#define MZ_FILE_STAT_STRUCT _stat64
#define MZ_FILE_STAT _stat64
#define MZ_FILE_STAT mz_stat64
#define MZ_FFLUSH fflush
#define MZ_FREOPEN mz_freopen
#define MZ_DELETE_FILE remove
#elif defined(__MINGW32__)
#elif defined(__MINGW32__) || defined(__WATCOMC__)
#ifndef MINIZ_NO_TIME
#include <sys/utime.h>
#endif
@@ -75,13 +105,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 +128,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 +144,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__)
#ifndef MINIZ_NO_TIME
#include <utime.h>
#endif
@@ -258,7 +291,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;
@@ -277,7 +310,7 @@ struct mz_zip_internal_state_tag
#define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size) (array_ptr)->m_element_size = element_size
#if defined(DEBUG) || defined(_DEBUG) || defined(NDEBUG)
#if defined(DEBUG) || defined(_DEBUG)
static MZ_FORCEINLINE mz_uint mz_zip_array_range_check(const mz_zip_array *pArray, mz_uint index)
{
MZ_ASSERT(index < pArray->m_size);
@@ -694,7 +727,7 @@ 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)
@@ -845,7 +878,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)
@@ -1319,7 +1352,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 +1367,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 +1460,8 @@ 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,6 +1474,9 @@ 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 (st) {
file_stat = *st;
} else
if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
return MZ_FALSE;
@@ -1570,17 +1607,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 +1632,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 +1655,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;
@@ -2080,7 +2116,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 +2485,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 +2503,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 +2864,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
{
@@ -3194,7 +3227,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); */
@@ -3287,7 +3320,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))
{
@@ -3434,35 +3467,37 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n
return MZ_TRUE;
}
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 size_to_add, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
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 = 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 = size_to_add, comp_size = 0;
mz_uint64 local_dir_header_ofs, cur_archive_file_ofs = pZip->m_archive_size, uncomp_size = 0, comp_size = 0;
size_t archive_name_size;
mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
mz_uint8 *pExtra_data = NULL;
mz_uint32 extra_size = 0;
mz_uint8 extra_data[MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE];
mz_zip_internal_state *pState;
mz_uint64 file_ofs = 0;
if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME))
gen_flags |= MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8;
mz_uint64 file_ofs = 0, cur_archive_header_file_ofs;
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);
pState = pZip->m_pState;
if ((!pState->m_zip64) && (uncomp_size > MZ_UINT32_MAX))
if ((!pState->m_zip64) && (max_size > MZ_UINT32_MAX))
{
/* Source file is too large for non-zip64 */
/*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
@@ -3519,7 +3554,7 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA
}
#endif
if (uncomp_size <= 3)
if (max_size <= 3)
level = 0;
if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes))
@@ -3535,19 +3570,25 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA
MZ_ASSERT((cur_archive_file_ofs & (pZip->m_file_offset_alignment - 1)) == 0);
}
if (uncomp_size && level)
if (max_size && level)
{
method = MZ_DEFLATED;
}
MZ_CLEAR_OBJ(local_dir_header);
MZ_CLEAR_ARR(local_dir_header);
if (pState->m_zip64)
{
if (uncomp_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX)
if (max_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX)
{
pExtra_data = extra_data;
extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
(uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
if (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE)
extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (max_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
(max_size >= MZ_UINT32_MAX) ? &comp_size : NULL,
(local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
else
extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, NULL,
NULL,
(local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
}
if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, (mz_uint16)(extra_size + user_extra_data_len), 0, 0, 0, method, gen_flags, dos_time, dos_date))
@@ -3598,9 +3639,8 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA
cur_archive_file_ofs += user_extra_data_len;
}
if (uncomp_size)
if (max_size)
{
mz_uint64 uncomp_remaining = uncomp_size;
void *pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, MZ_ZIP_MAX_IO_BUF_SIZE);
if (!pRead_buf)
{
@@ -3609,19 +3649,27 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA
if (!level)
{
while (uncomp_remaining)
while (1)
{
mz_uint n = (mz_uint)MZ_MIN((mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE, uncomp_remaining);
if ((read_callback(callback_opaque, file_ofs, pRead_buf, n) != n) || (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf, n) != n))
size_t n = read_callback(callback_opaque, file_ofs, pRead_buf, MZ_ZIP_MAX_IO_BUF_SIZE);
if (n == 0)
break;
if ((n > MZ_ZIP_MAX_IO_BUF_SIZE) || (file_ofs + n > max_size))
{
pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
}
file_ofs += n;
if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf, n) != n)
{
pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
}
file_ofs += n;
uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n);
uncomp_remaining -= n;
cur_archive_file_ofs += n;
}
uncomp_size = file_ofs;
comp_size = uncomp_size;
}
else
@@ -3648,24 +3696,26 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA
for (;;)
{
size_t in_buf_size = (mz_uint32)MZ_MIN(uncomp_remaining, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
tdefl_status status;
tdefl_flush flush = TDEFL_NO_FLUSH;
if (read_callback(callback_opaque, file_ofs, pRead_buf, in_buf_size)!= in_buf_size)
size_t n = read_callback(callback_opaque, file_ofs, pRead_buf, MZ_ZIP_MAX_IO_BUF_SIZE);
if ((n > MZ_ZIP_MAX_IO_BUF_SIZE) || (file_ofs + n > max_size))
{
mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
break;
}
file_ofs += in_buf_size;
uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, in_buf_size);
uncomp_remaining -= in_buf_size;
file_ofs += n;
uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n);
if (pZip->m_pNeeds_keepalive != NULL && pZip->m_pNeeds_keepalive(pZip->m_pIO_opaque))
flush = TDEFL_FULL_FLUSH;
status = tdefl_compress_buffer(pComp, pRead_buf, in_buf_size, uncomp_remaining ? flush : TDEFL_FINISH);
if (n == 0)
flush = TDEFL_FINISH;
status = tdefl_compress_buffer(pComp, pRead_buf, n, flush);
if (status == TDEFL_STATUS_DONE)
{
result = MZ_TRUE;
@@ -3686,6 +3736,7 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA
return MZ_FALSE;
}
uncomp_size = file_ofs;
comp_size = state.m_comp_size;
cur_archive_file_ofs = state.m_cur_archive_file_ofs;
}
@@ -3693,6 +3744,7 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA
pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
}
if (!(level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE))
{
mz_uint8 local_dir_footer[MZ_ZIP_DATA_DESCRIPTER_SIZE64];
mz_uint32 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE32;
@@ -3720,6 +3772,44 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA
cur_archive_file_ofs += local_dir_footer_size;
}
if (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE)
{
if (pExtra_data != NULL)
{
extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (max_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
(max_size >= MZ_UINT32_MAX) ? &comp_size : NULL, (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
}
if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header,
(mz_uint16)archive_name_size, (mz_uint16)(extra_size + user_extra_data_len),
(max_size >= MZ_UINT32_MAX) ? MZ_UINT32_MAX : uncomp_size,
(max_size >= MZ_UINT32_MAX) ? MZ_UINT32_MAX : comp_size,
uncomp_crc32, method, gen_flags, dos_time, dos_date))
return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
cur_archive_header_file_ofs = local_dir_header_ofs;
if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header))
return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
if (pExtra_data != NULL)
{
cur_archive_header_file_ofs += sizeof(local_dir_header);
if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs, pArchive_name, archive_name_size) != archive_name_size)
{
return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
}
cur_archive_header_file_ofs += archive_name_size;
if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs, extra_data, extra_size) != extra_size)
return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
cur_archive_header_file_ofs += extra_size;
}
}
if (pExtra_data != NULL)
{
extra_size = mz_zip_writer_create_zip64_extra_data(extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
@@ -3750,10 +3840,10 @@ static size_t mz_file_read_func_stdio(void *pOpaque, mz_uint64 file_ofs, void *p
return MZ_FREAD(pBuf, 1, n, pSrc_file);
}
mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 size_to_add, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 max_size, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len)
{
return mz_zip_writer_add_read_buf_callback(pZip, pArchive_name, mz_file_read_func_stdio, pSrc_file, size_to_add, pFile_time, pComment, comment_size, level_and_flags,
return mz_zip_writer_add_read_buf_callback(pZip, pArchive_name, mz_file_read_func_stdio, pSrc_file, max_size, pFile_time, pComment, comment_size, level_and_flags,
user_extra_data, user_extra_data_len, user_extra_data_central, user_extra_data_central_len);
}
@@ -3789,7 +3879,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))
@@ -4105,10 +4195,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);
@@ -4244,7 +4334,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
@@ -4272,7 +4362,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 */
@@ -4287,7 +4377,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);
@@ -4298,7 +4388,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));
@@ -4614,7 +4704,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;
}

View File

@@ -32,10 +32,6 @@ typedef struct
mz_uint16 m_bit_flag;
mz_uint16 m_method;
#ifndef MINIZ_NO_TIME
MZ_TIME_T m_time;
#endif
/* CRC-32 of uncompressed data. */
mz_uint32 m_crc32;
@@ -72,6 +68,11 @@ typedef struct
/* Guaranteed to be zero terminated, may be truncated to fit. */
char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE];
#ifdef MINIZ_NO_TIME
MZ_TIME_T m_padding;
#else
MZ_TIME_T m_time;
#endif
} mz_zip_archive_file_stat;
typedef size_t (*mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n);
@@ -97,7 +98,10 @@ typedef enum {
MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY = 0x2000, /* validate the local headers, but don't decompress the entire file and check the crc32 */
MZ_ZIP_FLAG_WRITE_ZIP64 = 0x4000, /* always use the zip64 file format, instead of the original zip file format with automatic switch to zip64. Use as flags parameter with mz_zip_writer_init*_v2 */
MZ_ZIP_FLAG_WRITE_ALLOW_READING = 0x8000,
MZ_ZIP_FLAG_ASCII_FILENAME = 0x10000
MZ_ZIP_FLAG_ASCII_FILENAME = 0x10000,
/*After adding a compressed file, seek back
to local file header and set the correct sizes*/
MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE = 0x20000
} mz_zip_flags;
typedef enum {
@@ -180,9 +184,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;
@@ -192,6 +194,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 */
@@ -315,9 +323,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
@@ -331,7 +339,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);
@@ -380,17 +390,18 @@ MINIZ_EXPORT mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const cha
/* Adds the contents of a file to an archive. This function also records the disk file's modified time into the archive. */
/* File data is supplied via a read callback function. User mz_zip_writer_add_(c)file to add a file directly.*/
MINIZ_EXPORT mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pArchive_name, mz_file_read_func read_callback, void* callback_opaque, mz_uint64 size_to_add,
MINIZ_EXPORT mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pArchive_name, mz_file_read_func read_callback, void* callback_opaque, mz_uint64 max_size,
const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data_local, mz_uint user_extra_data_local_len,
const char *user_extra_data_central, mz_uint user_extra_data_central_len);
#ifndef MINIZ_NO_STDIO
/* Adds the contents of a disk file to an archive. This function also records the disk file's modified time into the archive. */
/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */
MINIZ_EXPORT mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
/* Like mz_zip_writer_add_file(), except the file data is read from the specified FILE stream. */
MINIZ_EXPORT mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 size_to_add,
MINIZ_EXPORT mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 max_size,
const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data_local, mz_uint user_extra_data_local_len,
const char *user_extra_data_central, mz_uint user_extra_data_central_len);
#endif
@@ -404,7 +415,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);
@@ -421,11 +432,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 */