188#ifdef MINIZ_NO_INFLATE_APIS
189#define MINIZ_NO_ARCHIVE_APIS
192#ifdef MINIZ_NO_DEFLATE_APIS
193#define MINIZ_NO_ARCHIVE_WRITING_APIS
196#if defined(__TINYC__) && (defined(__linux) || defined(__linux__))
204#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_ARCHIVE_APIS)
208#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || \
209 defined(__i386) || defined(__i486__) || defined(__i486) || \
210 defined(i386) || defined(__ia64__) || defined(__x86_64__)
212#define MINIZ_X86_OR_X64_CPU 1
214#define MINIZ_X86_OR_X64_CPU 0
218#if !defined(MINIZ_LITTLE_ENDIAN)
219#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)
221#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
223#define MINIZ_LITTLE_ENDIAN 1
225#define MINIZ_LITTLE_ENDIAN 0
230#if MINIZ_X86_OR_X64_CPU
231#define MINIZ_LITTLE_ENDIAN 1
233#define MINIZ_LITTLE_ENDIAN 0
240#if defined(__has_feature)
241#if __has_feature(undefined_behavior_sanitizer)
242#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0
247#if !defined(MINIZ_USE_UNALIGNED_LOADS_AND_STORES)
248#if MINIZ_X86_OR_X64_CPU
251#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0
252#define MINIZ_UNALIGNED_USE_MEMCPY
254#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0
258#if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || \
259 defined(_LP64) || defined(__LP64__) || defined(__ia64__) || \
264#define MINIZ_HAS_64BIT_REGISTERS 1
266#define MINIZ_HAS_64BIT_REGISTERS 0
277typedef unsigned long mz_ulong;
282MINIZ_EXPORT
void mz_free(
void *p);
284#define MZ_ADLER32_INIT (1)
287MINIZ_EXPORT mz_ulong mz_adler32(mz_ulong adler,
const unsigned char *ptr,
290#define MZ_CRC32_INIT (0)
293MINIZ_EXPORT mz_ulong mz_crc32(mz_ulong crc,
const unsigned char *ptr,
298 MZ_DEFAULT_STRATEGY = 0,
311typedef void *(*mz_alloc_func)(
void *opaque,
size_t items,
size_t size);
312typedef void (*mz_free_func)(
void *opaque,
void *address);
313typedef void *(*mz_realloc_func)(
void *opaque,
void *address,
size_t items,
320 MZ_NO_COMPRESSION = 0,
322 MZ_BEST_COMPRESSION = 9,
323 MZ_UBER_COMPRESSION = 10,
324 MZ_DEFAULT_LEVEL = 6,
325 MZ_DEFAULT_COMPRESSION = -1
328#define MZ_VERSION "11.0.2"
329#define MZ_VERNUM 0xB002
330#define MZ_VER_MAJOR 11
331#define MZ_VER_MINOR 2
332#define MZ_VER_REVISION 0
333#define MZ_VER_SUBREVISION 0
335#ifndef MINIZ_NO_ZLIB_APIS
341 MZ_PARTIAL_FLUSH = 1,
354 MZ_STREAM_ERROR = -2,
358 MZ_VERSION_ERROR = -6,
359 MZ_PARAM_ERROR = -10000
363#define MZ_DEFAULT_WINDOW_BITS 15
365struct mz_internal_state;
368typedef struct mz_stream_s {
369 const unsigned char *next_in;
370 unsigned int avail_in;
373 unsigned char *next_out;
374 unsigned int avail_out;
378 struct mz_internal_state
394MINIZ_EXPORT
const char *mz_version(
void);
396#ifndef MINIZ_NO_DEFLATE_APIS
411MINIZ_EXPORT
int mz_deflateInit(
mz_streamp pStream,
int level);
420MINIZ_EXPORT
int mz_deflateInit2(
mz_streamp pStream,
int level,
int method,
421 int window_bits,
int mem_level,
int strategy);
425MINIZ_EXPORT
int mz_deflateReset(
mz_streamp pStream);
445MINIZ_EXPORT
int mz_deflate(
mz_streamp pStream,
int flush);
451MINIZ_EXPORT
int mz_deflateEnd(
mz_streamp pStream);
456MINIZ_EXPORT mz_ulong mz_deflateBound(
mz_streamp pStream, mz_ulong source_len);
461MINIZ_EXPORT
int mz_compress(
unsigned char *pDest, mz_ulong *pDest_len,
462 const unsigned char *pSource, mz_ulong source_len);
463MINIZ_EXPORT
int mz_compress2(
unsigned char *pDest, mz_ulong *pDest_len,
464 const unsigned char *pSource, mz_ulong source_len,
469MINIZ_EXPORT mz_ulong mz_compressBound(mz_ulong source_len);
473#ifndef MINIZ_NO_INFLATE_APIS
476MINIZ_EXPORT
int mz_inflateInit(
mz_streamp pStream);
483MINIZ_EXPORT
int mz_inflateInit2(
mz_streamp pStream,
int window_bits);
487MINIZ_EXPORT
int mz_inflateReset(
mz_streamp pStream);
515MINIZ_EXPORT
int mz_inflate(
mz_streamp pStream,
int flush);
518MINIZ_EXPORT
int mz_inflateEnd(
mz_streamp pStream);
523MINIZ_EXPORT
int mz_uncompress(
unsigned char *pDest, mz_ulong *pDest_len,
524 const unsigned char *pSource,
525 mz_ulong source_len);
526MINIZ_EXPORT
int mz_uncompress2(
unsigned char *pDest, mz_ulong *pDest_len,
527 const unsigned char *pSource,
528 mz_ulong *pSource_len);
533MINIZ_EXPORT
const char *mz_error(
int err);
539#ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
540typedef unsigned char Byte;
541typedef unsigned int uInt;
542typedef mz_ulong uLong;
550typedef void *
const voidpc;
552#define Z_NO_FLUSH MZ_NO_FLUSH
553#define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH
554#define Z_SYNC_FLUSH MZ_SYNC_FLUSH
555#define Z_FULL_FLUSH MZ_FULL_FLUSH
556#define Z_FINISH MZ_FINISH
557#define Z_BLOCK MZ_BLOCK
559#define Z_STREAM_END MZ_STREAM_END
560#define Z_NEED_DICT MZ_NEED_DICT
561#define Z_ERRNO MZ_ERRNO
562#define Z_STREAM_ERROR MZ_STREAM_ERROR
563#define Z_DATA_ERROR MZ_DATA_ERROR
564#define Z_MEM_ERROR MZ_MEM_ERROR
565#define Z_BUF_ERROR MZ_BUF_ERROR
566#define Z_VERSION_ERROR MZ_VERSION_ERROR
567#define Z_PARAM_ERROR MZ_PARAM_ERROR
568#define Z_NO_COMPRESSION MZ_NO_COMPRESSION
569#define Z_BEST_SPEED MZ_BEST_SPEED
570#define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION
571#define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION
572#define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY
573#define Z_FILTERED MZ_FILTERED
574#define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY
576#define Z_FIXED MZ_FIXED
577#define Z_DEFLATED MZ_DEFLATED
578#define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS
579#define alloc_func mz_alloc_func
580#define free_func mz_free_func
581#define internal_state mz_internal_state
582#define z_stream mz_stream
584#ifndef MINIZ_NO_DEFLATE_APIS
585#define deflateInit mz_deflateInit
586#define deflateInit2 mz_deflateInit2
587#define deflateReset mz_deflateReset
588#define deflate mz_deflate
589#define deflateEnd mz_deflateEnd
590#define deflateBound mz_deflateBound
591#define compress mz_compress
592#define compress2 mz_compress2
593#define compressBound mz_compressBound
596#ifndef MINIZ_NO_INFLATE_APIS
597#define inflateInit mz_inflateInit
598#define inflateInit2 mz_inflateInit2
599#define inflateReset mz_inflateReset
600#define inflate mz_inflate
601#define inflateEnd mz_inflateEnd
602#define uncompress mz_uncompress
603#define uncompress2 mz_uncompress2
606#define crc32 mz_crc32
607#define adler32 mz_adler32
609#define MAX_MEM_LEVEL 9
610#define zError mz_error
611#define ZLIB_VERSION MZ_VERSION
612#define ZLIB_VERNUM MZ_VERNUM
613#define ZLIB_VER_MAJOR MZ_VER_MAJOR
614#define ZLIB_VER_MINOR MZ_VER_MINOR
615#define ZLIB_VER_REVISION MZ_VER_REVISION
616#define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION
617#define zlibVersion mz_version
618#define zlib_version mz_version()
634typedef unsigned char mz_uint8;
635typedef signed short mz_int16;
636typedef unsigned short mz_uint16;
637typedef unsigned int mz_uint32;
638typedef unsigned int mz_uint;
639typedef int64_t mz_int64;
640typedef uint64_t mz_uint64;
649#define MZ_MACRO_END while (0, 0)
651#define MZ_MACRO_END while (0)
655#define MZ_FILE void *
662typedef struct mz_dummy_time_t_tag {
666#define MZ_TIME_T mz_dummy_time_t
668#define MZ_TIME_T time_t
671#define MZ_ASSERT(x) assert(x)
673#ifdef MINIZ_NO_MALLOC
674#define MZ_MALLOC(x) NULL
675#define MZ_FREE(x) (void)x, ((void)0)
676#define MZ_REALLOC(p, x) NULL
678#define MZ_MALLOC(x) malloc(x)
679#define MZ_FREE(x) free(x)
680#define MZ_REALLOC(p, x) realloc(p, x)
683#define MZ_MAX(a, b) (((a) > (b)) ? (a) : (b))
684#define MZ_MIN(a, b) (((a) < (b)) ? (a) : (b))
685#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
686#define MZ_CLEAR_ARR(obj) memset((obj), 0, sizeof(obj))
687#define MZ_CLEAR_PTR(obj) memset((obj), 0, sizeof(*obj))
689#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
690#define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
691#define MZ_READ_LE32(p) *((const mz_uint32 *)(p))
693#define MZ_READ_LE16(p) \
694 ((mz_uint32)(((const mz_uint8 *)(p))[0]) | \
695 ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U))
696#define MZ_READ_LE32(p) \
697 ((mz_uint32)(((const mz_uint8 *)(p))[0]) | \
698 ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | \
699 ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | \
700 ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U))
703#define MZ_READ_LE64(p) \
704 (((mz_uint64)MZ_READ_LE32(p)) | \
705 (((mz_uint64)MZ_READ_LE32((const mz_uint8 *)(p) + sizeof(mz_uint32))) \
709#define MZ_FORCEINLINE __forceinline
710#elif defined(__GNUC__)
711#define MZ_FORCEINLINE __inline__ __attribute__((__always_inline__))
713#define MZ_FORCEINLINE inline
720extern MINIZ_EXPORT
void *miniz_def_alloc_func(
void *opaque,
size_t items,
722extern MINIZ_EXPORT
void miniz_def_free_func(
void *opaque,
void *address);
723extern MINIZ_EXPORT
void *miniz_def_realloc_func(
void *opaque,
void *address,
724 size_t items,
size_t size);
726#define MZ_UINT16_MAX (0xFFFFU)
727#define MZ_UINT32_MAX (0xFFFFFFFFU)
734#ifndef MINIZ_NO_DEFLATE_APIS
743#ifndef TDEFL_LESS_MEMORY
744#define TDEFL_LESS_MEMORY 0
753 TDEFL_HUFFMAN_ONLY = 0,
754 TDEFL_DEFAULT_MAX_PROBES = 128,
755 TDEFL_MAX_PROBES_MASK = 0xFFF
776 TDEFL_WRITE_ZLIB_HEADER = 0x01000,
777 TDEFL_COMPUTE_ADLER32 = 0x02000,
778 TDEFL_GREEDY_PARSING_FLAG = 0x04000,
779 TDEFL_NONDETERMINISTIC_PARSING_FLAG = 0x08000,
780 TDEFL_RLE_MATCHES = 0x10000,
781 TDEFL_FILTER_MATCHES = 0x20000,
782 TDEFL_FORCE_ALL_STATIC_BLOCKS = 0x40000,
783 TDEFL_FORCE_ALL_RAW_BLOCKS = 0x80000
798MINIZ_EXPORT
void *tdefl_compress_mem_to_heap(
const void *pSrc_buf,
800 size_t *pOut_len,
int flags);
805MINIZ_EXPORT
size_t tdefl_compress_mem_to_mem(
void *pOut_buf,
807 const void *pSrc_buf,
808 size_t src_buf_len,
int flags);
826tdefl_write_image_to_png_file_in_memory_ex(
const void *pImage,
int w,
int h,
827 int num_chans,
size_t *pLen_out,
828 mz_uint level, mz_bool flip);
829MINIZ_EXPORT
void *tdefl_write_image_to_png_file_in_memory(
const void *pImage,
836typedef mz_bool (*tdefl_put_buf_func_ptr)(
const void *pBuf,
int len,
841MINIZ_EXPORT mz_bool tdefl_compress_mem_to_output(
842 const void *pBuf,
size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func,
843 void *pPut_buf_user,
int flags);
846 TDEFL_MAX_HUFF_TABLES = 3,
847 TDEFL_MAX_HUFF_SYMBOLS_0 = 288,
848 TDEFL_MAX_HUFF_SYMBOLS_1 = 32,
849 TDEFL_MAX_HUFF_SYMBOLS_2 = 19,
850 TDEFL_LZ_DICT_SIZE = 32768,
851 TDEFL_LZ_DICT_SIZE_MASK = TDEFL_LZ_DICT_SIZE - 1,
852 TDEFL_MIN_MATCH_LEN = 3,
853 TDEFL_MAX_MATCH_LEN = 258
860 TDEFL_LZ_CODE_BUF_SIZE = 24 * 1024,
861 TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10,
862 TDEFL_MAX_HUFF_SYMBOLS = 288,
863 TDEFL_LZ_HASH_BITS = 12,
864 TDEFL_LEVEL1_HASH_SIZE_MASK = 4095,
865 TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3,
866 TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS
870 TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024,
871 TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10,
872 TDEFL_MAX_HUFF_SYMBOLS = 288,
873 TDEFL_LZ_HASH_BITS = 15,
874 TDEFL_LEVEL1_HASH_SIZE_MASK = 4095,
875 TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3,
876 TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS
884 TDEFL_STATUS_BAD_PARAM = -2,
885 TDEFL_STATUS_PUT_BUF_FAILED = -1,
886 TDEFL_STATUS_OKAY = 0,
887 TDEFL_STATUS_DONE = 1
893 TDEFL_SYNC_FLUSH = 2,
894 TDEFL_FULL_FLUSH = 3,
900 tdefl_put_buf_func_ptr m_pPut_buf_func;
901 void *m_pPut_buf_user;
902 mz_uint m_flags, m_max_probes[2];
903 int m_greedy_parsing;
904 mz_uint m_adler32, m_lookahead_pos, m_lookahead_size, m_dict_size;
905 mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end;
906 mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in,
908 mz_uint m_saved_match_dist, m_saved_match_len, m_saved_lit,
909 m_output_flush_ofs, m_output_flush_remaining, m_finished, m_block_index,
911 tdefl_status m_prev_return_status;
912 const void *m_pIn_buf;
914 size_t *m_pIn_buf_size, *m_pOut_buf_size;
916 const mz_uint8 *m_pSrc;
917 size_t m_src_buf_left, m_out_buf_ofs;
918 mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE + TDEFL_MAX_MATCH_LEN - 1];
919 mz_uint16 m_huff_count[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
920 mz_uint16 m_huff_codes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
921 mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
922 mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE];
923 mz_uint16 m_next[TDEFL_LZ_DICT_SIZE];
924 mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE];
925 mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE];
939 tdefl_put_buf_func_ptr pPut_buf_func,
940 void *pPut_buf_user,
int flags);
947 size_t *pIn_buf_size,
void *pOut_buf,
948 size_t *pOut_buf_size,
968MINIZ_EXPORT mz_uint tdefl_create_comp_flags_from_zip_params(
int level,
972#ifndef MINIZ_NO_MALLOC
989#ifndef MINIZ_NO_INFLATE_APIS
1007 TINFL_FLAG_PARSE_ZLIB_HEADER = 1,
1008 TINFL_FLAG_HAS_MORE_INPUT = 2,
1009 TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4,
1010 TINFL_FLAG_COMPUTE_ADLER32 = 8
1025MINIZ_EXPORT
void *tinfl_decompress_mem_to_heap(
const void *pSrc_buf,
1027 size_t *pOut_len,
int flags);
1033#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1))
1034MINIZ_EXPORT
size_t tinfl_decompress_mem_to_mem(
void *pOut_buf,
1036 const void *pSrc_buf,
1037 size_t src_buf_len,
int flags);
1043typedef int (*tinfl_put_buf_func_ptr)(
const void *pBuf,
int len,
void *pUser);
1045tinfl_decompress_mem_to_callback(
const void *pIn_buf,
size_t *pIn_buf_size,
1046 tinfl_put_buf_func_ptr pPut_buf_func,
1047 void *pPut_buf_user,
int flags);
1052#ifndef MINIZ_NO_MALLOC
1056MINIZ_EXPORT tinfl_decompressor *tinfl_decompressor_alloc(
void);
1057MINIZ_EXPORT
void tinfl_decompressor_free(tinfl_decompressor *pDecomp);
1061#define TINFL_LZ_DICT_SIZE 32768
1073 TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS = -4,
1078 TINFL_STATUS_BAD_PARAM = -3,
1083 TINFL_STATUS_ADLER32_MISMATCH = -2,
1088 TINFL_STATUS_FAILED = -1,
1098 TINFL_STATUS_DONE = 0,
1107 TINFL_STATUS_NEEDS_MORE_INPUT = 1,
1119 TINFL_STATUS_HAS_MORE_OUTPUT = 2
1123#define tinfl_init(r) \
1128#define tinfl_get_adler32(r) (r)->m_check_adler32
1136MINIZ_EXPORT tinfl_status tinfl_decompress(
1137 tinfl_decompressor *r,
const mz_uint8 *pIn_buf_next,
size_t *pIn_buf_size,
1138 mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next,
size_t *pOut_buf_size,
1139 const mz_uint32 decomp_flags);
1143 TINFL_MAX_HUFF_TABLES = 3,
1144 TINFL_MAX_HUFF_SYMBOLS_0 = 288,
1145 TINFL_MAX_HUFF_SYMBOLS_1 = 32,
1146 TINFL_MAX_HUFF_SYMBOLS_2 = 19,
1147 TINFL_FAST_LOOKUP_BITS = 10,
1148 TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS
1151#if MINIZ_HAS_64BIT_REGISTERS
1152#define TINFL_USE_64BIT_BITBUF 1
1154#define TINFL_USE_64BIT_BITBUF 0
1157#if TINFL_USE_64BIT_BITBUF
1158typedef mz_uint64 tinfl_bit_buf_t;
1159#define TINFL_BITBUF_SIZE (64)
1161typedef mz_uint32 tinfl_bit_buf_t;
1162#define TINFL_BITBUF_SIZE (32)
1166 mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type,
1167 m_check_adler32, m_dist, m_counter, m_num_extra,
1168 m_table_sizes[TINFL_MAX_HUFF_TABLES];
1169 tinfl_bit_buf_t m_bit_buf;
1170 size_t m_dist_from_out_buf_start;
1171 mz_int16 m_look_up[TINFL_MAX_HUFF_TABLES][TINFL_FAST_LOOKUP_SIZE];
1172 mz_int16 m_tree_0[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
1173 mz_int16 m_tree_1[TINFL_MAX_HUFF_SYMBOLS_1 * 2];
1174 mz_int16 m_tree_2[TINFL_MAX_HUFF_SYMBOLS_2 * 2];
1175 mz_uint8 m_code_size_0[TINFL_MAX_HUFF_SYMBOLS_0];
1176 mz_uint8 m_code_size_1[TINFL_MAX_HUFF_SYMBOLS_1];
1177 mz_uint8 m_code_size_2[TINFL_MAX_HUFF_SYMBOLS_2];
1178 mz_uint8 m_raw_header[4],
1179 m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137];
1192#ifndef MINIZ_NO_ARCHIVE_APIS
1201 MZ_ZIP_MAX_IO_BUF_SIZE = 64 * 1024,
1202 MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE = 512,
1203 MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE = 512
1208 mz_uint32 m_file_index;
1212 mz_uint64 m_central_dir_ofs;
1215 mz_uint16 m_version_made_by;
1216 mz_uint16 m_version_needed;
1217 mz_uint16 m_bit_flag;
1224 mz_uint64 m_comp_size;
1229 mz_uint64 m_uncomp_size;
1232 mz_uint16 m_internal_attr;
1233 mz_uint32 m_external_attr;
1236 mz_uint64 m_local_header_ofs;
1239 mz_uint32 m_comment_size;
1242 mz_bool m_is_directory;
1246 mz_bool m_is_encrypted;
1250 mz_bool m_is_supported;
1254 char m_filename[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE];
1258 char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE];
1261 MZ_TIME_T m_padding;
1267typedef size_t (*mz_file_read_func)(
void *pOpaque, mz_uint64 file_ofs,
1268 void *pBuf,
size_t n);
1269typedef size_t (*mz_file_write_func)(
void *pOpaque, mz_uint64 file_ofs,
1270 const void *pBuf,
size_t n);
1271typedef mz_bool (*mz_file_needs_keepalive)(
void *pOpaque);
1277 MZ_ZIP_MODE_INVALID = 0,
1278 MZ_ZIP_MODE_READING = 1,
1279 MZ_ZIP_MODE_WRITING = 2,
1280 MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3
1284 MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100,
1285 MZ_ZIP_FLAG_IGNORE_PATH = 0x0200,
1286 MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400,
1287 MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY = 0x0800,
1288 MZ_ZIP_FLAG_VALIDATE_LOCATE_FILE_FLAG =
1292 MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY =
1295 MZ_ZIP_FLAG_WRITE_ZIP64 =
1299 MZ_ZIP_FLAG_WRITE_ALLOW_READING = 0x8000,
1300 MZ_ZIP_FLAG_ASCII_FILENAME = 0x10000,
1303 MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE = 0x20000
1307 MZ_ZIP_TYPE_INVALID = 0,
1319 MZ_ZIP_NO_ERROR = 0,
1320 MZ_ZIP_UNDEFINED_ERROR,
1321 MZ_ZIP_TOO_MANY_FILES,
1322 MZ_ZIP_FILE_TOO_LARGE,
1323 MZ_ZIP_UNSUPPORTED_METHOD,
1324 MZ_ZIP_UNSUPPORTED_ENCRYPTION,
1325 MZ_ZIP_UNSUPPORTED_FEATURE,
1326 MZ_ZIP_FAILED_FINDING_CENTRAL_DIR,
1327 MZ_ZIP_NOT_AN_ARCHIVE,
1328 MZ_ZIP_INVALID_HEADER_OR_CORRUPTED,
1329 MZ_ZIP_UNSUPPORTED_MULTIDISK,
1330 MZ_ZIP_DECOMPRESSION_FAILED,
1331 MZ_ZIP_COMPRESSION_FAILED,
1332 MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE,
1333 MZ_ZIP_CRC_CHECK_FAILED,
1334 MZ_ZIP_UNSUPPORTED_CDIR_SIZE,
1335 MZ_ZIP_ALLOC_FAILED,
1336 MZ_ZIP_FILE_OPEN_FAILED,
1337 MZ_ZIP_FILE_CREATE_FAILED,
1338 MZ_ZIP_FILE_WRITE_FAILED,
1339 MZ_ZIP_FILE_READ_FAILED,
1340 MZ_ZIP_FILE_CLOSE_FAILED,
1341 MZ_ZIP_FILE_SEEK_FAILED,
1342 MZ_ZIP_FILE_STAT_FAILED,
1343 MZ_ZIP_INVALID_PARAMETER,
1344 MZ_ZIP_INVALID_FILENAME,
1345 MZ_ZIP_BUF_TOO_SMALL,
1346 MZ_ZIP_INTERNAL_ERROR,
1347 MZ_ZIP_FILE_NOT_FOUND,
1348 MZ_ZIP_ARCHIVE_TOO_LARGE,
1349 MZ_ZIP_VALIDATION_FAILED,
1350 MZ_ZIP_WRITE_CALLBACK_FAILED,
1355 mz_uint64 m_archive_size;
1356 mz_uint64 m_central_directory_file_ofs;
1359 mz_uint32 m_total_files;
1360 mz_zip_mode m_zip_mode;
1361 mz_zip_type m_zip_type;
1362 mz_zip_error m_last_error;
1364 mz_uint64 m_file_offset_alignment;
1366 mz_alloc_func m_pAlloc;
1367 mz_free_func m_pFree;
1368 mz_realloc_func m_pRealloc;
1369 void *m_pAlloc_opaque;
1371 mz_file_read_func m_pRead;
1372 mz_file_write_func m_pWrite;
1373 mz_file_needs_keepalive m_pNeeds_keepalive;
1376 mz_zip_internal_state *m_pState;
1386 mz_uint64 read_buf_size, read_buf_ofs, read_buf_avail, comp_remaining,
1387 out_buf_ofs, cur_file_ofs;
1392 size_t out_blk_remain;
1394 tinfl_decompressor inflator;
1396#ifdef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
1408MINIZ_EXPORT mz_bool mz_zip_reader_init(
mz_zip_archive *pZip, mz_uint64 size,
1412 const void *pMem,
size_t size,
1415#ifndef MINIZ_NO_STDIO
1421MINIZ_EXPORT mz_bool mz_zip_reader_init_file(
mz_zip_archive *pZip,
1422 const char *pFilename,
1424MINIZ_EXPORT mz_bool mz_zip_reader_init_file_v2(
mz_zip_archive *pZip,
1425 const char *pFilename,
1427 mz_uint64 file_start_ofs,
1428 mz_uint64 archive_size);
1435MINIZ_EXPORT mz_bool mz_zip_reader_init_cfile(
mz_zip_archive *pZip,
1437 mz_uint64 archive_size,
1456MINIZ_EXPORT mz_uint mz_zip_reader_get_num_files(
mz_zip_archive *pZip);
1458MINIZ_EXPORT mz_uint64 mz_zip_get_archive_size(
mz_zip_archive *pZip);
1459MINIZ_EXPORT mz_uint64
1465MINIZ_EXPORT
size_t mz_zip_read_archive_data(
mz_zip_archive *pZip,
1466 mz_uint64 file_ofs,
void *pBuf,
1472MINIZ_EXPORT mz_zip_error mz_zip_set_last_error(
mz_zip_archive *pZip,
1473 mz_zip_error err_num);
1474MINIZ_EXPORT mz_zip_error mz_zip_peek_last_error(
mz_zip_archive *pZip);
1475MINIZ_EXPORT mz_zip_error mz_zip_clear_last_error(
mz_zip_archive *pZip);
1476MINIZ_EXPORT mz_zip_error mz_zip_get_last_error(
mz_zip_archive *pZip);
1477MINIZ_EXPORT
const char *mz_zip_get_error_string(mz_zip_error mz_err);
1480MINIZ_EXPORT mz_bool mz_zip_reader_is_file_a_directory(
mz_zip_archive *pZip,
1481 mz_uint file_index);
1484MINIZ_EXPORT mz_bool mz_zip_reader_is_file_encrypted(
mz_zip_archive *pZip,
1485 mz_uint file_index);
1489MINIZ_EXPORT mz_bool mz_zip_reader_is_file_supported(
mz_zip_archive *pZip,
1490 mz_uint file_index);
1496MINIZ_EXPORT mz_uint mz_zip_reader_get_filename(
mz_zip_archive *pZip,
1499 mz_uint filename_buf_size);
1506 const char *pComment, mz_uint flags);
1507MINIZ_EXPORT mz_bool mz_zip_reader_locate_file_v2(
mz_zip_archive *pZip,
1509 const char *pComment,
1511 mz_uint32 *file_index);
1514MINIZ_EXPORT mz_bool mz_zip_reader_file_stat(
mz_zip_archive *pZip,
1526MINIZ_EXPORT
size_t mz_zip_get_central_dir_size(
mz_zip_archive *pZip);
1531MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_mem_no_alloc(
1532 mz_zip_archive *pZip, mz_uint file_index,
void *pBuf,
size_t buf_size,
1533 mz_uint flags,
void *pUser_read_buf,
size_t user_read_buf_size);
1534MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(
1535 mz_zip_archive *pZip,
const char *pFilename,
void *pBuf,
size_t buf_size,
1536 mz_uint flags,
void *pUser_read_buf,
size_t user_read_buf_size);
1539MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_mem(
mz_zip_archive *pZip,
1541 void *pBuf,
size_t buf_size,
1543MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_mem(
mz_zip_archive *pZip,
1544 const char *pFilename,
1553MINIZ_EXPORT
void *mz_zip_reader_extract_to_heap(
mz_zip_archive *pZip,
1555 size_t *pSize, mz_uint flags);
1556MINIZ_EXPORT
void *mz_zip_reader_extract_file_to_heap(
mz_zip_archive *pZip,
1557 const char *pFilename,
1563MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_callback(
1564 mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback,
1565 void *pOpaque, mz_uint flags);
1566MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_callback(
1567 mz_zip_archive *pZip,
const char *pFilename, mz_file_write_func pCallback,
1568 void *pOpaque, mz_uint flags);
1572mz_zip_reader_extract_iter_new(
mz_zip_archive *pZip, mz_uint file_index,
1575mz_zip_reader_extract_file_iter_new(
mz_zip_archive *pZip,
const char *pFilename,
1577MINIZ_EXPORT
size_t mz_zip_reader_extract_iter_read(
1582#ifndef MINIZ_NO_STDIO
1586MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_file(
mz_zip_archive *pZip,
1588 const char *pDst_filename,
1590MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_file(
1592 const char *pDst_filename, mz_uint flags);
1596MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_cfile(
mz_zip_archive *pZip,
1600MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_cfile(
1601 mz_zip_archive *pZip,
const char *pArchive_filename, MZ_FILE *pFile,
1607 typedef void *mz_zip_streaming_extract_state_ptr;
1608 mz_zip_streaming_extract_state_ptr mz_zip_streaming_extract_begin(
mz_zip_archive *pZip, mz_uint file_index, mz_uint flags);
1609 mz_uint64 mz_zip_streaming_extract_get_size(
mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
1610 mz_uint64 mz_zip_streaming_extract_get_cur_ofs(
mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
1611 mz_bool mz_zip_streaming_extract_seek(
mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, mz_uint64 new_ofs);
1612 size_t mz_zip_streaming_extract_read(
mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState,
void *pBuf,
size_t buf_size);
1613 mz_bool mz_zip_streaming_extract_end(
mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
1622 mz_uint file_index, mz_uint flags);
1626MINIZ_EXPORT mz_bool mz_zip_validate_archive(
mz_zip_archive *pZip,
1630MINIZ_EXPORT mz_bool mz_zip_validate_mem_archive(
const void *pMem,
size_t size,
1632 mz_zip_error *pErr);
1633#ifndef MINIZ_NO_STDIO
1634MINIZ_EXPORT mz_bool mz_zip_validate_file_archive(
const char *pFilename,
1636 mz_zip_error *pErr);
1645#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
1653 mz_uint64 existing_size);
1655 mz_uint64 existing_size,
1658MINIZ_EXPORT mz_bool mz_zip_writer_init_heap(
1660 size_t initial_allocation_size);
1661MINIZ_EXPORT mz_bool mz_zip_writer_init_heap_v2(
1663 size_t initial_allocation_size, mz_uint flags);
1665#ifndef MINIZ_NO_STDIO
1667mz_zip_writer_init_file(
mz_zip_archive *pZip,
const char *pFilename,
1668 mz_uint64 size_to_reserve_at_beginning);
1669MINIZ_EXPORT mz_bool mz_zip_writer_init_file_v2(
1671 mz_uint64 size_to_reserve_at_beginning, mz_uint flags);
1672MINIZ_EXPORT mz_bool mz_zip_writer_init_cfile(
mz_zip_archive *pZip,
1673 MZ_FILE *pFile, mz_uint flags);
1689MINIZ_EXPORT mz_bool mz_zip_writer_init_from_reader(
mz_zip_archive *pZip,
1690 const char *pFilename);
1691MINIZ_EXPORT mz_bool mz_zip_writer_init_from_reader_v2(
mz_zip_archive *pZip,
1692 const char *pFilename,
1703 const char *pArchive_name,
1704 const void *pBuf,
size_t buf_size,
1705 mz_uint level_and_flags);
1711MINIZ_EXPORT mz_bool mz_zip_writer_add_mem_ex(
1712 mz_zip_archive *pZip,
const char *pArchive_name,
const void *pBuf,
1713 size_t buf_size,
const void *pComment, mz_uint16 comment_size,
1714 mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32);
1716MINIZ_EXPORT mz_bool mz_zip_writer_add_mem_ex_v2(
1717 mz_zip_archive *pZip,
const char *pArchive_name,
const void *pBuf,
1718 size_t buf_size,
const void *pComment, mz_uint16 comment_size,
1719 mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32,
1720 MZ_TIME_T *last_modified,
const char *user_extra_data_local,
1721 mz_uint user_extra_data_local_len,
const char *user_extra_data_central,
1722 mz_uint user_extra_data_central_len);
1728MINIZ_EXPORT mz_bool mz_zip_writer_add_read_buf_callback(
1730 mz_file_read_func read_callback,
void *callback_opaque, mz_uint64 max_size,
1731 const MZ_TIME_T *pFile_time,
const void *pComment, mz_uint16 comment_size,
1732 mz_uint level_and_flags, mz_uint32 ext_attributes,
1733 const char *user_extra_data_local, mz_uint user_extra_data_local_len,
1734 const char *user_extra_data_central, mz_uint user_extra_data_central_len);
1736#ifndef MINIZ_NO_STDIO
1742MINIZ_EXPORT mz_bool mz_zip_writer_add_file(
1743 mz_zip_archive *pZip,
const char *pArchive_name,
const char *pSrc_filename,
1744 const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
1745 mz_uint32 ext_attributes);
1749MINIZ_EXPORT mz_bool mz_zip_writer_add_cfile(
1750 mz_zip_archive *pZip,
const char *pArchive_name, MZ_FILE *pSrc_file,
1751 mz_uint64 max_size,
const MZ_TIME_T *pFile_time,
const void *pComment,
1752 mz_uint16 comment_size, mz_uint level_and_flags, mz_uint32 ext_attributes,
1753 const char *user_extra_data_local, mz_uint user_extra_data_local_len,
1754 const char *user_extra_data_central, mz_uint user_extra_data_central_len);
1762MINIZ_EXPORT mz_bool mz_zip_writer_add_from_zip_reader(
1771MINIZ_EXPORT mz_bool mz_zip_writer_finalize_archive(
mz_zip_archive *pZip);
1777MINIZ_EXPORT mz_bool mz_zip_writer_finalize_heap_archive(
mz_zip_archive *pZip,
1800MINIZ_EXPORT mz_bool mz_zip_add_mem_to_archive_file_in_place(
1801 const char *pZip_filename,
const char *pArchive_name,
const void *pBuf,
1802 size_t buf_size,
const void *pComment, mz_uint16 comment_size,
1803 mz_uint level_and_flags);
1804MINIZ_EXPORT mz_bool mz_zip_add_mem_to_archive_file_in_place_v2(
1805 const char *pZip_filename,
const char *pArchive_name,
const void *pBuf,
1806 size_t buf_size,
const void *pComment, mz_uint16 comment_size,
1807 mz_uint level_and_flags, mz_zip_error *pErr);
1809#ifndef MINIZ_NO_STDIO
1815mz_zip_extract_archive_file_to_heap(
const char *pZip_filename,
1816 const char *pArchive_name,
size_t *pSize,
1818MINIZ_EXPORT
void *mz_zip_extract_archive_file_to_heap_v2(
1819 const char *pZip_filename,
const char *pArchive_name,
const char *pComment,
1820 size_t *pSize, mz_uint flags, mz_zip_error *pErr);
1831#ifndef MINIZ_HEADER_FILE_ONLY
1858typedef unsigned char mz_validate_uint16[
sizeof(mz_uint16) == 2 ? 1 : -1];
1859typedef unsigned char mz_validate_uint32[
sizeof(mz_uint32) == 4 ? 1 : -1];
1860typedef unsigned char mz_validate_uint64[
sizeof(mz_uint64) == 8 ? 1 : -1];
1868mz_ulong mz_adler32(mz_ulong adler,
const unsigned char *ptr,
size_t buf_len) {
1869 mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16);
1870 size_t block_len = buf_len % 5552;
1872 return MZ_ADLER32_INIT;
1874 for (i = 0; i + 7 < block_len; i += 8, ptr += 8) {
1875 s1 += ptr[0], s2 += s1;
1876 s1 += ptr[1], s2 += s1;
1877 s1 += ptr[2], s2 += s1;
1878 s1 += ptr[3], s2 += s1;
1879 s1 += ptr[4], s2 += s1;
1880 s1 += ptr[5], s2 += s1;
1881 s1 += ptr[6], s2 += s1;
1882 s1 += ptr[7], s2 += s1;
1884 for (; i < block_len; ++i)
1885 s1 += *ptr++, s2 += s1;
1886 s1 %= 65521U, s2 %= 65521U;
1887 buf_len -= block_len;
1890 return (s2 << 16) + s1;
1897 mz_ulong mz_crc32(mz_ulong crc,
const mz_uint8 *ptr,
size_t buf_len)
1899 static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
1900 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c };
1901 mz_uint32 crcu32 = (mz_uint32)crc;
1903 return MZ_CRC32_INIT;
1907 mz_uint8 b = *ptr++;
1908 crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)];
1909 crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)];
1913#elif defined(USE_EXTERNAL_MZCRC)
1918mz_ulong mz_crc32(mz_ulong crc,
const mz_uint8 *ptr,
size_t buf_len);
1922mz_ulong mz_crc32(mz_ulong crc,
const mz_uint8 *ptr,
size_t buf_len) {
1923 static const mz_uint32 s_crc_table[256] = {
1924 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
1925 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
1926 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
1927 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
1928 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
1929 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
1930 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
1931 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
1932 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
1933 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
1934 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
1935 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
1936 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
1937 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
1938 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
1939 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
1940 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
1941 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
1942 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
1943 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
1944 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
1945 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
1946 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
1947 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
1948 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
1949 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
1950 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
1951 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
1952 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
1953 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
1954 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
1955 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
1956 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
1957 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
1958 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
1959 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
1960 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
1961 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
1962 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
1963 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
1964 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
1965 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
1966 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D};
1968 mz_uint32 crc32 = (mz_uint32)crc ^ 0xFFFFFFFF;
1969 const mz_uint8 *pByte_buf = (
const mz_uint8 *)ptr;
1971 while (buf_len >= 4) {
1972 crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF];
1973 crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[1]) & 0xFF];
1974 crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[2]) & 0xFF];
1975 crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[3]) & 0xFF];
1981 crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF];
1990void mz_free(
void *p) { MZ_FREE(p); }
1992MINIZ_EXPORT
void *miniz_def_alloc_func(
void *opaque,
size_t items,
1994 (void)opaque, (
void)items, (void)size;
1995 return MZ_MALLOC(items * size);
1997MINIZ_EXPORT
void miniz_def_free_func(
void *opaque,
void *address) {
1998 (void)opaque, (
void)address;
2001MINIZ_EXPORT
void *miniz_def_realloc_func(
void *opaque,
void *address,
2002 size_t items,
size_t size) {
2003 (void)opaque, (
void)address, (void)items, (
void)size;
2004 return MZ_REALLOC(address, items * size);
2007const char *mz_version(
void) {
return MZ_VERSION; }
2009#ifndef MINIZ_NO_ZLIB_APIS
2011#ifndef MINIZ_NO_DEFLATE_APIS
2013int mz_deflateInit(
mz_streamp pStream,
int level) {
2014 return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9,
2015 MZ_DEFAULT_STRATEGY);
2018int mz_deflateInit2(
mz_streamp pStream,
int level,
int method,
int window_bits,
2019 int mem_level,
int strategy) {
2021 mz_uint comp_flags =
2022 TDEFL_COMPUTE_ADLER32 |
2023 tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy);
2026 return MZ_STREAM_ERROR;
2027 if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) ||
2028 ((window_bits != MZ_DEFAULT_WINDOW_BITS) &&
2029 (-window_bits != MZ_DEFAULT_WINDOW_BITS)))
2030 return MZ_PARAM_ERROR;
2032 pStream->data_type = 0;
2033 pStream->adler = MZ_ADLER32_INIT;
2034 pStream->msg = NULL;
2035 pStream->reserved = 0;
2036 pStream->total_in = 0;
2037 pStream->total_out = 0;
2038 if (!pStream->zalloc)
2039 pStream->zalloc = miniz_def_alloc_func;
2040 if (!pStream->zfree)
2041 pStream->zfree = miniz_def_free_func;
2046 return MZ_MEM_ERROR;
2048 pStream->state = (
struct mz_internal_state *)pComp;
2050 if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY) {
2051 mz_deflateEnd(pStream);
2052 return MZ_PARAM_ERROR;
2059 if ((!pStream) || (!pStream->state) || (!pStream->zalloc) ||
2061 return MZ_STREAM_ERROR;
2062 pStream->total_in = pStream->total_out = 0;
2068int mz_deflate(
mz_streamp pStream,
int flush) {
2069 size_t in_bytes, out_bytes;
2070 mz_ulong orig_total_in, orig_total_out;
2071 int mz_status = MZ_OK;
2073 if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) ||
2074 (!pStream->next_out))
2075 return MZ_STREAM_ERROR;
2076 if (!pStream->avail_out)
2077 return MZ_BUF_ERROR;
2079 if (flush == MZ_PARTIAL_FLUSH)
2080 flush = MZ_SYNC_FLUSH;
2084 return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR;
2086 orig_total_in = pStream->total_in;
2087 orig_total_out = pStream->total_out;
2089 tdefl_status defl_status;
2090 in_bytes = pStream->avail_in;
2091 out_bytes = pStream->avail_out;
2094 pStream->next_in, &in_bytes, pStream->next_out,
2095 &out_bytes, (tdefl_flush)flush);
2096 pStream->next_in += (mz_uint)in_bytes;
2097 pStream->avail_in -= (mz_uint)in_bytes;
2098 pStream->total_in += (mz_uint)in_bytes;
2101 pStream->next_out += (mz_uint)out_bytes;
2102 pStream->avail_out -= (mz_uint)out_bytes;
2103 pStream->total_out += (mz_uint)out_bytes;
2105 if (defl_status < 0) {
2106 mz_status = MZ_STREAM_ERROR;
2108 }
else if (defl_status == TDEFL_STATUS_DONE) {
2109 mz_status = MZ_STREAM_END;
2111 }
else if (!pStream->avail_out)
2113 else if ((!pStream->avail_in) && (flush != MZ_FINISH)) {
2114 if ((flush) || (pStream->total_in != orig_total_in) ||
2115 (pStream->total_out != orig_total_out))
2117 return MZ_BUF_ERROR;
2126 return MZ_STREAM_ERROR;
2127 if (pStream->state) {
2128 pStream->zfree(pStream->opaque, pStream->state);
2129 pStream->state = NULL;
2134mz_ulong mz_deflateBound(
mz_streamp pStream, mz_ulong source_len) {
2139 return MZ_MAX(128 + (source_len * 110) / 100,
2140 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5);
2143int mz_compress2(
unsigned char *pDest, mz_ulong *pDest_len,
2144 const unsigned char *pSource, mz_ulong source_len,
int level) {
2147 memset(&stream, 0,
sizeof(stream));
2149#if defined(__MINGW32__) || defined(__MINGW64__) || defined(__WATCOMC__)
2152 if ((mz_uint64)(source_len | *pDest_len) > 0xFFFFFFFFU)
2153 return MZ_PARAM_ERROR;
2155 stream.next_in = pSource;
2156 stream.avail_in = (mz_uint32)source_len;
2157 stream.next_out = pDest;
2158 stream.avail_out = (mz_uint32)*pDest_len;
2160 status = mz_deflateInit(&stream, level);
2161 if (status != MZ_OK)
2164 status = mz_deflate(&stream, MZ_FINISH);
2165 if (status != MZ_STREAM_END) {
2166 mz_deflateEnd(&stream);
2167 return (status == MZ_OK) ? MZ_BUF_ERROR : status;
2170 *pDest_len = stream.total_out;
2171 return mz_deflateEnd(&stream);
2174int mz_compress(
unsigned char *pDest, mz_ulong *pDest_len,
2175 const unsigned char *pSource, mz_ulong source_len) {
2176 return mz_compress2(pDest, pDest_len, pSource, source_len,
2177 MZ_DEFAULT_COMPRESSION);
2180mz_ulong mz_compressBound(mz_ulong source_len) {
2181 return mz_deflateBound(NULL, source_len);
2186#ifndef MINIZ_NO_INFLATE_APIS
2189 tinfl_decompressor m_decomp;
2190 mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed;
2192 mz_uint8 m_dict[TINFL_LZ_DICT_SIZE];
2193 tinfl_status m_last_status;
2196int mz_inflateInit2(
mz_streamp pStream,
int window_bits) {
2199 return MZ_STREAM_ERROR;
2200 if ((window_bits != MZ_DEFAULT_WINDOW_BITS) &&
2201 (-window_bits != MZ_DEFAULT_WINDOW_BITS))
2202 return MZ_PARAM_ERROR;
2204 pStream->data_type = 0;
2206 pStream->msg = NULL;
2207 pStream->total_in = 0;
2208 pStream->total_out = 0;
2209 pStream->reserved = 0;
2210 if (!pStream->zalloc)
2211 pStream->zalloc = miniz_def_alloc_func;
2212 if (!pStream->zfree)
2213 pStream->zfree = miniz_def_free_func;
2215 pDecomp = (
inflate_state *)pStream->zalloc(pStream->opaque, 1,
2218 return MZ_MEM_ERROR;
2220 pStream->state = (
struct mz_internal_state *)pDecomp;
2222 tinfl_init(&pDecomp->m_decomp);
2223 pDecomp->m_dict_ofs = 0;
2224 pDecomp->m_dict_avail = 0;
2225 pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
2226 pDecomp->m_first_call = 1;
2227 pDecomp->m_has_flushed = 0;
2228 pDecomp->m_window_bits = window_bits;
2234 return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS);
2240 return MZ_STREAM_ERROR;
2242 pStream->data_type = 0;
2244 pStream->msg = NULL;
2245 pStream->total_in = 0;
2246 pStream->total_out = 0;
2247 pStream->reserved = 0;
2251 tinfl_init(&pDecomp->m_decomp);
2252 pDecomp->m_dict_ofs = 0;
2253 pDecomp->m_dict_avail = 0;
2254 pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
2255 pDecomp->m_first_call = 1;
2256 pDecomp->m_has_flushed = 0;
2262int mz_inflate(
mz_streamp pStream,
int flush) {
2264 mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32;
2265 size_t in_bytes, out_bytes, orig_avail_in;
2266 tinfl_status status;
2268 if ((!pStream) || (!pStream->state))
2269 return MZ_STREAM_ERROR;
2270 if (flush == MZ_PARTIAL_FLUSH)
2271 flush = MZ_SYNC_FLUSH;
2272 if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH))
2273 return MZ_STREAM_ERROR;
2276 if (pState->m_window_bits > 0)
2277 decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER;
2278 orig_avail_in = pStream->avail_in;
2280 first_call = pState->m_first_call;
2281 pState->m_first_call = 0;
2282 if (pState->m_last_status < 0)
2283 return MZ_DATA_ERROR;
2285 if (pState->m_has_flushed && (flush != MZ_FINISH))
2286 return MZ_STREAM_ERROR;
2287 pState->m_has_flushed |= (flush == MZ_FINISH);
2289 if ((flush == MZ_FINISH) && (first_call)) {
2292 decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF;
2293 in_bytes = pStream->avail_in;
2294 out_bytes = pStream->avail_out;
2295 status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes,
2296 pStream->next_out, pStream->next_out, &out_bytes,
2298 pState->m_last_status = status;
2299 pStream->next_in += (mz_uint)in_bytes;
2300 pStream->avail_in -= (mz_uint)in_bytes;
2301 pStream->total_in += (mz_uint)in_bytes;
2302 pStream->adler = tinfl_get_adler32(&pState->m_decomp);
2303 pStream->next_out += (mz_uint)out_bytes;
2304 pStream->avail_out -= (mz_uint)out_bytes;
2305 pStream->total_out += (mz_uint)out_bytes;
2308 return MZ_DATA_ERROR;
2309 else if (status != TINFL_STATUS_DONE) {
2310 pState->m_last_status = TINFL_STATUS_FAILED;
2311 return MZ_BUF_ERROR;
2313 return MZ_STREAM_END;
2316 if (flush != MZ_FINISH)
2317 decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT;
2319 if (pState->m_dict_avail) {
2320 n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
2321 memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
2322 pStream->next_out += n;
2323 pStream->avail_out -= n;
2324 pStream->total_out += n;
2325 pState->m_dict_avail -= n;
2326 pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
2327 return ((pState->m_last_status == TINFL_STATUS_DONE) &&
2328 (!pState->m_dict_avail))
2334 in_bytes = pStream->avail_in;
2335 out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs;
2337 status = tinfl_decompress(
2338 &pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict,
2339 pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags);
2340 pState->m_last_status = status;
2342 pStream->next_in += (mz_uint)in_bytes;
2343 pStream->avail_in -= (mz_uint)in_bytes;
2344 pStream->total_in += (mz_uint)in_bytes;
2345 pStream->adler = tinfl_get_adler32(&pState->m_decomp);
2347 pState->m_dict_avail = (mz_uint)out_bytes;
2349 n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
2350 memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
2351 pStream->next_out += n;
2352 pStream->avail_out -= n;
2353 pStream->total_out += n;
2354 pState->m_dict_avail -= n;
2355 pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
2358 return MZ_DATA_ERROR;
2361 else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in))
2362 return MZ_BUF_ERROR;
2365 else if (flush == MZ_FINISH) {
2368 if (status == TINFL_STATUS_DONE)
2369 return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END;
2373 else if (!pStream->avail_out)
2374 return MZ_BUF_ERROR;
2375 }
else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) ||
2376 (!pStream->avail_out) || (pState->m_dict_avail))
2380 return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail))
2387 return MZ_STREAM_ERROR;
2388 if (pStream->state) {
2389 pStream->zfree(pStream->opaque, pStream->state);
2390 pStream->state = NULL;
2394int mz_uncompress2(
unsigned char *pDest, mz_ulong *pDest_len,
2395 const unsigned char *pSource, mz_ulong *pSource_len) {
2398 memset(&stream, 0,
sizeof(stream));
2400#if defined(__MINGW32__) || defined(__MINGW64__) || defined(__WATCOMC__)
2403 if ((mz_uint64)(*pSource_len | *pDest_len) > 0xFFFFFFFFU)
2404 return MZ_PARAM_ERROR;
2406 stream.next_in = pSource;
2407 stream.avail_in = (mz_uint32)*pSource_len;
2408 stream.next_out = pDest;
2409 stream.avail_out = (mz_uint32)*pDest_len;
2411 status = mz_inflateInit(&stream);
2412 if (status != MZ_OK)
2415 status = mz_inflate(&stream, MZ_FINISH);
2416 *pSource_len = *pSource_len - stream.avail_in;
2417 if (status != MZ_STREAM_END) {
2418 mz_inflateEnd(&stream);
2419 return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR
2422 *pDest_len = stream.total_out;
2424 return mz_inflateEnd(&stream);
2427int mz_uncompress(
unsigned char *pDest, mz_ulong *pDest_len,
2428 const unsigned char *pSource, mz_ulong source_len) {
2429 return mz_uncompress2(pDest, pDest_len, pSource, &source_len);
2434const char *mz_error(
int err) {
2437 const char *m_pDesc;
2438 } s_error_descs[] = {{MZ_OK,
""},
2439 {MZ_STREAM_END,
"stream end"},
2440 {MZ_NEED_DICT,
"need dictionary"},
2441 {MZ_ERRNO,
"file error"},
2442 {MZ_STREAM_ERROR,
"stream error"},
2443 {MZ_DATA_ERROR,
"data error"},
2444 {MZ_MEM_ERROR,
"out of memory"},
2445 {MZ_BUF_ERROR,
"buf error"},
2446 {MZ_VERSION_ERROR,
"version error"},
2447 {MZ_PARAM_ERROR,
"parameter error"}};
2449 for (i = 0; i <
sizeof(s_error_descs) /
sizeof(s_error_descs[0]); ++i)
2450 if (s_error_descs[i].m_err == err)
2451 return s_error_descs[i].m_pDesc;
2513#ifndef MINIZ_NO_DEFLATE_APIS
2523static const mz_uint16 s_tdefl_len_sym[256] = {
2524 257, 258, 259, 260, 261, 262, 263, 264, 265, 265, 266, 266, 267, 267, 268,
2525 268, 269, 269, 269, 269, 270, 270, 270, 270, 271, 271, 271, 271, 272, 272,
2526 272, 272, 273, 273, 273, 273, 273, 273, 273, 273, 274, 274, 274, 274, 274,
2527 274, 274, 274, 275, 275, 275, 275, 275, 275, 275, 275, 276, 276, 276, 276,
2528 276, 276, 276, 276, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
2529 277, 277, 277, 277, 277, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
2530 278, 278, 278, 278, 278, 278, 279, 279, 279, 279, 279, 279, 279, 279, 279,
2531 279, 279, 279, 279, 279, 279, 279, 280, 280, 280, 280, 280, 280, 280, 280,
2532 280, 280, 280, 280, 280, 280, 280, 280, 281, 281, 281, 281, 281, 281, 281,
2533 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281,
2534 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 282, 282, 282, 282, 282,
2535 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282,
2536 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 283, 283, 283,
2537 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283,
2538 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 284,
2539 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
2540 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
2543static const mz_uint8 s_tdefl_len_extra[256] = {
2544 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
2545 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2546 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
2547 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2548 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2549 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2550 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2551 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2552 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2553 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2554 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0};
2556static const mz_uint8 s_tdefl_small_dist_sym[512] = {
2557 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8,
2558 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10,
2559 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11,
2560 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
2561 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
2562 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
2563 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14,
2564 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
2565 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
2566 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
2567 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
2568 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
2569 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
2570 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2571 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2572 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2573 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2574 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2575 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2576 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2577 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
2578 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
2579 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
2580 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
2581 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
2582 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
2583 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17};
2585static const mz_uint8 s_tdefl_small_dist_extra[512] = {
2586 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,
2587 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,
2588 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,
2589 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,
2590 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,
2591 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,
2592 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,
2593 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,
2594 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,
2595 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,
2596 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2597 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2598 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2599 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2600 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2601 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2602 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2603 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2604 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2605 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
2606 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
2608static const mz_uint8 s_tdefl_large_dist_sym[128] = {
2609 0, 0, 18, 19, 20, 20, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24,
2610 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26,
2611 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27,
2612 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
2613 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
2614 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
2615 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29};
2617static const mz_uint8 s_tdefl_large_dist_extra[128] = {
2618 0, 0, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11,
2619 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12,
2620 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
2621 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
2622 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
2623 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
2624 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13};
2629 mz_uint16 m_key, m_sym_index;
2634 mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2];
2637 for (i = 0; i < num_syms; i++) {
2638 mz_uint freq = pSyms0[i].m_key;
2639 hist[freq & 0xFF]++;
2640 hist[256 + ((freq >> 8) & 0xFF)]++;
2642 while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256]))
2644 for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8) {
2645 const mz_uint32 *pHist = &hist[pass << 8];
2646 mz_uint offsets[256], cur_ofs = 0;
2647 for (i = 0; i < 256; i++) {
2648 offsets[i] = cur_ofs;
2649 cur_ofs += pHist[i];
2651 for (i = 0; i < num_syms; i++)
2652 pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] =
2656 pCur_syms = pNew_syms;
2665static void tdefl_calculate_minimum_redundancy(
tdefl_sym_freq *A,
int n) {
2666 int root, leaf, next, avbl, used, dpth;
2673 A[0].m_key += A[1].m_key;
2676 for (next = 1; next < n - 1; next++) {
2677 if (leaf >= n || A[root].m_key < A[leaf].m_key) {
2678 A[next].m_key = A[root].m_key;
2679 A[root++].m_key = (mz_uint16)next;
2681 A[next].m_key = A[leaf++].m_key;
2682 if (leaf >= n || (root < next && A[root].m_key < A[leaf].m_key)) {
2683 A[next].m_key = (mz_uint16)(A[next].m_key + A[root].m_key);
2684 A[root++].m_key = (mz_uint16)next;
2686 A[next].m_key = (mz_uint16)(A[next].m_key + A[leaf++].m_key);
2689 for (next = n - 3; next >= 0; next--)
2690 A[next].m_key = A[A[next].m_key].m_key + 1;
2696 while (root >= 0 && (
int)A[root].m_key == dpth) {
2700 while (avbl > used) {
2701 A[next--].m_key = (mz_uint16)(dpth);
2711enum { TDEFL_MAX_SUPPORTED_HUFF_CODESIZE = 32 };
2712static void tdefl_huffman_enforce_max_code_size(
int *pNum_codes,
2714 int max_code_size) {
2716 mz_uint32 total = 0;
2717 if (code_list_len <= 1)
2719 for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++)
2720 pNum_codes[max_code_size] += pNum_codes[i];
2721 for (i = max_code_size; i > 0; i--)
2722 total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i));
2723 while (total != (1UL << max_code_size)) {
2724 pNum_codes[max_code_size]--;
2725 for (i = max_code_size - 1; i > 0; i--)
2726 if (pNum_codes[i]) {
2728 pNum_codes[i + 1] += 2;
2735static void tdefl_optimize_huffman_table(
tdefl_compressor *d,
int table_num,
2736 int table_len,
int code_size_limit,
2738 int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE];
2739 mz_uint next_code[TDEFL_MAX_SUPPORTED_HUFF_CODESIZE + 1];
2740 MZ_CLEAR_ARR(num_codes);
2742 for (i = 0; i < table_len; i++)
2743 num_codes[d->m_huff_code_sizes[table_num][i]]++;
2745 tdefl_sym_freq syms0[TDEFL_MAX_HUFF_SYMBOLS], syms1[TDEFL_MAX_HUFF_SYMBOLS],
2747 int num_used_syms = 0;
2748 const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0];
2749 for (i = 0; i < table_len; i++)
2750 if (pSym_count[i]) {
2751 syms0[num_used_syms].m_key = (mz_uint16)pSym_count[i];
2752 syms0[num_used_syms++].m_sym_index = (mz_uint16)i;
2755 pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1);
2756 tdefl_calculate_minimum_redundancy(pSyms, num_used_syms);
2758 for (i = 0; i < num_used_syms; i++)
2759 num_codes[pSyms[i].m_key]++;
2761 tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms,
2764 MZ_CLEAR_ARR(d->m_huff_code_sizes[table_num]);
2765 MZ_CLEAR_ARR(d->m_huff_codes[table_num]);
2766 for (i = 1, j = num_used_syms; i <= code_size_limit; i++)
2767 for (l = num_codes[i]; l > 0; l--)
2768 d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i);
2772 for (j = 0, i = 2; i <= code_size_limit; i++)
2773 next_code[i] = j = ((j + num_codes[i - 1]) << 1);
2775 for (i = 0; i < table_len; i++) {
2776 mz_uint rev_code = 0, code, code_size;
2777 if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0)
2779 code = next_code[code_size]++;
2780 for (l = code_size; l > 0; l--, code >>= 1)
2781 rev_code = (rev_code << 1) | (code & 1);
2782 d->m_huff_codes[table_num][i] = (mz_uint16)rev_code;
2786#define TDEFL_PUT_BITS(b, l) \
2790 MZ_ASSERT(bits <= ((1U << len) - 1U)); \
2791 d->m_bit_buffer |= (bits << d->m_bits_in); \
2792 d->m_bits_in += len; \
2793 while (d->m_bits_in >= 8) { \
2794 if (d->m_pOutput_buf < d->m_pOutput_buf_end) \
2795 *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \
2796 d->m_bit_buffer >>= 8; \
2797 d->m_bits_in -= 8; \
2802#define TDEFL_RLE_PREV_CODE_SIZE() \
2804 if (rle_repeat_count) { \
2805 if (rle_repeat_count < 3) { \
2806 d->m_huff_count[2][prev_code_size] = \
2807 (mz_uint16)(d->m_huff_count[2][prev_code_size] + \
2808 rle_repeat_count); \
2809 while (rle_repeat_count--) \
2810 packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \
2812 d->m_huff_count[2][16] = (mz_uint16)(d->m_huff_count[2][16] + 1); \
2813 packed_code_sizes[num_packed_code_sizes++] = 16; \
2814 packed_code_sizes[num_packed_code_sizes++] = \
2815 (mz_uint8)(rle_repeat_count - 3); \
2817 rle_repeat_count = 0; \
2821#define TDEFL_RLE_ZERO_CODE_SIZE() \
2823 if (rle_z_count) { \
2824 if (rle_z_count < 3) { \
2825 d->m_huff_count[2][0] = \
2826 (mz_uint16)(d->m_huff_count[2][0] + rle_z_count); \
2827 while (rle_z_count--) \
2828 packed_code_sizes[num_packed_code_sizes++] = 0; \
2829 } else if (rle_z_count <= 10) { \
2830 d->m_huff_count[2][17] = (mz_uint16)(d->m_huff_count[2][17] + 1); \
2831 packed_code_sizes[num_packed_code_sizes++] = 17; \
2832 packed_code_sizes[num_packed_code_sizes++] = \
2833 (mz_uint8)(rle_z_count - 3); \
2835 d->m_huff_count[2][18] = (mz_uint16)(d->m_huff_count[2][18] + 1); \
2836 packed_code_sizes[num_packed_code_sizes++] = 18; \
2837 packed_code_sizes[num_packed_code_sizes++] = \
2838 (mz_uint8)(rle_z_count - 11); \
2844static const mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = {
2845 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
2848 int num_lit_codes, num_dist_codes, num_bit_lengths;
2849 mz_uint i, total_code_sizes_to_pack, num_packed_code_sizes, rle_z_count,
2850 rle_repeat_count, packed_code_sizes_index;
2852 code_sizes_to_pack[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1],
2853 packed_code_sizes[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1],
2854 prev_code_size = 0xFF;
2856 d->m_huff_count[0][256] = 1;
2858 tdefl_optimize_huffman_table(d, 0, TDEFL_MAX_HUFF_SYMBOLS_0, 15, MZ_FALSE);
2859 tdefl_optimize_huffman_table(d, 1, TDEFL_MAX_HUFF_SYMBOLS_1, 15, MZ_FALSE);
2861 for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--)
2862 if (d->m_huff_code_sizes[0][num_lit_codes - 1])
2864 for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--)
2865 if (d->m_huff_code_sizes[1][num_dist_codes - 1])
2868 memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes);
2869 memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0],
2871 total_code_sizes_to_pack = num_lit_codes + num_dist_codes;
2872 num_packed_code_sizes = 0;
2874 rle_repeat_count = 0;
2876 memset(&d->m_huff_count[2][0], 0,
2877 sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2);
2878 for (i = 0; i < total_code_sizes_to_pack; i++) {
2879 mz_uint8 code_size = code_sizes_to_pack[i];
2881 TDEFL_RLE_PREV_CODE_SIZE();
2882 if (++rle_z_count == 138) {
2883 TDEFL_RLE_ZERO_CODE_SIZE();
2886 TDEFL_RLE_ZERO_CODE_SIZE();
2887 if (code_size != prev_code_size) {
2888 TDEFL_RLE_PREV_CODE_SIZE();
2889 d->m_huff_count[2][code_size] =
2890 (mz_uint16)(d->m_huff_count[2][code_size] + 1);
2891 packed_code_sizes[num_packed_code_sizes++] = code_size;
2892 }
else if (++rle_repeat_count == 6) {
2893 TDEFL_RLE_PREV_CODE_SIZE();
2896 prev_code_size = code_size;
2898 if (rle_repeat_count) {
2899 TDEFL_RLE_PREV_CODE_SIZE();
2901 TDEFL_RLE_ZERO_CODE_SIZE();
2904 tdefl_optimize_huffman_table(d, 2, TDEFL_MAX_HUFF_SYMBOLS_2, 7, MZ_FALSE);
2906 TDEFL_PUT_BITS(2, 2);
2908 TDEFL_PUT_BITS(num_lit_codes - 257, 5);
2909 TDEFL_PUT_BITS(num_dist_codes - 1, 5);
2911 for (num_bit_lengths = 18; num_bit_lengths >= 0; num_bit_lengths--)
2912 if (d->m_huff_code_sizes
2913 [2][s_tdefl_packed_code_size_syms_swizzle[num_bit_lengths]])
2915 num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1));
2916 TDEFL_PUT_BITS(num_bit_lengths - 4, 4);
2917 for (i = 0; (int)i < num_bit_lengths; i++)
2919 d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[i]], 3);
2921 for (packed_code_sizes_index = 0;
2922 packed_code_sizes_index < num_packed_code_sizes;) {
2923 mz_uint code = packed_code_sizes[packed_code_sizes_index++];
2924 MZ_ASSERT(code < TDEFL_MAX_HUFF_SYMBOLS_2);
2925 TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]);
2927 TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++],
2928 "\02\03\07"[code - 16]);
2934 mz_uint8 *p = &d->m_huff_code_sizes[0][0];
2936 for (i = 0; i <= 143; ++i)
2938 for (; i <= 255; ++i)
2940 for (; i <= 279; ++i)
2942 for (; i <= 287; ++i)
2945 memset(d->m_huff_code_sizes[1], 5, 32);
2947 tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE);
2948 tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE);
2950 TDEFL_PUT_BITS(1, 2);
2953static const mz_uint mz_bitmasks[17] = {
2954 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF,
2955 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF};
2957#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && \
2958 MINIZ_HAS_64BIT_REGISTERS
2961 mz_uint8 *pLZ_codes;
2962 mz_uint8 *pOutput_buf = d->m_pOutput_buf;
2963 mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf;
2964 mz_uint64 bit_buffer = d->m_bit_buffer;
2965 mz_uint bits_in = d->m_bits_in;
2967#define TDEFL_PUT_BITS_FAST(b, l) \
2969 bit_buffer |= (((mz_uint64)(b)) << bits_in); \
2974 for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end;
2977 flags = *pLZ_codes++ | 0x100;
2980 mz_uint s0, s1, n0, n1, sym, num_extra_bits;
2981 mz_uint match_len = pLZ_codes[0];
2982 mz_uint match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8));
2985 MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
2986 TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][s_tdefl_len_sym[match_len]],
2987 d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
2988 TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]],
2989 s_tdefl_len_extra[match_len]);
2992 s0 = s_tdefl_small_dist_sym[match_dist & 511];
2993 n0 = s_tdefl_small_dist_extra[match_dist & 511];
2994 s1 = s_tdefl_large_dist_sym[match_dist >> 8];
2995 n1 = s_tdefl_large_dist_extra[match_dist >> 8];
2996 sym = (match_dist < 512) ? s0 : s1;
2997 num_extra_bits = (match_dist < 512) ? n0 : n1;
2999 MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
3000 TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym],
3001 d->m_huff_code_sizes[1][sym]);
3002 TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits],
3005 mz_uint lit = *pLZ_codes++;
3006 MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
3007 TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit],
3008 d->m_huff_code_sizes[0][lit]);
3010 if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) {
3013 MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
3014 TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit],
3015 d->m_huff_code_sizes[0][lit]);
3017 if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) {
3020 MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
3021 TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit],
3022 d->m_huff_code_sizes[0][lit]);
3027 if (pOutput_buf >= d->m_pOutput_buf_end)
3030 memcpy(pOutput_buf, &bit_buffer,
sizeof(mz_uint64));
3031 pOutput_buf += (bits_in >> 3);
3032 bit_buffer >>= (bits_in & ~7);
3036#undef TDEFL_PUT_BITS_FAST
3038 d->m_pOutput_buf = pOutput_buf;
3040 d->m_bit_buffer = 0;
3043 mz_uint32 n = MZ_MIN(bits_in, 16);
3044 TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n);
3049 TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
3051 return (d->m_pOutput_buf < d->m_pOutput_buf_end);
3056 mz_uint8 *pLZ_codes;
3059 for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf;
3062 flags = *pLZ_codes++ | 0x100;
3064 mz_uint sym, num_extra_bits;
3065 mz_uint match_len = pLZ_codes[0],
3066 match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8));
3069 MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
3070 TDEFL_PUT_BITS(d->m_huff_codes[0][s_tdefl_len_sym[match_len]],
3071 d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
3072 TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]],
3073 s_tdefl_len_extra[match_len]);
3075 if (match_dist < 512) {
3076 sym = s_tdefl_small_dist_sym[match_dist];
3077 num_extra_bits = s_tdefl_small_dist_extra[match_dist];
3079 sym = s_tdefl_large_dist_sym[match_dist >> 8];
3080 num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8];
3082 MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
3083 TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
3084 TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
3086 mz_uint lit = *pLZ_codes++;
3087 MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
3088 TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
3092 TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
3094 return (d->m_pOutput_buf < d->m_pOutput_buf_end);
3099static mz_bool tdefl_compress_block(
tdefl_compressor *d, mz_bool static_block) {
3101 tdefl_start_static_block(d);
3103 tdefl_start_dynamic_block(d);
3104 return tdefl_compress_lz_codes(d);
3107static const mz_uint s_tdefl_num_probes[11] = {0, 1, 6, 32, 16, 32,
3108 128, 256, 512, 768, 1500};
3111 mz_uint saved_bit_buf, saved_bits_in;
3112 mz_uint8 *pSaved_output_buf;
3113 mz_bool comp_block_succeeded = MZ_FALSE;
3114 int n, use_raw_block =
3115 ((d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS) != 0) &&
3116 (d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size;
3117 mz_uint8 *pOutput_buf_start =
3118 ((d->m_pPut_buf_func == NULL) &&
3119 ((*d->m_pOut_buf_size - d->m_out_buf_ofs) >= TDEFL_OUT_BUF_SIZE))
3120 ? ((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs)
3123 d->m_pOutput_buf = pOutput_buf_start;
3124 d->m_pOutput_buf_end = d->m_pOutput_buf + TDEFL_OUT_BUF_SIZE - 16;
3126 MZ_ASSERT(!d->m_output_flush_remaining);
3127 d->m_output_flush_ofs = 0;
3128 d->m_output_flush_remaining = 0;
3130 *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left);
3131 d->m_pLZ_code_buf -= (d->m_num_flags_left == 8);
3133 if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index)) {
3134 const mz_uint8 cmf = 0x78;
3135 mz_uint8 flg, flevel = 3;
3136 mz_uint header, i, mz_un =
sizeof(s_tdefl_num_probes) /
sizeof(mz_uint);
3140 for (i = 0; i < mz_un; i++)
3141 if (s_tdefl_num_probes[i] == (d->m_flags & 0xFFF))
3151 header = cmf << 8 | (flevel << 6);
3152 header += 31 - (header % 31);
3153 flg = header & 0xFF;
3155 TDEFL_PUT_BITS(cmf, 8);
3156 TDEFL_PUT_BITS(flg, 8);
3159 TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1);
3161 pSaved_output_buf = d->m_pOutput_buf;
3162 saved_bit_buf = d->m_bit_buffer;
3163 saved_bits_in = d->m_bits_in;
3166 comp_block_succeeded =
3167 tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) ||
3168 (d->m_total_lz_bytes < 48));
3172 if (((use_raw_block) ||
3173 ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >=
3174 d->m_total_lz_bytes))) &&
3175 ((d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size)) {
3177 d->m_pOutput_buf = pSaved_output_buf;
3178 d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
3179 TDEFL_PUT_BITS(0, 2);
3181 TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
3183 for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF) {
3184 TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16);
3186 for (i = 0; i < d->m_total_lz_bytes; ++i) {
3188 d->m_dict[(d->m_lz_code_buf_dict_pos + i) & TDEFL_LZ_DICT_SIZE_MASK],
3194 else if (!comp_block_succeeded) {
3195 d->m_pOutput_buf = pSaved_output_buf;
3196 d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
3197 tdefl_compress_block(d, MZ_TRUE);
3201 if (flush == TDEFL_FINISH) {
3203 TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
3205 if (d->m_flags & TDEFL_WRITE_ZLIB_HEADER) {
3206 mz_uint i, a = d->m_adler32;
3207 for (i = 0; i < 4; i++) {
3208 TDEFL_PUT_BITS((a >> 24) & 0xFF, 8);
3214 TDEFL_PUT_BITS(0, 3);
3216 TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
3218 for (i = 2; i; --i, z ^= 0xFFFF) {
3219 TDEFL_PUT_BITS(z & 0xFFFF, 16);
3224 MZ_ASSERT(d->m_pOutput_buf < d->m_pOutput_buf_end);
3226 memset(&d->m_huff_count[0][0], 0,
3227 sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
3228 memset(&d->m_huff_count[1][0], 0,
3229 sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
3231 d->m_pLZ_code_buf = d->m_lz_code_buf + 1;
3232 d->m_pLZ_flags = d->m_lz_code_buf;
3233 d->m_num_flags_left = 8;
3234 d->m_lz_code_buf_dict_pos += d->m_total_lz_bytes;
3235 d->m_total_lz_bytes = 0;
3238 if ((n = (
int)(d->m_pOutput_buf - pOutput_buf_start)) != 0) {
3239 if (d->m_pPut_buf_func) {
3240 *d->m_pIn_buf_size = d->m_pSrc - (
const mz_uint8 *)d->m_pIn_buf;
3241 if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user))
3242 return (d->m_prev_return_status = TDEFL_STATUS_PUT_BUF_FAILED);
3243 }
else if (pOutput_buf_start == d->m_output_buf) {
3244 int bytes_to_copy = (int)MZ_MIN(
3245 (
size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs));
3246 memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf,
3248 d->m_out_buf_ofs += bytes_to_copy;
3249 if ((n -= bytes_to_copy) != 0) {
3250 d->m_output_flush_ofs = bytes_to_copy;
3251 d->m_output_flush_remaining = n;
3254 d->m_out_buf_ofs += n;
3258 return d->m_output_flush_remaining;
3261#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
3262#ifdef MINIZ_UNALIGNED_USE_MEMCPY
3263static mz_uint16 TDEFL_READ_UNALIGNED_WORD(
const mz_uint8 *p) {
3265 memcpy(&ret, p,
sizeof(mz_uint16));
3268static mz_uint16 TDEFL_READ_UNALIGNED_WORD2(
const mz_uint16 *p) {
3270 memcpy(&ret, p,
sizeof(mz_uint16));
3274#define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16 *)(p)
3275#define TDEFL_READ_UNALIGNED_WORD2(p) *(const mz_uint16 *)(p)
3277static MZ_FORCEINLINE
void
3278tdefl_find_match(
tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist,
3279 mz_uint max_match_len, mz_uint *pMatch_dist,
3280 mz_uint *pMatch_len) {
3281 mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK,
3282 match_len = *pMatch_len, probe_pos = pos, next_probe_pos,
3284 mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
3285 const mz_uint16 *s = (
const mz_uint16 *)(d->m_dict + pos), *p, *q;
3286 mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]),
3287 s01 = TDEFL_READ_UNALIGNED_WORD2(s);
3288 MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN);
3289 if (max_match_len <= match_len)
3293 if (--num_probes_left == 0)
3295#define TDEFL_PROBE \
3296 next_probe_pos = d->m_next[probe_pos]; \
3297 if ((!next_probe_pos) || \
3298 ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \
3300 probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
3301 if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) \
3309 q = (
const mz_uint16 *)(d->m_dict + probe_pos);
3310 if (TDEFL_READ_UNALIGNED_WORD2(q) != s01)
3316 (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) &&
3317 (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) &&
3318 (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) &&
3319 (TDEFL_READ_UNALIGNED_WORD2(++p) == TDEFL_READ_UNALIGNED_WORD2(++q)) &&
3322 *pMatch_dist = dist;
3323 *pMatch_len = MZ_MIN(max_match_len, (mz_uint)TDEFL_MAX_MATCH_LEN);
3325 }
else if ((probe_len = ((mz_uint)(p - s) * 2) +
3326 (mz_uint)(*(
const mz_uint8 *)p ==
3327 *(
const mz_uint8 *)q)) > match_len) {
3328 *pMatch_dist = dist;
3329 if ((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) ==
3332 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]);
3337static MZ_FORCEINLINE
void
3338tdefl_find_match(
tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist,
3339 mz_uint max_match_len, mz_uint *pMatch_dist,
3340 mz_uint *pMatch_len) {
3341 mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK,
3342 match_len = *pMatch_len, probe_pos = pos, next_probe_pos,
3344 mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
3345 const mz_uint8 *s = d->m_dict + pos, *p, *q;
3346 mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1];
3347 MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN);
3348 if (max_match_len <= match_len)
3352 if (--num_probes_left == 0)
3354#define TDEFL_PROBE \
3355 next_probe_pos = d->m_next[probe_pos]; \
3356 if ((!next_probe_pos) || \
3357 ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \
3359 probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
3360 if ((d->m_dict[probe_pos + match_len] == c0) && \
3361 (d->m_dict[probe_pos + match_len - 1] == c1)) \
3370 q = d->m_dict + probe_pos;
3371 for (probe_len = 0; probe_len < max_match_len; probe_len++)
3374 if (probe_len > match_len) {
3375 *pMatch_dist = dist;
3376 if ((*pMatch_len = match_len = probe_len) == max_match_len)
3378 c0 = d->m_dict[pos + match_len];
3379 c1 = d->m_dict[pos + match_len - 1];
3385#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
3386#ifdef MINIZ_UNALIGNED_USE_MEMCPY
3387static mz_uint32 TDEFL_READ_UNALIGNED_WORD32(
const mz_uint8 *p) {
3389 memcpy(&ret, p,
sizeof(mz_uint32));
3393#define TDEFL_READ_UNALIGNED_WORD32(p) *(const mz_uint32 *)(p)
3399 mz_uint lookahead_pos = d->m_lookahead_pos,
3400 lookahead_size = d->m_lookahead_size, dict_size = d->m_dict_size,
3401 total_lz_bytes = d->m_total_lz_bytes,
3402 num_flags_left = d->m_num_flags_left;
3403 mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags;
3404 mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
3406 while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size))) {
3407 const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096;
3409 (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK;
3410 mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(
3411 d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size);
3412 d->m_src_buf_left -= num_bytes_to_process;
3413 lookahead_size += num_bytes_to_process;
3415 while (num_bytes_to_process) {
3416 mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process);
3417 memcpy(d->m_dict + dst_pos, d->m_pSrc, n);
3418 if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
3419 memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc,
3420 MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos));
3422 dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK;
3423 num_bytes_to_process -= n;
3426 dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size);
3427 if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE))
3430 while (lookahead_size >= 4) {
3431 mz_uint cur_match_dist, cur_match_len = 1;
3432 mz_uint8 *pCur_dict = d->m_dict + cur_pos;
3433 mz_uint first_trigram = TDEFL_READ_UNALIGNED_WORD32(pCur_dict) & 0xFFFFFF;
3435 (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) &
3436 TDEFL_LEVEL1_HASH_SIZE_MASK;
3437 mz_uint probe_pos = d->m_hash[hash];
3438 d->m_hash[hash] = (mz_uint16)lookahead_pos;
3440 if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <=
3442 ((TDEFL_READ_UNALIGNED_WORD32(
3443 d->m_dict + (probe_pos &= TDEFL_LZ_DICT_SIZE_MASK)) &
3444 0xFFFFFF) == first_trigram)) {
3445 const mz_uint16 *p = (
const mz_uint16 *)pCur_dict;
3446 const mz_uint16 *q = (
const mz_uint16 *)(d->m_dict + probe_pos);
3447 mz_uint32 probe_len = 32;
3449 }
while ((TDEFL_READ_UNALIGNED_WORD2(++p) ==
3450 TDEFL_READ_UNALIGNED_WORD2(++q)) &&
3451 (TDEFL_READ_UNALIGNED_WORD2(++p) ==
3452 TDEFL_READ_UNALIGNED_WORD2(++q)) &&
3453 (TDEFL_READ_UNALIGNED_WORD2(++p) ==
3454 TDEFL_READ_UNALIGNED_WORD2(++q)) &&
3455 (TDEFL_READ_UNALIGNED_WORD2(++p) ==
3456 TDEFL_READ_UNALIGNED_WORD2(++q)) &&
3458 cur_match_len = ((mz_uint)(p - (
const mz_uint16 *)pCur_dict) * 2) +
3459 (mz_uint)(*(
const mz_uint8 *)p == *(
const mz_uint8 *)q);
3461 cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0;
3463 if ((cur_match_len < TDEFL_MIN_MATCH_LEN) ||
3464 ((cur_match_len == TDEFL_MIN_MATCH_LEN) &&
3465 (cur_match_dist >= 8U * 1024U))) {
3467 *pLZ_code_buf++ = (mz_uint8)first_trigram;
3468 *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
3469 d->m_huff_count[0][(mz_uint8)first_trigram]++;
3472 cur_match_len = MZ_MIN(cur_match_len, lookahead_size);
3474 MZ_ASSERT((cur_match_len >= TDEFL_MIN_MATCH_LEN) &&
3475 (cur_match_dist >= 1) &&
3476 (cur_match_dist <= TDEFL_LZ_DICT_SIZE));
3480 pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN);
3481#ifdef MINIZ_UNALIGNED_USE_MEMCPY
3482 memcpy(&pLZ_code_buf[1], &cur_match_dist,
sizeof(cur_match_dist));
3484 *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist;
3487 *pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80);
3489 s0 = s_tdefl_small_dist_sym[cur_match_dist & 511];
3490 s1 = s_tdefl_large_dist_sym[cur_match_dist >> 8];
3491 d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++;
3493 d->m_huff_count[0][s_tdefl_len_sym[cur_match_len -
3494 TDEFL_MIN_MATCH_LEN]]++;
3497 *pLZ_code_buf++ = (mz_uint8)first_trigram;
3498 *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
3499 d->m_huff_count[0][(mz_uint8)first_trigram]++;
3502 if (--num_flags_left == 0) {
3504 pLZ_flags = pLZ_code_buf++;
3507 total_lz_bytes += cur_match_len;
3508 lookahead_pos += cur_match_len;
3510 MZ_MIN(dict_size + cur_match_len, (mz_uint)TDEFL_LZ_DICT_SIZE);
3511 cur_pos = (cur_pos + cur_match_len) & TDEFL_LZ_DICT_SIZE_MASK;
3512 MZ_ASSERT(lookahead_size >= cur_match_len);
3513 lookahead_size -= cur_match_len;
3515 if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) {
3517 d->m_lookahead_pos = lookahead_pos;
3518 d->m_lookahead_size = lookahead_size;
3519 d->m_dict_size = dict_size;
3520 d->m_total_lz_bytes = total_lz_bytes;
3521 d->m_pLZ_code_buf = pLZ_code_buf;
3522 d->m_pLZ_flags = pLZ_flags;
3523 d->m_num_flags_left = num_flags_left;
3524 if ((n = tdefl_flush_block(d, 0)) != 0)
3525 return (n < 0) ? MZ_FALSE : MZ_TRUE;
3526 total_lz_bytes = d->m_total_lz_bytes;
3527 pLZ_code_buf = d->m_pLZ_code_buf;
3528 pLZ_flags = d->m_pLZ_flags;
3529 num_flags_left = d->m_num_flags_left;
3533 while (lookahead_size) {
3534 mz_uint8 lit = d->m_dict[cur_pos];
3537 *pLZ_code_buf++ = lit;
3538 *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
3539 if (--num_flags_left == 0) {
3541 pLZ_flags = pLZ_code_buf++;
3544 d->m_huff_count[0][lit]++;
3547 dict_size = MZ_MIN(dict_size + 1, (mz_uint)TDEFL_LZ_DICT_SIZE);
3548 cur_pos = (cur_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK;
3551 if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) {
3553 d->m_lookahead_pos = lookahead_pos;
3554 d->m_lookahead_size = lookahead_size;
3555 d->m_dict_size = dict_size;
3556 d->m_total_lz_bytes = total_lz_bytes;
3557 d->m_pLZ_code_buf = pLZ_code_buf;
3558 d->m_pLZ_flags = pLZ_flags;
3559 d->m_num_flags_left = num_flags_left;
3560 if ((n = tdefl_flush_block(d, 0)) != 0)
3561 return (n < 0) ? MZ_FALSE : MZ_TRUE;
3562 total_lz_bytes = d->m_total_lz_bytes;
3563 pLZ_code_buf = d->m_pLZ_code_buf;
3564 pLZ_flags = d->m_pLZ_flags;
3565 num_flags_left = d->m_num_flags_left;
3570 d->m_lookahead_pos = lookahead_pos;
3571 d->m_lookahead_size = lookahead_size;
3572 d->m_dict_size = dict_size;
3573 d->m_total_lz_bytes = total_lz_bytes;
3574 d->m_pLZ_code_buf = pLZ_code_buf;
3575 d->m_pLZ_flags = pLZ_flags;
3576 d->m_num_flags_left = num_flags_left;
3583 d->m_total_lz_bytes++;
3584 *d->m_pLZ_code_buf++ = lit;
3585 *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1);
3586 if (--d->m_num_flags_left == 0) {
3587 d->m_num_flags_left = 8;
3588 d->m_pLZ_flags = d->m_pLZ_code_buf++;
3590 d->m_huff_count[0][lit]++;
3593static MZ_FORCEINLINE
void
3594tdefl_record_match(
tdefl_compressor *d, mz_uint match_len, mz_uint match_dist) {
3597 MZ_ASSERT((match_len >= TDEFL_MIN_MATCH_LEN) && (match_dist >= 1) &&
3598 (match_dist <= TDEFL_LZ_DICT_SIZE));
3600 d->m_total_lz_bytes += match_len;
3602 d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN);
3605 d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF);
3606 d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8);
3607 d->m_pLZ_code_buf += 3;
3609 *d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80);
3610 if (--d->m_num_flags_left == 0) {
3611 d->m_num_flags_left = 8;
3612 d->m_pLZ_flags = d->m_pLZ_code_buf++;
3615 s0 = s_tdefl_small_dist_sym[match_dist & 511];
3616 s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127];
3617 d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++;
3618 d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++;
3622 const mz_uint8 *pSrc = d->m_pSrc;
3623 size_t src_buf_left = d->m_src_buf_left;
3624 tdefl_flush flush = d->m_flush;
3626 while ((src_buf_left) || ((flush) && (d->m_lookahead_size))) {
3627 mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos;
3630 if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1)) {
3631 mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) &
3632 TDEFL_LZ_DICT_SIZE_MASK,
3633 ins_pos = d->m_lookahead_pos + d->m_lookahead_size - 2;
3634 mz_uint hash = (d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK]
3635 << TDEFL_LZ_HASH_SHIFT) ^
3636 d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK];
3637 mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(
3638 src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size);
3639 const mz_uint8 *pSrc_end = pSrc ? pSrc + num_bytes_to_process : NULL;
3640 src_buf_left -= num_bytes_to_process;
3641 d->m_lookahead_size += num_bytes_to_process;
3642 while (pSrc != pSrc_end) {
3643 mz_uint8 c = *pSrc++;
3644 d->m_dict[dst_pos] = c;
3645 if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
3646 d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
3647 hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1);
3648 d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash];
3649 d->m_hash[hash] = (mz_uint16)(ins_pos);
3650 dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK;
3654 while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) {
3655 mz_uint8 c = *pSrc++;
3656 mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) &
3657 TDEFL_LZ_DICT_SIZE_MASK;
3659 d->m_dict[dst_pos] = c;
3660 if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
3661 d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
3662 if ((++d->m_lookahead_size + d->m_dict_size) >= TDEFL_MIN_MATCH_LEN) {
3663 mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2;
3664 mz_uint hash = ((d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK]
3665 << (TDEFL_LZ_HASH_SHIFT * 2)) ^
3666 (d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK]
3667 << TDEFL_LZ_HASH_SHIFT) ^
3669 (TDEFL_LZ_HASH_SIZE - 1);
3670 d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash];
3671 d->m_hash[hash] = (mz_uint16)(ins_pos);
3676 MZ_MIN(TDEFL_LZ_DICT_SIZE - d->m_lookahead_size, d->m_dict_size);
3677 if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
3684 d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1);
3685 cur_pos = d->m_lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
3686 if (d->m_flags & (TDEFL_RLE_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS)) {
3687 if ((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))) {
3688 mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK];
3690 while (cur_match_len < d->m_lookahead_size) {
3691 if (d->m_dict[cur_pos + cur_match_len] != c)
3695 if (cur_match_len < TDEFL_MIN_MATCH_LEN)
3701 tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size,
3702 d->m_lookahead_size, &cur_match_dist, &cur_match_len);
3704 if (((cur_match_len == TDEFL_MIN_MATCH_LEN) &&
3705 (cur_match_dist >= 8U * 1024U)) ||
3706 (cur_pos == cur_match_dist) ||
3707 ((d->m_flags & TDEFL_FILTER_MATCHES) && (cur_match_len <= 5))) {
3708 cur_match_dist = cur_match_len = 0;
3710 if (d->m_saved_match_len) {
3711 if (cur_match_len > d->m_saved_match_len) {
3712 tdefl_record_literal(d, (mz_uint8)d->m_saved_lit);
3713 if (cur_match_len >= 128) {
3714 tdefl_record_match(d, cur_match_len, cur_match_dist);
3715 d->m_saved_match_len = 0;
3716 len_to_move = cur_match_len;
3718 d->m_saved_lit = d->m_dict[cur_pos];
3719 d->m_saved_match_dist = cur_match_dist;
3720 d->m_saved_match_len = cur_match_len;
3723 tdefl_record_match(d, d->m_saved_match_len, d->m_saved_match_dist);
3724 len_to_move = d->m_saved_match_len - 1;
3725 d->m_saved_match_len = 0;
3727 }
else if (!cur_match_dist)
3728 tdefl_record_literal(d,
3729 d->m_dict[MZ_MIN(cur_pos,
sizeof(d->m_dict) - 1)]);
3730 else if ((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) ||
3731 (cur_match_len >= 128)) {
3732 tdefl_record_match(d, cur_match_len, cur_match_dist);
3733 len_to_move = cur_match_len;
3735 d->m_saved_lit = d->m_dict[MZ_MIN(cur_pos,
sizeof(d->m_dict) - 1)];
3736 d->m_saved_match_dist = cur_match_dist;
3737 d->m_saved_match_len = cur_match_len;
3740 d->m_lookahead_pos += len_to_move;
3741 MZ_ASSERT(d->m_lookahead_size >= len_to_move);
3742 d->m_lookahead_size -= len_to_move;
3744 MZ_MIN(d->m_dict_size + len_to_move, (mz_uint)TDEFL_LZ_DICT_SIZE);
3747 if ((d->m_pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) ||
3748 ((d->m_total_lz_bytes > 31 * 1024) &&
3749 (((((mz_uint)(d->m_pLZ_code_buf - d->m_lz_code_buf) * 115) >> 7) >=
3750 d->m_total_lz_bytes) ||
3751 (d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS)))) {
3754 d->m_src_buf_left = src_buf_left;
3755 if ((n = tdefl_flush_block(d, 0)) != 0)
3756 return (n < 0) ? MZ_FALSE : MZ_TRUE;
3761 d->m_src_buf_left = src_buf_left;
3766 if (d->m_pIn_buf_size) {
3767 *d->m_pIn_buf_size = d->m_pSrc - (
const mz_uint8 *)d->m_pIn_buf;
3770 if (d->m_pOut_buf_size) {
3771 size_t n = MZ_MIN(*d->m_pOut_buf_size - d->m_out_buf_ofs,
3772 d->m_output_flush_remaining);
3773 memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs,
3774 d->m_output_buf + d->m_output_flush_ofs, n);
3775 d->m_output_flush_ofs += (mz_uint)n;
3776 d->m_output_flush_remaining -= (mz_uint)n;
3777 d->m_out_buf_ofs += n;
3779 *d->m_pOut_buf_size = d->m_out_buf_ofs;
3782 return (d->m_finished && !d->m_output_flush_remaining) ? TDEFL_STATUS_DONE
3783 : TDEFL_STATUS_OKAY;
3787 size_t *pIn_buf_size,
void *pOut_buf,
3788 size_t *pOut_buf_size, tdefl_flush flush) {
3794 return TDEFL_STATUS_BAD_PARAM;
3797 d->m_pIn_buf = pIn_buf;
3798 d->m_pIn_buf_size = pIn_buf_size;
3799 d->m_pOut_buf = pOut_buf;
3800 d->m_pOut_buf_size = pOut_buf_size;
3801 d->m_pSrc = (
const mz_uint8 *)(pIn_buf);
3802 d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0;
3803 d->m_out_buf_ofs = 0;
3806 if (((d->m_pPut_buf_func != NULL) ==
3807 ((pOut_buf != NULL) || (pOut_buf_size != NULL))) ||
3808 (d->m_prev_return_status != TDEFL_STATUS_OKAY) ||
3809 (d->m_wants_to_finish && (flush != TDEFL_FINISH)) ||
3810 (pIn_buf_size && *pIn_buf_size && !pIn_buf) ||
3811 (pOut_buf_size && *pOut_buf_size && !pOut_buf)) {
3816 return (d->m_prev_return_status = TDEFL_STATUS_BAD_PARAM);
3818 d->m_wants_to_finish |= (flush == TDEFL_FINISH);
3820 if ((d->m_output_flush_remaining) || (d->m_finished))
3821 return (d->m_prev_return_status = tdefl_flush_output_buffer(d));
3823#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
3824 if (((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) &&
3825 ((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) &&
3826 ((d->m_flags & (TDEFL_FILTER_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS |
3827 TDEFL_RLE_MATCHES)) == 0)) {
3828 if (!tdefl_compress_fast(d))
3829 return d->m_prev_return_status;
3833 if (!tdefl_compress_normal(d))
3834 return d->m_prev_return_status;
3837 if ((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) &&
3840 (mz_uint32)mz_adler32(d->m_adler32, (
const mz_uint8 *)pIn_buf,
3841 d->m_pSrc - (
const mz_uint8 *)pIn_buf);
3843 if ((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) &&
3844 (!d->m_output_flush_remaining)) {
3845 if (tdefl_flush_block(d, flush) < 0)
3846 return d->m_prev_return_status;
3847 d->m_finished = (flush == TDEFL_FINISH);
3848 if (flush == TDEFL_FULL_FLUSH) {
3849 MZ_CLEAR_ARR(d->m_hash);
3850 MZ_CLEAR_ARR(d->m_next);
3855 return (d->m_prev_return_status = tdefl_flush_output_buffer(d));
3858tdefl_status tdefl_compress_buffer(
tdefl_compressor *d,
const void *pIn_buf,
3859 size_t in_buf_size, tdefl_flush flush) {
3860 MZ_ASSERT(d->m_pPut_buf_func);
3861 return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush);
3865 tdefl_put_buf_func_ptr pPut_buf_func,
3866 void *pPut_buf_user,
int flags) {
3867 d->m_pPut_buf_func = pPut_buf_func;
3868 d->m_pPut_buf_user = pPut_buf_user;
3869 d->m_flags = (mz_uint)(flags);
3870 d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3;
3871 d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0;
3872 d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3;
3873 if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG))
3874 MZ_CLEAR_ARR(d->m_hash);
3875 d->m_lookahead_pos = d->m_lookahead_size = d->m_dict_size =
3876 d->m_total_lz_bytes = d->m_lz_code_buf_dict_pos = d->m_bits_in = 0;
3877 d->m_output_flush_ofs = d->m_output_flush_remaining = d->m_finished =
3878 d->m_block_index = d->m_bit_buffer = d->m_wants_to_finish = 0;
3879 d->m_pLZ_code_buf = d->m_lz_code_buf + 1;
3880 d->m_pLZ_flags = d->m_lz_code_buf;
3881 *d->m_pLZ_flags = 0;
3882 d->m_num_flags_left = 8;
3883 d->m_pOutput_buf = d->m_output_buf;
3884 d->m_pOutput_buf_end = d->m_output_buf;
3885 d->m_prev_return_status = TDEFL_STATUS_OKAY;
3886 d->m_saved_match_dist = d->m_saved_match_len = d->m_saved_lit = 0;
3888 d->m_pIn_buf = NULL;
3889 d->m_pOut_buf = NULL;
3890 d->m_pIn_buf_size = NULL;
3891 d->m_pOut_buf_size = NULL;
3892 d->m_flush = TDEFL_NO_FLUSH;
3894 d->m_src_buf_left = 0;
3895 d->m_out_buf_ofs = 0;
3896 if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG))
3897 MZ_CLEAR_ARR(d->m_dict);
3898 memset(&d->m_huff_count[0][0], 0,
3899 sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
3900 memset(&d->m_huff_count[1][0], 0,
3901 sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
3902 return TDEFL_STATUS_OKAY;
3906 return d->m_prev_return_status;
3911mz_bool tdefl_compress_mem_to_output(
const void *pBuf,
size_t buf_len,
3912 tdefl_put_buf_func_ptr pPut_buf_func,
3913 void *pPut_buf_user,
int flags) {
3916 if (((buf_len) && (!pBuf)) || (!pPut_buf_func))
3921 succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags) ==
3924 succeeded && (tdefl_compress_buffer(pComp, pBuf, buf_len, TDEFL_FINISH) ==
3931 size_t m_size, m_capacity;
3933 mz_bool m_expandable;
3936static mz_bool tdefl_output_buffer_putter(
const void *pBuf,
int len,
3939 size_t new_size = p->m_size + len;
3940 if (new_size > p->m_capacity) {
3941 size_t new_capacity = p->m_capacity;
3943 if (!p->m_expandable)
3946 new_capacity = MZ_MAX(128U, new_capacity << 1U);
3947 }
while (new_size > new_capacity);
3948 pNew_buf = (mz_uint8 *)MZ_REALLOC(p->m_pBuf, new_capacity);
3951 p->m_pBuf = pNew_buf;
3952 p->m_capacity = new_capacity;
3954 memcpy((mz_uint8 *)p->m_pBuf + p->m_size, pBuf, len);
3955 p->m_size = new_size;
3959void *tdefl_compress_mem_to_heap(
const void *pSrc_buf,
size_t src_buf_len,
3960 size_t *pOut_len,
int flags) {
3962 MZ_CLEAR_OBJ(out_buf);
3967 out_buf.m_expandable = MZ_TRUE;
3968 if (!tdefl_compress_mem_to_output(
3969 pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags))
3971 *pOut_len = out_buf.m_size;
3972 return out_buf.m_pBuf;
3975size_t tdefl_compress_mem_to_mem(
void *pOut_buf,
size_t out_buf_len,
3976 const void *pSrc_buf,
size_t src_buf_len,
3979 MZ_CLEAR_OBJ(out_buf);
3982 out_buf.m_pBuf = (mz_uint8 *)pOut_buf;
3983 out_buf.m_capacity = out_buf_len;
3984 if (!tdefl_compress_mem_to_output(
3985 pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags))
3987 return out_buf.m_size;
3993mz_uint tdefl_create_comp_flags_from_zip_params(
int level,
int window_bits,
3995 mz_uint comp_flags =
3996 s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] |
3997 ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0);
3998 if (window_bits > 0)
3999 comp_flags |= TDEFL_WRITE_ZLIB_HEADER;
4002 comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS;
4003 else if (strategy == MZ_FILTERED)
4004 comp_flags |= TDEFL_FILTER_MATCHES;
4005 else if (strategy == MZ_HUFFMAN_ONLY)
4006 comp_flags &= ~TDEFL_MAX_PROBES_MASK;
4007 else if (strategy == MZ_FIXED)
4008 comp_flags |= TDEFL_FORCE_ALL_STATIC_BLOCKS;
4009 else if (strategy == MZ_RLE)
4010 comp_flags |= TDEFL_RLE_MATCHES;
4016#pragma warning(push)
4017#pragma warning(disable : 4204)
4027void *tdefl_write_image_to_png_file_in_memory_ex(
const void *pImage,
int w,
4028 int h,
int num_chans,
4030 mz_uint level, mz_bool flip) {
4033 static const mz_uint s_tdefl_png_num_probes[11] = {
4034 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500};
4038 int i, bpl = w * num_chans, y, z;
4043 MZ_CLEAR_OBJ(out_buf);
4044 out_buf.m_expandable = MZ_TRUE;
4045 out_buf.m_capacity = 57 + MZ_MAX(64, (1 + bpl) * h);
4046 if (NULL == (out_buf.m_pBuf = (mz_uint8 *)MZ_MALLOC(out_buf.m_capacity))) {
4051 for (z = 41; z; --z)
4052 tdefl_output_buffer_putter(&z, 1, &out_buf);
4054 tdefl_init(pComp, tdefl_output_buffer_putter, &out_buf,
4055 s_tdefl_png_num_probes[MZ_MIN(10, level)] |
4056 TDEFL_WRITE_ZLIB_HEADER);
4057 for (y = 0; y < h; ++y) {
4058 tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH);
4059 tdefl_compress_buffer(pComp,
4060 (mz_uint8 *)pImage + (flip ? (h - 1 - y) : y) * bpl,
4061 bpl, TDEFL_NO_FLUSH);
4063 if (tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) !=
4064 TDEFL_STATUS_DONE) {
4066 MZ_FREE(out_buf.m_pBuf);
4070 *pLen_out = out_buf.m_size - 41;
4072 static const mz_uint8 chans[] = {0x00, 0x00, 0x04, 0x02, 0x06};
4073 mz_uint8 pnghdr[41] = {0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00,
4074 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00,
4075 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
4076 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4077 0x00, 0x49, 0x44, 0x41, 0x54};
4078 pnghdr[18] = (mz_uint8)(w >> 8);
4079 pnghdr[19] = (mz_uint8)w;
4080 pnghdr[22] = (mz_uint8)(h >> 8);
4081 pnghdr[23] = (mz_uint8)h;
4082 pnghdr[25] = chans[num_chans];
4083 pnghdr[33] = (mz_uint8)(*pLen_out >> 24);
4084 pnghdr[34] = (mz_uint8)(*pLen_out >> 16);
4085 pnghdr[35] = (mz_uint8)(*pLen_out >> 8);
4086 pnghdr[36] = (mz_uint8)*pLen_out;
4087 c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, pnghdr + 12, 17);
4088 for (i = 0; i < 4; ++i, c <<= 8)
4089 ((mz_uint8 *)(pnghdr + 29))[i] = (mz_uint8)(c >> 24);
4090 memcpy(out_buf.m_pBuf, pnghdr, 41);
4093 if (!tdefl_output_buffer_putter(
4094 "\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf)) {
4097 MZ_FREE(out_buf.m_pBuf);
4100 c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, out_buf.m_pBuf + 41 - 4,
4102 for (i = 0; i < 4; ++i, c <<= 8)
4103 (out_buf.m_pBuf + out_buf.m_size - 16)[i] = (mz_uint8)(c >> 24);
4107 return out_buf.m_pBuf;
4109void *tdefl_write_image_to_png_file_in_memory(
const void *pImage,
int w,
int h,
4110 int num_chans,
size_t *pLen_out) {
4114 return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans,
4115 pLen_out, 6, MZ_FALSE);
4118#ifndef MINIZ_NO_MALLOC
4165#ifndef MINIZ_NO_INFLATE_APIS
4174#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
4175#define TINFL_MEMSET(p, c, l) memset(p, c, l)
4177#define TINFL_CR_BEGIN \
4178 switch (r->m_state) { \
4180#define TINFL_CR_RETURN(state_index, result) \
4183 r->m_state = state_index; \
4185 case state_index:; \
4188#define TINFL_CR_RETURN_FOREVER(state_index, result) \
4191 TINFL_CR_RETURN(state_index, result); \
4195#define TINFL_CR_FINISH }
4197#define TINFL_GET_BYTE(state_index, c) \
4199 while (pIn_buf_cur >= pIn_buf_end) { \
4200 TINFL_CR_RETURN(state_index, \
4201 (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) \
4202 ? TINFL_STATUS_NEEDS_MORE_INPUT \
4203 : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS); \
4205 c = *pIn_buf_cur++; \
4209#define TINFL_NEED_BITS(state_index, n) \
4212 TINFL_GET_BYTE(state_index, c); \
4213 bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
4215 } while (num_bits < (mz_uint)(n))
4216#define TINFL_SKIP_BITS(state_index, n) \
4218 if (num_bits < (mz_uint)(n)) { \
4219 TINFL_NEED_BITS(state_index, n); \
4225#define TINFL_GET_BITS(state_index, b, n) \
4227 if (num_bits < (mz_uint)(n)) { \
4228 TINFL_NEED_BITS(state_index, n); \
4230 b = bit_buf & ((1 << (n)) - 1); \
4245#define TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree) \
4247 temp = pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
4249 code_len = temp >> 9; \
4250 if ((code_len) && (num_bits >= code_len)) \
4252 } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \
4253 code_len = TINFL_FAST_LOOKUP_BITS; \
4255 temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \
4256 } while ((temp < 0) && (num_bits >= (code_len + 1))); \
4260 TINFL_GET_BYTE(state_index, c); \
4261 bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
4263 } while (num_bits < 15);
4280#define TINFL_HUFF_DECODE(state_index, sym, pLookUp, pTree) \
4283 mz_uint code_len, c; \
4284 if (num_bits < 15) { \
4285 if ((pIn_buf_end - pIn_buf_cur) < 2) { \
4286 TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree); \
4288 bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | \
4289 (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); \
4294 if ((temp = pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
4295 code_len = temp >> 9, temp &= 511; \
4297 code_len = TINFL_FAST_LOOKUP_BITS; \
4299 temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \
4300 } while (temp < 0); \
4303 bit_buf >>= code_len; \
4304 num_bits -= code_len; \
4308static void tinfl_clear_tree(tinfl_decompressor *r) {
4310 MZ_CLEAR_ARR(r->m_tree_0);
4311 else if (r->m_type == 1)
4312 MZ_CLEAR_ARR(r->m_tree_1);
4314 MZ_CLEAR_ARR(r->m_tree_2);
4317tinfl_status tinfl_decompress(tinfl_decompressor *r,
4318 const mz_uint8 *pIn_buf_next,
4319 size_t *pIn_buf_size, mz_uint8 *pOut_buf_start,
4320 mz_uint8 *pOut_buf_next,
size_t *pOut_buf_size,
4321 const mz_uint32 decomp_flags) {
4322 static const mz_uint16 s_length_base[31] = {
4323 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
4324 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
4325 static const mz_uint8 s_length_extra[31] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
4326 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4,
4327 4, 4, 5, 5, 5, 5, 0, 0, 0};
4328 static const mz_uint16 s_dist_base[32] = {
4329 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33,
4330 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537,
4331 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0};
4332 static const mz_uint8 s_dist_extra[32] = {
4333 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6,
4334 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
4335 static const mz_uint8 s_length_dezigzag[19] = {
4336 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
4337 static const mz_uint16 s_min_table_sizes[3] = {257, 1, 4};
4339 mz_int16 *pTrees[3];
4340 mz_uint8 *pCode_sizes[3];
4342 tinfl_status status = TINFL_STATUS_FAILED;
4343 mz_uint32 num_bits, dist, counter, num_extra;
4344 tinfl_bit_buf_t bit_buf;
4345 const mz_uint8 *pIn_buf_cur = pIn_buf_next, *
const pIn_buf_end =
4346 pIn_buf_next + *pIn_buf_size;
4347 mz_uint8 *pOut_buf_cur = pOut_buf_next, *
const pOut_buf_end =
4348 pOut_buf_next ? pOut_buf_next +
4351 size_t out_buf_size_mask =
4352 (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)
4354 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1,
4355 dist_from_out_buf_start;
4360 if (((out_buf_size_mask + 1) & out_buf_size_mask) ||
4361 (pOut_buf_next < pOut_buf_start)) {
4362 *pIn_buf_size = *pOut_buf_size = 0;
4363 return TINFL_STATUS_BAD_PARAM;
4366 pTrees[0] = r->m_tree_0;
4367 pTrees[1] = r->m_tree_1;
4368 pTrees[2] = r->m_tree_2;
4369 pCode_sizes[0] = r->m_code_size_0;
4370 pCode_sizes[1] = r->m_code_size_1;
4371 pCode_sizes[2] = r->m_code_size_2;
4373 num_bits = r->m_num_bits;
4374 bit_buf = r->m_bit_buf;
4376 counter = r->m_counter;
4377 num_extra = r->m_num_extra;
4378 dist_from_out_buf_start = r->m_dist_from_out_buf_start;
4381 bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0;
4382 r->m_z_adler32 = r->m_check_adler32 = 1;
4383 if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) {
4384 TINFL_GET_BYTE(1, r->m_zhdr0);
4385 TINFL_GET_BYTE(2, r->m_zhdr1);
4386 counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) ||
4387 (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8));
4388 if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
4389 counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) ||
4390 ((out_buf_size_mask + 1) <
4391 (size_t)((
size_t)1 << (8U + (r->m_zhdr0 >> 4)))));
4393 TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED);
4398 TINFL_GET_BITS(3, r->m_final, 3);
4399 r->m_type = r->m_final >> 1;
4400 if (r->m_type == 0) {
4401 TINFL_SKIP_BITS(5, num_bits & 7);
4402 for (counter = 0; counter < 4; ++counter) {
4404 TINFL_GET_BITS(6, r->m_raw_header[counter], 8);
4406 TINFL_GET_BYTE(7, r->m_raw_header[counter]);
4408 if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) !=
4410 (r->m_raw_header[2] | (r->m_raw_header[3] << 8)))) {
4411 TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED);
4413 while ((counter) && (num_bits)) {
4414 TINFL_GET_BITS(51, dist, 8);
4415 while (pOut_buf_cur >= pOut_buf_end) {
4416 TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT);
4418 *pOut_buf_cur++ = (mz_uint8)dist;
4423 while (pOut_buf_cur >= pOut_buf_end) {
4424 TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT);
4426 while (pIn_buf_cur >= pIn_buf_end) {
4427 TINFL_CR_RETURN(38, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT)
4428 ? TINFL_STATUS_NEEDS_MORE_INPUT
4429 : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS);
4431 n = MZ_MIN(MZ_MIN((
size_t)(pOut_buf_end - pOut_buf_cur),
4432 (
size_t)(pIn_buf_end - pIn_buf_cur)),
4434 TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n);
4437 counter -= (mz_uint)n;
4439 }
else if (r->m_type == 3) {
4440 TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED);
4442 if (r->m_type == 1) {
4443 mz_uint8 *p = r->m_code_size_0;
4445 r->m_table_sizes[0] = 288;
4446 r->m_table_sizes[1] = 32;
4447 TINFL_MEMSET(r->m_code_size_1, 5, 32);
4448 for (i = 0; i <= 143; ++i)
4450 for (; i <= 255; ++i)
4452 for (; i <= 279; ++i)
4454 for (; i <= 287; ++i)
4457 for (counter = 0; counter < 3; counter++) {
4458 TINFL_GET_BITS(11, r->m_table_sizes[counter],
"\05\05\04"[counter]);
4459 r->m_table_sizes[counter] += s_min_table_sizes[counter];
4461 MZ_CLEAR_ARR(r->m_code_size_2);
4462 for (counter = 0; counter < r->m_table_sizes[2]; counter++) {
4464 TINFL_GET_BITS(14, s, 3);
4465 r->m_code_size_2[s_length_dezigzag[counter]] = (mz_uint8)s;
4467 r->m_table_sizes[2] = 19;
4469 for (; (int)r->m_type >= 0; r->m_type--) {
4470 int tree_next, tree_cur;
4473 mz_uint8 *pCode_size;
4474 mz_uint i, j, used_syms, total, sym_index, next_code[17],
4476 pLookUp = r->m_look_up[r->m_type];
4477 pTree = pTrees[r->m_type];
4478 pCode_size = pCode_sizes[r->m_type];
4479 MZ_CLEAR_ARR(total_syms);
4480 TINFL_MEMSET(pLookUp, 0,
sizeof(r->m_look_up[0]));
4481 tinfl_clear_tree(r);
4482 for (i = 0; i < r->m_table_sizes[r->m_type]; ++i)
4483 total_syms[pCode_size[i]]++;
4484 used_syms = 0, total = 0;
4485 next_code[0] = next_code[1] = 0;
4486 for (i = 1; i <= 15; ++i) {
4487 used_syms += total_syms[i];
4488 next_code[i + 1] = (total = ((total + total_syms[i]) << 1));
4490 if ((65536 != total) && (used_syms > 1)) {
4491 TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED);
4493 for (tree_next = -1, sym_index = 0;
4494 sym_index < r->m_table_sizes[r->m_type]; ++sym_index) {
4495 mz_uint rev_code = 0, l, cur_code, code_size = pCode_size[sym_index];
4498 cur_code = next_code[code_size]++;
4499 for (l = code_size; l > 0; l--, cur_code >>= 1)
4500 rev_code = (rev_code << 1) | (cur_code & 1);
4501 if (code_size <= TINFL_FAST_LOOKUP_BITS) {
4502 mz_int16 k = (mz_int16)((code_size << 9) | sym_index);
4503 while (rev_code < TINFL_FAST_LOOKUP_SIZE) {
4504 pLookUp[rev_code] = k;
4505 rev_code += (1 << code_size);
4510 (tree_cur = pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) {
4511 pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] =
4512 (mz_int16)tree_next;
4513 tree_cur = tree_next;
4516 rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1);
4517 for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--) {
4518 tree_cur -= ((rev_code >>= 1) & 1);
4519 if (!pTree[-tree_cur - 1]) {
4520 pTree[-tree_cur - 1] = (mz_int16)tree_next;
4521 tree_cur = tree_next;
4524 tree_cur = pTree[-tree_cur - 1];
4526 tree_cur -= ((rev_code >>= 1) & 1);
4527 pTree[-tree_cur - 1] = (mz_int16)sym_index;
4529 if (r->m_type == 2) {
4531 counter < (r->m_table_sizes[0] + r->m_table_sizes[1]);) {
4533 TINFL_HUFF_DECODE(16, dist, r->m_look_up[2], r->m_tree_2);
4535 r->m_len_codes[counter++] = (mz_uint8)dist;
4538 if ((dist == 16) && (!counter)) {
4539 TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED);
4541 num_extra =
"\02\03\07"[dist - 16];
4542 TINFL_GET_BITS(18, s, num_extra);
4543 s +=
"\03\03\013"[dist - 16];
4544 TINFL_MEMSET(r->m_len_codes + counter,
4545 (dist == 16) ? r->m_len_codes[counter - 1] : 0, s);
4548 if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter) {
4549 TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED);
4551 TINFL_MEMCPY(r->m_code_size_0, r->m_len_codes, r->m_table_sizes[0]);
4552 TINFL_MEMCPY(r->m_code_size_1, r->m_len_codes + r->m_table_sizes[0],
4553 r->m_table_sizes[1]);
4559 if (((pIn_buf_end - pIn_buf_cur) < 4) ||
4560 ((pOut_buf_end - pOut_buf_cur) < 2)) {
4561 TINFL_HUFF_DECODE(23, counter, r->m_look_up[0], r->m_tree_0);
4564 while (pOut_buf_cur >= pOut_buf_end) {
4565 TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT);
4567 *pOut_buf_cur++ = (mz_uint8)counter;
4571#if TINFL_USE_64BIT_BITBUF
4572 if (num_bits < 30) {
4574 (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits);
4579 if (num_bits < 15) {
4581 (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
4587 r->m_look_up[0][bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >=
4589 code_len = sym2 >> 9;
4591 code_len = TINFL_FAST_LOOKUP_BITS;
4593 sym2 = r->m_tree_0[~sym2 + ((bit_buf >> code_len++) & 1)];
4597 bit_buf >>= code_len;
4598 num_bits -= code_len;
4602#if !TINFL_USE_64BIT_BITBUF
4603 if (num_bits < 15) {
4605 (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
4611 r->m_look_up[0][bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >=
4613 code_len = sym2 >> 9;
4615 code_len = TINFL_FAST_LOOKUP_BITS;
4617 sym2 = r->m_tree_0[~sym2 + ((bit_buf >> code_len++) & 1)];
4620 bit_buf >>= code_len;
4621 num_bits -= code_len;
4623 pOut_buf_cur[0] = (mz_uint8)counter;
4629 pOut_buf_cur[1] = (mz_uint8)sym2;
4633 if ((counter &= 511) == 256)
4636 num_extra = s_length_extra[counter - 257];
4637 counter = s_length_base[counter - 257];
4640 TINFL_GET_BITS(25, extra_bits, num_extra);
4641 counter += extra_bits;
4644 TINFL_HUFF_DECODE(26, dist, r->m_look_up[1], r->m_tree_1);
4645 num_extra = s_dist_extra[dist];
4646 dist = s_dist_base[dist];
4649 TINFL_GET_BITS(27, extra_bits, num_extra);
4653 dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
4654 if ((dist == 0 || dist > dist_from_out_buf_start ||
4655 dist_from_out_buf_start == 0) &&
4656 (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) {
4657 TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED);
4660 pSrc = pOut_buf_start +
4661 ((dist_from_out_buf_start - dist) & out_buf_size_mask);
4663 if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end) {
4665 while (pOut_buf_cur >= pOut_buf_end) {
4666 TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT);
4669 pOut_buf_start[(dist_from_out_buf_start++ - dist) &
4674#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
4675 else if ((counter >= 9) && (counter <= dist)) {
4676 const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
4678#ifdef MINIZ_UNALIGNED_USE_MEMCPY
4679 memcpy(pOut_buf_cur, pSrc,
sizeof(mz_uint32) * 2);
4681 ((mz_uint32 *)pOut_buf_cur)[0] = ((
const mz_uint32 *)pSrc)[0];
4682 ((mz_uint32 *)pOut_buf_cur)[1] = ((
const mz_uint32 *)pSrc)[1];
4685 }
while ((pSrc += 8) < pSrc_end);
4686 if ((counter &= 7) < 3) {
4688 pOut_buf_cur[0] = pSrc[0];
4690 pOut_buf_cur[1] = pSrc[1];
4691 pOut_buf_cur += counter;
4697 while (counter > 2) {
4698 pOut_buf_cur[0] = pSrc[0];
4699 pOut_buf_cur[1] = pSrc[1];
4700 pOut_buf_cur[2] = pSrc[2];
4706 pOut_buf_cur[0] = pSrc[0];
4708 pOut_buf_cur[1] = pSrc[1];
4709 pOut_buf_cur += counter;
4713 }
while (!(r->m_final & 1));
4721 TINFL_SKIP_BITS(32, num_bits & 7);
4722 while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8)) {
4726 bit_buf &= ~(~(tinfl_bit_buf_t)0 << num_bits);
4727 MZ_ASSERT(!num_bits);
4731 if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) {
4732 for (counter = 0; counter < 4; ++counter) {
4735 TINFL_GET_BITS(41, s, 8);
4737 TINFL_GET_BYTE(42, s);
4738 r->m_z_adler32 = (r->m_z_adler32 << 8) | s;
4741 TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE);
4753 if ((status != TINFL_STATUS_NEEDS_MORE_INPUT) &&
4754 (status != TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS)) {
4755 while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8)) {
4760 r->m_num_bits = num_bits;
4761 r->m_bit_buf = bit_buf & ~(~(tinfl_bit_buf_t)0 << num_bits);
4763 r->m_counter = counter;
4764 r->m_num_extra = num_extra;
4765 r->m_dist_from_out_buf_start = dist_from_out_buf_start;
4766 *pIn_buf_size = pIn_buf_cur - pIn_buf_next;
4767 *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
4769 (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) &&
4771 const mz_uint8 *ptr = pOut_buf_next;
4772 size_t buf_len = *pOut_buf_size;
4773 mz_uint32 i, s1 = r->m_check_adler32 & 0xffff,
4774 s2 = r->m_check_adler32 >> 16;
4775 size_t block_len = buf_len % 5552;
4777 for (i = 0; i + 7 < block_len; i += 8, ptr += 8) {
4778 s1 += ptr[0], s2 += s1;
4779 s1 += ptr[1], s2 += s1;
4780 s1 += ptr[2], s2 += s1;
4781 s1 += ptr[3], s2 += s1;
4782 s1 += ptr[4], s2 += s1;
4783 s1 += ptr[5], s2 += s1;
4784 s1 += ptr[6], s2 += s1;
4785 s1 += ptr[7], s2 += s1;
4787 for (; i < block_len; ++i)
4788 s1 += *ptr++, s2 += s1;
4789 s1 %= 65521U, s2 %= 65521U;
4790 buf_len -= block_len;
4793 r->m_check_adler32 = (s2 << 16) + s1;
4794 if ((status == TINFL_STATUS_DONE) &&
4795 (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) &&
4796 (r->m_check_adler32 != r->m_z_adler32))
4797 status = TINFL_STATUS_ADLER32_MISMATCH;
4803void *tinfl_decompress_mem_to_heap(
const void *pSrc_buf,
size_t src_buf_len,
4804 size_t *pOut_len,
int flags) {
4805 tinfl_decompressor decomp;
4806 void *pBuf = NULL, *pNew_buf;
4807 size_t src_buf_ofs = 0, out_buf_capacity = 0;
4809 tinfl_init(&decomp);
4811 size_t src_buf_size = src_buf_len - src_buf_ofs,
4812 dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity;
4813 tinfl_status status = tinfl_decompress(
4814 &decomp, (
const mz_uint8 *)pSrc_buf + src_buf_ofs, &src_buf_size,
4815 (mz_uint8 *)pBuf, pBuf ? (mz_uint8 *)pBuf + *pOut_len : NULL,
4817 (flags & ~TINFL_FLAG_HAS_MORE_INPUT) |
4818 TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
4819 if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT)) {
4824 src_buf_ofs += src_buf_size;
4825 *pOut_len += dst_buf_size;
4826 if (status == TINFL_STATUS_DONE)
4828 new_out_buf_capacity = out_buf_capacity * 2;
4829 if (new_out_buf_capacity < 128)
4830 new_out_buf_capacity = 128;
4831 pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity);
4838 out_buf_capacity = new_out_buf_capacity;
4843size_t tinfl_decompress_mem_to_mem(
void *pOut_buf,
size_t out_buf_len,
4844 const void *pSrc_buf,
size_t src_buf_len,
4846 tinfl_decompressor decomp;
4847 tinfl_status status;
4848 tinfl_init(&decomp);
4850 tinfl_decompress(&decomp, (
const mz_uint8 *)pSrc_buf, &src_buf_len,
4851 (mz_uint8 *)pOut_buf, (mz_uint8 *)pOut_buf, &out_buf_len,
4852 (flags & ~TINFL_FLAG_HAS_MORE_INPUT) |
4853 TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
4854 return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED
4858int tinfl_decompress_mem_to_callback(
const void *pIn_buf,
size_t *pIn_buf_size,
4859 tinfl_put_buf_func_ptr pPut_buf_func,
4860 void *pPut_buf_user,
int flags) {
4862 tinfl_decompressor decomp;
4863 mz_uint8 *pDict = (mz_uint8 *)MZ_MALLOC(TINFL_LZ_DICT_SIZE);
4864 size_t in_buf_ofs = 0, dict_ofs = 0;
4866 return TINFL_STATUS_FAILED;
4867 memset(pDict, 0, TINFL_LZ_DICT_SIZE);
4868 tinfl_init(&decomp);
4870 size_t in_buf_size = *pIn_buf_size - in_buf_ofs,
4871 dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs;
4872 tinfl_status status =
4873 tinfl_decompress(&decomp, (
const mz_uint8 *)pIn_buf + in_buf_ofs,
4874 &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size,
4875 (flags & ~(TINFL_FLAG_HAS_MORE_INPUT |
4876 TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)));
4877 in_buf_ofs += in_buf_size;
4878 if ((dst_buf_size) &&
4879 (!(*pPut_buf_func)(pDict + dict_ofs, (
int)dst_buf_size, pPut_buf_user)))
4881 if (status != TINFL_STATUS_HAS_MORE_OUTPUT) {
4882 result = (status == TINFL_STATUS_DONE);
4885 dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1);
4888 *pIn_buf_size = in_buf_ofs;
4892#ifndef MINIZ_NO_MALLOC
4893tinfl_decompressor *tinfl_decompressor_alloc(
void) {
4894 tinfl_decompressor *pDecomp =
4895 (tinfl_decompressor *)MZ_MALLOC(
sizeof(tinfl_decompressor));
4897 tinfl_init(pDecomp);
4901void tinfl_decompressor_free(tinfl_decompressor *pDecomp) { MZ_FREE(pDecomp); }
4936#ifndef MINIZ_NO_ARCHIVE_APIS
4944#ifdef MINIZ_NO_STDIO
4945#define MZ_FILE void *
4947#include <sys/stat.h>
4949#if defined(_MSC_VER) || defined(__MINGW64__) || defined(__MINGW32__)
4951#ifndef WIN32_LEAN_AND_MEAN
4952#define WIN32_LEAN_AND_MEAN
4955#define MICROSOFT_WINDOWS_WINBASE_H_DEFINE_INTERLOCKED_CPLUSPLUS_OVERLOADS 0
4962static WCHAR *mz_utf8z_to_widechar(
const char *str) {
4963 int reqChars = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
4964 WCHAR *wStr = (WCHAR *)malloc(reqChars *
sizeof(WCHAR));
4965 MultiByteToWideChar(CP_UTF8, 0, str, -1, wStr, reqChars);
4969static FILE *mz_fopen(
const char *pFilename,
const char *pMode) {
4970 WCHAR *wFilename = mz_utf8z_to_widechar(pFilename);
4971 WCHAR *wMode = mz_utf8z_to_widechar(pMode);
4973#ifdef ZIP_ENABLE_SHARABLE_FILE_OPEN
4974 pFile = _wfopen(wFilename, wMode);
4976 errno_t err = _wfopen_s(&pFile, wFilename, wMode);
4980#ifdef ZIP_ENABLE_SHARABLE_FILE_OPEN
4983 return err ? NULL : pFile;
4987static FILE *mz_freopen(
const char *pPath,
const char *pMode, FILE *pStream) {
4988 WCHAR *wPath = mz_utf8z_to_widechar(pPath);
4989 WCHAR *wMode = mz_utf8z_to_widechar(pMode);
4991#ifdef ZIP_ENABLE_SHARABLE_FILE_OPEN
4992 pFile = _wfreopen(wPath, wMode, pStream);
4994 errno_t err = _wfreopen_s(&pFile, wPath, wMode, pStream);
4998#ifdef ZIP_ENABLE_SHARABLE_FILE_OPEN
5001 return err ? NULL : pFile;
5005#if defined(__MINGW32__)
5006static int mz_stat(
const char *path,
struct _stat *buffer) {
5007 WCHAR *wPath = mz_utf8z_to_widechar(path);
5008 int res = _wstat(wPath, buffer);
5013static int mz_stat64(
const char *path,
struct __stat64 *buffer) {
5014 WCHAR *wPath = mz_utf8z_to_widechar(path);
5015 int res = _wstat64(wPath, buffer);
5021static int mz_mkdir(
const char *pDirname) {
5022 WCHAR *wDirname = mz_utf8z_to_widechar(pDirname);
5023 int res = _wmkdir(wDirname);
5028#ifndef MINIZ_NO_TIME
5029#include <sys/utime.h>
5031#define MZ_FOPEN mz_fopen
5032#define MZ_FCLOSE fclose
5033#define MZ_FREAD fread
5034#define MZ_FWRITE fwrite
5035#define MZ_FTELL64 _ftelli64
5036#define MZ_FSEEK64 _fseeki64
5037#if defined(__MINGW32__)
5038#define MZ_FILE_STAT_STRUCT _stat
5039#define MZ_FILE_STAT mz_stat
5041#define MZ_FILE_STAT_STRUCT _stat64
5042#define MZ_FILE_STAT mz_stat64
5044#define MZ_FFLUSH fflush
5045#define MZ_FREOPEN mz_freopen
5046#define MZ_DELETE_FILE remove
5047#define MZ_MKDIR(d) mz_mkdir(d)
5049#elif defined(__MINGW32__) || defined(__WATCOMC__)
5050#ifndef MINIZ_NO_TIME
5051#include <sys/utime.h>
5053#define MZ_FOPEN(f, m) fopen(f, m)
5054#define MZ_FCLOSE fclose
5055#define MZ_FREAD fread
5056#define MZ_FWRITE fwrite
5057#define MZ_FTELL64 _ftelli64
5058#define MZ_FSEEK64 _fseeki64
5059#define MZ_FILE_STAT_STRUCT stat
5060#define MZ_FILE_STAT stat
5061#define MZ_FFLUSH fflush
5062#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
5063#define MZ_DELETE_FILE remove
5064#define MZ_MKDIR(d) _mkdir(d)
5066#elif defined(__TINYC__)
5067#ifndef MINIZ_NO_TIME
5068#include <sys/utime.h>
5070#define MZ_FOPEN(f, m) fopen(f, m)
5071#define MZ_FCLOSE fclose
5072#define MZ_FREAD fread
5073#define MZ_FWRITE fwrite
5074#define MZ_FTELL64 ftell
5075#define MZ_FSEEK64 fseek
5076#define MZ_FILE_STAT_STRUCT stat
5077#define MZ_FILE_STAT stat
5078#define MZ_FFLUSH fflush
5079#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
5080#define MZ_DELETE_FILE remove
5081#if defined(_WIN32) || defined(_WIN64)
5082#define MZ_MKDIR(d) _mkdir(d)
5084#define MZ_MKDIR(d) mkdir(d, 0755)
5087#elif defined(__USE_LARGEFILE64)
5088#ifndef MINIZ_NO_TIME
5091#define MZ_FOPEN(f, m) fopen64(f, m)
5092#define MZ_FCLOSE fclose
5093#define MZ_FREAD fread
5094#define MZ_FWRITE fwrite
5095#define MZ_FTELL64 ftello64
5096#define MZ_FSEEK64 fseeko64
5097#define MZ_FILE_STAT_STRUCT stat64
5098#define MZ_FILE_STAT stat64
5099#define MZ_FFLUSH fflush
5100#define MZ_FREOPEN(p, m, s) freopen64(p, m, s)
5101#define MZ_DELETE_FILE remove
5102#define MZ_MKDIR(d) mkdir(d, 0755)
5104#elif defined(__APPLE__) || defined(__FreeBSD__) || \
5105 (defined(__linux__) && defined(__x86_64__))
5106#ifndef MINIZ_NO_TIME
5109#define MZ_FOPEN(f, m) fopen(f, m)
5110#define MZ_FCLOSE fclose
5111#define MZ_FREAD fread
5112#define MZ_FWRITE fwrite
5113#define MZ_FTELL64 ftello
5114#define MZ_FSEEK64 fseeko
5115#define MZ_FILE_STAT_STRUCT stat
5116#define MZ_FILE_STAT stat
5117#define MZ_FFLUSH fflush
5118#define MZ_FREOPEN(p, m, s) freopen(p, m, s)
5119#define MZ_DELETE_FILE remove
5120#define MZ_MKDIR(d) mkdir(d, 0755)
5124 "Using fopen, ftello, fseeko, stat() etc. path for file I/O - this path may not support large files.")
5125#ifndef MINIZ_NO_TIME
5128#define MZ_FOPEN(f, m) fopen(f, m)
5129#define MZ_FCLOSE fclose
5130#define MZ_FREAD fread
5131#define MZ_FWRITE fwrite
5132#ifdef __STRICT_ANSI__
5133#define MZ_FTELL64 ftell
5134#define MZ_FSEEK64 fseek
5136#define MZ_FTELL64 ftello
5137#define MZ_FSEEK64 fseeko
5139#define MZ_FILE_STAT_STRUCT stat
5140#define MZ_FILE_STAT stat
5141#define MZ_FFLUSH fflush
5142#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
5143#define MZ_DELETE_FILE remove
5144#define MZ_MKDIR(d) mkdir(d, 0755)
5152#define CHMOD(f, m) chmod(f, m)
5155#define MZ_TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c))
5162 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06054b50,
5163 MZ_ZIP_CENTRAL_DIR_HEADER_SIG = 0x02014b50,
5164 MZ_ZIP_LOCAL_DIR_HEADER_SIG = 0x04034b50,
5165 MZ_ZIP_LOCAL_DIR_HEADER_SIZE = 30,
5166 MZ_ZIP_CENTRAL_DIR_HEADER_SIZE = 46,
5167 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE = 22,
5170 MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06064b50,
5171 MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG = 0x07064b50,
5172 MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE = 56,
5173 MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE = 20,
5174 MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID = 0x0001,
5175 MZ_ZIP_DATA_DESCRIPTOR_ID = 0x08074b50,
5176 MZ_ZIP_DATA_DESCRIPTER_SIZE64 = 24,
5177 MZ_ZIP_DATA_DESCRIPTER_SIZE32 = 16,
5180 MZ_ZIP_CDH_SIG_OFS = 0,
5181 MZ_ZIP_CDH_VERSION_MADE_BY_OFS = 4,
5182 MZ_ZIP_CDH_VERSION_NEEDED_OFS = 6,
5183 MZ_ZIP_CDH_BIT_FLAG_OFS = 8,
5184 MZ_ZIP_CDH_METHOD_OFS = 10,
5185 MZ_ZIP_CDH_FILE_TIME_OFS = 12,
5186 MZ_ZIP_CDH_FILE_DATE_OFS = 14,
5187 MZ_ZIP_CDH_CRC32_OFS = 16,
5188 MZ_ZIP_CDH_COMPRESSED_SIZE_OFS = 20,
5189 MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS = 24,
5190 MZ_ZIP_CDH_FILENAME_LEN_OFS = 28,
5191 MZ_ZIP_CDH_EXTRA_LEN_OFS = 30,
5192 MZ_ZIP_CDH_COMMENT_LEN_OFS = 32,
5193 MZ_ZIP_CDH_DISK_START_OFS = 34,
5194 MZ_ZIP_CDH_INTERNAL_ATTR_OFS = 36,
5195 MZ_ZIP_CDH_EXTERNAL_ATTR_OFS = 38,
5196 MZ_ZIP_CDH_LOCAL_HEADER_OFS = 42,
5199 MZ_ZIP_LDH_SIG_OFS = 0,
5200 MZ_ZIP_LDH_VERSION_NEEDED_OFS = 4,
5201 MZ_ZIP_LDH_BIT_FLAG_OFS = 6,
5202 MZ_ZIP_LDH_METHOD_OFS = 8,
5203 MZ_ZIP_LDH_FILE_TIME_OFS = 10,
5204 MZ_ZIP_LDH_FILE_DATE_OFS = 12,
5205 MZ_ZIP_LDH_CRC32_OFS = 14,
5206 MZ_ZIP_LDH_COMPRESSED_SIZE_OFS = 18,
5207 MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS = 22,
5208 MZ_ZIP_LDH_FILENAME_LEN_OFS = 26,
5209 MZ_ZIP_LDH_EXTRA_LEN_OFS = 28,
5210 MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR = 1 << 3,
5213 MZ_ZIP_ECDH_SIG_OFS = 0,
5214 MZ_ZIP_ECDH_NUM_THIS_DISK_OFS = 4,
5215 MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS = 6,
5216 MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 8,
5217 MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS = 10,
5218 MZ_ZIP_ECDH_CDIR_SIZE_OFS = 12,
5219 MZ_ZIP_ECDH_CDIR_OFS_OFS = 16,
5220 MZ_ZIP_ECDH_COMMENT_SIZE_OFS = 20,
5223 MZ_ZIP64_ECDL_SIG_OFS = 0,
5224 MZ_ZIP64_ECDL_NUM_DISK_CDIR_OFS = 4,
5225 MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS = 8,
5226 MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS = 16,
5229 MZ_ZIP64_ECDH_SIG_OFS = 0,
5230 MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS = 4,
5231 MZ_ZIP64_ECDH_VERSION_MADE_BY_OFS = 12,
5232 MZ_ZIP64_ECDH_VERSION_NEEDED_OFS = 14,
5233 MZ_ZIP64_ECDH_NUM_THIS_DISK_OFS = 16,
5234 MZ_ZIP64_ECDH_NUM_DISK_CDIR_OFS = 20,
5235 MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 24,
5236 MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS = 32,
5237 MZ_ZIP64_ECDH_CDIR_SIZE_OFS = 40,
5238 MZ_ZIP64_ECDH_CDIR_OFS_OFS = 48,
5239 MZ_ZIP_VERSION_MADE_BY_DOS_FILESYSTEM_ID = 0,
5240 MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG = 0x10,
5241 MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED = 1,
5242 MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG = 32,
5243 MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION = 64,
5244 MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_LOCAL_DIR_IS_MASKED = 8192,
5245 MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8 = 1 << 11
5250 size_t m_size, m_capacity;
5251 mz_uint m_element_size;
5260 mz_uint32 m_init_flags;
5269 mz_bool m_zip64_has_extended_info_fields;
5274 mz_uint64 m_file_archive_start_ofs;
5278 size_t m_mem_capacity;
5281#define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size) \
5282 (array_ptr)->m_element_size = element_size
5284#if defined(DEBUG) || defined(_DEBUG)
5285static MZ_FORCEINLINE mz_uint
5286mz_zip_array_range_check(
const mz_zip_array *pArray, mz_uint index) {
5287 MZ_ASSERT(index < pArray->m_size);
5290#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) \
5291 ((element_type *)((array_ptr) \
5292 ->m_p))[mz_zip_array_range_check(array_ptr, index)]
5294#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) \
5295 ((element_type *)((array_ptr)->m_p))[index]
5298static MZ_FORCEINLINE
void mz_zip_array_init(
mz_zip_array *pArray,
5299 mz_uint32 element_size) {
5301 pArray->m_element_size = element_size;
5304static MZ_FORCEINLINE
void mz_zip_array_clear(
mz_zip_archive *pZip,
5306 pZip->m_pFree(pZip->m_pAlloc_opaque, pArray->m_p);
5312 size_t min_new_capacity,
5315 size_t new_capacity = min_new_capacity;
5316 MZ_ASSERT(pArray->m_element_size);
5317 if (pArray->m_capacity >= min_new_capacity)
5320 new_capacity = MZ_MAX(1, pArray->m_capacity);
5321 while (new_capacity < min_new_capacity)
5324 if (NULL == (pNew_p = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pArray->m_p,
5325 pArray->m_element_size, new_capacity)))
5327 pArray->m_p = pNew_p;
5328 pArray->m_capacity = new_capacity;
5332static MZ_FORCEINLINE mz_bool mz_zip_array_reserve(
mz_zip_archive *pZip,
5334 size_t new_capacity,
5336 if (new_capacity > pArray->m_capacity) {
5337 if (!mz_zip_array_ensure_capacity(pZip, pArray, new_capacity, growing))
5343static MZ_FORCEINLINE mz_bool mz_zip_array_resize(
mz_zip_archive *pZip,
5347 if (new_size > pArray->m_capacity) {
5348 if (!mz_zip_array_ensure_capacity(pZip, pArray, new_size, growing))
5351 pArray->m_size = new_size;
5355static MZ_FORCEINLINE mz_bool mz_zip_array_ensure_room(
mz_zip_archive *pZip,
5358 return mz_zip_array_reserve(pZip, pArray, pArray->m_size + n, MZ_TRUE);
5361static MZ_FORCEINLINE mz_bool mz_zip_array_push_back(
mz_zip_archive *pZip,
5363 const void *pElements,
5365 size_t orig_size = pArray->m_size;
5366 if (!mz_zip_array_resize(pZip, pArray, orig_size + n, MZ_TRUE))
5369 memcpy((mz_uint8 *)pArray->m_p + orig_size * pArray->m_element_size,
5370 pElements, n * pArray->m_element_size);
5374#ifndef MINIZ_NO_TIME
5375static MZ_TIME_T mz_zip_dos_to_time_t(
int dos_time,
int dos_date) {
5377 memset(&tm, 0,
sizeof(tm));
5379 tm.tm_year = ((dos_date >> 9) & 127) + 1980 - 1900;
5380 tm.tm_mon = ((dos_date >> 5) & 15) - 1;
5381 tm.tm_mday = dos_date & 31;
5382 tm.tm_hour = (dos_time >> 11) & 31;
5383 tm.tm_min = (dos_time >> 5) & 63;
5384 tm.tm_sec = (dos_time << 1) & 62;
5388#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
5389static void mz_zip_time_t_to_dos_time(MZ_TIME_T time, mz_uint16 *pDOS_time,
5390 mz_uint16 *pDOS_date) {
5392 struct tm tm_struct;
5393 struct tm *tm = &tm_struct;
5394 errno_t err = localtime_s(tm, &time);
5401 struct tm *tm = localtime(&time);
5404 *pDOS_time = (mz_uint16)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) +
5405 ((tm->tm_sec) >> 1));
5406 *pDOS_date = (mz_uint16)(((tm->tm_year + 1900 - 1980) << 9) +
5407 ((tm->tm_mon + 1) << 5) + tm->tm_mday);
5411#ifndef MINIZ_NO_STDIO
5412#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
5413static mz_bool mz_zip_get_file_modified_time(
const char *pFilename,
5415 struct MZ_FILE_STAT_STRUCT file_stat;
5419 if (MZ_FILE_STAT(pFilename, &file_stat) != 0)
5422 *pTime = file_stat.st_mtime;
5428static mz_bool mz_zip_set_file_times(
const char *pFilename,
5429 MZ_TIME_T access_time,
5430 MZ_TIME_T modified_time) {
5433 memset(&t, 0,
sizeof(t));
5434 t.actime = access_time;
5435 t.modtime = modified_time;
5437 return !utime(pFilename, &t);
5442static MZ_FORCEINLINE mz_bool mz_zip_set_error(
mz_zip_archive *pZip,
5443 mz_zip_error err_num) {
5445 pZip->m_last_error = err_num;
5452 if ((!pZip) || (pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
5453 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
5455 if (!pZip->m_pAlloc)
5456 pZip->m_pAlloc = miniz_def_alloc_func;
5458 pZip->m_pFree = miniz_def_free_func;
5459 if (!pZip->m_pRealloc)
5460 pZip->m_pRealloc = miniz_def_realloc_func;
5462 pZip->m_archive_size = 0;
5463 pZip->m_central_directory_file_ofs = 0;
5464 pZip->m_total_files = 0;
5465 pZip->m_last_error = MZ_ZIP_NO_ERROR;
5467 if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(
5468 pZip->m_pAlloc_opaque, 1,
sizeof(mz_zip_internal_state))))
5469 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
5471 memset(pZip->m_pState, 0,
sizeof(mz_zip_internal_state));
5472 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir,
5474 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets,
5476 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets,
5478 pZip->m_pState->m_init_flags = flags;
5479 pZip->m_pState->m_zip64 = MZ_FALSE;
5480 pZip->m_pState->m_zip64_has_extended_info_fields = MZ_FALSE;
5482 pZip->m_zip_mode = MZ_ZIP_MODE_READING;
5487static MZ_FORCEINLINE mz_bool
5488mz_zip_reader_filename_less(
const mz_zip_array *pCentral_dir_array,
5490 mz_uint l_index, mz_uint r_index) {
5491 const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(
5492 pCentral_dir_array, mz_uint8,
5493 MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32,
5496 const mz_uint8 *pR = &MZ_ZIP_ARRAY_ELEMENT(
5497 pCentral_dir_array, mz_uint8,
5498 MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, r_index));
5499 mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS),
5500 r_len = MZ_READ_LE16(pR + MZ_ZIP_CDH_FILENAME_LEN_OFS);
5501 mz_uint8 l = 0, r = 0;
5502 pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
5503 pR += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
5504 pE = pL + MZ_MIN(l_len, r_len);
5506 if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR)))
5511 return (pL == pE) ? (l_len < r_len) : (l < r);
5514#define MZ_SWAP_UINT32(a, b) \
5526mz_zip_reader_sort_central_dir_offsets_by_filename(
mz_zip_archive *pZip) {
5527 mz_zip_internal_state *pState = pZip->m_pState;
5528 const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
5529 const mz_zip_array *pCentral_dir = &pState->m_central_dir;
5530 mz_uint32 *pIndices;
5531 mz_uint32 start, end;
5532 const mz_uint32 size = pZip->m_total_files;
5537 pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets,
5540 start = (size - 2U) >> 1U;
5542 mz_uint64 child, root = start;
5544 if ((child = (root << 1U) + 1U) >= size)
5546 child += (((child + 1U) < size) &&
5547 (mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets,
5549 pIndices[child + 1U])));
5550 if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets,
5551 pIndices[root], pIndices[child]))
5553 MZ_SWAP_UINT32(pIndices[root], pIndices[child]);
5563 mz_uint64 child, root = 0;
5564 MZ_SWAP_UINT32(pIndices[end], pIndices[0]);
5566 if ((child = (root << 1U) + 1U) >= end)
5569 (((child + 1U) < end) &&
5570 mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets,
5571 pIndices[child], pIndices[child + 1U]));
5572 if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets,
5573 pIndices[root], pIndices[child]))
5575 MZ_SWAP_UINT32(pIndices[root], pIndices[child]);
5582static mz_bool mz_zip_reader_locate_header_sig(
mz_zip_archive *pZip,
5583 mz_uint32 record_sig,
5584 mz_uint32 record_size,
5586 mz_int64 cur_file_ofs;
5587 mz_uint32 buf_u32[4096 /
sizeof(mz_uint32)];
5588 mz_uint8 *pBuf = (mz_uint8 *)buf_u32;
5591 if (pZip->m_archive_size < record_size)
5596 MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)
sizeof(buf_u32), 0);
5599 n = (int)MZ_MIN(
sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs);
5601 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n)
5604 for (i = n - 4; i >= 0; --i) {
5605 mz_uint s = MZ_READ_LE32(pBuf + i);
5606 if (s == record_sig) {
5607 if ((pZip->m_archive_size - (cur_file_ofs + i)) >= record_size)
5619 if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >=
5620 ((mz_uint64)(MZ_UINT16_MAX) + record_size)))
5623 cur_file_ofs = MZ_MAX(cur_file_ofs - (
sizeof(buf_u32) - 3), 0);
5626 *pOfs = cur_file_ofs;
5630static mz_bool mz_zip_reader_eocd64_valid(
mz_zip_archive *pZip, uint64_t offset,
5632 if (pZip->m_pRead(pZip->m_pIO_opaque, offset, buf,
5633 MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) ==
5634 MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) {
5635 if (MZ_READ_LE32(buf + MZ_ZIP64_ECDH_SIG_OFS) ==
5636 MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG) {
5644static mz_bool mz_zip_reader_read_central_dir(
mz_zip_archive *pZip,
5646 mz_uint cdir_size = 0, cdir_entries_on_this_disk = 0, num_this_disk = 0,
5647 cdir_disk_index = 0;
5648 mz_uint64 cdir_ofs = 0, eocd_ofs = 0, archive_ofs = 0;
5649 mz_int64 cur_file_ofs = 0;
5652 mz_uint32 buf_u32[4096 /
sizeof(mz_uint32)];
5653 mz_uint8 *pBuf = (mz_uint8 *)buf_u32;
5654 mz_bool sort_central_dir =
5655 ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0);
5656 mz_uint32 zip64_end_of_central_dir_locator_u32
5657 [(MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE +
sizeof(mz_uint32) - 1) /
5659 mz_uint8 *pZip64_locator = (mz_uint8 *)zip64_end_of_central_dir_locator_u32;
5661 mz_uint32 zip64_end_of_central_dir_header_u32
5662 [(MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE +
sizeof(mz_uint32) - 1) /
5664 mz_uint8 *pZip64_end_of_central_dir =
5665 (mz_uint8 *)zip64_end_of_central_dir_header_u32;
5667 mz_uint64 zip64_end_of_central_dir_ofs = 0;
5671 if (pZip->m_archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
5672 return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
5674 if (!mz_zip_reader_locate_header_sig(
5675 pZip, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG,
5676 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE, &cur_file_ofs))
5677 return mz_zip_set_error(pZip, MZ_ZIP_FAILED_FINDING_CENTRAL_DIR);
5679 eocd_ofs = cur_file_ofs;
5681 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf,
5682 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) !=
5683 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
5684 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
5686 if (MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) !=
5687 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG)
5688 return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
5690 if (cur_file_ofs >= (MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE +
5691 MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)) {
5692 if (pZip->m_pRead(pZip->m_pIO_opaque,
5693 cur_file_ofs - MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE,
5695 MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) ==
5696 MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) {
5697 if (MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_SIG_OFS) ==
5698 MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG) {
5699 pZip->m_pState->m_zip64 = MZ_TRUE;
5704 if (pZip->m_pState->m_zip64) {
5707 if (cur_file_ofs < MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE +
5708 MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)
5709 return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
5711 zip64_end_of_central_dir_ofs = cur_file_ofs -
5712 MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE -
5713 MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE;
5715 if (!mz_zip_reader_eocd64_valid(pZip, zip64_end_of_central_dir_ofs,
5716 pZip64_end_of_central_dir)) {
5718 zip64_end_of_central_dir_ofs = MZ_READ_LE64(
5719 pZip64_locator + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS);
5721 if (zip64_end_of_central_dir_ofs >
5722 (pZip->m_archive_size - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE))
5723 return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
5725 if (!mz_zip_reader_eocd64_valid(pZip, zip64_end_of_central_dir_ofs,
5726 pZip64_end_of_central_dir))
5727 return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
5731 pZip->m_total_files = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS);
5732 cdir_entries_on_this_disk =
5733 MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS);
5734 num_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS);
5735 cdir_disk_index = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS);
5736 cdir_size = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_SIZE_OFS);
5737 cdir_ofs = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS);
5739 if (pZip->m_pState->m_zip64) {
5740 mz_uint32 zip64_total_num_of_disks =
5741 MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS);
5742 mz_uint64 zip64_cdir_total_entries = MZ_READ_LE64(
5743 pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS);
5744 mz_uint64 zip64_cdir_total_entries_on_this_disk = MZ_READ_LE64(
5745 pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS);
5746 mz_uint64 zip64_size_of_end_of_central_dir_record = MZ_READ_LE64(
5747 pZip64_end_of_central_dir + MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS);
5748 mz_uint64 zip64_size_of_central_directory =
5749 MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_SIZE_OFS);
5751 if (zip64_size_of_end_of_central_dir_record <
5752 (MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE - 12))
5753 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
5755 if (zip64_total_num_of_disks != 1U)
5756 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK);
5759 if (zip64_cdir_total_entries > MZ_UINT32_MAX)
5760 return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
5762 pZip->m_total_files = (mz_uint32)zip64_cdir_total_entries;
5764 if (zip64_cdir_total_entries_on_this_disk > MZ_UINT32_MAX)
5765 return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
5767 cdir_entries_on_this_disk =
5768 (mz_uint32)zip64_cdir_total_entries_on_this_disk;
5772 if (zip64_size_of_central_directory > MZ_UINT32_MAX)
5773 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);
5775 cdir_size = (mz_uint32)zip64_size_of_central_directory;
5777 num_this_disk = MZ_READ_LE32(pZip64_end_of_central_dir +
5778 MZ_ZIP64_ECDH_NUM_THIS_DISK_OFS);
5780 cdir_disk_index = MZ_READ_LE32(pZip64_end_of_central_dir +
5781 MZ_ZIP64_ECDH_NUM_DISK_CDIR_OFS);
5784 MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_OFS_OFS);
5787 if (pZip->m_total_files != cdir_entries_on_this_disk)
5788 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK);
5790 if (((num_this_disk | cdir_disk_index) != 0) &&
5791 ((num_this_disk != 1) || (cdir_disk_index != 1)))
5792 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK);
5795 (mz_uint64)pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)
5796 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
5798 if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size)
5799 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
5801 if (eocd_ofs < cdir_ofs + cdir_size)
5802 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
5806 archive_ofs = eocd_ofs - (cdir_ofs + cdir_size);
5807 if (pZip->m_pState->m_zip64) {
5808 if (archive_ofs < MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE +
5809 MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE)
5810 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
5812 archive_ofs -= MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE +
5813 MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE;
5817 if ((pZip->m_zip_type == MZ_ZIP_TYPE_FILE ||
5818 pZip->m_zip_type == MZ_ZIP_TYPE_CFILE) &&
5819 pZip->m_pState->m_file_archive_start_ofs == 0) {
5820 pZip->m_pState->m_file_archive_start_ofs = archive_ofs;
5821 pZip->m_archive_size -= archive_ofs;
5824 pZip->m_central_directory_file_ofs = cdir_ofs;
5826 if (pZip->m_total_files) {
5831 if ((!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir, cdir_size,
5833 (!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir_offsets,
5834 pZip->m_total_files, MZ_FALSE)))
5835 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
5837 if (sort_central_dir) {
5838 if (!mz_zip_array_resize(pZip,
5839 &pZip->m_pState->m_sorted_central_dir_offsets,
5840 pZip->m_total_files, MZ_FALSE))
5841 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
5844 if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs,
5845 pZip->m_pState->m_central_dir.m_p,
5846 cdir_size) != cdir_size)
5847 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
5851 p = (
const mz_uint8 *)pZip->m_pState->m_central_dir.m_p;
5852 for (n = cdir_size, i = 0; i < pZip->m_total_files; ++i) {
5853 mz_uint total_header_size, disk_index, bit_flags, filename_size,
5855 mz_uint64 comp_size, decomp_size, local_header_ofs;
5857 if ((n < MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) ||
5858 (MZ_READ_LE32(p) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG))
5859 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
5861 MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32,
5863 (mz_uint32)(p - (
const mz_uint8 *)pZip->m_pState->m_central_dir.m_p);
5865 if (sort_central_dir)
5866 MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_sorted_central_dir_offsets,
5869 comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
5870 decomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
5871 local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
5872 filename_size = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
5873 ext_data_size = MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS);
5875 if ((!pZip->m_pState->m_zip64_has_extended_info_fields) &&
5877 (MZ_MAX(MZ_MAX(comp_size, decomp_size), local_header_ofs) ==
5881 mz_uint32 extra_size_remaining = ext_data_size;
5883 if (extra_size_remaining) {
5884 const mz_uint8 *pExtra_data;
5887 if (MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + ext_data_size >
5889 buf = MZ_MALLOC(ext_data_size);
5891 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
5893 if (pZip->m_pRead(pZip->m_pIO_opaque,
5894 cdir_ofs + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE +
5896 buf, ext_data_size) != ext_data_size) {
5898 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
5901 pExtra_data = (mz_uint8 *)buf;
5903 pExtra_data = p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size;
5908 mz_uint32 field_data_size;
5910 if (extra_size_remaining < (
sizeof(mz_uint16) * 2)) {
5912 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
5915 field_id = MZ_READ_LE16(pExtra_data);
5916 field_data_size = MZ_READ_LE16(pExtra_data +
sizeof(mz_uint16));
5918 if ((field_data_size +
sizeof(mz_uint16) * 2) >
5919 extra_size_remaining) {
5921 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
5924 if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) {
5929 pZip->m_pState->m_zip64 = MZ_TRUE;
5930 pZip->m_pState->m_zip64_has_extended_info_fields = MZ_TRUE;
5934 pExtra_data +=
sizeof(mz_uint16) * 2 + field_data_size;
5935 extra_size_remaining =
5936 extra_size_remaining -
sizeof(mz_uint16) * 2 - field_data_size;
5937 }
while (extra_size_remaining);
5945 if ((comp_size != MZ_UINT32_MAX) && (decomp_size != MZ_UINT32_MAX)) {
5946 if (((!MZ_READ_LE32(p + MZ_ZIP_CDH_METHOD_OFS)) &&
5947 (decomp_size != comp_size)) ||
5948 (decomp_size && !comp_size))
5949 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
5952 disk_index = MZ_READ_LE16(p + MZ_ZIP_CDH_DISK_START_OFS);
5953 if ((disk_index == MZ_UINT16_MAX) ||
5954 ((disk_index != num_this_disk) && (disk_index != 1)))
5955 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK);
5957 if (comp_size != MZ_UINT32_MAX) {
5958 if (((mz_uint64)MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS) +
5959 MZ_ZIP_LOCAL_DIR_HEADER_SIZE + comp_size) > pZip->m_archive_size)
5960 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
5963 bit_flags = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
5964 if (bit_flags & MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_LOCAL_DIR_IS_MASKED)
5965 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);
5967 if ((total_header_size = MZ_ZIP_CENTRAL_DIR_HEADER_SIZE +
5968 MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) +
5969 MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS) +
5970 MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS)) >
5972 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
5974 n -= total_header_size;
5975 p += total_header_size;
5979 if (sort_central_dir)
5980 mz_zip_reader_sort_central_dir_offsets_by_filename(pZip);
5991 mz_bool set_last_error) {
5992 mz_bool status = MZ_TRUE;
5997 if ((!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) ||
5998 (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) {
6000 pZip->m_last_error = MZ_ZIP_INVALID_PARAMETER;
6005 if (pZip->m_pState) {
6006 mz_zip_internal_state *pState = pZip->m_pState;
6007 pZip->m_pState = NULL;
6009 mz_zip_array_clear(pZip, &pState->m_central_dir);
6010 mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
6011 mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets);
6013#ifndef MINIZ_NO_STDIO
6014 if (pState->m_pFile) {
6015 if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE) {
6016 if (MZ_FCLOSE(pState->m_pFile) == EOF) {
6018 pZip->m_last_error = MZ_ZIP_FILE_CLOSE_FAILED;
6022 pState->m_pFile = NULL;
6026 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
6028 pZip->m_zip_mode = MZ_ZIP_MODE_INVALID;
6034 return mz_zip_reader_end_internal(pZip, MZ_TRUE);
6038 if ((!pZip) || (!pZip->m_pRead))
6039 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6041 if (!mz_zip_reader_init_internal(pZip, flags))
6044 pZip->m_zip_type = MZ_ZIP_TYPE_USER;
6045 pZip->m_archive_size = size;
6047 if (!mz_zip_reader_read_central_dir(pZip, flags)) {
6048 mz_zip_reader_end_internal(pZip, MZ_FALSE);
6055static size_t mz_zip_mem_read_func(
void *pOpaque, mz_uint64 file_ofs,
6056 void *pBuf,
size_t n) {
6058 size_t s = (file_ofs >= pZip->m_archive_size)
6060 : (size_t)MZ_MIN(pZip->m_archive_size - file_ofs, n);
6061 memcpy(pBuf, (
const mz_uint8 *)pZip->m_pState->m_pMem + file_ofs, s);
6065mz_bool mz_zip_reader_init_mem(
mz_zip_archive *pZip,
const void *pMem,
6066 size_t size, mz_uint flags) {
6068 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6070 if (size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
6071 return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
6073 if (!mz_zip_reader_init_internal(pZip, flags))
6076 pZip->m_zip_type = MZ_ZIP_TYPE_MEMORY;
6077 pZip->m_archive_size = size;
6078 pZip->m_pRead = mz_zip_mem_read_func;
6079 pZip->m_pIO_opaque = pZip;
6080 pZip->m_pNeeds_keepalive = NULL;
6083 pZip->m_pState->m_pMem =
const_cast<void *
>(pMem);
6085 pZip->m_pState->m_pMem = (
void *)pMem;
6088 pZip->m_pState->m_mem_size = size;
6090 if (!mz_zip_reader_read_central_dir(pZip, flags)) {
6091 mz_zip_reader_end_internal(pZip, MZ_FALSE);
6098#ifndef MINIZ_NO_STDIO
6099static size_t mz_zip_file_read_func(
void *pOpaque, mz_uint64 file_ofs,
6100 void *pBuf,
size_t n) {
6102 mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
6104 file_ofs += pZip->m_pState->m_file_archive_start_ofs;
6106 if (((mz_int64)file_ofs < 0) ||
6107 (((cur_ofs != (mz_int64)file_ofs)) &&
6108 (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET))))
6111 return MZ_FREAD(pBuf, 1, n, pZip->m_pState->m_pFile);
6114mz_bool mz_zip_reader_init_file(
mz_zip_archive *pZip,
const char *pFilename,
6116 return mz_zip_reader_init_file_v2(pZip, pFilename, flags, 0, 0);
6119mz_bool mz_zip_reader_init_file_v2(
mz_zip_archive *pZip,
const char *pFilename,
6120 mz_uint flags, mz_uint64 file_start_ofs,
6121 mz_uint64 archive_size) {
6122 mz_uint64 file_size;
6125 if ((!pZip) || (!pFilename) ||
6127 (archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)))
6128 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6130 pFile = MZ_FOPEN(pFilename,
"rb");
6132 return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);
6134 file_size = archive_size;
6136 if (MZ_FSEEK64(pFile, 0, SEEK_END)) {
6138 return mz_zip_set_error(pZip, MZ_ZIP_FILE_SEEK_FAILED);
6141 file_size = MZ_FTELL64(pFile);
6147 if (file_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) {
6149 return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
6152 if (!mz_zip_reader_init_internal(pZip, flags)) {
6157 pZip->m_zip_type = MZ_ZIP_TYPE_FILE;
6158 pZip->m_pRead = mz_zip_file_read_func;
6159 pZip->m_pIO_opaque = pZip;
6160 pZip->m_pState->m_pFile = pFile;
6161 pZip->m_archive_size = file_size;
6162 pZip->m_pState->m_file_archive_start_ofs = file_start_ofs;
6164 if (!mz_zip_reader_read_central_dir(pZip, flags)) {
6165 mz_zip_reader_end_internal(pZip, MZ_FALSE);
6172mz_bool mz_zip_reader_init_cfile(
mz_zip_archive *pZip, MZ_FILE *pFile,
6173 mz_uint64 archive_size, mz_uint flags) {
6174 mz_uint64 cur_file_ofs;
6176 if ((!pZip) || (!pFile))
6177 return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);
6179 cur_file_ofs = MZ_FTELL64(pFile);
6181 if (!archive_size) {
6182 if (MZ_FSEEK64(pFile, 0, SEEK_END))
6183 return mz_zip_set_error(pZip, MZ_ZIP_FILE_SEEK_FAILED);
6185 archive_size = MZ_FTELL64(pFile) - cur_file_ofs;
6187 if (archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
6188 return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
6191 if (!mz_zip_reader_init_internal(pZip, flags))
6194 pZip->m_zip_type = MZ_ZIP_TYPE_CFILE;
6195 pZip->m_pRead = mz_zip_file_read_func;
6197 pZip->m_pIO_opaque = pZip;
6198 pZip->m_pState->m_pFile = pFile;
6199 pZip->m_archive_size = archive_size;
6200 pZip->m_pState->m_file_archive_start_ofs = cur_file_ofs;
6202 if (!mz_zip_reader_read_central_dir(pZip, flags)) {
6203 mz_zip_reader_end_internal(pZip, MZ_FALSE);
6212static MZ_FORCEINLINE
const mz_uint8 *mz_zip_get_cdh(
mz_zip_archive *pZip,
6213 mz_uint file_index) {
6214 if ((!pZip) || (!pZip->m_pState) || (file_index >= pZip->m_total_files))
6216 return &MZ_ZIP_ARRAY_ELEMENT(
6217 &pZip->m_pState->m_central_dir, mz_uint8,
6218 MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32,
6223 mz_uint file_index) {
6225 const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
6227 mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6231 m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
6232 return (m_bit_flag &
6233 (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED |
6234 MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION)) != 0;
6238 mz_uint file_index) {
6242 const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
6244 mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6248 method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS);
6249 bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
6251 if ((method != 0) && (method != MZ_DEFLATED)) {
6252 mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD);
6256 if (bit_flag & (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED |
6257 MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION)) {
6258 mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);
6262 if (bit_flag & MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG) {
6263 mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE);
6271 mz_uint file_index) {
6272 mz_uint filename_len, attribute_mapping_id, external_attr;
6273 const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
6275 mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6279 filename_len = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
6281 if (*(p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_len - 1) ==
'/')
6292 attribute_mapping_id = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS) >> 8;
6293 (void)attribute_mapping_id;
6295 external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS);
6296 if ((external_attr & MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG) != 0) {
6305 const mz_uint8 *pCentral_dir_header,
6307 mz_bool *pFound_zip64_extra_data) {
6309 const mz_uint8 *p = pCentral_dir_header;
6311 if (pFound_zip64_extra_data)
6312 *pFound_zip64_extra_data = MZ_FALSE;
6314 if ((!p) || (!pStat))
6315 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6318 pStat->m_file_index = file_index;
6319 pStat->m_central_dir_ofs = MZ_ZIP_ARRAY_ELEMENT(
6320 &pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index);
6321 pStat->m_version_made_by = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS);
6322 pStat->m_version_needed = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_NEEDED_OFS);
6323 pStat->m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
6324 pStat->m_method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS);
6325#ifndef MINIZ_NO_TIME
6327 mz_zip_dos_to_time_t(MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_TIME_OFS),
6328 MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_DATE_OFS));
6330 pStat->m_crc32 = MZ_READ_LE32(p + MZ_ZIP_CDH_CRC32_OFS);
6331 pStat->m_comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
6332 pStat->m_uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
6333 pStat->m_internal_attr = MZ_READ_LE16(p + MZ_ZIP_CDH_INTERNAL_ATTR_OFS);
6334 pStat->m_external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS);
6335 pStat->m_local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
6338 n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
6339 n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE - 1);
6340 memcpy(pStat->m_filename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n);
6341 pStat->m_filename[n] =
'\0';
6343 n = MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS);
6344 n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE - 1);
6345 pStat->m_comment_size = n;
6346 memcpy(pStat->m_comment,
6347 p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE +
6348 MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) +
6349 MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS),
6351 pStat->m_comment[n] =
'\0';
6354 pStat->m_is_directory = mz_zip_reader_is_file_a_directory(pZip, file_index);
6355 pStat->m_is_encrypted = mz_zip_reader_is_file_encrypted(pZip, file_index);
6356 pStat->m_is_supported = mz_zip_reader_is_file_supported(pZip, file_index);
6361 if (MZ_MAX(MZ_MAX(pStat->m_comp_size, pStat->m_uncomp_size),
6362 pStat->m_local_header_ofs) == MZ_UINT32_MAX) {
6365 mz_uint32 extra_size_remaining = MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS);
6367 if (extra_size_remaining) {
6368 const mz_uint8 *pExtra_data =
6369 p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE +
6370 MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
6374 mz_uint32 field_data_size;
6376 if (extra_size_remaining < (
sizeof(mz_uint16) * 2))
6377 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
6379 field_id = MZ_READ_LE16(pExtra_data);
6380 field_data_size = MZ_READ_LE16(pExtra_data +
sizeof(mz_uint16));
6382 if ((field_data_size +
sizeof(mz_uint16) * 2) > extra_size_remaining)
6383 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
6385 if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) {
6386 const mz_uint8 *pField_data = pExtra_data +
sizeof(mz_uint16) * 2;
6387 mz_uint32 field_data_remaining = field_data_size;
6389 if (pFound_zip64_extra_data)
6390 *pFound_zip64_extra_data = MZ_TRUE;
6392 if (pStat->m_uncomp_size == MZ_UINT32_MAX) {
6393 if (field_data_remaining <
sizeof(mz_uint64))
6394 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
6396 pStat->m_uncomp_size = MZ_READ_LE64(pField_data);
6397 pField_data +=
sizeof(mz_uint64);
6398 field_data_remaining -=
sizeof(mz_uint64);
6401 if (pStat->m_comp_size == MZ_UINT32_MAX) {
6402 if (field_data_remaining <
sizeof(mz_uint64))
6403 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
6405 pStat->m_comp_size = MZ_READ_LE64(pField_data);
6406 pField_data +=
sizeof(mz_uint64);
6407 field_data_remaining -=
sizeof(mz_uint64);
6410 if (pStat->m_local_header_ofs == MZ_UINT32_MAX) {
6411 if (field_data_remaining <
sizeof(mz_uint64))
6412 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
6414 pStat->m_local_header_ofs = MZ_READ_LE64(pField_data);
6415 pField_data +=
sizeof(mz_uint64);
6416 field_data_remaining -=
sizeof(mz_uint64);
6422 pExtra_data +=
sizeof(mz_uint16) * 2 + field_data_size;
6423 extra_size_remaining =
6424 extra_size_remaining -
sizeof(mz_uint16) * 2 - field_data_size;
6425 }
while (extra_size_remaining);
6432static MZ_FORCEINLINE mz_bool mz_zip_string_equal(
const char *pA,
6433 const char *pB, mz_uint len,
6436 if (flags & MZ_ZIP_FLAG_CASE_SENSITIVE)
6437 return 0 == memcmp(pA, pB, len);
6438 for (i = 0; i < len; ++i)
6439 if (MZ_TOLOWER(pA[i]) != MZ_TOLOWER(pB[i]))
6444static MZ_FORCEINLINE
int
6445mz_zip_filename_compare(
const mz_zip_array *pCentral_dir_array,
6447 mz_uint l_index,
const char *pR, mz_uint r_len) {
6448 const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(
6449 pCentral_dir_array, mz_uint8,
6450 MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32,
6453 mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS);
6454 mz_uint8 l = 0, r = 0;
6455 pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
6456 pE = pL + MZ_MIN(l_len, r_len);
6458 if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR)))
6463 return (pL == pE) ? (int)(l_len - r_len) : (l - r);
6466static mz_bool mz_zip_locate_file_binary_search(
mz_zip_archive *pZip,
6467 const char *pFilename,
6468 mz_uint32 *pIndex) {
6469 mz_zip_internal_state *pState = pZip->m_pState;
6470 const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
6471 const mz_zip_array *pCentral_dir = &pState->m_central_dir;
6472 mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(
6473 &pState->m_sorted_central_dir_offsets, mz_uint32, 0);
6474 const mz_uint32 size = pZip->m_total_files;
6475 const mz_uint filename_len = (mz_uint)strlen(pFilename);
6485 mz_int64 l = 0, h = (mz_int64)size - 1;
6488 mz_int64 m = l + ((h - l) >> 1);
6489 mz_uint32 file_index = pIndices[(mz_uint32)m];
6491 int comp = mz_zip_filename_compare(pCentral_dir, pCentral_dir_offsets,
6492 file_index, pFilename, filename_len);
6495 *pIndex = file_index;
6497 }
else if (comp < 0)
6504 return mz_zip_set_error(pZip, MZ_ZIP_FILE_NOT_FOUND);
6507int mz_zip_reader_locate_file(
mz_zip_archive *pZip,
const char *pName,
6508 const char *pComment, mz_uint flags) {
6510 if (!mz_zip_reader_locate_file_v2(pZip, pName, pComment, flags, &index))
6516mz_bool mz_zip_reader_locate_file_v2(
mz_zip_archive *pZip,
const char *pName,
6517 const char *pComment, mz_uint flags,
6518 mz_uint32 *pIndex) {
6520 size_t name_len, comment_len;
6525 if ((!pZip) || (!pZip->m_pState) || (!pName))
6526 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6529 if (((pZip->m_pState->m_init_flags &
6530 MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0) &&
6531 (pZip->m_zip_mode == MZ_ZIP_MODE_READING) &&
6532 ((flags & (MZ_ZIP_FLAG_IGNORE_PATH | MZ_ZIP_FLAG_CASE_SENSITIVE)) == 0) &&
6533 (!pComment) && (pZip->m_pState->m_sorted_central_dir_offsets.m_size)) {
6534 return mz_zip_locate_file_binary_search(pZip, pName, pIndex);
6538 name_len = strlen(pName);
6539 if (name_len > MZ_UINT16_MAX)
6540 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6542 comment_len = pComment ? strlen(pComment) : 0;
6543 if (comment_len > MZ_UINT16_MAX)
6544 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6546 for (file_index = 0; file_index < pZip->m_total_files; file_index++) {
6547 const mz_uint8 *pHeader = &MZ_ZIP_ARRAY_ELEMENT(
6548 &pZip->m_pState->m_central_dir, mz_uint8,
6549 MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32,
6551 mz_uint filename_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_FILENAME_LEN_OFS);
6552 const char *pFilename =
6553 (
const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
6554 if (filename_len < name_len)
6557 mz_uint file_extra_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_EXTRA_LEN_OFS),
6559 MZ_READ_LE16(pHeader + MZ_ZIP_CDH_COMMENT_LEN_OFS);
6560 const char *pFile_comment = pFilename + filename_len + file_extra_len;
6561 if ((file_comment_len != comment_len) ||
6562 (!mz_zip_string_equal(pComment, pFile_comment, file_comment_len,
6566 if ((flags & MZ_ZIP_FLAG_IGNORE_PATH) && (filename_len)) {
6567 int ofs = filename_len - 1;
6569 if ((pFilename[ofs] ==
'/') || (pFilename[ofs] ==
'\\') ||
6570 (pFilename[ofs] ==
':'))
6572 }
while (--ofs >= 0);
6575 filename_len -= ofs;
6577 if ((filename_len == name_len) &&
6578 (mz_zip_string_equal(pName, pFilename, filename_len, flags))) {
6580 *pIndex = file_index;
6585 return mz_zip_set_error(pZip, MZ_ZIP_FILE_NOT_FOUND);
6588static mz_bool mz_zip_reader_extract_to_mem_no_alloc1(
6589 mz_zip_archive *pZip, mz_uint file_index,
void *pBuf,
size_t buf_size,
6590 mz_uint flags,
void *pUser_read_buf,
size_t user_read_buf_size,
6592 int status = TINFL_STATUS_DONE;
6593 mz_uint64 needed_size, cur_file_ofs, comp_remaining,
6594 out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail;
6598 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE +
sizeof(mz_uint32) - 1) /
6600 mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
6601 tinfl_decompressor inflator;
6603 if ((!pZip) || (!pZip->m_pState) || ((buf_size) && (!pBuf)) ||
6604 ((user_read_buf_size) && (!pUser_read_buf)) || (!pZip->m_pRead))
6605 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6609 }
else if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
6613 if ((file_stat.m_is_directory) || (!file_stat.m_comp_size))
6617 if (file_stat.m_bit_flag &
6618 (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED |
6619 MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION |
6620 MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG))
6621 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);
6624 if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) &&
6625 (file_stat.m_method != MZ_DEFLATED))
6626 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD);
6629 needed_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size
6630 : file_stat.m_uncomp_size;
6631 if (buf_size < needed_size)
6632 return mz_zip_set_error(pZip, MZ_ZIP_BUF_TOO_SMALL);
6635 cur_file_ofs = file_stat.m_local_header_ofs;
6636 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header,
6637 MZ_ZIP_LOCAL_DIR_HEADER_SIZE) !=
6638 MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
6639 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
6641 if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
6642 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
6644 cur_file_ofs += (mz_uint64)(MZ_ZIP_LOCAL_DIR_HEADER_SIZE) +
6645 MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) +
6646 MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
6647 if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
6648 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
6650 if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) {
6652 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf,
6653 (
size_t)needed_size) != needed_size)
6654 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
6656#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
6657 if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) == 0) {
6658 if (mz_crc32(MZ_CRC32_INIT, (
const mz_uint8 *)pBuf,
6659 (
size_t)file_stat.m_uncomp_size) != file_stat.m_crc32)
6660 return mz_zip_set_error(pZip, MZ_ZIP_CRC_CHECK_FAILED);
6669 tinfl_init(&inflator);
6671 if (pZip->m_pState->m_pMem) {
6673 pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
6674 read_buf_size = read_buf_avail = file_stat.m_comp_size;
6676 }
else if (pUser_read_buf) {
6678 if (!user_read_buf_size)
6680 pRead_buf = (mz_uint8 *)pUser_read_buf;
6681 read_buf_size = user_read_buf_size;
6683 comp_remaining = file_stat.m_comp_size;
6687 MZ_MIN(file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
6688 if (((
sizeof(
size_t) ==
sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
6689 return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
6691 if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1,
6692 (
size_t)read_buf_size)))
6693 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6696 comp_remaining = file_stat.m_comp_size;
6703 out_buf_size = (size_t)(file_stat.m_uncomp_size - out_buf_ofs);
6704 if ((!read_buf_avail) && (!pZip->m_pState->m_pMem)) {
6705 read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
6706 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf,
6707 (
size_t)read_buf_avail) != read_buf_avail) {
6708 status = TINFL_STATUS_FAILED;
6709 mz_zip_set_error(pZip, MZ_ZIP_DECOMPRESSION_FAILED);
6712 cur_file_ofs += read_buf_avail;
6713 comp_remaining -= read_buf_avail;
6716 in_buf_size = (size_t)read_buf_avail;
6717 status = tinfl_decompress(
6718 &inflator, (mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size,
6719 (mz_uint8 *)pBuf, (mz_uint8 *)pBuf + out_buf_ofs, &out_buf_size,
6720 TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF |
6721 (comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0));
6722 read_buf_avail -= in_buf_size;
6723 read_buf_ofs += in_buf_size;
6724 out_buf_ofs += out_buf_size;
6725 }
while (status == TINFL_STATUS_NEEDS_MORE_INPUT);
6727 if (status == TINFL_STATUS_DONE) {
6729 if (out_buf_ofs != file_stat.m_uncomp_size) {
6730 mz_zip_set_error(pZip, MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE);
6731 status = TINFL_STATUS_FAILED;
6733#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
6734 else if (mz_crc32(MZ_CRC32_INIT, (
const mz_uint8 *)pBuf,
6735 (
size_t)file_stat.m_uncomp_size) != file_stat.m_crc32) {
6736 mz_zip_set_error(pZip, MZ_ZIP_CRC_CHECK_FAILED);
6737 status = TINFL_STATUS_FAILED;
6742 if ((!pZip->m_pState->m_pMem) && (!pUser_read_buf))
6743 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6745 return status == TINFL_STATUS_DONE;
6748mz_bool mz_zip_reader_extract_to_mem_no_alloc(
mz_zip_archive *pZip,
6749 mz_uint file_index,
void *pBuf,
6750 size_t buf_size, mz_uint flags,
6751 void *pUser_read_buf,
6752 size_t user_read_buf_size) {
6753 return mz_zip_reader_extract_to_mem_no_alloc1(pZip, file_index, pBuf,
6754 buf_size, flags, pUser_read_buf,
6755 user_read_buf_size, NULL);
6758mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(
6759 mz_zip_archive *pZip,
const char *pFilename,
void *pBuf,
size_t buf_size,
6760 mz_uint flags,
void *pUser_read_buf,
size_t user_read_buf_size) {
6761 mz_uint32 file_index;
6762 if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index))
6764 return mz_zip_reader_extract_to_mem_no_alloc1(pZip, file_index, pBuf,
6765 buf_size, flags, pUser_read_buf,
6766 user_read_buf_size, NULL);
6769mz_bool mz_zip_reader_extract_to_mem(
mz_zip_archive *pZip, mz_uint file_index,
6770 void *pBuf,
size_t buf_size,
6772 return mz_zip_reader_extract_to_mem_no_alloc1(pZip, file_index, pBuf,
6773 buf_size, flags, NULL, 0, NULL);
6777 const char *pFilename,
void *pBuf,
6778 size_t buf_size, mz_uint flags) {
6779 return mz_zip_reader_extract_file_to_mem_no_alloc(pZip, pFilename, pBuf,
6780 buf_size, flags, NULL, 0);
6783void *mz_zip_reader_extract_to_heap(
mz_zip_archive *pZip, mz_uint file_index,
6784 size_t *pSize, mz_uint flags) {
6786 mz_uint64 alloc_size;
6792 if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
6795 alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size
6796 : file_stat.m_uncomp_size;
6797 if (((
sizeof(
size_t) ==
sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF)) {
6798 mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
6803 (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (
size_t)alloc_size))) {
6804 mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6808 if (!mz_zip_reader_extract_to_mem_no_alloc1(pZip, file_index, pBuf,
6809 (
size_t)alloc_size, flags, NULL,
6811 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
6816 *pSize = (size_t)alloc_size;
6821 const char *pFilename,
size_t *pSize,
6823 mz_uint32 file_index;
6824 if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags,
6830 return mz_zip_reader_extract_to_heap(pZip, file_index, pSize, flags);
6835 mz_file_write_func pCallback,
6836 void *pOpaque, mz_uint flags) {
6837 int status = TINFL_STATUS_DONE;
6838#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
6839 mz_uint file_crc32 = MZ_CRC32_INIT;
6841 mz_uint64 read_buf_size, read_buf_ofs = 0, read_buf_avail, comp_remaining,
6842 out_buf_ofs = 0, cur_file_ofs;
6844 void *pRead_buf = NULL;
6845 void *pWrite_buf = NULL;
6847 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE +
sizeof(mz_uint32) - 1) /
6849 mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
6851 if ((!pZip) || (!pZip->m_pState) || (!pCallback) || (!pZip->m_pRead))
6852 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
6854 if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
6858 if ((file_stat.m_is_directory) || (!file_stat.m_comp_size))
6862 if (file_stat.m_bit_flag &
6863 (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED |
6864 MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION |
6865 MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG))
6866 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);
6869 if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) &&
6870 (file_stat.m_method != MZ_DEFLATED))
6871 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD);
6876 cur_file_ofs = file_stat.m_local_header_ofs;
6877 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header,
6878 MZ_ZIP_LOCAL_DIR_HEADER_SIZE) !=
6879 MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
6880 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
6882 if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
6883 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
6885 cur_file_ofs += (mz_uint64)(MZ_ZIP_LOCAL_DIR_HEADER_SIZE) +
6886 MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) +
6887 MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
6888 if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
6889 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
6893 if (pZip->m_pState->m_pMem) {
6894 pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
6895 read_buf_size = read_buf_avail = file_stat.m_comp_size;
6899 MZ_MIN(file_stat.m_comp_size, (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
6900 if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1,
6901 (
size_t)read_buf_size)))
6902 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6905 comp_remaining = file_stat.m_comp_size;
6908 if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) {
6910 if (pZip->m_pState->m_pMem) {
6911 if (((
sizeof(
size_t) ==
sizeof(mz_uint32))) &&
6912 (file_stat.m_comp_size > MZ_UINT32_MAX))
6913 return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
6915 if (pCallback(pOpaque, out_buf_ofs, pRead_buf,
6916 (
size_t)file_stat.m_comp_size) != file_stat.m_comp_size) {
6917 mz_zip_set_error(pZip, MZ_ZIP_WRITE_CALLBACK_FAILED);
6918 status = TINFL_STATUS_FAILED;
6919 }
else if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) {
6920#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
6922 (mz_uint32)mz_crc32(file_crc32, (
const mz_uint8 *)pRead_buf,
6923 (size_t)file_stat.m_comp_size);
6927 cur_file_ofs += file_stat.m_comp_size;
6928 out_buf_ofs += file_stat.m_comp_size;
6931 while (comp_remaining) {
6932 read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
6933 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf,
6934 (
size_t)read_buf_avail) != read_buf_avail) {
6935 mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
6936 status = TINFL_STATUS_FAILED;
6940#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
6941 if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) {
6942 file_crc32 = (mz_uint32)mz_crc32(
6943 file_crc32, (
const mz_uint8 *)pRead_buf, (size_t)read_buf_avail);
6947 if (pCallback(pOpaque, out_buf_ofs, pRead_buf,
6948 (
size_t)read_buf_avail) != read_buf_avail) {
6949 mz_zip_set_error(pZip, MZ_ZIP_WRITE_CALLBACK_FAILED);
6950 status = TINFL_STATUS_FAILED;
6954 cur_file_ofs += read_buf_avail;
6955 out_buf_ofs += read_buf_avail;
6956 comp_remaining -= read_buf_avail;
6960 tinfl_decompressor inflator;
6961 tinfl_init(&inflator);
6963 if (NULL == (pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1,
6964 TINFL_LZ_DICT_SIZE))) {
6965 mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
6966 status = TINFL_STATUS_FAILED;
6969 mz_uint8 *pWrite_buf_cur =
6970 (mz_uint8 *)pWrite_buf + (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
6973 TINFL_LZ_DICT_SIZE - (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
6974 if ((!read_buf_avail) && (!pZip->m_pState->m_pMem)) {
6975 read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
6976 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf,
6977 (
size_t)read_buf_avail) != read_buf_avail) {
6978 mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
6979 status = TINFL_STATUS_FAILED;
6982 cur_file_ofs += read_buf_avail;
6983 comp_remaining -= read_buf_avail;
6987 in_buf_size = (size_t)read_buf_avail;
6988 status = tinfl_decompress(
6989 &inflator, (
const mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size,
6990 (mz_uint8 *)pWrite_buf, pWrite_buf_cur, &out_buf_size,
6991 comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0);
6992 read_buf_avail -= in_buf_size;
6993 read_buf_ofs += in_buf_size;
6996 if (pCallback(pOpaque, out_buf_ofs, pWrite_buf_cur, out_buf_size) !=
6998 mz_zip_set_error(pZip, MZ_ZIP_WRITE_CALLBACK_FAILED);
6999 status = TINFL_STATUS_FAILED;
7003#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
7005 (mz_uint32)mz_crc32(file_crc32, pWrite_buf_cur, out_buf_size);
7007 if ((out_buf_ofs += out_buf_size) > file_stat.m_uncomp_size) {
7008 mz_zip_set_error(pZip, MZ_ZIP_DECOMPRESSION_FAILED);
7009 status = TINFL_STATUS_FAILED;
7013 }
while ((status == TINFL_STATUS_NEEDS_MORE_INPUT) ||
7014 (status == TINFL_STATUS_HAS_MORE_OUTPUT));
7018 if ((status == TINFL_STATUS_DONE) &&
7019 (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))) {
7021 if (out_buf_ofs != file_stat.m_uncomp_size) {
7022 mz_zip_set_error(pZip, MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE);
7023 status = TINFL_STATUS_FAILED;
7025#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
7026 else if (file_crc32 != file_stat.m_crc32) {
7027 mz_zip_set_error(pZip, MZ_ZIP_DECOMPRESSION_FAILED);
7028 status = TINFL_STATUS_FAILED;
7033 if (!pZip->m_pState->m_pMem)
7034 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
7037 pZip->m_pFree(pZip->m_pAlloc_opaque, pWrite_buf);
7039 return status == TINFL_STATUS_DONE;
7042mz_bool mz_zip_reader_extract_file_to_callback(
mz_zip_archive *pZip,
7043 const char *pFilename,
7044 mz_file_write_func pCallback,
7045 void *pOpaque, mz_uint flags) {
7046 mz_uint32 file_index;
7047 if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index))
7050 return mz_zip_reader_extract_to_callback(pZip, file_index, pCallback, pOpaque,
7055mz_zip_reader_extract_iter_new(
mz_zip_archive *pZip, mz_uint file_index,
7059 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE +
sizeof(mz_uint32) - 1) /
7061 mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
7064 if ((!pZip) || (!pZip->m_pState))
7071 mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
7076 if (!mz_zip_reader_file_stat(pZip, file_index, &pState->file_stat)) {
7077 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
7082 if (pState->file_stat.m_bit_flag &
7083 (MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED |
7084 MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION |
7085 MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG)) {
7086 mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);
7087 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
7092 if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) &&
7093 (pState->file_stat.m_method != 0) &&
7094 (pState->file_stat.m_method != MZ_DEFLATED)) {
7095 mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD);
7096 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
7101 pState->pZip = pZip;
7102 pState->flags = flags;
7105 pState->status = TINFL_STATUS_DONE;
7106#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
7107 pState->file_crc32 = MZ_CRC32_INIT;
7109 pState->read_buf_ofs = 0;
7110 pState->out_buf_ofs = 0;
7111 pState->pRead_buf = NULL;
7112 pState->pWrite_buf = NULL;
7113 pState->out_blk_remain = 0;
7116 pState->cur_file_ofs = pState->file_stat.m_local_header_ofs;
7117 if (pZip->m_pRead(pZip->m_pIO_opaque, pState->cur_file_ofs, pLocal_header,
7118 MZ_ZIP_LOCAL_DIR_HEADER_SIZE) !=
7119 MZ_ZIP_LOCAL_DIR_HEADER_SIZE) {
7120 mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
7121 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
7125 if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) {
7126 mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
7127 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
7131 pState->cur_file_ofs +=
7132 (mz_uint64)(MZ_ZIP_LOCAL_DIR_HEADER_SIZE) +
7133 MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) +
7134 MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
7135 if ((pState->cur_file_ofs + pState->file_stat.m_comp_size) >
7136 pZip->m_archive_size) {
7137 mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
7138 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
7144 if (pZip->m_pState->m_pMem) {
7146 (mz_uint8 *)pZip->m_pState->m_pMem + pState->cur_file_ofs;
7147 pState->read_buf_size = pState->read_buf_avail =
7148 pState->file_stat.m_comp_size;
7149 pState->comp_remaining = pState->file_stat.m_comp_size;
7151 if (!((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ||
7152 (!pState->file_stat.m_method))) {
7154 pState->read_buf_size = MZ_MIN(pState->file_stat.m_comp_size,
7155 (mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE);
7157 (pState->pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1,
7158 (
size_t)pState->read_buf_size))) {
7159 mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
7160 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
7166 pState->read_buf_size = 0;
7168 pState->read_buf_avail = 0;
7169 pState->comp_remaining = pState->file_stat.m_comp_size;
7172 if (!((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ||
7173 (!pState->file_stat.m_method))) {
7175 tinfl_init(&pState->inflator);
7178 if (NULL == (pState->pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1,
7179 TINFL_LZ_DICT_SIZE))) {
7180 mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
7181 if (pState->pRead_buf)
7182 pZip->m_pFree(pZip->m_pAlloc_opaque, pState->pRead_buf);
7183 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
7192mz_zip_reader_extract_file_iter_new(
mz_zip_archive *pZip,
const char *pFilename,
7194 mz_uint32 file_index;
7197 if (!mz_zip_reader_locate_file_v2(pZip, pFilename, NULL, flags, &file_index))
7201 return mz_zip_reader_extract_iter_new(pZip, file_index, flags);
7205 void *pvBuf,
size_t buf_size) {
7206 size_t copied_to_caller = 0;
7209 if ((!pState) || (!pState->pZip) || (!pState->pZip->m_pState) || (!pvBuf))
7212 if ((pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ||
7213 (!pState->file_stat.m_method)) {
7216 copied_to_caller = (size_t)MZ_MIN(buf_size, pState->comp_remaining);
7219 if (pState->pZip->m_pState->m_pMem) {
7221 memcpy(pvBuf, pState->pRead_buf, copied_to_caller);
7222 pState->pRead_buf = ((mz_uint8 *)pState->pRead_buf) + copied_to_caller;
7225 if (pState->pZip->m_pRead(pState->pZip->m_pIO_opaque,
7226 pState->cur_file_ofs, pvBuf,
7227 copied_to_caller) != copied_to_caller) {
7229 mz_zip_set_error(pState->pZip, MZ_ZIP_FILE_READ_FAILED);
7230 pState->status = TINFL_STATUS_FAILED;
7231 copied_to_caller = 0;
7235#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
7237 if (!(pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
7238 pState->file_crc32 = (mz_uint32)mz_crc32(
7239 pState->file_crc32, (
const mz_uint8 *)pvBuf, copied_to_caller);
7243 pState->cur_file_ofs += copied_to_caller;
7244 pState->out_buf_ofs += copied_to_caller;
7245 pState->comp_remaining -= copied_to_caller;
7249 mz_uint8 *pWrite_buf_cur =
7250 (mz_uint8 *)pState->pWrite_buf +
7251 (pState->out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
7255 out_buf_size = TINFL_LZ_DICT_SIZE -
7256 (pState->out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
7258 if (!pState->out_blk_remain) {
7260 if ((!pState->read_buf_avail) && (!pState->pZip->m_pState->m_pMem)) {
7262 pState->read_buf_avail =
7263 MZ_MIN(pState->read_buf_size, pState->comp_remaining);
7264 if (pState->pZip->m_pRead(pState->pZip->m_pIO_opaque,
7265 pState->cur_file_ofs, pState->pRead_buf,
7266 (
size_t)pState->read_buf_avail) !=
7267 pState->read_buf_avail) {
7268 mz_zip_set_error(pState->pZip, MZ_ZIP_FILE_READ_FAILED);
7269 pState->status = TINFL_STATUS_FAILED;
7274 pState->cur_file_ofs += pState->read_buf_avail;
7275 pState->comp_remaining -= pState->read_buf_avail;
7276 pState->read_buf_ofs = 0;
7280 in_buf_size = (size_t)pState->read_buf_avail;
7281 pState->status = tinfl_decompress(
7283 (
const mz_uint8 *)pState->pRead_buf + pState->read_buf_ofs,
7284 &in_buf_size, (mz_uint8 *)pState->pWrite_buf, pWrite_buf_cur,
7286 pState->comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0);
7287 pState->read_buf_avail -= in_buf_size;
7288 pState->read_buf_ofs += in_buf_size;
7291 pState->out_blk_remain = out_buf_size;
7294 if (pState->out_blk_remain) {
7297 MZ_MIN((buf_size - copied_to_caller), pState->out_blk_remain);
7300 memcpy((mz_uint8 *)pvBuf + copied_to_caller, pWrite_buf_cur, to_copy);
7302#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
7304 pState->file_crc32 =
7305 (mz_uint32)mz_crc32(pState->file_crc32, pWrite_buf_cur, to_copy);
7309 pState->out_blk_remain -= to_copy;
7312 if ((pState->out_buf_ofs += to_copy) >
7313 pState->file_stat.m_uncomp_size) {
7314 mz_zip_set_error(pState->pZip, MZ_ZIP_DECOMPRESSION_FAILED);
7315 pState->status = TINFL_STATUS_FAILED;
7320 copied_to_caller += to_copy;
7322 }
while ((copied_to_caller < buf_size) &&
7323 ((pState->status == TINFL_STATUS_NEEDS_MORE_INPUT) ||
7324 (pState->status == TINFL_STATUS_HAS_MORE_OUTPUT)));
7328 return copied_to_caller;
7336 if ((!pState) || (!pState->pZip) || (!pState->pZip->m_pState))
7340 if ((pState->status == TINFL_STATUS_DONE) &&
7341 (!(pState->flags & MZ_ZIP_FLAG_COMPRESSED_DATA))) {
7343 if (pState->out_buf_ofs != pState->file_stat.m_uncomp_size) {
7344 mz_zip_set_error(pState->pZip, MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE);
7345 pState->status = TINFL_STATUS_FAILED;
7347#ifndef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
7348 else if (pState->file_crc32 != pState->file_stat.m_crc32) {
7349 mz_zip_set_error(pState->pZip, MZ_ZIP_DECOMPRESSION_FAILED);
7350 pState->status = TINFL_STATUS_FAILED;
7356 if (!pState->pZip->m_pState->m_pMem)
7357 pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState->pRead_buf);
7358 if (pState->pWrite_buf)
7359 pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState->pWrite_buf);
7362 status = pState->status;
7365 pState->pZip->m_pFree(pState->pZip->m_pAlloc_opaque, pState);
7367 return status == TINFL_STATUS_DONE;
7370#ifndef MINIZ_NO_STDIO
7371static size_t mz_zip_file_write_callback(
void *pOpaque, mz_uint64 ofs,
7372 const void *pBuf,
size_t n) {
7375 return MZ_FWRITE(pBuf, 1, n, (MZ_FILE *)pOpaque);
7378mz_bool mz_zip_reader_extract_to_file(
mz_zip_archive *pZip, mz_uint file_index,
7379 const char *pDst_filename,
7385 if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
7388 if ((file_stat.m_is_directory) || (!file_stat.m_is_supported))
7389 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE);
7391 pFile = MZ_FOPEN(pDst_filename,
"wb");
7393 return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);
7395 status = mz_zip_reader_extract_to_callback(
7396 pZip, file_index, mz_zip_file_write_callback, pFile, flags);
7398 if (MZ_FCLOSE(pFile) == EOF) {
7400 mz_zip_set_error(pZip, MZ_ZIP_FILE_CLOSE_FAILED);
7405#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_STDIO)
7407 mz_zip_set_file_times(pDst_filename, file_stat.m_time, file_stat.m_time);
7414 const char *pArchive_filename,
7415 const char *pDst_filename,
7417 mz_uint32 file_index;
7418 if (!mz_zip_reader_locate_file_v2(pZip, pArchive_filename, NULL, flags,
7422 return mz_zip_reader_extract_to_file(pZip, file_index, pDst_filename, flags);
7425mz_bool mz_zip_reader_extract_to_cfile(
mz_zip_archive *pZip, mz_uint file_index,
7426 MZ_FILE *pFile, mz_uint flags) {
7429 if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
7432 if ((file_stat.m_is_directory) || (!file_stat.m_is_supported))
7433 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE);
7435 return mz_zip_reader_extract_to_callback(
7436 pZip, file_index, mz_zip_file_write_callback, pFile, flags);
7440 const char *pArchive_filename,
7441 MZ_FILE *pFile, mz_uint flags) {
7442 mz_uint32 file_index;
7443 if (!mz_zip_reader_locate_file_v2(pZip, pArchive_filename, NULL, flags,
7447 return mz_zip_reader_extract_to_cfile(pZip, file_index, pFile, flags);
7451static size_t mz_zip_compute_crc32_callback(
void *pOpaque, mz_uint64 file_ofs,
7452 const void *pBuf,
size_t n) {
7453 mz_uint32 *p = (mz_uint32 *)pOpaque;
7455 *p = (mz_uint32)mz_crc32(*p, (
const mz_uint8 *)pBuf, n);
7459mz_bool mz_zip_validate_file(
mz_zip_archive *pZip, mz_uint file_index,
7462 mz_zip_internal_state *pState;
7463 const mz_uint8 *pCentral_dir_header;
7464 mz_bool found_zip64_ext_data_in_cdir = MZ_FALSE;
7465 mz_bool found_zip64_ext_data_in_ldir = MZ_FALSE;
7467 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE +
sizeof(mz_uint32) - 1) /
7469 mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
7470 mz_uint64 local_header_ofs = 0;
7471 mz_uint32 local_header_filename_len, local_header_extra_len,
7473 mz_uint64 local_header_comp_size, local_header_uncomp_size;
7474 mz_uint32 uncomp_crc32 = MZ_CRC32_INIT;
7475 mz_bool has_data_descriptor;
7476 mz_uint32 local_header_bit_flags;
7479 mz_zip_array_init(&file_data_array, 1);
7481 if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) ||
7483 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
7485 if (file_index > pZip->m_total_files)
7486 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
7488 pState = pZip->m_pState;
7490 pCentral_dir_header = mz_zip_get_cdh(pZip, file_index);
7492 if (!mz_zip_file_stat_internal(pZip, file_index, pCentral_dir_header,
7493 &file_stat, &found_zip64_ext_data_in_cdir))
7497 if ((file_stat.m_is_directory) || (!file_stat.m_uncomp_size))
7501 if (file_stat.m_is_encrypted)
7502 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);
7505 if ((file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED))
7506 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_METHOD);
7508 if (!file_stat.m_is_supported)
7509 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_FEATURE);
7512 local_header_ofs = file_stat.m_local_header_ofs;
7513 if (pZip->m_pRead(pZip->m_pIO_opaque, local_header_ofs, pLocal_header,
7514 MZ_ZIP_LOCAL_DIR_HEADER_SIZE) !=
7515 MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
7516 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
7518 if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
7519 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
7521 local_header_filename_len =
7522 MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS);
7523 local_header_extra_len =
7524 MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
7525 local_header_comp_size =
7526 MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS);
7527 local_header_uncomp_size =
7528 MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS);
7529 local_header_crc32 = MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_CRC32_OFS);
7530 local_header_bit_flags =
7531 MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS);
7532 has_data_descriptor = (local_header_bit_flags & 8) != 0;
7534 if (local_header_filename_len != strlen(file_stat.m_filename))
7535 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
7537 if ((local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE +
7538 local_header_filename_len + local_header_extra_len +
7539 file_stat.m_comp_size) > pZip->m_archive_size)
7540 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
7542 if (!mz_zip_array_resize(
7543 pZip, &file_data_array,
7544 MZ_MAX(local_header_filename_len, local_header_extra_len),
7546 mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
7547 goto handle_failure;
7550 if (local_header_filename_len) {
7551 if (pZip->m_pRead(pZip->m_pIO_opaque,
7552 local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE,
7553 file_data_array.m_p,
7554 local_header_filename_len) != local_header_filename_len) {
7555 mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
7556 goto handle_failure;
7562 if (memcmp(file_stat.m_filename, file_data_array.m_p,
7563 local_header_filename_len) != 0) {
7564 mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
7565 goto handle_failure;
7569 if ((local_header_extra_len) &&
7570 ((local_header_comp_size == MZ_UINT32_MAX) ||
7571 (local_header_uncomp_size == MZ_UINT32_MAX))) {
7572 mz_uint32 extra_size_remaining = local_header_extra_len;
7573 const mz_uint8 *pExtra_data = (
const mz_uint8 *)file_data_array.m_p;
7575 if (pZip->m_pRead(pZip->m_pIO_opaque,
7576 local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE +
7577 local_header_filename_len,
7578 file_data_array.m_p,
7579 local_header_extra_len) != local_header_extra_len) {
7580 mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
7581 goto handle_failure;
7585 mz_uint32 field_id, field_data_size, field_total_size;
7587 if (extra_size_remaining < (
sizeof(mz_uint16) * 2)) {
7588 mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
7589 goto handle_failure;
7592 field_id = MZ_READ_LE16(pExtra_data);
7593 field_data_size = MZ_READ_LE16(pExtra_data +
sizeof(mz_uint16));
7594 field_total_size = field_data_size +
sizeof(mz_uint16) * 2;
7596 if (field_total_size > extra_size_remaining) {
7597 mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
7598 goto handle_failure;
7601 if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) {
7602 const mz_uint8 *pSrc_field_data = pExtra_data +
sizeof(mz_uint32);
7604 if (field_data_size <
sizeof(mz_uint64) * 2) {
7605 mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
7606 goto handle_failure;
7609 local_header_uncomp_size = MZ_READ_LE64(pSrc_field_data);
7610 local_header_comp_size =
7611 MZ_READ_LE64(pSrc_field_data +
sizeof(mz_uint64));
7613 found_zip64_ext_data_in_ldir = MZ_TRUE;
7617 pExtra_data += field_total_size;
7618 extra_size_remaining -= field_total_size;
7619 }
while (extra_size_remaining);
7626 if ((has_data_descriptor) && (!local_header_comp_size) &&
7627 (!local_header_crc32)) {
7628 mz_uint8 descriptor_buf[32];
7630 const mz_uint8 *pSrc;
7631 mz_uint32 file_crc32;
7632 mz_uint64 comp_size = 0, uncomp_size = 0;
7634 mz_uint32 num_descriptor_uint32s =
7635 ((pState->m_zip64) || (found_zip64_ext_data_in_ldir)) ? 6 : 4;
7637 if (pZip->m_pRead(pZip->m_pIO_opaque,
7638 local_header_ofs + MZ_ZIP_LOCAL_DIR_HEADER_SIZE +
7639 local_header_filename_len + local_header_extra_len +
7640 file_stat.m_comp_size,
7642 sizeof(mz_uint32) * num_descriptor_uint32s) !=
7643 (
sizeof(mz_uint32) * num_descriptor_uint32s)) {
7644 mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
7645 goto handle_failure;
7648 has_id = (MZ_READ_LE32(descriptor_buf) == MZ_ZIP_DATA_DESCRIPTOR_ID);
7649 pSrc = has_id ? (descriptor_buf +
sizeof(mz_uint32)) : descriptor_buf;
7651 file_crc32 = MZ_READ_LE32(pSrc);
7653 if ((pState->m_zip64) || (found_zip64_ext_data_in_ldir)) {
7654 comp_size = MZ_READ_LE64(pSrc +
sizeof(mz_uint32));
7655 uncomp_size = MZ_READ_LE64(pSrc +
sizeof(mz_uint32) +
sizeof(mz_uint64));
7657 comp_size = MZ_READ_LE32(pSrc +
sizeof(mz_uint32));
7658 uncomp_size = MZ_READ_LE32(pSrc +
sizeof(mz_uint32) +
sizeof(mz_uint32));
7661 if ((file_crc32 != file_stat.m_crc32) ||
7662 (comp_size != file_stat.m_comp_size) ||
7663 (uncomp_size != file_stat.m_uncomp_size)) {
7664 mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
7665 goto handle_failure;
7668 if ((local_header_crc32 != file_stat.m_crc32) ||
7669 (local_header_comp_size != file_stat.m_comp_size) ||
7670 (local_header_uncomp_size != file_stat.m_uncomp_size)) {
7671 mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
7672 goto handle_failure;
7676 mz_zip_array_clear(pZip, &file_data_array);
7678 if ((flags & MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY) == 0) {
7679 if (!mz_zip_reader_extract_to_callback(
7680 pZip, file_index, mz_zip_compute_crc32_callback, &uncomp_crc32, 0))
7684 if (uncomp_crc32 != file_stat.m_crc32) {
7685 mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
7693 mz_zip_array_clear(pZip, &file_data_array);
7697mz_bool mz_zip_validate_archive(
mz_zip_archive *pZip, mz_uint flags) {
7698 mz_zip_internal_state *pState;
7701 if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) ||
7703 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
7705 pState = pZip->m_pState;
7708 if (!pState->m_zip64) {
7709 if (pZip->m_total_files > MZ_UINT16_MAX)
7710 return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
7712 if (pZip->m_archive_size > MZ_UINT32_MAX)
7713 return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
7715 if (pState->m_central_dir.m_size >= MZ_UINT32_MAX)
7716 return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
7719 for (i = 0; i < pZip->m_total_files; i++) {
7720 if (MZ_ZIP_FLAG_VALIDATE_LOCATE_FILE_FLAG & flags) {
7721 mz_uint32 found_index;
7724 if (!mz_zip_reader_file_stat(pZip, i, &stat))
7727 if (!mz_zip_reader_locate_file_v2(pZip, stat.m_filename, NULL, 0,
7733 if (found_index != i)
7734 return mz_zip_set_error(pZip, MZ_ZIP_VALIDATION_FAILED);
7737 if (!mz_zip_validate_file(pZip, i, flags))
7744mz_bool mz_zip_validate_mem_archive(
const void *pMem,
size_t size,
7745 mz_uint flags, mz_zip_error *pErr) {
7746 mz_bool success = MZ_TRUE;
7748 mz_zip_error actual_err = MZ_ZIP_NO_ERROR;
7750 if ((!pMem) || (!size)) {
7752 *pErr = MZ_ZIP_INVALID_PARAMETER;
7756 mz_zip_zero_struct(&zip);
7758 if (!mz_zip_reader_init_mem(&zip, pMem, size, flags)) {
7760 *pErr = zip.m_last_error;
7764 if (!mz_zip_validate_archive(&zip, flags)) {
7765 actual_err = zip.m_last_error;
7769 if (!mz_zip_reader_end_internal(&zip, success)) {
7771 actual_err = zip.m_last_error;
7781#ifndef MINIZ_NO_STDIO
7782mz_bool mz_zip_validate_file_archive(
const char *pFilename, mz_uint flags,
7783 mz_zip_error *pErr) {
7784 mz_bool success = MZ_TRUE;
7786 mz_zip_error actual_err = MZ_ZIP_NO_ERROR;
7790 *pErr = MZ_ZIP_INVALID_PARAMETER;
7794 mz_zip_zero_struct(&zip);
7796 if (!mz_zip_reader_init_file_v2(&zip, pFilename, flags, 0, 0)) {
7798 *pErr = zip.m_last_error;
7802 if (!mz_zip_validate_archive(&zip, flags)) {
7803 actual_err = zip.m_last_error;
7807 if (!mz_zip_reader_end_internal(&zip, success)) {
7809 actual_err = zip.m_last_error;
7822#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
7824static MZ_FORCEINLINE
void mz_write_le16(mz_uint8 *p, mz_uint16 v) {
7826 p[1] = (mz_uint8)(v >> 8);
7828static MZ_FORCEINLINE
void mz_write_le32(mz_uint8 *p, mz_uint32 v) {
7830 p[1] = (mz_uint8)(v >> 8);
7831 p[2] = (mz_uint8)(v >> 16);
7832 p[3] = (mz_uint8)(v >> 24);
7834static MZ_FORCEINLINE
void mz_write_le64(mz_uint8 *p, mz_uint64 v) {
7835 mz_write_le32(p, (mz_uint32)v);
7836 mz_write_le32(p +
sizeof(mz_uint32), (mz_uint32)(v >> 32));
7839#define MZ_WRITE_LE16(p, v) mz_write_le16((mz_uint8 *)(p), (mz_uint16)(v))
7840#define MZ_WRITE_LE32(p, v) mz_write_le32((mz_uint8 *)(p), (mz_uint32)(v))
7841#define MZ_WRITE_LE64(p, v) mz_write_le64((mz_uint8 *)(p), (mz_uint64)(v))
7843static size_t mz_zip_heap_write_func(
void *pOpaque, mz_uint64 file_ofs,
7844 const void *pBuf,
size_t n) {
7846 mz_zip_internal_state *pState = pZip->m_pState;
7847 mz_uint64 new_size = MZ_MAX(file_ofs + n, pState->m_mem_size);
7854 if ((
sizeof(
size_t) ==
sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF)) {
7855 mz_zip_set_error(pZip, MZ_ZIP_FILE_TOO_LARGE);
7859 if (new_size > pState->m_mem_capacity) {
7861 size_t new_capacity = MZ_MAX(64, pState->m_mem_capacity);
7863 while (new_capacity < new_size)
7866 if (NULL == (pNew_block = pZip->m_pRealloc(
7867 pZip->m_pAlloc_opaque, pState->m_pMem, 1, new_capacity))) {
7868 mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
7872 pState->m_pMem = pNew_block;
7873 pState->m_mem_capacity = new_capacity;
7875 memcpy((mz_uint8 *)pState->m_pMem + file_ofs, pBuf, n);
7876 pState->m_mem_size = (size_t)new_size;
7881 mz_bool set_last_error) {
7882 mz_zip_internal_state *pState;
7883 mz_bool status = MZ_TRUE;
7885 if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) ||
7886 ((pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) &&
7887 (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED))) {
7889 mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
7893 pState = pZip->m_pState;
7894 pZip->m_pState = NULL;
7895 mz_zip_array_clear(pZip, &pState->m_central_dir);
7896 mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
7897 mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets);
7899#ifndef MINIZ_NO_STDIO
7900 if (pState->m_pFile) {
7901 if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE) {
7902 if (MZ_FCLOSE(pState->m_pFile) == EOF) {
7904 mz_zip_set_error(pZip, MZ_ZIP_FILE_CLOSE_FAILED);
7909 pState->m_pFile = NULL;
7913 if ((pZip->m_pWrite == mz_zip_heap_write_func) && (pState->m_pMem)) {
7914 pZip->m_pFree(pZip->m_pAlloc_opaque, pState->m_pMem);
7915 pState->m_pMem = NULL;
7918 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
7919 pZip->m_zip_mode = MZ_ZIP_MODE_INVALID;
7923mz_bool mz_zip_writer_init_v2(
mz_zip_archive *pZip, mz_uint64 existing_size,
7925 mz_bool zip64 = (flags & MZ_ZIP_FLAG_WRITE_ZIP64) != 0;
7927 if ((!pZip) || (pZip->m_pState) || (!pZip->m_pWrite) ||
7928 (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
7929 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
7931 if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING) {
7933 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
7936 if (pZip->m_file_offset_alignment) {
7938 if (pZip->m_file_offset_alignment & (pZip->m_file_offset_alignment - 1))
7939 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
7942 if (!pZip->m_pAlloc)
7943 pZip->m_pAlloc = miniz_def_alloc_func;
7945 pZip->m_pFree = miniz_def_free_func;
7946 if (!pZip->m_pRealloc)
7947 pZip->m_pRealloc = miniz_def_realloc_func;
7949 pZip->m_archive_size = existing_size;
7950 pZip->m_central_directory_file_ofs = 0;
7951 pZip->m_total_files = 0;
7953 if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(
7954 pZip->m_pAlloc_opaque, 1,
sizeof(mz_zip_internal_state))))
7955 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
7957 memset(pZip->m_pState, 0,
sizeof(mz_zip_internal_state));
7959 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir,
7961 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets,
7963 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets,
7966 pZip->m_pState->m_zip64 = zip64;
7967 pZip->m_pState->m_zip64_has_extended_info_fields = zip64;
7969 pZip->m_zip_type = MZ_ZIP_TYPE_USER;
7970 pZip->m_zip_mode = MZ_ZIP_MODE_WRITING;
7975mz_bool mz_zip_writer_init(
mz_zip_archive *pZip, mz_uint64 existing_size) {
7976 return mz_zip_writer_init_v2(pZip, existing_size, 0);
7980 size_t size_to_reserve_at_beginning,
7981 size_t initial_allocation_size,
7983 pZip->m_pWrite = mz_zip_heap_write_func;
7984 pZip->m_pNeeds_keepalive = NULL;
7986 if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING)
7987 pZip->m_pRead = mz_zip_mem_read_func;
7989 pZip->m_pIO_opaque = pZip;
7991 if (!mz_zip_writer_init_v2(pZip, size_to_reserve_at_beginning, flags))
7994 pZip->m_zip_type = MZ_ZIP_TYPE_HEAP;
7996 if (0 != (initial_allocation_size = MZ_MAX(initial_allocation_size,
7997 size_to_reserve_at_beginning))) {
7998 if (NULL == (pZip->m_pState->m_pMem = pZip->m_pAlloc(
7999 pZip->m_pAlloc_opaque, 1, initial_allocation_size))) {
8000 mz_zip_writer_end_internal(pZip, MZ_FALSE);
8001 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
8003 pZip->m_pState->m_mem_capacity = initial_allocation_size;
8010 size_t size_to_reserve_at_beginning,
8011 size_t initial_allocation_size) {
8012 return mz_zip_writer_init_heap_v2(pZip, size_to_reserve_at_beginning,
8013 initial_allocation_size, 0);
8016#ifndef MINIZ_NO_STDIO
8017static size_t mz_zip_file_write_func(
void *pOpaque, mz_uint64 file_ofs,
8018 const void *pBuf,
size_t n) {
8020 mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
8022 file_ofs += pZip->m_pState->m_file_archive_start_ofs;
8024 if (((mz_int64)file_ofs < 0) ||
8025 (((cur_ofs != (mz_int64)file_ofs)) &&
8026 (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET)))) {
8027 mz_zip_set_error(pZip, MZ_ZIP_FILE_SEEK_FAILED);
8031 return MZ_FWRITE(pBuf, 1, n, pZip->m_pState->m_pFile);
8034mz_bool mz_zip_writer_init_file(
mz_zip_archive *pZip,
const char *pFilename,
8035 mz_uint64 size_to_reserve_at_beginning) {
8036 return mz_zip_writer_init_file_v2(pZip, pFilename,
8037 size_to_reserve_at_beginning, 0);
8040mz_bool mz_zip_writer_init_file_v2(
mz_zip_archive *pZip,
const char *pFilename,
8041 mz_uint64 size_to_reserve_at_beginning,
8045 pZip->m_pWrite = mz_zip_file_write_func;
8046 pZip->m_pNeeds_keepalive = NULL;
8048 if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING)
8049 pZip->m_pRead = mz_zip_file_read_func;
8051 pZip->m_pIO_opaque = pZip;
8053 if (!mz_zip_writer_init_v2(pZip, size_to_reserve_at_beginning, flags))
8056 if (NULL == (pFile = MZ_FOPEN(
8058 (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING) ?
"w+b" :
"wb"))) {
8059 mz_zip_writer_end(pZip);
8060 return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);
8063 pZip->m_pState->m_pFile = pFile;
8064 pZip->m_zip_type = MZ_ZIP_TYPE_FILE;
8066 if (size_to_reserve_at_beginning) {
8067 mz_uint64 cur_ofs = 0;
8073 size_t n = (size_t)MZ_MIN(
sizeof(buf), size_to_reserve_at_beginning);
8074 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_ofs, buf, n) != n) {
8075 mz_zip_writer_end(pZip);
8076 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
8079 size_to_reserve_at_beginning -= n;
8080 }
while (size_to_reserve_at_beginning);
8086mz_bool mz_zip_writer_init_cfile(
mz_zip_archive *pZip, MZ_FILE *pFile,
8088 pZip->m_pWrite = mz_zip_file_write_func;
8089 pZip->m_pNeeds_keepalive = NULL;
8091 if (flags & MZ_ZIP_FLAG_WRITE_ALLOW_READING)
8092 pZip->m_pRead = mz_zip_file_read_func;
8094 pZip->m_pIO_opaque = pZip;
8096 if (!mz_zip_writer_init_v2(pZip, 0, flags))
8099 pZip->m_pState->m_pFile = pFile;
8100 pZip->m_pState->m_file_archive_start_ofs =
8101 MZ_FTELL64(pZip->m_pState->m_pFile);
8102 pZip->m_zip_type = MZ_ZIP_TYPE_CFILE;
8109 const char *pFilename,
8111 mz_zip_internal_state *pState;
8113 if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
8114 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
8116 if (flags & MZ_ZIP_FLAG_WRITE_ZIP64) {
8120 if (!pZip->m_pState->m_zip64)
8121 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
8126 if (pZip->m_pState->m_zip64) {
8127 if (pZip->m_total_files == MZ_UINT32_MAX)
8128 return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
8130 if (pZip->m_total_files == MZ_UINT16_MAX)
8131 return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
8133 if ((pZip->m_archive_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE +
8134 MZ_ZIP_LOCAL_DIR_HEADER_SIZE) > MZ_UINT32_MAX)
8135 return mz_zip_set_error(pZip, MZ_ZIP_FILE_TOO_LARGE);
8138 pState = pZip->m_pState;
8140 if (pState->m_pFile) {
8141#ifdef MINIZ_NO_STDIO
8143 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
8145 if (pZip->m_pIO_opaque != pZip)
8146 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
8148 if (pZip->m_zip_type == MZ_ZIP_TYPE_FILE) {
8150 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
8155 (pState->m_pFile = MZ_FREOPEN(pFilename,
"r+b", pState->m_pFile))) {
8158 mz_zip_reader_end_internal(pZip, MZ_FALSE);
8159 return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);
8163 pZip->m_pWrite = mz_zip_file_write_func;
8164 pZip->m_pNeeds_keepalive = NULL;
8166 }
else if (pState->m_pMem) {
8169 if (pZip->m_pIO_opaque != pZip)
8170 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
8172 pState->m_mem_capacity = pState->m_mem_size;
8173 pZip->m_pWrite = mz_zip_heap_write_func;
8174 pZip->m_pNeeds_keepalive = NULL;
8178 else if (!pZip->m_pWrite)
8179 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
8185 pZip->m_archive_size = pZip->m_central_directory_file_ofs;
8186 pZip->m_central_directory_file_ofs = 0;
8193 mz_zip_array_clear(pZip, &pZip->m_pState->m_sorted_central_dir_offsets);
8195 pZip->m_zip_mode = MZ_ZIP_MODE_WRITING;
8201 const char *pFilename) {
8202 return mz_zip_writer_init_from_reader_v2(pZip, pFilename, 0);
8206mz_bool mz_zip_writer_add_mem(
mz_zip_archive *pZip,
const char *pArchive_name,
8207 const void *pBuf,
size_t buf_size,
8208 mz_uint level_and_flags) {
8209 return mz_zip_writer_add_mem_ex(pZip, pArchive_name, pBuf, buf_size, NULL, 0,
8210 level_and_flags, 0, 0);
8215 mz_uint64 m_cur_archive_file_ofs;
8216 mz_uint64 m_comp_size;
8219static mz_bool mz_zip_writer_add_put_buf_callback(
const void *pBuf,
int len,
8222 if ((
int)pState->m_pZip->m_pWrite(pState->m_pZip->m_pIO_opaque,
8223 pState->m_cur_archive_file_ofs, pBuf,
8227 pState->m_cur_archive_file_ofs += len;
8228 pState->m_comp_size += len;
8232#define MZ_ZIP64_MAX_LOCAL_EXTRA_FIELD_SIZE \
8233 (sizeof(mz_uint16) * 2 + sizeof(mz_uint64) * 2)
8234#define MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE \
8235 (sizeof(mz_uint16) * 2 + sizeof(mz_uint64) * 3)
8237mz_zip_writer_create_zip64_extra_data(mz_uint8 *pBuf, mz_uint64 *pUncomp_size,
8238 mz_uint64 *pComp_size,
8239 mz_uint64 *pLocal_header_ofs) {
8240 mz_uint8 *pDst = pBuf;
8241 mz_uint32 field_size = 0;
8243 MZ_WRITE_LE16(pDst + 0, MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID);
8244 MZ_WRITE_LE16(pDst + 2, 0);
8245 pDst +=
sizeof(mz_uint16) * 2;
8248 MZ_WRITE_LE64(pDst, *pUncomp_size);
8249 pDst +=
sizeof(mz_uint64);
8250 field_size +=
sizeof(mz_uint64);
8254 MZ_WRITE_LE64(pDst, *pComp_size);
8255 pDst +=
sizeof(mz_uint64);
8256 field_size +=
sizeof(mz_uint64);
8259 if (pLocal_header_ofs) {
8260 MZ_WRITE_LE64(pDst, *pLocal_header_ofs);
8261 pDst +=
sizeof(mz_uint64);
8262 field_size +=
sizeof(mz_uint64);
8265 MZ_WRITE_LE16(pBuf + 2, field_size);
8267 return (mz_uint32)(pDst - pBuf);
8270static mz_bool mz_zip_writer_create_local_dir_header(
8272 mz_uint16 extra_size, mz_uint64 uncomp_size, mz_uint64 comp_size,
8273 mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags,
8274 mz_uint16 dos_time, mz_uint16 dos_date) {
8276 memset(pDst, 0, MZ_ZIP_LOCAL_DIR_HEADER_SIZE);
8277 MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_SIG_OFS, MZ_ZIP_LOCAL_DIR_HEADER_SIG);
8278 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_VERSION_NEEDED_OFS, method ? 20 : 0);
8279 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_BIT_FLAG_OFS, bit_flags);
8280 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_METHOD_OFS, method);
8281 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_TIME_OFS, dos_time);
8282 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_DATE_OFS, dos_date);
8283 MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_CRC32_OFS, uncomp_crc32);
8284 MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS,
8285 MZ_MIN(comp_size, MZ_UINT32_MAX));
8286 MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS,
8287 MZ_MIN(uncomp_size, MZ_UINT32_MAX));
8288 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILENAME_LEN_OFS, filename_size);
8289 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_EXTRA_LEN_OFS, extra_size);
8293static mz_bool mz_zip_writer_create_central_dir_header(
8295 mz_uint16 extra_size, mz_uint16 comment_size, mz_uint64 uncomp_size,
8296 mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method,
8297 mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date,
8298 mz_uint64 local_header_ofs, mz_uint32 ext_attributes) {
8300 memset(pDst, 0, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE);
8301 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_SIG_OFS, MZ_ZIP_CENTRAL_DIR_HEADER_SIG);
8302 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_VERSION_MADE_BY_OFS, 0x031E);
8303 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_VERSION_NEEDED_OFS, method ? 20 : 0);
8304 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_BIT_FLAG_OFS, bit_flags);
8305 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_METHOD_OFS, method);
8306 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_TIME_OFS, dos_time);
8307 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_DATE_OFS, dos_date);
8308 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_CRC32_OFS, uncomp_crc32);
8309 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS,
8310 MZ_MIN(comp_size, MZ_UINT32_MAX));
8311 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS,
8312 MZ_MIN(uncomp_size, MZ_UINT32_MAX));
8313 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILENAME_LEN_OFS, filename_size);
8314 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_EXTRA_LEN_OFS, extra_size);
8315 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_COMMENT_LEN_OFS, comment_size);
8316 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS, ext_attributes);
8317 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_LOCAL_HEADER_OFS,
8318 MZ_MIN(local_header_ofs, MZ_UINT32_MAX));
8322static mz_bool mz_zip_writer_add_to_central_dir(
8323 mz_zip_archive *pZip,
const char *pFilename, mz_uint16 filename_size,
8324 const void *pExtra, mz_uint16 extra_size,
const void *pComment,
8325 mz_uint16 comment_size, mz_uint64 uncomp_size, mz_uint64 comp_size,
8326 mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags,
8327 mz_uint16 dos_time, mz_uint16 dos_date, mz_uint64 local_header_ofs,
8328 mz_uint32 ext_attributes,
const char *user_extra_data,
8329 mz_uint user_extra_data_len) {
8330 mz_zip_internal_state *pState = pZip->m_pState;
8331 mz_uint32 central_dir_ofs = (mz_uint32)pState->m_central_dir.m_size;
8332 size_t orig_central_dir_size = pState->m_central_dir.m_size;
8333 mz_uint8 central_dir_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE];
8335 if (!pZip->m_pState->m_zip64) {
8336 if (local_header_ofs > 0xFFFFFFFF)
8337 return mz_zip_set_error(pZip, MZ_ZIP_FILE_TOO_LARGE);
8341 if (((mz_uint64)pState->m_central_dir.m_size +
8342 MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + extra_size +
8343 user_extra_data_len + comment_size) >= MZ_UINT32_MAX)
8344 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);
8346 if (!mz_zip_writer_create_central_dir_header(
8347 pZip, central_dir_header, filename_size,
8348 (mz_uint16)(extra_size + user_extra_data_len), comment_size,
8349 uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time,
8350 dos_date, local_header_ofs, ext_attributes))
8351 return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
8353 if ((!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_dir_header,
8354 MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) ||
8355 (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pFilename,
8357 (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pExtra,
8359 (!mz_zip_array_push_back(pZip, &pState->m_central_dir, user_extra_data,
8360 user_extra_data_len)) ||
8361 (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pComment,
8363 (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets,
8364 ¢ral_dir_ofs, 1))) {
8367 mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size,
8369 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
8375static mz_bool mz_zip_writer_validate_archive_name(
const char *pArchive_name) {
8379 if (*pArchive_name ==
'/')
8389mz_zip_writer_compute_padding_needed_for_file_alignment(
mz_zip_archive *pZip) {
8391 if (!pZip->m_file_offset_alignment)
8393 n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1));
8394 return (mz_uint)((pZip->m_file_offset_alignment - n) &
8395 (pZip->m_file_offset_alignment - 1));
8399 mz_uint64 cur_file_ofs, mz_uint32 n) {
8401 memset(buf, 0, MZ_MIN(
sizeof(buf), n));
8403 mz_uint32 s = MZ_MIN(
sizeof(buf), n);
8404 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_file_ofs, buf, s) != s)
8405 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
8414 const char *pArchive_name,
const void *pBuf,
8415 size_t buf_size,
const void *pComment,
8416 mz_uint16 comment_size,
8417 mz_uint level_and_flags, mz_uint64 uncomp_size,
8418 mz_uint32 uncomp_crc32) {
8419 return mz_zip_writer_add_mem_ex_v2(
8420 pZip, pArchive_name, pBuf, buf_size, pComment, comment_size,
8421 level_and_flags, uncomp_size, uncomp_crc32, NULL, NULL, 0, NULL, 0);
8424mz_bool mz_zip_writer_add_mem_ex_v2(
8425 mz_zip_archive *pZip,
const char *pArchive_name,
const void *pBuf,
8426 size_t buf_size,
const void *pComment, mz_uint16 comment_size,
8427 mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32,
8428 MZ_TIME_T *last_modified,
const char *user_extra_data,
8429 mz_uint user_extra_data_len,
const char *user_extra_data_central,
8430 mz_uint user_extra_data_central_len) {
8431 mz_uint16 method = 0, dos_time = 0, dos_date = 0;
8432 mz_uint level, ext_attributes = 0, num_alignment_padding_bytes;
8433 mz_uint64 local_dir_header_ofs = pZip->m_archive_size,
8434 cur_archive_file_ofs = pZip->m_archive_size, comp_size = 0;
8435 size_t archive_name_size;
8436 mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
8438 mz_bool store_data_uncompressed;
8439 mz_zip_internal_state *pState;
8440 mz_uint8 *pExtra_data = NULL;
8441 mz_uint32 extra_size = 0;
8442 mz_uint8 extra_data[MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE];
8443 mz_uint16 bit_flags = 0;
8445 if ((
int)level_and_flags < 0)
8446 level_and_flags = MZ_DEFAULT_LEVEL;
8449 (buf_size && !(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)))
8450 bit_flags |= MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR;
8452 if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME))
8453 bit_flags |= MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8;
8455 level = level_and_flags & 0xF;
8456 store_data_uncompressed =
8457 ((!level) || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA));
8459 if ((!pZip) || (!pZip->m_pState) ||
8460 (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || ((buf_size) && (!pBuf)) ||
8461 (!pArchive_name) || ((comment_size) && (!pComment)) ||
8462 (level > MZ_UBER_COMPRESSION))
8463 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
8465 pState = pZip->m_pState;
8467 if (pState->m_zip64) {
8468 if (pZip->m_total_files == MZ_UINT32_MAX)
8469 return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
8471 if (pZip->m_total_files == MZ_UINT16_MAX) {
8472 pState->m_zip64 = MZ_TRUE;
8475 if (((mz_uint64)buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF)) {
8476 pState->m_zip64 = MZ_TRUE;
8481 if ((!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (uncomp_size))
8482 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
8484 if (!mz_zip_writer_validate_archive_name(pArchive_name))
8485 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME);
8487#ifndef MINIZ_NO_TIME
8488 if (last_modified != NULL) {
8489 mz_zip_time_t_to_dos_time(*last_modified, &dos_time, &dos_date);
8493 mz_zip_time_t_to_dos_time(cur_time, &dos_time, &dos_date);
8496 (void)last_modified;
8499 if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) {
8501 (mz_uint32)mz_crc32(MZ_CRC32_INIT, (
const mz_uint8 *)pBuf, buf_size);
8502 uncomp_size = buf_size;
8503 if (uncomp_size <= 3) {
8505 store_data_uncompressed = MZ_TRUE;
8509 archive_name_size = strlen(pArchive_name);
8510 if (archive_name_size > MZ_UINT16_MAX)
8511 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME);
8513 num_alignment_padding_bytes =
8514 mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
8517 if (((mz_uint64)pState->m_central_dir.m_size +
8518 MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size +
8519 MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE + comment_size) >= MZ_UINT32_MAX)
8520 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);
8522 if (!pState->m_zip64) {
8524 if ((pZip->m_archive_size + num_alignment_padding_bytes +
8525 MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size +
8526 MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size +
8527 user_extra_data_len + pState->m_central_dir.m_size +
8528 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + user_extra_data_central_len +
8529 MZ_ZIP_DATA_DESCRIPTER_SIZE32) > 0xFFFFFFFF) {
8530 pState->m_zip64 = MZ_TRUE;
8535 if ((archive_name_size) && (pArchive_name[archive_name_size - 1] ==
'/')) {
8537 ext_attributes |= MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG;
8540 if ((buf_size) || (uncomp_size))
8541 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
8547 if ((!mz_zip_array_ensure_room(
8548 pZip, &pState->m_central_dir,
8549 MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size +
8550 (pState->m_zip64 ? MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE : 0))) ||
8551 (!mz_zip_array_ensure_room(pZip, &pState->m_central_dir_offsets, 1)))
8552 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
8554 if ((!store_data_uncompressed) && (buf_size)) {
8557 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
8560 if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs,
8561 num_alignment_padding_bytes)) {
8562 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
8566 local_dir_header_ofs += num_alignment_padding_bytes;
8567 if (pZip->m_file_offset_alignment) {
8568 MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) ==
8571 cur_archive_file_ofs += num_alignment_padding_bytes;
8573 MZ_CLEAR_ARR(local_dir_header);
8575 if (!store_data_uncompressed ||
8576 (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) {
8577 method = MZ_DEFLATED;
8580 if (pState->m_zip64) {
8581 if (uncomp_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX) {
8582 pExtra_data = extra_data;
8583 extra_size = mz_zip_writer_create_zip64_extra_data(
8584 extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
8585 (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL,
8586 (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs
8590 if (!mz_zip_writer_create_local_dir_header(
8591 pZip, local_dir_header, (mz_uint16)archive_name_size,
8592 (mz_uint16)(extra_size + user_extra_data_len), 0, 0, 0, method,
8593 bit_flags, dos_time, dos_date))
8594 return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
8596 if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs,
8598 sizeof(local_dir_header)) !=
sizeof(local_dir_header))
8599 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
8601 cur_archive_file_ofs +=
sizeof(local_dir_header);
8603 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name,
8604 archive_name_size) != archive_name_size) {
8605 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
8606 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
8608 cur_archive_file_ofs += archive_name_size;
8610 if (pExtra_data != NULL) {
8611 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, extra_data,
8612 extra_size) != extra_size)
8613 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
8615 cur_archive_file_ofs += extra_size;
8618 if ((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX))
8619 return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
8620 if (!mz_zip_writer_create_local_dir_header(
8621 pZip, local_dir_header, (mz_uint16)archive_name_size,
8622 (mz_uint16)user_extra_data_len, 0, 0, 0, method, bit_flags,
8623 dos_time, dos_date))
8624 return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
8626 if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs,
8628 sizeof(local_dir_header)) !=
sizeof(local_dir_header))
8629 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
8631 cur_archive_file_ofs +=
sizeof(local_dir_header);
8633 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name,
8634 archive_name_size) != archive_name_size) {
8635 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
8636 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
8638 cur_archive_file_ofs += archive_name_size;
8641 if (user_extra_data_len > 0) {
8642 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs,
8644 user_extra_data_len) != user_extra_data_len)
8645 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
8647 cur_archive_file_ofs += user_extra_data_len;
8650 if (store_data_uncompressed) {
8651 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pBuf,
8652 buf_size) != buf_size) {
8653 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
8654 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
8657 cur_archive_file_ofs += buf_size;
8658 comp_size = buf_size;
8659 }
else if (buf_size) {
8662 state.m_pZip = pZip;
8663 state.m_cur_archive_file_ofs = cur_archive_file_ofs;
8664 state.m_comp_size = 0;
8666 if ((tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state,
8667 tdefl_create_comp_flags_from_zip_params(
8668 level, -15, MZ_DEFAULT_STRATEGY)) !=
8669 TDEFL_STATUS_OKAY) ||
8670 (tdefl_compress_buffer(pComp, pBuf, buf_size, TDEFL_FINISH) !=
8671 TDEFL_STATUS_DONE)) {
8672 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
8673 return mz_zip_set_error(pZip, MZ_ZIP_COMPRESSION_FAILED);
8676 comp_size = state.m_comp_size;
8677 cur_archive_file_ofs = state.m_cur_archive_file_ofs;
8680 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
8684 mz_uint8 local_dir_footer[MZ_ZIP_DATA_DESCRIPTER_SIZE64];
8685 mz_uint32 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE32;
8687 MZ_ASSERT(bit_flags & MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR);
8689 MZ_WRITE_LE32(local_dir_footer + 0, MZ_ZIP_DATA_DESCRIPTOR_ID);
8690 MZ_WRITE_LE32(local_dir_footer + 4, uncomp_crc32);
8691 if (pExtra_data == NULL) {
8692 if (comp_size > MZ_UINT32_MAX)
8693 return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
8695 MZ_WRITE_LE32(local_dir_footer + 8, comp_size);
8696 MZ_WRITE_LE32(local_dir_footer + 12, uncomp_size);
8698 MZ_WRITE_LE64(local_dir_footer + 8, comp_size);
8699 MZ_WRITE_LE64(local_dir_footer + 16, uncomp_size);
8700 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE64;
8703 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs,
8705 local_dir_footer_size) != local_dir_footer_size)
8708 cur_archive_file_ofs += local_dir_footer_size;
8711 if (pExtra_data != NULL) {
8712 extra_size = mz_zip_writer_create_zip64_extra_data(
8713 extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
8714 (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL,
8715 (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
8718 if (!mz_zip_writer_add_to_central_dir(
8719 pZip, pArchive_name, (mz_uint16)archive_name_size, pExtra_data,
8720 (mz_uint16)extra_size, pComment, comment_size, uncomp_size, comp_size,
8721 uncomp_crc32, method, bit_flags, dos_time, dos_date,
8722 local_dir_header_ofs, ext_attributes, user_extra_data_central,
8723 user_extra_data_central_len))
8726 pZip->m_total_files++;
8727 pZip->m_archive_size = cur_archive_file_ofs;
8732mz_bool mz_zip_writer_add_read_buf_callback(
8734 mz_file_read_func read_callback,
void *callback_opaque, mz_uint64 max_size,
8735 const MZ_TIME_T *pFile_time,
const void *pComment, mz_uint16 comment_size,
8736 mz_uint level_and_flags, mz_uint32 ext_attributes,
8737 const char *user_extra_data, mz_uint user_extra_data_len,
8738 const char *user_extra_data_central, mz_uint user_extra_data_central_len) {
8739 mz_uint16 gen_flags;
8740 mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes;
8741 mz_uint16 method = 0, dos_time = 0, dos_date = 0;
8742 mz_uint64 local_dir_header_ofs, cur_archive_file_ofs = pZip->m_archive_size,
8743 uncomp_size = 0, comp_size = 0;
8744 size_t archive_name_size;
8745 mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
8746 mz_uint8 *pExtra_data = NULL;
8747 mz_uint32 extra_size = 0;
8748 mz_uint8 extra_data[MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE];
8749 mz_zip_internal_state *pState;
8750 mz_uint64 file_ofs = 0, cur_archive_header_file_ofs;
8752 if ((
int)level_and_flags < 0)
8753 level_and_flags = MZ_DEFAULT_LEVEL;
8754 level = level_and_flags & 0xF;
8756 gen_flags = (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE)
8758 : MZ_ZIP_LDH_BIT_FLAG_HAS_LOCATOR;
8760 if (!(level_and_flags & MZ_ZIP_FLAG_ASCII_FILENAME))
8761 gen_flags |= MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8;
8764 if ((!pZip) || (!pZip->m_pState) ||
8765 (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) ||
8766 ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION))
8767 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
8769 pState = pZip->m_pState;
8771 if ((!pState->m_zip64) && (max_size > MZ_UINT32_MAX)) {
8774 pState->m_zip64 = MZ_TRUE;
8778 if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)
8779 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
8781 if (!mz_zip_writer_validate_archive_name(pArchive_name))
8782 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME);
8784 if (pState->m_zip64) {
8785 if (pZip->m_total_files == MZ_UINT32_MAX)
8786 return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
8788 if (pZip->m_total_files == MZ_UINT16_MAX) {
8789 pState->m_zip64 = MZ_TRUE;
8794 archive_name_size = strlen(pArchive_name);
8795 if (archive_name_size > MZ_UINT16_MAX)
8796 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_FILENAME);
8798 num_alignment_padding_bytes =
8799 mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
8802 if (((mz_uint64)pState->m_central_dir.m_size +
8803 MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size +
8804 MZ_ZIP64_MAX_CENTRAL_EXTRA_FIELD_SIZE + comment_size) >= MZ_UINT32_MAX)
8805 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);
8807 if (!pState->m_zip64) {
8809 if ((pZip->m_archive_size + num_alignment_padding_bytes +
8810 MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size +
8811 MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size +
8812 user_extra_data_len + pState->m_central_dir.m_size +
8813 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 1024 +
8814 MZ_ZIP_DATA_DESCRIPTER_SIZE32 + user_extra_data_central_len) >
8816 pState->m_zip64 = MZ_TRUE;
8821#ifndef MINIZ_NO_TIME
8823 mz_zip_time_t_to_dos_time(*pFile_time, &dos_time, &dos_date);
8832 if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs,
8833 num_alignment_padding_bytes)) {
8834 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
8837 cur_archive_file_ofs += num_alignment_padding_bytes;
8838 local_dir_header_ofs = cur_archive_file_ofs;
8840 if (pZip->m_file_offset_alignment) {
8841 MZ_ASSERT((cur_archive_file_ofs & (pZip->m_file_offset_alignment - 1)) ==
8845 if (max_size && level) {
8846 method = MZ_DEFLATED;
8849 MZ_CLEAR_ARR(local_dir_header);
8850 if (pState->m_zip64) {
8851 if (max_size >= MZ_UINT32_MAX || local_dir_header_ofs >= MZ_UINT32_MAX) {
8852 pExtra_data = extra_data;
8853 if (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE)
8854 extra_size = mz_zip_writer_create_zip64_extra_data(
8855 extra_data, (max_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
8856 (max_size >= MZ_UINT32_MAX) ? &comp_size : NULL,
8857 (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs
8860 extra_size = mz_zip_writer_create_zip64_extra_data(
8861 extra_data, NULL, NULL,
8862 (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs
8866 if (!mz_zip_writer_create_local_dir_header(
8867 pZip, local_dir_header, (mz_uint16)archive_name_size,
8868 (mz_uint16)(extra_size + user_extra_data_len), 0, 0, 0, method,
8869 gen_flags, dos_time, dos_date))
8870 return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
8872 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs,
8874 sizeof(local_dir_header)) !=
sizeof(local_dir_header))
8875 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
8877 cur_archive_file_ofs +=
sizeof(local_dir_header);
8879 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name,
8880 archive_name_size) != archive_name_size) {
8881 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
8884 cur_archive_file_ofs += archive_name_size;
8886 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, extra_data,
8887 extra_size) != extra_size)
8888 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
8890 cur_archive_file_ofs += extra_size;
8892 if ((comp_size > MZ_UINT32_MAX) || (cur_archive_file_ofs > MZ_UINT32_MAX))
8893 return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
8894 if (!mz_zip_writer_create_local_dir_header(
8895 pZip, local_dir_header, (mz_uint16)archive_name_size,
8896 (mz_uint16)user_extra_data_len, 0, 0, 0, method, gen_flags,
8897 dos_time, dos_date))
8898 return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
8900 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs,
8902 sizeof(local_dir_header)) !=
sizeof(local_dir_header))
8903 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
8905 cur_archive_file_ofs +=
sizeof(local_dir_header);
8907 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name,
8908 archive_name_size) != archive_name_size) {
8909 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
8912 cur_archive_file_ofs += archive_name_size;
8915 if (user_extra_data_len > 0) {
8916 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs,
8918 user_extra_data_len) != user_extra_data_len)
8919 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
8921 cur_archive_file_ofs += user_extra_data_len;
8926 pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, MZ_ZIP_MAX_IO_BUF_SIZE);
8928 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
8933 size_t n = read_callback(callback_opaque, file_ofs, pRead_buf,
8934 MZ_ZIP_MAX_IO_BUF_SIZE);
8938 if ((n > MZ_ZIP_MAX_IO_BUF_SIZE) || (file_ofs + n > max_size)) {
8939 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
8940 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
8942 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf,
8944 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
8945 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
8949 (mz_uint32)mz_crc32(uncomp_crc32, (
const mz_uint8 *)pRead_buf, n);
8950 cur_archive_file_ofs += n;
8952 uncomp_size = file_ofs;
8953 comp_size = uncomp_size;
8955 mz_bool result = MZ_FALSE;
8960 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
8961 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
8964 state.m_pZip = pZip;
8965 state.m_cur_archive_file_ofs = cur_archive_file_ofs;
8966 state.m_comp_size = 0;
8968 if (tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state,
8969 tdefl_create_comp_flags_from_zip_params(
8970 level, -15, MZ_DEFAULT_STRATEGY)) !=
8971 TDEFL_STATUS_OKAY) {
8972 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
8973 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
8974 return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
8978 tdefl_status status;
8979 tdefl_flush flush = TDEFL_NO_FLUSH;
8981 size_t n = read_callback(callback_opaque, file_ofs, pRead_buf,
8982 MZ_ZIP_MAX_IO_BUF_SIZE);
8983 if ((n > MZ_ZIP_MAX_IO_BUF_SIZE) || (file_ofs + n > max_size)) {
8984 mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
8990 (mz_uint32)mz_crc32(uncomp_crc32, (
const mz_uint8 *)pRead_buf, n);
8992 if (pZip->m_pNeeds_keepalive != NULL &&
8993 pZip->m_pNeeds_keepalive(pZip->m_pIO_opaque))
8994 flush = TDEFL_FULL_FLUSH;
8997 flush = TDEFL_FINISH;
8999 status = tdefl_compress_buffer(pComp, pRead_buf, n, flush);
9000 if (status == TDEFL_STATUS_DONE) {
9003 }
else if (status != TDEFL_STATUS_OKAY) {
9004 mz_zip_set_error(pZip, MZ_ZIP_COMPRESSION_FAILED);
9009 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
9012 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
9016 uncomp_size = file_ofs;
9017 comp_size = state.m_comp_size;
9018 cur_archive_file_ofs = state.m_cur_archive_file_ofs;
9021 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
9024 if (!(level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE)) {
9025 mz_uint8 local_dir_footer[MZ_ZIP_DATA_DESCRIPTER_SIZE64];
9026 mz_uint32 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE32;
9028 MZ_WRITE_LE32(local_dir_footer + 0, MZ_ZIP_DATA_DESCRIPTOR_ID);
9029 MZ_WRITE_LE32(local_dir_footer + 4, uncomp_crc32);
9030 if (pExtra_data == NULL) {
9031 if (comp_size > MZ_UINT32_MAX)
9032 return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
9034 MZ_WRITE_LE32(local_dir_footer + 8, comp_size);
9035 MZ_WRITE_LE32(local_dir_footer + 12, uncomp_size);
9037 MZ_WRITE_LE64(local_dir_footer + 8, comp_size);
9038 MZ_WRITE_LE64(local_dir_footer + 16, uncomp_size);
9039 local_dir_footer_size = MZ_ZIP_DATA_DESCRIPTER_SIZE64;
9042 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs,
9044 local_dir_footer_size) != local_dir_footer_size)
9047 cur_archive_file_ofs += local_dir_footer_size;
9050 if (level_and_flags & MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE) {
9051 if (pExtra_data != NULL) {
9052 extra_size = mz_zip_writer_create_zip64_extra_data(
9053 extra_data, (max_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
9054 (max_size >= MZ_UINT32_MAX) ? &comp_size : NULL,
9055 (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs
9059 if (!mz_zip_writer_create_local_dir_header(
9060 pZip, local_dir_header, (mz_uint16)archive_name_size,
9061 (mz_uint16)(extra_size + user_extra_data_len),
9062 (max_size >= MZ_UINT32_MAX) ? MZ_UINT32_MAX : uncomp_size,
9063 (max_size >= MZ_UINT32_MAX) ? MZ_UINT32_MAX : comp_size,
9064 uncomp_crc32, method, gen_flags, dos_time, dos_date))
9065 return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR);
9067 cur_archive_header_file_ofs = local_dir_header_ofs;
9069 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs,
9071 sizeof(local_dir_header)) !=
sizeof(local_dir_header))
9072 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
9074 if (pExtra_data != NULL) {
9075 cur_archive_header_file_ofs +=
sizeof(local_dir_header);
9077 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs,
9079 archive_name_size) != archive_name_size) {
9080 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
9083 cur_archive_header_file_ofs += archive_name_size;
9085 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_header_file_ofs,
9086 extra_data, extra_size) != extra_size)
9087 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
9089 cur_archive_header_file_ofs += extra_size;
9093 if (pExtra_data != NULL) {
9094 extra_size = mz_zip_writer_create_zip64_extra_data(
9095 extra_data, (uncomp_size >= MZ_UINT32_MAX) ? &uncomp_size : NULL,
9096 (uncomp_size >= MZ_UINT32_MAX) ? &comp_size : NULL,
9097 (local_dir_header_ofs >= MZ_UINT32_MAX) ? &local_dir_header_ofs : NULL);
9100 if (!mz_zip_writer_add_to_central_dir(
9101 pZip, pArchive_name, (mz_uint16)archive_name_size, pExtra_data,
9102 (mz_uint16)extra_size, pComment, comment_size, uncomp_size, comp_size,
9103 uncomp_crc32, method, gen_flags, dos_time, dos_date,
9104 local_dir_header_ofs, ext_attributes, user_extra_data_central,
9105 user_extra_data_central_len))
9108 pZip->m_total_files++;
9109 pZip->m_archive_size = cur_archive_file_ofs;
9114#ifndef MINIZ_NO_STDIO
9116static size_t mz_file_read_func_stdio(
void *pOpaque, mz_uint64 file_ofs,
9117 void *pBuf,
size_t n) {
9118 MZ_FILE *pSrc_file = (MZ_FILE *)pOpaque;
9119 mz_int64 cur_ofs = MZ_FTELL64(pSrc_file);
9121 if (((mz_int64)file_ofs < 0) ||
9122 (((cur_ofs != (mz_int64)file_ofs)) &&
9123 (MZ_FSEEK64(pSrc_file, (mz_int64)file_ofs, SEEK_SET))))
9126 return MZ_FREAD(pBuf, 1, n, pSrc_file);
9129mz_bool mz_zip_writer_add_cfile(
9130 mz_zip_archive *pZip,
const char *pArchive_name, MZ_FILE *pSrc_file,
9131 mz_uint64 max_size,
const MZ_TIME_T *pFile_time,
const void *pComment,
9132 mz_uint16 comment_size, mz_uint level_and_flags, mz_uint32 ext_attributes,
9133 const char *user_extra_data, mz_uint user_extra_data_len,
9134 const char *user_extra_data_central, mz_uint user_extra_data_central_len) {
9135 return mz_zip_writer_add_read_buf_callback(
9136 pZip, pArchive_name, mz_file_read_func_stdio, pSrc_file, max_size,
9137 pFile_time, pComment, comment_size, level_and_flags, ext_attributes,
9138 user_extra_data, user_extra_data_len, user_extra_data_central,
9139 user_extra_data_central_len);
9142mz_bool mz_zip_writer_add_file(
mz_zip_archive *pZip,
const char *pArchive_name,
9143 const char *pSrc_filename,
const void *pComment,
9144 mz_uint16 comment_size, mz_uint level_and_flags,
9145 mz_uint32 ext_attributes) {
9146 MZ_FILE *pSrc_file = NULL;
9147 mz_uint64 uncomp_size = 0;
9148 MZ_TIME_T file_modified_time;
9149 MZ_TIME_T *pFile_time = NULL;
9152 memset(&file_modified_time, 0,
sizeof(file_modified_time));
9154#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_STDIO)
9155 pFile_time = &file_modified_time;
9156 if (!mz_zip_get_file_modified_time(pSrc_filename, &file_modified_time))
9157 return mz_zip_set_error(pZip, MZ_ZIP_FILE_STAT_FAILED);
9160 pSrc_file = MZ_FOPEN(pSrc_filename,
"rb");
9162 return mz_zip_set_error(pZip, MZ_ZIP_FILE_OPEN_FAILED);
9164 MZ_FSEEK64(pSrc_file, 0, SEEK_END);
9165 uncomp_size = MZ_FTELL64(pSrc_file);
9166 MZ_FSEEK64(pSrc_file, 0, SEEK_SET);
9168 status = mz_zip_writer_add_cfile(
9169 pZip, pArchive_name, pSrc_file, uncomp_size, pFile_time, pComment,
9170 comment_size, level_and_flags, ext_attributes, NULL, 0, NULL, 0);
9172 MZ_FCLOSE(pSrc_file);
9178static mz_bool mz_zip_writer_update_zip64_extension_block(
9180 mz_uint32 ext_len, mz_uint64 *pComp_size, mz_uint64 *pUncomp_size,
9181 mz_uint64 *pLocal_header_ofs, mz_uint32 *pDisk_start) {
9183 if (!mz_zip_array_reserve(pZip, pNew_ext, ext_len + 64, MZ_FALSE))
9184 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
9186 mz_zip_array_resize(pZip, pNew_ext, 0, MZ_FALSE);
9188 if ((pUncomp_size) || (pComp_size) || (pLocal_header_ofs) || (pDisk_start)) {
9189 mz_uint8 new_ext_block[64];
9190 mz_uint8 *pDst = new_ext_block;
9191 mz_write_le16(pDst, MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID);
9192 mz_write_le16(pDst +
sizeof(mz_uint16), 0);
9193 pDst +=
sizeof(mz_uint16) * 2;
9196 mz_write_le64(pDst, *pUncomp_size);
9197 pDst +=
sizeof(mz_uint64);
9201 mz_write_le64(pDst, *pComp_size);
9202 pDst +=
sizeof(mz_uint64);
9205 if (pLocal_header_ofs) {
9206 mz_write_le64(pDst, *pLocal_header_ofs);
9207 pDst +=
sizeof(mz_uint64);
9211 mz_write_le32(pDst, *pDisk_start);
9212 pDst +=
sizeof(mz_uint32);
9215 mz_write_le16(new_ext_block +
sizeof(mz_uint16),
9216 (mz_uint16)((pDst - new_ext_block) -
sizeof(mz_uint16) * 2));
9218 if (!mz_zip_array_push_back(pZip, pNew_ext, new_ext_block,
9219 pDst - new_ext_block))
9220 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
9223 if ((pExt) && (ext_len)) {
9224 mz_uint32 extra_size_remaining = ext_len;
9225 const mz_uint8 *pExtra_data = pExt;
9228 mz_uint32 field_id, field_data_size, field_total_size;
9230 if (extra_size_remaining < (
sizeof(mz_uint16) * 2))
9231 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
9233 field_id = MZ_READ_LE16(pExtra_data);
9234 field_data_size = MZ_READ_LE16(pExtra_data +
sizeof(mz_uint16));
9235 field_total_size = field_data_size +
sizeof(mz_uint16) * 2;
9237 if (field_total_size > extra_size_remaining)
9238 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
9240 if (field_id != MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) {
9241 if (!mz_zip_array_push_back(pZip, pNew_ext, pExtra_data,
9243 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
9246 pExtra_data += field_total_size;
9247 extra_size_remaining -= field_total_size;
9248 }
while (extra_size_remaining);
9257 mz_uint src_file_index) {
9258 mz_uint n, bit_flags, num_alignment_padding_bytes,
9259 src_central_dir_following_data_size;
9260 mz_uint64 src_archive_bytes_remaining, local_dir_header_ofs;
9261 mz_uint64 cur_src_file_ofs, cur_dst_file_ofs;
9263 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE +
sizeof(mz_uint32) - 1) /
9265 mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
9266 mz_uint8 new_central_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE];
9267 size_t orig_central_dir_size;
9268 mz_zip_internal_state *pState;
9270 const mz_uint8 *pSrc_central_header;
9272 mz_uint32 src_filename_len, src_comment_len, src_ext_len;
9273 mz_uint32 local_header_filename_size, local_header_extra_len;
9274 mz_uint64 local_header_comp_size, local_header_uncomp_size;
9275 mz_bool found_zip64_ext_data_in_ldir = MZ_FALSE;
9278 if ((!pZip) || (!pZip->m_pState) ||
9279 (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pSource_zip->m_pRead))
9280 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
9282 pState = pZip->m_pState;
9286 if ((pSource_zip->m_pState->m_zip64) && (!pZip->m_pState->m_zip64))
9287 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
9291 (pSrc_central_header = mz_zip_get_cdh(pSource_zip, src_file_index)))
9292 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
9294 if (MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_SIG_OFS) !=
9295 MZ_ZIP_CENTRAL_DIR_HEADER_SIG)
9296 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
9299 MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_FILENAME_LEN_OFS);
9301 MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_COMMENT_LEN_OFS);
9302 src_ext_len = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS);
9303 src_central_dir_following_data_size =
9304 src_filename_len + src_ext_len + src_comment_len;
9308 if ((pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE +
9309 src_central_dir_following_data_size + 32) >= MZ_UINT32_MAX)
9310 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);
9312 num_alignment_padding_bytes =
9313 mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
9315 if (!pState->m_zip64) {
9316 if (pZip->m_total_files == MZ_UINT16_MAX)
9317 return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
9321 if (pZip->m_total_files == MZ_UINT32_MAX)
9322 return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
9325 if (!mz_zip_file_stat_internal(pSource_zip, src_file_index,
9326 pSrc_central_header, &src_file_stat, NULL))
9329 cur_src_file_ofs = src_file_stat.m_local_header_ofs;
9330 cur_dst_file_ofs = pZip->m_archive_size;
9333 if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs,
9334 pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) !=
9335 MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
9336 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
9338 if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
9339 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
9341 cur_src_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE;
9345 local_header_filename_size =
9346 MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS);
9347 local_header_extra_len =
9348 MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
9349 local_header_comp_size =
9350 MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS);
9351 local_header_uncomp_size =
9352 MZ_READ_LE32(pLocal_header + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS);
9353 src_archive_bytes_remaining = src_file_stat.m_comp_size +
9354 local_header_filename_size +
9355 local_header_extra_len;
9358 if ((local_header_extra_len) &&
9359 ((local_header_comp_size == MZ_UINT32_MAX) ||
9360 (local_header_uncomp_size == MZ_UINT32_MAX))) {
9362 const mz_uint8 *pExtra_data;
9363 mz_uint32 extra_size_remaining = local_header_extra_len;
9365 mz_zip_array_init(&file_data_array, 1);
9366 if (!mz_zip_array_resize(pZip, &file_data_array, local_header_extra_len,
9368 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
9371 if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque,
9372 src_file_stat.m_local_header_ofs +
9373 MZ_ZIP_LOCAL_DIR_HEADER_SIZE +
9374 local_header_filename_size,
9375 file_data_array.m_p, local_header_extra_len) !=
9376 local_header_extra_len) {
9377 mz_zip_array_clear(pZip, &file_data_array);
9378 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
9381 pExtra_data = (
const mz_uint8 *)file_data_array.m_p;
9384 mz_uint32 field_id, field_data_size, field_total_size;
9386 if (extra_size_remaining < (
sizeof(mz_uint16) * 2)) {
9387 mz_zip_array_clear(pZip, &file_data_array);
9388 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
9391 field_id = MZ_READ_LE16(pExtra_data);
9392 field_data_size = MZ_READ_LE16(pExtra_data +
sizeof(mz_uint16));
9393 field_total_size = field_data_size +
sizeof(mz_uint16) * 2;
9395 if (field_total_size > extra_size_remaining) {
9396 mz_zip_array_clear(pZip, &file_data_array);
9397 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
9400 if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) {
9401 const mz_uint8 *pSrc_field_data = pExtra_data +
sizeof(mz_uint32);
9403 if (field_data_size <
sizeof(mz_uint64) * 2) {
9404 mz_zip_array_clear(pZip, &file_data_array);
9405 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
9408 local_header_uncomp_size = MZ_READ_LE64(pSrc_field_data);
9409 local_header_comp_size = MZ_READ_LE64(
9413 found_zip64_ext_data_in_ldir = MZ_TRUE;
9417 pExtra_data += field_total_size;
9418 extra_size_remaining -= field_total_size;
9419 }
while (extra_size_remaining);
9421 mz_zip_array_clear(pZip, &file_data_array);
9424 if (!pState->m_zip64) {
9430 mz_uint64 approx_new_archive_size =
9431 cur_dst_file_ofs + num_alignment_padding_bytes +
9432 MZ_ZIP_LOCAL_DIR_HEADER_SIZE + src_archive_bytes_remaining +
9433 (
sizeof(mz_uint32) * 4) + pState->m_central_dir.m_size +
9434 MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_central_dir_following_data_size +
9435 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 64;
9437 if (approx_new_archive_size >= MZ_UINT32_MAX)
9438 return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
9442 if (!mz_zip_writer_write_zeros(pZip, cur_dst_file_ofs,
9443 num_alignment_padding_bytes))
9446 cur_dst_file_ofs += num_alignment_padding_bytes;
9448 local_dir_header_ofs = cur_dst_file_ofs;
9449 if (pZip->m_file_offset_alignment) {
9450 MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) ==
9456 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pLocal_header,
9457 MZ_ZIP_LOCAL_DIR_HEADER_SIZE) !=
9458 MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
9459 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
9461 cur_dst_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE;
9465 if (NULL == (pBuf = pZip->m_pAlloc(
9466 pZip->m_pAlloc_opaque, 1,
9467 (
size_t)MZ_MAX(32U, MZ_MIN((mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE,
9468 src_archive_bytes_remaining)))))
9469 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
9471 while (src_archive_bytes_remaining) {
9472 n = (mz_uint)MZ_MIN((mz_uint64)MZ_ZIP_MAX_IO_BUF_SIZE,
9473 src_archive_bytes_remaining);
9474 if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf,
9476 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
9477 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
9479 cur_src_file_ofs += n;
9481 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n) {
9482 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
9483 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
9485 cur_dst_file_ofs += n;
9487 src_archive_bytes_remaining -= n;
9491 bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS);
9492 if (bit_flags & 8) {
9494 if ((pSource_zip->m_pState->m_zip64) || (found_zip64_ext_data_in_ldir)) {
9502 if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs,
9503 pBuf, (
sizeof(mz_uint32) * 6)) !=
9504 (
sizeof(mz_uint32) * 6)) {
9505 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
9506 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
9509 n =
sizeof(mz_uint32) *
9510 ((MZ_READ_LE32(pBuf) == MZ_ZIP_DATA_DESCRIPTOR_ID) ? 6 : 5);
9515 if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs,
9516 pBuf,
sizeof(mz_uint32) * 4) !=
9517 sizeof(mz_uint32) * 4) {
9518 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
9519 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
9522 has_id = (MZ_READ_LE32(pBuf) == MZ_ZIP_DATA_DESCRIPTOR_ID);
9524 if (pZip->m_pState->m_zip64) {
9526 const mz_uint8 *pSrc_descriptor =
9527 (
const mz_uint8 *)pBuf + (has_id ?
sizeof(mz_uint32) : 0);
9528 const mz_uint32 src_crc32 = MZ_READ_LE32(pSrc_descriptor);
9529 const mz_uint64 src_comp_size =
9530 MZ_READ_LE32(pSrc_descriptor +
sizeof(mz_uint32));
9531 const mz_uint64 src_uncomp_size =
9532 MZ_READ_LE32(pSrc_descriptor + 2 *
sizeof(mz_uint32));
9534 mz_write_le32((mz_uint8 *)pBuf, MZ_ZIP_DATA_DESCRIPTOR_ID);
9535 mz_write_le32((mz_uint8 *)pBuf +
sizeof(mz_uint32) * 1, src_crc32);
9536 mz_write_le64((mz_uint8 *)pBuf +
sizeof(mz_uint32) * 2, src_comp_size);
9537 mz_write_le64((mz_uint8 *)pBuf +
sizeof(mz_uint32) * 4,
9540 n =
sizeof(mz_uint32) * 6;
9543 n =
sizeof(mz_uint32) * (has_id ? 4 : 3);
9547 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n) {
9548 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
9549 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
9552 cur_src_file_ofs += n;
9553 cur_dst_file_ofs += n;
9555 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
9558 orig_central_dir_size = pState->m_central_dir.m_size;
9560 memcpy(new_central_header, pSrc_central_header,
9561 MZ_ZIP_CENTRAL_DIR_HEADER_SIZE);
9563 if (pState->m_zip64) {
9567 const mz_uint8 *pSrc_ext =
9568 pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + src_filename_len;
9571 mz_zip_array_init(&new_ext_block,
sizeof(mz_uint8));
9573 MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS,
9575 MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS,
9577 MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS,
9580 if (!mz_zip_writer_update_zip64_extension_block(
9581 &new_ext_block, pZip, pSrc_ext, src_ext_len,
9582 &src_file_stat.m_comp_size, &src_file_stat.m_uncomp_size,
9583 &local_dir_header_ofs, NULL)) {
9584 mz_zip_array_clear(pZip, &new_ext_block);
9588 MZ_WRITE_LE16(new_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS,
9589 new_ext_block.m_size);
9591 if (!mz_zip_array_push_back(pZip, &pState->m_central_dir,
9593 MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) {
9594 mz_zip_array_clear(pZip, &new_ext_block);
9595 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
9598 if (!mz_zip_array_push_back(pZip, &pState->m_central_dir,
9599 pSrc_central_header +
9600 MZ_ZIP_CENTRAL_DIR_HEADER_SIZE,
9601 src_filename_len)) {
9602 mz_zip_array_clear(pZip, &new_ext_block);
9603 mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size,
9605 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
9608 if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, new_ext_block.m_p,
9609 new_ext_block.m_size)) {
9610 mz_zip_array_clear(pZip, &new_ext_block);
9611 mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size,
9613 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
9616 if (!mz_zip_array_push_back(pZip, &pState->m_central_dir,
9617 pSrc_central_header +
9618 MZ_ZIP_CENTRAL_DIR_HEADER_SIZE +
9619 src_filename_len + src_ext_len,
9621 mz_zip_array_clear(pZip, &new_ext_block);
9622 mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size,
9624 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
9627 mz_zip_array_clear(pZip, &new_ext_block);
9630 if (cur_dst_file_ofs > MZ_UINT32_MAX)
9631 return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
9633 if (local_dir_header_ofs >= MZ_UINT32_MAX)
9634 return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE);
9636 MZ_WRITE_LE32(new_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS,
9637 local_dir_header_ofs);
9639 if (!mz_zip_array_push_back(pZip, &pState->m_central_dir,
9641 MZ_ZIP_CENTRAL_DIR_HEADER_SIZE))
9642 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
9644 if (!mz_zip_array_push_back(pZip, &pState->m_central_dir,
9645 pSrc_central_header +
9646 MZ_ZIP_CENTRAL_DIR_HEADER_SIZE,
9647 src_central_dir_following_data_size)) {
9648 mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size,
9650 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
9656 if (pState->m_central_dir.m_size >= MZ_UINT32_MAX) {
9658 mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size,
9660 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);
9663 n = (mz_uint32)orig_central_dir_size;
9664 if (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &n, 1)) {
9665 mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size,
9667 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
9670 pZip->m_total_files++;
9671 pZip->m_archive_size = cur_dst_file_ofs;
9677 mz_zip_internal_state *pState;
9678 mz_uint64 central_dir_ofs, central_dir_size;
9681 if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING))
9682 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
9684 pState = pZip->m_pState;
9686 if (pState->m_zip64) {
9687 if ((mz_uint64)pState->m_central_dir.m_size >= MZ_UINT32_MAX)
9688 return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
9690 if ((pZip->m_total_files > MZ_UINT16_MAX) ||
9691 ((pZip->m_archive_size + pState->m_central_dir.m_size +
9692 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) > MZ_UINT32_MAX))
9693 return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
9696 central_dir_ofs = 0;
9697 central_dir_size = 0;
9698 if (pZip->m_total_files) {
9700 central_dir_ofs = pZip->m_archive_size;
9701 central_dir_size = pState->m_central_dir.m_size;
9702 pZip->m_central_directory_file_ofs = central_dir_ofs;
9703 if (pZip->m_pWrite(pZip->m_pIO_opaque, central_dir_ofs,
9704 pState->m_central_dir.m_p,
9705 (
size_t)central_dir_size) != central_dir_size)
9706 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
9708 pZip->m_archive_size += central_dir_size;
9711 if (pState->m_zip64) {
9713 mz_uint64 rel_ofs_to_zip64_ecdr = pZip->m_archive_size;
9716 MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDH_SIG_OFS,
9717 MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG);
9718 MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS,
9719 MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE -
sizeof(mz_uint32) -
9721 MZ_WRITE_LE16(hdr + MZ_ZIP64_ECDH_VERSION_MADE_BY_OFS,
9723 MZ_WRITE_LE16(hdr + MZ_ZIP64_ECDH_VERSION_NEEDED_OFS, 0x002D);
9724 MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS,
9725 pZip->m_total_files);
9726 MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS,
9727 pZip->m_total_files);
9728 MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_SIZE_OFS, central_dir_size);
9729 MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDH_CDIR_OFS_OFS, central_dir_ofs);
9730 if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr,
9731 MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) !=
9732 MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)
9733 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
9735 pZip->m_archive_size += MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE;
9739 MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDL_SIG_OFS,
9740 MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG);
9741 MZ_WRITE_LE64(hdr + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS,
9742 rel_ofs_to_zip64_ecdr);
9743 MZ_WRITE_LE32(hdr + MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS, 1);
9744 if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr,
9745 MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) !=
9746 MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE)
9747 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
9749 pZip->m_archive_size += MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE;
9754 MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_SIG_OFS,
9755 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG);
9756 MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS,
9757 MZ_MIN(MZ_UINT16_MAX, pZip->m_total_files));
9758 MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS,
9759 MZ_MIN(MZ_UINT16_MAX, pZip->m_total_files));
9760 MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_SIZE_OFS,
9761 MZ_MIN(MZ_UINT32_MAX, central_dir_size));
9762 MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_OFS_OFS,
9763 MZ_MIN(MZ_UINT32_MAX, central_dir_ofs));
9765 if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr,
9766 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) !=
9767 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
9768 return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
9770#ifndef MINIZ_NO_STDIO
9771 if ((pState->m_pFile) && (MZ_FFLUSH(pState->m_pFile) == EOF))
9772 return mz_zip_set_error(pZip, MZ_ZIP_FILE_CLOSE_FAILED);
9775 pZip->m_archive_size += MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE;
9777 pZip->m_zip_mode = MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED;
9781mz_bool mz_zip_writer_finalize_heap_archive(
mz_zip_archive *pZip,
void **ppBuf,
9783 if ((!ppBuf) || (!pSize))
9784 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
9789 if ((!pZip) || (!pZip->m_pState))
9790 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
9792 if (pZip->m_pWrite != mz_zip_heap_write_func)
9793 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
9795 if (!mz_zip_writer_finalize_archive(pZip))
9798 *ppBuf = pZip->m_pState->m_pMem;
9799 *pSize = pZip->m_pState->m_mem_size;
9800 pZip->m_pState->m_pMem = NULL;
9801 pZip->m_pState->m_mem_size = pZip->m_pState->m_mem_capacity = 0;
9807 return mz_zip_writer_end_internal(pZip, MZ_TRUE);
9810#ifndef MINIZ_NO_STDIO
9811mz_bool mz_zip_add_mem_to_archive_file_in_place(
9812 const char *pZip_filename,
const char *pArchive_name,
const void *pBuf,
9813 size_t buf_size,
const void *pComment, mz_uint16 comment_size,
9814 mz_uint level_and_flags) {
9815 return mz_zip_add_mem_to_archive_file_in_place_v2(
9816 pZip_filename, pArchive_name, pBuf, buf_size, pComment, comment_size,
9817 level_and_flags, NULL);
9820mz_bool mz_zip_add_mem_to_archive_file_in_place_v2(
9821 const char *pZip_filename,
const char *pArchive_name,
const void *pBuf,
9822 size_t buf_size,
const void *pComment, mz_uint16 comment_size,
9823 mz_uint level_and_flags, mz_zip_error *pErr) {
9824 mz_bool status, created_new_archive = MZ_FALSE;
9826 struct MZ_FILE_STAT_STRUCT file_stat;
9827 mz_zip_error actual_err = MZ_ZIP_NO_ERROR;
9829 mz_zip_zero_struct(&zip_archive);
9830 if ((
int)level_and_flags < 0)
9831 level_and_flags = MZ_DEFAULT_LEVEL;
9833 if ((!pZip_filename) || (!pArchive_name) || ((buf_size) && (!pBuf)) ||
9834 ((comment_size) && (!pComment)) ||
9835 ((level_and_flags & 0xF) > MZ_UBER_COMPRESSION)) {
9837 *pErr = MZ_ZIP_INVALID_PARAMETER;
9841 if (!mz_zip_writer_validate_archive_name(pArchive_name)) {
9843 *pErr = MZ_ZIP_INVALID_FILENAME;
9850 if (MZ_FILE_STAT(pZip_filename, &file_stat) != 0) {
9852 if (!mz_zip_writer_init_file_v2(&zip_archive, pZip_filename, 0,
9855 *pErr = zip_archive.m_last_error;
9859 created_new_archive = MZ_TRUE;
9862 if (!mz_zip_reader_init_file_v2(
9863 &zip_archive, pZip_filename,
9864 level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY, 0,
9867 *pErr = zip_archive.m_last_error;
9871 if (!mz_zip_writer_init_from_reader_v2(&zip_archive, pZip_filename,
9874 *pErr = zip_archive.m_last_error;
9876 mz_zip_reader_end_internal(&zip_archive, MZ_FALSE);
9883 mz_zip_writer_add_mem_ex(&zip_archive, pArchive_name, pBuf, buf_size,
9884 pComment, comment_size, level_and_flags, 0, 0);
9885 actual_err = zip_archive.m_last_error;
9889 if (!mz_zip_writer_finalize_archive(&zip_archive)) {
9891 actual_err = zip_archive.m_last_error;
9896 if (!mz_zip_writer_end_internal(&zip_archive, status)) {
9898 actual_err = zip_archive.m_last_error;
9903 if ((!status) && (created_new_archive)) {
9905 int ignoredStatus = MZ_DELETE_FILE(pZip_filename);
9906 (void)ignoredStatus;
9915void *mz_zip_extract_archive_file_to_heap_v2(
const char *pZip_filename,
9916 const char *pArchive_name,
9917 const char *pComment,
9918 size_t *pSize, mz_uint flags,
9919 mz_zip_error *pErr) {
9920 mz_uint32 file_index;
9927 if ((!pZip_filename) || (!pArchive_name)) {
9929 *pErr = MZ_ZIP_INVALID_PARAMETER;
9934 mz_zip_zero_struct(&zip_archive);
9935 if (!mz_zip_reader_init_file_v2(
9936 &zip_archive, pZip_filename,
9937 flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY, 0, 0)) {
9939 *pErr = zip_archive.m_last_error;
9944 if (mz_zip_reader_locate_file_v2(&zip_archive, pArchive_name, pComment, flags,
9946 p = mz_zip_reader_extract_to_heap(&zip_archive, file_index, pSize, flags);
9949 mz_zip_reader_end_internal(&zip_archive, p != NULL);
9952 *pErr = zip_archive.m_last_error;
9957void *mz_zip_extract_archive_file_to_heap(
const char *pZip_filename,
9958 const char *pArchive_name,
9959 size_t *pSize, mz_uint flags) {
9960 return mz_zip_extract_archive_file_to_heap_v2(pZip_filename, pArchive_name,
9961 NULL, pSize, flags, NULL);
9971 return pZip ? pZip->m_zip_mode : MZ_ZIP_MODE_INVALID;
9975 return pZip ? pZip->m_zip_type : MZ_ZIP_TYPE_INVALID;
9978mz_zip_error mz_zip_set_last_error(
mz_zip_archive *pZip, mz_zip_error err_num) {
9979 mz_zip_error prev_err;
9982 return MZ_ZIP_INVALID_PARAMETER;
9984 prev_err = pZip->m_last_error;
9986 pZip->m_last_error = err_num;
9992 return MZ_ZIP_INVALID_PARAMETER;
9994 return pZip->m_last_error;
9998 return mz_zip_set_last_error(pZip, MZ_ZIP_NO_ERROR);
10002 mz_zip_error prev_err;
10005 return MZ_ZIP_INVALID_PARAMETER;
10007 prev_err = pZip->m_last_error;
10009 pZip->m_last_error = MZ_ZIP_NO_ERROR;
10013const char *mz_zip_get_error_string(mz_zip_error mz_err) {
10015 case MZ_ZIP_NO_ERROR:
10017 case MZ_ZIP_UNDEFINED_ERROR:
10018 return "undefined error";
10019 case MZ_ZIP_TOO_MANY_FILES:
10020 return "too many files";
10021 case MZ_ZIP_FILE_TOO_LARGE:
10022 return "file too large";
10023 case MZ_ZIP_UNSUPPORTED_METHOD:
10024 return "unsupported method";
10025 case MZ_ZIP_UNSUPPORTED_ENCRYPTION:
10026 return "unsupported encryption";
10027 case MZ_ZIP_UNSUPPORTED_FEATURE:
10028 return "unsupported feature";
10029 case MZ_ZIP_FAILED_FINDING_CENTRAL_DIR:
10030 return "failed finding central directory";
10031 case MZ_ZIP_NOT_AN_ARCHIVE:
10032 return "not a ZIP archive";
10033 case MZ_ZIP_INVALID_HEADER_OR_CORRUPTED:
10034 return "invalid header or archive is corrupted";
10035 case MZ_ZIP_UNSUPPORTED_MULTIDISK:
10036 return "unsupported multidisk archive";
10037 case MZ_ZIP_DECOMPRESSION_FAILED:
10038 return "decompression failed or archive is corrupted";
10039 case MZ_ZIP_COMPRESSION_FAILED:
10040 return "compression failed";
10041 case MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE:
10042 return "unexpected decompressed size";
10043 case MZ_ZIP_CRC_CHECK_FAILED:
10044 return "CRC-32 check failed";
10045 case MZ_ZIP_UNSUPPORTED_CDIR_SIZE:
10046 return "unsupported central directory size";
10047 case MZ_ZIP_ALLOC_FAILED:
10048 return "allocation failed";
10049 case MZ_ZIP_FILE_OPEN_FAILED:
10050 return "file open failed";
10051 case MZ_ZIP_FILE_CREATE_FAILED:
10052 return "file create failed";
10053 case MZ_ZIP_FILE_WRITE_FAILED:
10054 return "file write failed";
10055 case MZ_ZIP_FILE_READ_FAILED:
10056 return "file read failed";
10057 case MZ_ZIP_FILE_CLOSE_FAILED:
10058 return "file close failed";
10059 case MZ_ZIP_FILE_SEEK_FAILED:
10060 return "file seek failed";
10061 case MZ_ZIP_FILE_STAT_FAILED:
10062 return "file stat failed";
10063 case MZ_ZIP_INVALID_PARAMETER:
10064 return "invalid parameter";
10065 case MZ_ZIP_INVALID_FILENAME:
10066 return "invalid filename";
10067 case MZ_ZIP_BUF_TOO_SMALL:
10068 return "buffer too small";
10069 case MZ_ZIP_INTERNAL_ERROR:
10070 return "internal error";
10071 case MZ_ZIP_FILE_NOT_FOUND:
10072 return "file not found";
10073 case MZ_ZIP_ARCHIVE_TOO_LARGE:
10074 return "archive is too large";
10075 case MZ_ZIP_VALIDATION_FAILED:
10076 return "validation failed";
10077 case MZ_ZIP_WRITE_CALLBACK_FAILED:
10078 return "write callback failed";
10079 case MZ_ZIP_TOTAL_ERRORS:
10080 return "total errors";
10085 return "unknown error";
10091 if ((!pZip) || (!pZip->m_pState))
10094 return pZip->m_pState->m_zip64;
10098 if ((!pZip) || (!pZip->m_pState))
10101 return pZip->m_pState->m_central_dir.m_size;
10105 return pZip ? pZip->m_total_files : 0;
10111 return pZip->m_archive_size;
10114mz_uint64 mz_zip_get_archive_file_start_offset(
mz_zip_archive *pZip) {
10115 if ((!pZip) || (!pZip->m_pState))
10117 return pZip->m_pState->m_file_archive_start_ofs;
10121 if ((!pZip) || (!pZip->m_pState))
10123 return pZip->m_pState->m_pFile;
10126size_t mz_zip_read_archive_data(
mz_zip_archive *pZip, mz_uint64 file_ofs,
10127 void *pBuf,
size_t n) {
10128 if ((!pZip) || (!pZip->m_pState) || (!pBuf) || (!pZip->m_pRead))
10129 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
10131 return pZip->m_pRead(pZip->m_pIO_opaque, file_ofs, pBuf, n);
10134mz_uint mz_zip_reader_get_filename(
mz_zip_archive *pZip, mz_uint file_index,
10135 char *pFilename, mz_uint filename_buf_size) {
10137 const mz_uint8 *p = mz_zip_get_cdh(pZip, file_index);
10139 if (filename_buf_size)
10140 pFilename[0] =
'\0';
10141 mz_zip_set_error(pZip, MZ_ZIP_INVALID_PARAMETER);
10144 n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
10145 if (filename_buf_size) {
10146 n = MZ_MIN(n, filename_buf_size - 1);
10147 memcpy(pFilename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n);
10148 pFilename[n] =
'\0';
10153mz_bool mz_zip_reader_file_stat(
mz_zip_archive *pZip, mz_uint file_index,
10155 return mz_zip_file_stat_internal(
10156 pZip, file_index, mz_zip_get_cdh(pZip, file_index), pStat, NULL);
10163 if (pZip->m_zip_mode == MZ_ZIP_MODE_READING)
10164 return mz_zip_reader_end(pZip);
10165#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
10166 else if ((pZip->m_zip_mode == MZ_ZIP_MODE_WRITING) ||
10167 (pZip->m_zip_mode == MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED))
10168 return mz_zip_writer_end(pZip);