221#ifndef MINIZ_HEADER_INCLUDED
222#define MINIZ_HEADER_INCLUDED
263#if defined(__TINYC__) && (defined(__linux) || defined(__linux__))
269#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_ARCHIVE_APIS)
273#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || \
274 defined(__i386) || defined(__i486__) || defined(__i486) || \
275 defined(i386) || defined(__ia64__) || defined(__x86_64__)
277#define MINIZ_X86_OR_X64_CPU 1
280#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU
282#define MINIZ_LITTLE_ENDIAN 1
286#if !defined(MINIZ_USE_UNALIGNED_LOADS_AND_STORES)
287#if MINIZ_X86_OR_X64_CPU
290#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
291#define MINIZ_UNALIGNED_USE_MEMCPY
293#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0
297#if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || \
298 defined(_LP64) || defined(__LP64__) || defined(__ia64__) || \
303#define MINIZ_HAS_64BIT_REGISTERS 1
307#define ftello64 ftello
308#define fseeko64 fseeko
310#define freopen64 freopen
313#define MZ_PLATFORM 19
317#if defined(_WIN64) || defined(_WIN32) || defined(__WIN32__)
333typedef unsigned long mz_ulong;
338void mz_free(
void *p);
340#define MZ_ADLER32_INIT (1)
343mz_ulong mz_adler32(mz_ulong adler,
const unsigned char *ptr,
size_t buf_len);
345#define MZ_CRC32_INIT (0)
348mz_ulong mz_crc32(mz_ulong crc,
const unsigned char *ptr,
size_t buf_len);
352 MZ_DEFAULT_STRATEGY = 0,
363 MZ_ZIP_UNDEFINED_ERROR,
364 MZ_ZIP_TOO_MANY_FILES,
365 MZ_ZIP_FILE_TOO_LARGE,
366 MZ_ZIP_UNSUPPORTED_METHOD,
367 MZ_ZIP_UNSUPPORTED_ENCRYPTION,
368 MZ_ZIP_UNSUPPORTED_FEATURE,
369 MZ_ZIP_FAILED_FINDING_CENTRAL_DIR,
370 MZ_ZIP_NOT_AN_ARCHIVE,
371 MZ_ZIP_INVALID_HEADER_OR_CORRUPTED,
372 MZ_ZIP_UNSUPPORTED_MULTIDISK,
373 MZ_ZIP_DECOMPRESSION_FAILED,
374 MZ_ZIP_COMPRESSION_FAILED,
375 MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE,
376 MZ_ZIP_CRC_CHECK_FAILED,
377 MZ_ZIP_UNSUPPORTED_CDIR_SIZE,
379 MZ_ZIP_FILE_OPEN_FAILED,
380 MZ_ZIP_FILE_CREATE_FAILED,
381 MZ_ZIP_FILE_WRITE_FAILED,
382 MZ_ZIP_FILE_READ_FAILED,
383 MZ_ZIP_FILE_CLOSE_FAILED,
384 MZ_ZIP_FILE_SEEK_FAILED,
385 MZ_ZIP_FILE_STAT_FAILED,
386 MZ_ZIP_INVALID_PARAMETER,
387 MZ_ZIP_INVALID_FILENAME,
388 MZ_ZIP_BUF_TOO_SMALL,
389 MZ_ZIP_INTERNAL_ERROR,
390 MZ_ZIP_FILE_NOT_FOUND,
391 MZ_ZIP_ARCHIVE_TOO_LARGE,
392 MZ_ZIP_VALIDATION_FAILED,
393 MZ_ZIP_WRITE_CALLBACK_FAILED,
400#ifndef MINIZ_NO_ZLIB_APIS
405typedef void *(*mz_alloc_func)(
void *opaque,
size_t items,
size_t size);
406typedef void (*mz_free_func)(
void *opaque,
void *address);
407typedef void *(*mz_realloc_func)(
void *opaque,
void *address,
size_t items,
410#define MZ_VERSION "9.1.15"
411#define MZ_VERNUM 0x91F0
412#define MZ_VER_MAJOR 9
413#define MZ_VER_MINOR 1
414#define MZ_VER_REVISION 15
415#define MZ_VER_SUBREVISION 0
421 MZ_PARTIAL_FLUSH = 1,
434 MZ_STREAM_ERROR = -2,
438 MZ_VERSION_ERROR = -6,
439 MZ_PARAM_ERROR = -10000
446 MZ_NO_COMPRESSION = 0,
448 MZ_BEST_COMPRESSION = 9,
449 MZ_UBER_COMPRESSION = 10,
450 MZ_DEFAULT_LEVEL = 6,
451 MZ_DEFAULT_COMPRESSION = -1
455#define MZ_DEFAULT_WINDOW_BITS 15
457struct mz_internal_state;
461 const unsigned char *next_in;
462 unsigned int avail_in;
465 unsigned char *next_out;
466 unsigned int avail_out;
470 struct mz_internal_state *state;
485const char *mz_version(
void);
500int mz_deflateInit(
mz_streamp pStream,
int level);
509int mz_deflateInit2(
mz_streamp pStream,
int level,
int method,
int window_bits,
510 int mem_level,
int strategy);
542mz_ulong mz_deflateBound(
mz_streamp pStream, mz_ulong source_len);
547int mz_compress(
unsigned char *pDest, mz_ulong *pDest_len,
548 const unsigned char *pSource, mz_ulong source_len);
549int mz_compress2(
unsigned char *pDest, mz_ulong *pDest_len,
550 const unsigned char *pSource, mz_ulong source_len,
int level);
554mz_ulong mz_compressBound(mz_ulong source_len);
563int mz_inflateInit2(
mz_streamp pStream,
int window_bits);
596int mz_uncompress(
unsigned char *pDest, mz_ulong *pDest_len,
597 const unsigned char *pSource, mz_ulong source_len);
601const char *mz_error(
int err);
607#ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
608typedef unsigned char Byte;
609typedef unsigned int uInt;
610typedef mz_ulong uLong;
618typedef void *
const voidpc;
620#define Z_NO_FLUSH MZ_NO_FLUSH
621#define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH
622#define Z_SYNC_FLUSH MZ_SYNC_FLUSH
623#define Z_FULL_FLUSH MZ_FULL_FLUSH
624#define Z_FINISH MZ_FINISH
625#define Z_BLOCK MZ_BLOCK
627#define Z_STREAM_END MZ_STREAM_END
628#define Z_NEED_DICT MZ_NEED_DICT
629#define Z_ERRNO MZ_ERRNO
630#define Z_STREAM_ERROR MZ_STREAM_ERROR
631#define Z_DATA_ERROR MZ_DATA_ERROR
632#define Z_MEM_ERROR MZ_MEM_ERROR
633#define Z_BUF_ERROR MZ_BUF_ERROR
634#define Z_VERSION_ERROR MZ_VERSION_ERROR
635#define Z_PARAM_ERROR MZ_PARAM_ERROR
636#define Z_NO_COMPRESSION MZ_NO_COMPRESSION
637#define Z_BEST_SPEED MZ_BEST_SPEED
638#define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION
639#define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION
640#define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY
641#define Z_FILTERED MZ_FILTERED
642#define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY
644#define Z_FIXED MZ_FIXED
645#define Z_DEFLATED MZ_DEFLATED
646#define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS
647#define alloc_func mz_alloc_func
648#define free_func mz_free_func
649#define internal_state mz_internal_state
650#define z_stream mz_stream
651#define deflateInit mz_deflateInit
652#define deflateInit2 mz_deflateInit2
653#define deflateReset mz_deflateReset
654#define deflate mz_deflate
655#define deflateEnd mz_deflateEnd
656#define deflateBound mz_deflateBound
657#define compress mz_compress
658#define compress2 mz_compress2
659#define compressBound mz_compressBound
660#define inflateInit mz_inflateInit
661#define inflateInit2 mz_inflateInit2
662#define inflate mz_inflate
663#define inflateEnd mz_inflateEnd
664#define uncompress mz_uncompress
665#define crc32 mz_crc32
666#define adler32 mz_adler32
668#define MAX_MEM_LEVEL 9
669#define zError mz_error
670#define ZLIB_VERSION MZ_VERSION
671#define ZLIB_VERNUM MZ_VERNUM
672#define ZLIB_VER_MAJOR MZ_VER_MAJOR
673#define ZLIB_VER_MINOR MZ_VER_MINOR
674#define ZLIB_VER_REVISION MZ_VER_REVISION
675#define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION
676#define zlibVersion mz_version
677#define zlib_version mz_version()
684typedef unsigned char mz_uint8;
685typedef signed short mz_int16;
686typedef unsigned short mz_uint16;
687typedef unsigned int mz_uint32;
688typedef unsigned int mz_uint;
689typedef long long mz_int64;
690typedef unsigned long long mz_uint64;
699#define MZ_MACRO_END while (0, 0)
701#define MZ_MACRO_END while (0)
706#ifndef MINIZ_NO_ARCHIVE_APIS
709 MZ_ZIP_MAX_IO_BUF_SIZE = 64 * 1024,
710 MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE = 260,
711 MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE = 256
715 mz_uint32 m_file_index;
716 mz_uint32 m_central_dir_ofs;
717 mz_uint16 m_version_made_by;
718 mz_uint16 m_version_needed;
719 mz_uint16 m_bit_flag;
725 mz_uint64 m_comp_size;
726 mz_uint64 m_uncomp_size;
727 mz_uint16 m_internal_attr;
728 mz_uint32 m_external_attr;
729 mz_uint64 m_local_header_ofs;
730 mz_uint32 m_comment_size;
731 char m_filename[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE];
732 char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE];
735typedef size_t (*mz_file_read_func)(
void *pOpaque, mz_uint64 file_ofs,
736 void *pBuf,
size_t n);
737typedef size_t (*mz_file_write_func)(
void *pOpaque, mz_uint64 file_ofs,
738 const void *pBuf,
size_t n);
739typedef mz_bool (*mz_file_needs_keepalive)(
void *pOpaque);
745 MZ_ZIP_MODE_INVALID = 0,
746 MZ_ZIP_MODE_READING = 1,
747 MZ_ZIP_MODE_WRITING = 2,
748 MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3
752 MZ_ZIP_TYPE_INVALID = 0,
762 mz_uint64 m_archive_size;
763 mz_uint64 m_central_directory_file_ofs;
766 mz_uint32 m_total_files;
767 mz_zip_mode m_zip_mode;
768 mz_zip_type m_zip_type;
769 mz_zip_error m_last_error;
771 mz_uint64 m_file_offset_alignment;
773 mz_alloc_func m_pAlloc;
774 mz_free_func m_pFree;
775 mz_realloc_func m_pRealloc;
776 void *m_pAlloc_opaque;
778 mz_file_read_func m_pRead;
779 mz_file_write_func m_pWrite;
780 mz_file_needs_keepalive m_pNeeds_keepalive;
788 MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100,
789 MZ_ZIP_FLAG_IGNORE_PATH = 0x0200,
790 MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400,
791 MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY = 0x0800
800mz_bool mz_zip_reader_init_mem(
mz_zip_archive *pZip,
const void *pMem,
801 size_t size, mz_uint32 flags);
803#ifndef MINIZ_NO_STDIO
804mz_bool mz_zip_reader_init_file(
mz_zip_archive *pZip,
const char *pFilename,
812mz_bool mz_zip_reader_file_stat(
mz_zip_archive *pZip, mz_uint file_index,
825mz_uint mz_zip_reader_get_filename(
mz_zip_archive *pZip, mz_uint file_index,
826 char *pFilename, mz_uint filename_buf_size);
831int mz_zip_reader_locate_file(
mz_zip_archive *pZip,
const char *pName,
832 const char *pComment, mz_uint flags);
835mz_bool mz_zip_reader_extract_to_mem_no_alloc(
mz_zip_archive *pZip,
836 mz_uint file_index,
void *pBuf,
837 size_t buf_size, mz_uint flags,
838 void *pUser_read_buf,
839 size_t user_read_buf_size);
840mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(
841 mz_zip_archive *pZip,
const char *pFilename,
void *pBuf,
size_t buf_size,
842 mz_uint flags,
void *pUser_read_buf,
size_t user_read_buf_size);
845mz_bool mz_zip_reader_extract_to_mem(
mz_zip_archive *pZip, mz_uint file_index,
846 void *pBuf,
size_t buf_size,
849 const char *pFilename,
void *pBuf,
850 size_t buf_size, mz_uint flags);
853void *mz_zip_reader_extract_to_heap(
mz_zip_archive *pZip, mz_uint file_index,
854 size_t *pSize, mz_uint flags);
856 const char *pFilename,
size_t *pSize,
862 mz_file_write_func pCallback,
863 void *pOpaque, mz_uint flags);
864mz_bool mz_zip_reader_extract_file_to_callback(
mz_zip_archive *pZip,
865 const char *pFilename,
866 mz_file_write_func pCallback,
867 void *pOpaque, mz_uint flags);
869#ifndef MINIZ_NO_STDIO
873mz_bool mz_zip_reader_extract_to_file(
mz_zip_archive *pZip, mz_uint file_index,
874 const char *pDst_filename, mz_uint flags);
876 const char *pArchive_filename,
877 const char *pDst_filename,
887#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
890mz_bool mz_zip_writer_init(
mz_zip_archive *pZip, mz_uint64 existing_size);
892 size_t size_to_reserve_at_beginning,
893 size_t initial_allocation_size);
895#ifndef MINIZ_NO_STDIO
896mz_bool mz_zip_writer_init_file(
mz_zip_archive *pZip,
const char *pFilename,
897 mz_uint64 size_to_reserve_at_beginning);
913 const char *pFilename);
921mz_bool mz_zip_writer_add_mem(
mz_zip_archive *pZip,
const char *pArchive_name,
922 const void *pBuf,
size_t buf_size,
923 mz_uint level_and_flags);
925 const char *pArchive_name,
const void *pBuf,
926 size_t buf_size,
const void *pComment,
927 mz_uint16 comment_size,
928 mz_uint level_and_flags, mz_uint64 uncomp_size,
929 mz_uint32 uncomp_crc32);
931#ifndef MINIZ_NO_STDIO
936mz_bool mz_zip_writer_add_file(
mz_zip_archive *pZip,
const char *pArchive_name,
937 const char *pSrc_filename,
const void *pComment,
938 mz_uint16 comment_size, mz_uint level_and_flags,
939 mz_uint32 ext_attributes);
954mz_bool mz_zip_writer_finalize_heap_archive(
mz_zip_archive *pZip,
void **pBuf,
968mz_bool mz_zip_add_mem_to_archive_file_in_place(
969 const char *pZip_filename,
const char *pArchive_name,
const void *pBuf,
970 size_t buf_size,
const void *pComment, mz_uint16 comment_size,
971 mz_uint level_and_flags);
975void *mz_zip_extract_archive_file_to_heap(
const char *pZip_filename,
976 const char *pArchive_name,
977 size_t *pSize, mz_uint zip_flags);
997 TINFL_FLAG_PARSE_ZLIB_HEADER = 1,
998 TINFL_FLAG_HAS_MORE_INPUT = 2,
999 TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4,
1000 TINFL_FLAG_COMPUTE_ADLER32 = 8
1013void *tinfl_decompress_mem_to_heap(
const void *pSrc_buf,
size_t src_buf_len,
1014 size_t *pOut_len,
int flags);
1019#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1))
1020size_t tinfl_decompress_mem_to_mem(
void *pOut_buf,
size_t out_buf_len,
1021 const void *pSrc_buf,
size_t src_buf_len,
1027typedef int (*tinfl_put_buf_func_ptr)(
const void *pBuf,
int len,
void *pUser);
1028int tinfl_decompress_mem_to_callback(
const void *pIn_buf,
size_t *pIn_buf_size,
1029 tinfl_put_buf_func_ptr pPut_buf_func,
1030 void *pPut_buf_user,
int flags);
1036#define TINFL_LZ_DICT_SIZE 32768
1040 TINFL_STATUS_BAD_PARAM = -3,
1041 TINFL_STATUS_ADLER32_MISMATCH = -2,
1042 TINFL_STATUS_FAILED = -1,
1043 TINFL_STATUS_DONE = 0,
1044 TINFL_STATUS_NEEDS_MORE_INPUT = 1,
1045 TINFL_STATUS_HAS_MORE_OUTPUT = 2
1049#define tinfl_init(r) \
1054#define tinfl_get_adler32(r) (r)->m_check_adler32
1063 const mz_uint8 *pIn_buf_next,
1064 size_t *pIn_buf_size, mz_uint8 *pOut_buf_start,
1065 mz_uint8 *pOut_buf_next,
size_t *pOut_buf_size,
1066 const mz_uint32 decomp_flags);
1070 TINFL_MAX_HUFF_TABLES = 3,
1071 TINFL_MAX_HUFF_SYMBOLS_0 = 288,
1072 TINFL_MAX_HUFF_SYMBOLS_1 = 32,
1073 TINFL_MAX_HUFF_SYMBOLS_2 = 19,
1074 TINFL_FAST_LOOKUP_BITS = 10,
1075 TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS
1079 mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0];
1080 mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE],
1081 m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
1084#if MINIZ_HAS_64BIT_REGISTERS
1085#define TINFL_USE_64BIT_BITBUF 1
1088#if TINFL_USE_64BIT_BITBUF
1089typedef mz_uint64 tinfl_bit_buf_t;
1090#define TINFL_BITBUF_SIZE (64)
1092typedef mz_uint32 tinfl_bit_buf_t;
1093#define TINFL_BITBUF_SIZE (32)
1097 mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type,
1098 m_check_adler32, m_dist, m_counter, m_num_extra,
1099 m_table_sizes[TINFL_MAX_HUFF_TABLES];
1100 tinfl_bit_buf_t m_bit_buf;
1101 size_t m_dist_from_out_buf_start;
1103 mz_uint8 m_raw_header[4],
1104 m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137];
1111#define TDEFL_LESS_MEMORY 0
1119 TDEFL_HUFFMAN_ONLY = 0,
1120 TDEFL_DEFAULT_MAX_PROBES = 128,
1121 TDEFL_MAX_PROBES_MASK = 0xFFF
1139 TDEFL_WRITE_ZLIB_HEADER = 0x01000,
1140 TDEFL_COMPUTE_ADLER32 = 0x02000,
1141 TDEFL_GREEDY_PARSING_FLAG = 0x04000,
1142 TDEFL_NONDETERMINISTIC_PARSING_FLAG = 0x08000,
1143 TDEFL_RLE_MATCHES = 0x10000,
1144 TDEFL_FILTER_MATCHES = 0x20000,
1145 TDEFL_FORCE_ALL_STATIC_BLOCKS = 0x40000,
1146 TDEFL_FORCE_ALL_RAW_BLOCKS = 0x80000
1160void *tdefl_compress_mem_to_heap(
const void *pSrc_buf,
size_t src_buf_len,
1161 size_t *pOut_len,
int flags);
1165size_t tdefl_compress_mem_to_mem(
void *pOut_buf,
size_t out_buf_len,
1166 const void *pSrc_buf,
size_t src_buf_len,
1182void *tdefl_write_image_to_png_file_in_memory_ex(
const void *pImage,
int w,
1183 int h,
int num_chans,
1185 mz_uint level, mz_bool flip);
1186void *tdefl_write_image_to_png_file_in_memory(
const void *pImage,
int w,
int h,
1187 int num_chans,
size_t *pLen_out);
1191typedef mz_bool (*tdefl_put_buf_func_ptr)(
const void *pBuf,
int len,
1196mz_bool tdefl_compress_mem_to_output(
const void *pBuf,
size_t buf_len,
1197 tdefl_put_buf_func_ptr pPut_buf_func,
1198 void *pPut_buf_user,
int flags);
1201 TDEFL_MAX_HUFF_TABLES = 3,
1202 TDEFL_MAX_HUFF_SYMBOLS_0 = 288,
1203 TDEFL_MAX_HUFF_SYMBOLS_1 = 32,
1204 TDEFL_MAX_HUFF_SYMBOLS_2 = 19,
1205 TDEFL_LZ_DICT_SIZE = 32768,
1206 TDEFL_LZ_DICT_SIZE_MASK = TDEFL_LZ_DICT_SIZE - 1,
1207 TDEFL_MIN_MATCH_LEN = 3,
1208 TDEFL_MAX_MATCH_LEN = 258
1213#if TDEFL_LESS_MEMORY
1215 TDEFL_LZ_CODE_BUF_SIZE = 24 * 1024,
1216 TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10,
1217 TDEFL_MAX_HUFF_SYMBOLS = 288,
1218 TDEFL_LZ_HASH_BITS = 12,
1219 TDEFL_LEVEL1_HASH_SIZE_MASK = 4095,
1220 TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3,
1221 TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS
1225 TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024,
1226 TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10,
1227 TDEFL_MAX_HUFF_SYMBOLS = 288,
1228 TDEFL_LZ_HASH_BITS = 15,
1229 TDEFL_LEVEL1_HASH_SIZE_MASK = 4095,
1230 TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3,
1231 TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS
1239 TDEFL_STATUS_BAD_PARAM = -2,
1240 TDEFL_STATUS_PUT_BUF_FAILED = -1,
1241 TDEFL_STATUS_OKAY = 0,
1242 TDEFL_STATUS_DONE = 1,
1248 TDEFL_SYNC_FLUSH = 2,
1249 TDEFL_FULL_FLUSH = 3,
1255 tdefl_put_buf_func_ptr m_pPut_buf_func;
1256 void *m_pPut_buf_user;
1257 mz_uint m_flags, m_max_probes[2];
1258 int m_greedy_parsing;
1259 mz_uint m_adler32, m_lookahead_pos, m_lookahead_size, m_dict_size;
1260 mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end;
1261 mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in,
1263 mz_uint m_saved_match_dist, m_saved_match_len, m_saved_lit,
1264 m_output_flush_ofs, m_output_flush_remaining, m_finished, m_block_index,
1266 tdefl_status m_prev_return_status;
1267 const void *m_pIn_buf;
1269 size_t *m_pIn_buf_size, *m_pOut_buf_size;
1270 tdefl_flush m_flush;
1271 const mz_uint8 *m_pSrc;
1272 size_t m_src_buf_left, m_out_buf_ofs;
1273 mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE + TDEFL_MAX_MATCH_LEN - 1];
1274 mz_uint16 m_huff_count[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
1275 mz_uint16 m_huff_codes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
1276 mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
1277 mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE];
1278 mz_uint16 m_next[TDEFL_LZ_DICT_SIZE];
1279 mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE];
1280 mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE];
1291 tdefl_put_buf_func_ptr pPut_buf_func,
1292 void *pPut_buf_user,
int flags);
1298 size_t *pIn_buf_size,
void *pOut_buf,
1299 size_t *pOut_buf_size, tdefl_flush flush);
1304tdefl_status tdefl_compress_buffer(
tdefl_compressor *d,
const void *pIn_buf,
1305 size_t in_buf_size, tdefl_flush flush);
1312#ifndef MINIZ_NO_ZLIB_APIS
1318mz_uint tdefl_create_comp_flags_from_zip_params(
int level,
int window_bits,
1322#define MZ_UINT16_MAX (0xFFFFU)
1323#define MZ_UINT32_MAX (0xFFFFFFFFU)
1334#ifndef MINIZ_HEADER_FILE_ONLY
1336typedef unsigned char mz_validate_uint16[
sizeof(mz_uint16) == 2 ? 1 : -1];
1337typedef unsigned char mz_validate_uint32[
sizeof(mz_uint32) == 4 ? 1 : -1];
1338typedef unsigned char mz_validate_uint64[
sizeof(mz_uint64) == 8 ? 1 : -1];
1343#define MZ_ASSERT(x) assert(x)
1345#ifdef MINIZ_NO_MALLOC
1346#define MZ_MALLOC(x) NULL
1347#define MZ_FREE(x) (void)x, ((void)0)
1348#define MZ_REALLOC(p, x) NULL
1350#define MZ_MALLOC(x) malloc(x)
1351#define MZ_FREE(x) free(x)
1352#define MZ_REALLOC(p, x) realloc(p, x)
1355#define MZ_MAX(a, b) (((a) > (b)) ? (a) : (b))
1356#define MZ_MIN(a, b) (((a) < (b)) ? (a) : (b))
1357#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
1359#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
1360#define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
1361#define MZ_READ_LE32(p) *((const mz_uint32 *)(p))
1363#define MZ_READ_LE16(p) \
1364 ((mz_uint32)(((const mz_uint8 *)(p))[0]) | \
1365 ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U))
1366#define MZ_READ_LE32(p) \
1367 ((mz_uint32)(((const mz_uint8 *)(p))[0]) | \
1368 ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | \
1369 ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | \
1370 ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U))
1373#define MZ_READ_LE64(p) \
1374 (((mz_uint64)MZ_READ_LE32(p)) | \
1375 (((mz_uint64)MZ_READ_LE32((const mz_uint8 *)(p) + sizeof(mz_uint32))) \
1379#define MZ_FORCEINLINE __forceinline
1380#elif defined(__GNUC__)
1381#define MZ_FORCEINLINE inline __attribute__((__always_inline__))
1383#define MZ_FORCEINLINE inline
1392mz_ulong mz_adler32(mz_ulong adler,
const unsigned char *ptr,
size_t buf_len) {
1393 mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16);
1394 size_t block_len = buf_len % 5552;
1396 return MZ_ADLER32_INIT;
1398 for (i = 0; i + 7 < block_len; i += 8, ptr += 8) {
1399 s1 += ptr[0], s2 += s1;
1400 s1 += ptr[1], s2 += s1;
1401 s1 += ptr[2], s2 += s1;
1402 s1 += ptr[3], s2 += s1;
1403 s1 += ptr[4], s2 += s1;
1404 s1 += ptr[5], s2 += s1;
1405 s1 += ptr[6], s2 += s1;
1406 s1 += ptr[7], s2 += s1;
1408 for (; i < block_len; ++i)
1409 s1 += *ptr++, s2 += s1;
1410 s1 %= 65521U, s2 %= 65521U;
1411 buf_len -= block_len;
1414 return (s2 << 16) + s1;
1420mz_ulong mz_crc32(mz_ulong crc,
const mz_uint8 *ptr,
size_t buf_len) {
1421 static const mz_uint32 s_crc32[16] = {
1422 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4,
1423 0x4db26158, 0x5005713c, 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
1424 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c};
1425 mz_uint32 crcu32 = (mz_uint32)crc;
1427 return MZ_CRC32_INIT;
1430 mz_uint8 b = *ptr++;
1431 crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)];
1432 crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)];
1437void mz_free(
void *p) { MZ_FREE(p); }
1439#ifndef MINIZ_NO_ZLIB_APIS
1441static void *def_alloc_func(
void *opaque,
size_t items,
size_t size) {
1442 (void)opaque, (
void)items, (void)size;
1443 return MZ_MALLOC(items * size);
1445static void def_free_func(
void *opaque,
void *address) {
1446 (void)opaque, (
void)address;
1449static void *def_realloc_func(
void *opaque,
void *address,
size_t items,
1451 (void)opaque, (
void)address, (void)items, (
void)size;
1452 return MZ_REALLOC(address, items * size);
1455const char *mz_version(
void) {
return MZ_VERSION; }
1457int mz_deflateInit(
mz_streamp pStream,
int level) {
1458 return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9,
1459 MZ_DEFAULT_STRATEGY);
1462int mz_deflateInit2(
mz_streamp pStream,
int level,
int method,
int window_bits,
1463 int mem_level,
int strategy) {
1465 mz_uint comp_flags =
1466 TDEFL_COMPUTE_ADLER32 |
1467 tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy);
1470 return MZ_STREAM_ERROR;
1471 if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) ||
1472 ((window_bits != MZ_DEFAULT_WINDOW_BITS) &&
1473 (-window_bits != MZ_DEFAULT_WINDOW_BITS)))
1474 return MZ_PARAM_ERROR;
1476 pStream->data_type = 0;
1477 pStream->adler = MZ_ADLER32_INIT;
1478 pStream->msg = NULL;
1479 pStream->reserved = 0;
1480 pStream->total_in = 0;
1481 pStream->total_out = 0;
1482 if (!pStream->zalloc)
1483 pStream->zalloc = def_alloc_func;
1484 if (!pStream->zfree)
1485 pStream->zfree = def_free_func;
1490 return MZ_MEM_ERROR;
1492 pStream->state = (
struct mz_internal_state *)pComp;
1494 if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY) {
1495 mz_deflateEnd(pStream);
1496 return MZ_PARAM_ERROR;
1503 if ((!pStream) || (!pStream->state) || (!pStream->zalloc) ||
1505 return MZ_STREAM_ERROR;
1506 pStream->total_in = pStream->total_out = 0;
1512int mz_deflate(
mz_streamp pStream,
int flush) {
1513 size_t in_bytes, out_bytes;
1514 mz_ulong orig_total_in, orig_total_out;
1515 int mz_status = MZ_OK;
1517 if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) ||
1518 (!pStream->next_out))
1519 return MZ_STREAM_ERROR;
1520 if (!pStream->avail_out)
1521 return MZ_BUF_ERROR;
1523 if (flush == MZ_PARTIAL_FLUSH)
1524 flush = MZ_SYNC_FLUSH;
1528 return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR;
1530 orig_total_in = pStream->total_in;
1531 orig_total_out = pStream->total_out;
1533 tdefl_status defl_status;
1534 in_bytes = pStream->avail_in;
1535 out_bytes = pStream->avail_out;
1538 pStream->next_in, &in_bytes, pStream->next_out,
1539 &out_bytes, (tdefl_flush)flush);
1540 pStream->next_in += (mz_uint)in_bytes;
1541 pStream->avail_in -= (mz_uint)in_bytes;
1542 pStream->total_in += (mz_uint)in_bytes;
1545 pStream->next_out += (mz_uint)out_bytes;
1546 pStream->avail_out -= (mz_uint)out_bytes;
1547 pStream->total_out += (mz_uint)out_bytes;
1549 if (defl_status < 0) {
1550 mz_status = MZ_STREAM_ERROR;
1552 }
else if (defl_status == TDEFL_STATUS_DONE) {
1553 mz_status = MZ_STREAM_END;
1555 }
else if (!pStream->avail_out)
1557 else if ((!pStream->avail_in) && (flush != MZ_FINISH)) {
1558 if ((flush) || (pStream->total_in != orig_total_in) ||
1559 (pStream->total_out != orig_total_out))
1561 return MZ_BUF_ERROR;
1569 return MZ_STREAM_ERROR;
1570 if (pStream->state) {
1571 pStream->zfree(pStream->opaque, pStream->state);
1572 pStream->state = NULL;
1577mz_ulong mz_deflateBound(
mz_streamp pStream, mz_ulong source_len) {
1581 return MZ_MAX(128 + (source_len * 110) / 100,
1582 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5);
1585int mz_compress2(
unsigned char *pDest, mz_ulong *pDest_len,
1586 const unsigned char *pSource, mz_ulong source_len,
int level) {
1589 memset(&stream, 0,
sizeof(stream));
1592 if ((source_len | *pDest_len) > 0xFFFFFFFFU)
1593 return MZ_PARAM_ERROR;
1595 stream.next_in = pSource;
1596 stream.avail_in = (mz_uint32)source_len;
1597 stream.next_out = pDest;
1598 stream.avail_out = (mz_uint32)*pDest_len;
1600 status = mz_deflateInit(&stream, level);
1601 if (status != MZ_OK)
1604 status = mz_deflate(&stream, MZ_FINISH);
1605 if (status != MZ_STREAM_END) {
1606 mz_deflateEnd(&stream);
1607 return (status == MZ_OK) ? MZ_BUF_ERROR : status;
1610 *pDest_len = stream.total_out;
1611 return mz_deflateEnd(&stream);
1614int mz_compress(
unsigned char *pDest, mz_ulong *pDest_len,
1615 const unsigned char *pSource, mz_ulong source_len) {
1616 return mz_compress2(pDest, pDest_len, pSource, source_len,
1617 MZ_DEFAULT_COMPRESSION);
1620mz_ulong mz_compressBound(mz_ulong source_len) {
1621 return mz_deflateBound(NULL, source_len);
1626 mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed;
1628 mz_uint8 m_dict[TINFL_LZ_DICT_SIZE];
1629 tinfl_status m_last_status;
1632int mz_inflateInit2(
mz_streamp pStream,
int window_bits) {
1635 return MZ_STREAM_ERROR;
1636 if ((window_bits != MZ_DEFAULT_WINDOW_BITS) &&
1637 (-window_bits != MZ_DEFAULT_WINDOW_BITS))
1638 return MZ_PARAM_ERROR;
1640 pStream->data_type = 0;
1642 pStream->msg = NULL;
1643 pStream->total_in = 0;
1644 pStream->total_out = 0;
1645 pStream->reserved = 0;
1646 if (!pStream->zalloc)
1647 pStream->zalloc = def_alloc_func;
1648 if (!pStream->zfree)
1649 pStream->zfree = def_free_func;
1651 pDecomp = (
inflate_state *)pStream->zalloc(pStream->opaque, 1,
1654 return MZ_MEM_ERROR;
1656 pStream->state = (
struct mz_internal_state *)pDecomp;
1658 tinfl_init(&pDecomp->m_decomp);
1659 pDecomp->m_dict_ofs = 0;
1660 pDecomp->m_dict_avail = 0;
1661 pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
1662 pDecomp->m_first_call = 1;
1663 pDecomp->m_has_flushed = 0;
1664 pDecomp->m_window_bits = window_bits;
1670 return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS);
1673int mz_inflate(
mz_streamp pStream,
int flush) {
1675 mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32;
1676 size_t in_bytes, out_bytes, orig_avail_in;
1677 tinfl_status status;
1679 if ((!pStream) || (!pStream->state))
1680 return MZ_STREAM_ERROR;
1681 if (flush == MZ_PARTIAL_FLUSH)
1682 flush = MZ_SYNC_FLUSH;
1683 if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH))
1684 return MZ_STREAM_ERROR;
1687 if (pState->m_window_bits > 0)
1688 decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER;
1689 orig_avail_in = pStream->avail_in;
1691 first_call = pState->m_first_call;
1692 pState->m_first_call = 0;
1693 if (pState->m_last_status < 0)
1694 return MZ_DATA_ERROR;
1696 if (pState->m_has_flushed && (flush != MZ_FINISH))
1697 return MZ_STREAM_ERROR;
1698 pState->m_has_flushed |= (flush == MZ_FINISH);
1700 if ((flush == MZ_FINISH) && (first_call)) {
1703 decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF;
1704 in_bytes = pStream->avail_in;
1705 out_bytes = pStream->avail_out;
1706 status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes,
1707 pStream->next_out, pStream->next_out, &out_bytes,
1709 pState->m_last_status = status;
1710 pStream->next_in += (mz_uint)in_bytes;
1711 pStream->avail_in -= (mz_uint)in_bytes;
1712 pStream->total_in += (mz_uint)in_bytes;
1713 pStream->adler = tinfl_get_adler32(&pState->m_decomp);
1714 pStream->next_out += (mz_uint)out_bytes;
1715 pStream->avail_out -= (mz_uint)out_bytes;
1716 pStream->total_out += (mz_uint)out_bytes;
1719 return MZ_DATA_ERROR;
1720 else if (status != TINFL_STATUS_DONE) {
1721 pState->m_last_status = TINFL_STATUS_FAILED;
1722 return MZ_BUF_ERROR;
1724 return MZ_STREAM_END;
1727 if (flush != MZ_FINISH)
1728 decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT;
1730 if (pState->m_dict_avail) {
1731 n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
1732 memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
1733 pStream->next_out += n;
1734 pStream->avail_out -= n;
1735 pStream->total_out += n;
1736 pState->m_dict_avail -= n;
1737 pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
1738 return ((pState->m_last_status == TINFL_STATUS_DONE) &&
1739 (!pState->m_dict_avail))
1745 in_bytes = pStream->avail_in;
1746 out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs;
1748 status = tinfl_decompress(
1749 &pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict,
1750 pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags);
1751 pState->m_last_status = status;
1753 pStream->next_in += (mz_uint)in_bytes;
1754 pStream->avail_in -= (mz_uint)in_bytes;
1755 pStream->total_in += (mz_uint)in_bytes;
1756 pStream->adler = tinfl_get_adler32(&pState->m_decomp);
1758 pState->m_dict_avail = (mz_uint)out_bytes;
1760 n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
1761 memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
1762 pStream->next_out += n;
1763 pStream->avail_out -= n;
1764 pStream->total_out += n;
1765 pState->m_dict_avail -= n;
1766 pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
1769 return MZ_DATA_ERROR;
1772 else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in))
1773 return MZ_BUF_ERROR;
1776 else if (flush == MZ_FINISH) {
1779 if (status == TINFL_STATUS_DONE)
1780 return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END;
1784 else if (!pStream->avail_out)
1785 return MZ_BUF_ERROR;
1786 }
else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) ||
1787 (!pStream->avail_out) || (pState->m_dict_avail))
1791 return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail))
1798 return MZ_STREAM_ERROR;
1799 if (pStream->state) {
1800 pStream->zfree(pStream->opaque, pStream->state);
1801 pStream->state = NULL;
1806int mz_uncompress(
unsigned char *pDest, mz_ulong *pDest_len,
1807 const unsigned char *pSource, mz_ulong source_len) {
1810 memset(&stream, 0,
sizeof(stream));
1813 if ((source_len | *pDest_len) > 0xFFFFFFFFU)
1814 return MZ_PARAM_ERROR;
1816 stream.next_in = pSource;
1817 stream.avail_in = (mz_uint32)source_len;
1818 stream.next_out = pDest;
1819 stream.avail_out = (mz_uint32)*pDest_len;
1821 status = mz_inflateInit(&stream);
1822 if (status != MZ_OK)
1825 status = mz_inflate(&stream, MZ_FINISH);
1826 if (status != MZ_STREAM_END) {
1827 mz_inflateEnd(&stream);
1828 return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR
1831 *pDest_len = stream.total_out;
1833 return mz_inflateEnd(&stream);
1836const char *mz_error(
int err) {
1839 const char *m_pDesc;
1840 } s_error_descs[] = {{MZ_OK,
""},
1841 {MZ_STREAM_END,
"stream end"},
1842 {MZ_NEED_DICT,
"need dictionary"},
1843 {MZ_ERRNO,
"file error"},
1844 {MZ_STREAM_ERROR,
"stream error"},
1845 {MZ_DATA_ERROR,
"data error"},
1846 {MZ_MEM_ERROR,
"out of memory"},
1847 {MZ_BUF_ERROR,
"buf error"},
1848 {MZ_VERSION_ERROR,
"version error"},
1849 {MZ_PARAM_ERROR,
"parameter error"}};
1851 for (i = 0; i <
sizeof(s_error_descs) /
sizeof(s_error_descs[0]); ++i)
1852 if (s_error_descs[i].m_err == err)
1853 return s_error_descs[i].m_pDesc;
1862#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
1863#define TINFL_MEMSET(p, c, l) memset(p, c, l)
1865#define TINFL_CR_BEGIN \
1866 switch (r->m_state) { \
1868#define TINFL_CR_RETURN(state_index, result) \
1871 r->m_state = state_index; \
1873 case state_index:; \
1876#define TINFL_CR_RETURN_FOREVER(state_index, result) \
1879 TINFL_CR_RETURN(state_index, result); \
1883#define TINFL_CR_FINISH }
1889#define TINFL_GET_BYTE(state_index, c) \
1891 if (pIn_buf_cur >= pIn_buf_end) { \
1893 if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \
1894 TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \
1895 if (pIn_buf_cur < pIn_buf_end) { \
1896 c = *pIn_buf_cur++; \
1905 c = *pIn_buf_cur++; \
1909#define TINFL_NEED_BITS(state_index, n) \
1912 TINFL_GET_BYTE(state_index, c); \
1913 bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
1915 } while (num_bits < (mz_uint)(n))
1916#define TINFL_SKIP_BITS(state_index, n) \
1918 if (num_bits < (mz_uint)(n)) { \
1919 TINFL_NEED_BITS(state_index, n); \
1925#define TINFL_GET_BITS(state_index, b, n) \
1927 if (num_bits < (mz_uint)(n)) { \
1928 TINFL_NEED_BITS(state_index, n); \
1930 b = bit_buf & ((1 << (n)) - 1); \
1943#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \
1945 temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
1947 code_len = temp >> 9; \
1948 if ((code_len) && (num_bits >= code_len)) \
1950 } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \
1951 code_len = TINFL_FAST_LOOKUP_BITS; \
1953 temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
1954 } while ((temp < 0) && (num_bits >= (code_len + 1))); \
1958 TINFL_GET_BYTE(state_index, c); \
1959 bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
1961 } while (num_bits < 15);
1971#define TINFL_HUFF_DECODE(state_index, sym, pHuff) \
1974 mz_uint code_len, c; \
1975 if (num_bits < 15) { \
1976 if ((pIn_buf_end - pIn_buf_cur) < 2) { \
1977 TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
1979 bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | \
1980 (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); \
1985 if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= \
1987 code_len = temp >> 9, temp &= 511; \
1989 code_len = TINFL_FAST_LOOKUP_BITS; \
1991 temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
1992 } while (temp < 0); \
1995 bit_buf >>= code_len; \
1996 num_bits -= code_len; \
2001 const mz_uint8 *pIn_buf_next,
2002 size_t *pIn_buf_size, mz_uint8 *pOut_buf_start,
2003 mz_uint8 *pOut_buf_next,
size_t *pOut_buf_size,
2004 const mz_uint32 decomp_flags) {
2005 static const int s_length_base[31] = {
2006 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
2007 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
2008 static const int s_length_extra[31] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
2009 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4,
2010 4, 4, 5, 5, 5, 5, 0, 0, 0};
2011 static const int s_dist_base[32] = {
2012 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33,
2013 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537,
2014 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0};
2015 static const int s_dist_extra[32] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
2016 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
2017 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
2018 static const mz_uint8 s_length_dezigzag[19] = {
2019 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
2020 static const int s_min_table_sizes[3] = {257, 1, 4};
2022 tinfl_status status = TINFL_STATUS_FAILED;
2023 mz_uint32 num_bits, dist, counter, num_extra;
2024 tinfl_bit_buf_t bit_buf;
2025 const mz_uint8 *pIn_buf_cur = pIn_buf_next, *
const pIn_buf_end =
2026 pIn_buf_next + *pIn_buf_size;
2027 mz_uint8 *pOut_buf_cur = pOut_buf_next, *
const pOut_buf_end =
2028 pOut_buf_next + *pOut_buf_size;
2029 size_t out_buf_size_mask =
2030 (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)
2032 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1,
2033 dist_from_out_buf_start;
2038 if (((out_buf_size_mask + 1) & out_buf_size_mask) ||
2039 (pOut_buf_next < pOut_buf_start)) {
2040 *pIn_buf_size = *pOut_buf_size = 0;
2041 return TINFL_STATUS_BAD_PARAM;
2044 num_bits = r->m_num_bits;
2045 bit_buf = r->m_bit_buf;
2047 counter = r->m_counter;
2048 num_extra = r->m_num_extra;
2049 dist_from_out_buf_start = r->m_dist_from_out_buf_start;
2052 bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0;
2053 r->m_z_adler32 = r->m_check_adler32 = 1;
2054 if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) {
2055 TINFL_GET_BYTE(1, r->m_zhdr0);
2056 TINFL_GET_BYTE(2, r->m_zhdr1);
2057 counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) ||
2058 (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8));
2059 if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
2060 counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) ||
2061 ((out_buf_size_mask + 1) <
2062 (size_t)(1U << (8U + (r->m_zhdr0 >> 4)))));
2064 TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED);
2069 TINFL_GET_BITS(3, r->m_final, 3);
2070 r->m_type = r->m_final >> 1;
2071 if (r->m_type == 0) {
2072 TINFL_SKIP_BITS(5, num_bits & 7);
2073 for (counter = 0; counter < 4; ++counter) {
2075 TINFL_GET_BITS(6, r->m_raw_header[counter], 8);
2077 TINFL_GET_BYTE(7, r->m_raw_header[counter]);
2079 if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) !=
2081 (r->m_raw_header[2] | (r->m_raw_header[3] << 8)))) {
2082 TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED);
2084 while ((counter) && (num_bits)) {
2085 TINFL_GET_BITS(51, dist, 8);
2086 while (pOut_buf_cur >= pOut_buf_end) {
2087 TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT);
2089 *pOut_buf_cur++ = (mz_uint8)dist;
2094 while (pOut_buf_cur >= pOut_buf_end) {
2095 TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT);
2097 while (pIn_buf_cur >= pIn_buf_end) {
2098 if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) {
2099 TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT);
2101 TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED);
2104 n = MZ_MIN(MZ_MIN((
size_t)(pOut_buf_end - pOut_buf_cur),
2105 (
size_t)(pIn_buf_end - pIn_buf_cur)),
2107 TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n);
2110 counter -= (mz_uint)n;
2112 }
else if (r->m_type == 3) {
2113 TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED);
2115 if (r->m_type == 1) {
2116 mz_uint8 *p = r->m_tables[0].m_code_size;
2118 r->m_table_sizes[0] = 288;
2119 r->m_table_sizes[1] = 32;
2120 TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32);
2121 for (i = 0; i <= 143; ++i)
2123 for (; i <= 255; ++i)
2125 for (; i <= 279; ++i)
2127 for (; i <= 287; ++i)
2130 for (counter = 0; counter < 3; counter++) {
2131 TINFL_GET_BITS(11, r->m_table_sizes[counter],
"\05\05\04"[counter]);
2132 r->m_table_sizes[counter] += s_min_table_sizes[counter];
2134 MZ_CLEAR_OBJ(r->m_tables[2].m_code_size);
2135 for (counter = 0; counter < r->m_table_sizes[2]; counter++) {
2137 TINFL_GET_BITS(14, s, 3);
2138 r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s;
2140 r->m_table_sizes[2] = 19;
2142 for (; (int)r->m_type >= 0; r->m_type--) {
2143 int tree_next, tree_cur;
2145 mz_uint i, j, used_syms, total, sym_index, next_code[17],
2147 pTable = &r->m_tables[r->m_type];
2148 MZ_CLEAR_OBJ(total_syms);
2149 MZ_CLEAR_OBJ(pTable->m_look_up);
2150 MZ_CLEAR_OBJ(pTable->m_tree);
2151 for (i = 0; i < r->m_table_sizes[r->m_type]; ++i)
2152 total_syms[pTable->m_code_size[i]]++;
2153 used_syms = 0, total = 0;
2154 next_code[0] = next_code[1] = 0;
2155 for (i = 1; i <= 15; ++i) {
2156 used_syms += total_syms[i];
2157 next_code[i + 1] = (total = ((total + total_syms[i]) << 1));
2159 if ((65536 != total) && (used_syms > 1)) {
2160 TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED);
2162 for (tree_next = -1, sym_index = 0;
2163 sym_index < r->m_table_sizes[r->m_type]; ++sym_index) {
2164 mz_uint rev_code = 0, l, cur_code,
2165 code_size = pTable->m_code_size[sym_index];
2168 cur_code = next_code[code_size]++;
2169 for (l = code_size; l > 0; l--, cur_code >>= 1)
2170 rev_code = (rev_code << 1) | (cur_code & 1);
2171 if (code_size <= TINFL_FAST_LOOKUP_BITS) {
2172 mz_int16 k = (mz_int16)((code_size << 9) | sym_index);
2173 while (rev_code < TINFL_FAST_LOOKUP_SIZE) {
2174 pTable->m_look_up[rev_code] = k;
2175 rev_code += (1 << code_size);
2180 (tree_cur = pTable->m_look_up[rev_code &
2181 (TINFL_FAST_LOOKUP_SIZE - 1)])) {
2182 pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] =
2183 (mz_int16)tree_next;
2184 tree_cur = tree_next;
2187 rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1);
2188 for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--) {
2189 tree_cur -= ((rev_code >>= 1) & 1);
2190 if (!pTable->m_tree[-tree_cur - 1]) {
2191 pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next;
2192 tree_cur = tree_next;
2195 tree_cur = pTable->m_tree[-tree_cur - 1];
2198 tree_cur -= (rev_code & 1);
2199 pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
2201 if (r->m_type == 2) {
2203 counter < (r->m_table_sizes[0] + r->m_table_sizes[1]);) {
2205 TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]);
2207 r->m_len_codes[counter++] = (mz_uint8)dist;
2210 if ((dist == 16) && (!counter)) {
2211 TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED);
2213 num_extra =
"\02\03\07"[dist - 16];
2214 TINFL_GET_BITS(18, s, num_extra);
2215 s +=
"\03\03\013"[dist - 16];
2216 TINFL_MEMSET(r->m_len_codes + counter,
2217 (dist == 16) ? r->m_len_codes[counter - 1] : 0, s);
2220 if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter) {
2221 TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED);
2223 TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes,
2224 r->m_table_sizes[0]);
2225 TINFL_MEMCPY(r->m_tables[1].m_code_size,
2226 r->m_len_codes + r->m_table_sizes[0],
2227 r->m_table_sizes[1]);
2233 if (((pIn_buf_end - pIn_buf_cur) < 4) ||
2234 ((pOut_buf_end - pOut_buf_cur) < 2)) {
2235 TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]);
2238 while (pOut_buf_cur >= pOut_buf_end) {
2239 TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT);
2241 *pOut_buf_cur++ = (mz_uint8)counter;
2245#if TINFL_USE_64BIT_BITBUF
2246 if (num_bits < 30) {
2248 (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits);
2253 if (num_bits < 15) {
2255 (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
2262 .m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >=
2264 code_len = sym2 >> 9;
2266 code_len = TINFL_FAST_LOOKUP_BITS;
2268 sym2 = r->m_tables[0]
2269 .m_tree[~sym2 + ((bit_buf >> code_len++) & 1)];
2273 bit_buf >>= code_len;
2274 num_bits -= code_len;
2278#if !TINFL_USE_64BIT_BITBUF
2279 if (num_bits < 15) {
2281 (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
2288 .m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >=
2290 code_len = sym2 >> 9;
2292 code_len = TINFL_FAST_LOOKUP_BITS;
2294 sym2 = r->m_tables[0]
2295 .m_tree[~sym2 + ((bit_buf >> code_len++) & 1)];
2298 bit_buf >>= code_len;
2299 num_bits -= code_len;
2301 pOut_buf_cur[0] = (mz_uint8)counter;
2307 pOut_buf_cur[1] = (mz_uint8)sym2;
2311 if ((counter &= 511) == 256)
2314 num_extra = s_length_extra[counter - 257];
2315 counter = s_length_base[counter - 257];
2318 TINFL_GET_BITS(25, extra_bits, num_extra);
2319 counter += extra_bits;
2322 TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]);
2323 num_extra = s_dist_extra[dist];
2324 dist = s_dist_base[dist];
2327 TINFL_GET_BITS(27, extra_bits, num_extra);
2331 dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
2332 if ((dist > dist_from_out_buf_start) &&
2333 (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) {
2334 TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED);
2337 pSrc = pOut_buf_start +
2338 ((dist_from_out_buf_start - dist) & out_buf_size_mask);
2340 if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end) {
2342 while (pOut_buf_cur >= pOut_buf_end) {
2343 TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT);
2346 pOut_buf_start[(dist_from_out_buf_start++ - dist) &
2351#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
2352 else if ((counter >= 9) && (counter <= dist)) {
2353 const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
2355 ((mz_uint32 *)pOut_buf_cur)[0] = ((
const mz_uint32 *)pSrc)[0];
2356 ((mz_uint32 *)pOut_buf_cur)[1] = ((
const mz_uint32 *)pSrc)[1];
2358 }
while ((pSrc += 8) < pSrc_end);
2359 if ((counter &= 7) < 3) {
2361 pOut_buf_cur[0] = pSrc[0];
2363 pOut_buf_cur[1] = pSrc[1];
2364 pOut_buf_cur += counter;
2371 pOut_buf_cur[0] = pSrc[0];
2372 pOut_buf_cur[1] = pSrc[1];
2373 pOut_buf_cur[2] = pSrc[2];
2376 }
while ((
int)(counter -= 3) > 2);
2377 if ((
int)counter > 0) {
2378 pOut_buf_cur[0] = pSrc[0];
2379 if ((
int)counter > 1)
2380 pOut_buf_cur[1] = pSrc[1];
2381 pOut_buf_cur += counter;
2385 }
while (!(r->m_final & 1));
2386 if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) {
2387 TINFL_SKIP_BITS(32, num_bits & 7);
2388 for (counter = 0; counter < 4; ++counter) {
2391 TINFL_GET_BITS(41, s, 8);
2393 TINFL_GET_BYTE(42, s);
2394 r->m_z_adler32 = (r->m_z_adler32 << 8) | s;
2397 TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE);
2401 r->m_num_bits = num_bits;
2402 r->m_bit_buf = bit_buf;
2404 r->m_counter = counter;
2405 r->m_num_extra = num_extra;
2406 r->m_dist_from_out_buf_start = dist_from_out_buf_start;
2407 *pIn_buf_size = pIn_buf_cur - pIn_buf_next;
2408 *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
2410 (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) &&
2412 const mz_uint8 *ptr = pOut_buf_next;
2413 size_t buf_len = *pOut_buf_size;
2414 mz_uint32 i, s1 = r->m_check_adler32 & 0xffff,
2415 s2 = r->m_check_adler32 >> 16;
2416 size_t block_len = buf_len % 5552;
2418 for (i = 0; i + 7 < block_len; i += 8, ptr += 8) {
2419 s1 += ptr[0], s2 += s1;
2420 s1 += ptr[1], s2 += s1;
2421 s1 += ptr[2], s2 += s1;
2422 s1 += ptr[3], s2 += s1;
2423 s1 += ptr[4], s2 += s1;
2424 s1 += ptr[5], s2 += s1;
2425 s1 += ptr[6], s2 += s1;
2426 s1 += ptr[7], s2 += s1;
2428 for (; i < block_len; ++i)
2429 s1 += *ptr++, s2 += s1;
2430 s1 %= 65521U, s2 %= 65521U;
2431 buf_len -= block_len;
2434 r->m_check_adler32 = (s2 << 16) + s1;
2435 if ((status == TINFL_STATUS_DONE) &&
2436 (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) &&
2437 (r->m_check_adler32 != r->m_z_adler32))
2438 status = TINFL_STATUS_ADLER32_MISMATCH;
2444void *tinfl_decompress_mem_to_heap(
const void *pSrc_buf,
size_t src_buf_len,
2445 size_t *pOut_len,
int flags) {
2447 void *pBuf = NULL, *pNew_buf;
2448 size_t src_buf_ofs = 0, out_buf_capacity = 0;
2450 tinfl_init(&decomp);
2452 size_t src_buf_size = src_buf_len - src_buf_ofs,
2453 dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity;
2454 tinfl_status status = tinfl_decompress(
2455 &decomp, (
const mz_uint8 *)pSrc_buf + src_buf_ofs, &src_buf_size,
2456 (mz_uint8 *)pBuf, pBuf ? (mz_uint8 *)pBuf + *pOut_len : NULL,
2458 (flags & ~TINFL_FLAG_HAS_MORE_INPUT) |
2459 TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
2460 if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT)) {
2465 src_buf_ofs += src_buf_size;
2466 *pOut_len += dst_buf_size;
2467 if (status == TINFL_STATUS_DONE)
2469 new_out_buf_capacity = out_buf_capacity * 2;
2470 if (new_out_buf_capacity < 128)
2471 new_out_buf_capacity = 128;
2472 pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity);
2479 out_buf_capacity = new_out_buf_capacity;
2484size_t tinfl_decompress_mem_to_mem(
void *pOut_buf,
size_t out_buf_len,
2485 const void *pSrc_buf,
size_t src_buf_len,
2488 tinfl_status status;
2489 tinfl_init(&decomp);
2491 tinfl_decompress(&decomp, (
const mz_uint8 *)pSrc_buf, &src_buf_len,
2492 (mz_uint8 *)pOut_buf, (mz_uint8 *)pOut_buf, &out_buf_len,
2493 (flags & ~TINFL_FLAG_HAS_MORE_INPUT) |
2494 TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
2495 return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED
2499int tinfl_decompress_mem_to_callback(
const void *pIn_buf,
size_t *pIn_buf_size,
2500 tinfl_put_buf_func_ptr pPut_buf_func,
2501 void *pPut_buf_user,
int flags) {
2504 mz_uint8 *pDict = (mz_uint8 *)MZ_MALLOC(TINFL_LZ_DICT_SIZE);
2505 size_t in_buf_ofs = 0, dict_ofs = 0;
2507 return TINFL_STATUS_FAILED;
2508 tinfl_init(&decomp);
2510 size_t in_buf_size = *pIn_buf_size - in_buf_ofs,
2511 dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs;
2512 tinfl_status status =
2513 tinfl_decompress(&decomp, (
const mz_uint8 *)pIn_buf + in_buf_ofs,
2514 &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size,
2515 (flags & ~(TINFL_FLAG_HAS_MORE_INPUT |
2516 TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)));
2517 in_buf_ofs += in_buf_size;
2518 if ((dst_buf_size) &&
2519 (!(*pPut_buf_func)(pDict + dict_ofs, (
int)dst_buf_size, pPut_buf_user)))
2521 if (status != TINFL_STATUS_HAS_MORE_OUTPUT) {
2522 result = (status == TINFL_STATUS_DONE);
2525 dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1);
2528 *pIn_buf_size = in_buf_ofs;
2536static const mz_uint16 s_tdefl_len_sym[256] = {
2537 257, 258, 259, 260, 261, 262, 263, 264, 265, 265, 266, 266, 267, 267, 268,
2538 268, 269, 269, 269, 269, 270, 270, 270, 270, 271, 271, 271, 271, 272, 272,
2539 272, 272, 273, 273, 273, 273, 273, 273, 273, 273, 274, 274, 274, 274, 274,
2540 274, 274, 274, 275, 275, 275, 275, 275, 275, 275, 275, 276, 276, 276, 276,
2541 276, 276, 276, 276, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
2542 277, 277, 277, 277, 277, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
2543 278, 278, 278, 278, 278, 278, 279, 279, 279, 279, 279, 279, 279, 279, 279,
2544 279, 279, 279, 279, 279, 279, 279, 280, 280, 280, 280, 280, 280, 280, 280,
2545 280, 280, 280, 280, 280, 280, 280, 280, 281, 281, 281, 281, 281, 281, 281,
2546 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281,
2547 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 282, 282, 282, 282, 282,
2548 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282,
2549 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 283, 283, 283,
2550 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283,
2551 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 284,
2552 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
2553 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
2556static const mz_uint8 s_tdefl_len_extra[256] = {
2557 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
2558 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2559 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
2560 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2561 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
2562 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2563 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2564 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2565 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2566 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
2567 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0};
2569static const mz_uint8 s_tdefl_small_dist_sym[512] = {
2570 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8,
2571 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10,
2572 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11,
2573 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
2574 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
2575 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
2576 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14,
2577 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
2578 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
2579 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
2580 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
2581 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
2582 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
2583 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2584 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2585 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2586 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2587 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2588 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2589 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2590 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
2591 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
2592 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
2593 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
2594 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
2595 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
2596 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17};
2598static const mz_uint8 s_tdefl_small_dist_extra[512] = {
2599 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,
2600 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,
2601 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,
2602 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,
2603 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,
2604 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,
2605 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,
2606 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,
2607 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,
2608 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,
2609 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,
2610 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,
2611 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,
2612 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,
2613 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,
2614 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,
2615 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,
2616 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,
2617 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,
2618 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,
2619 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
2621static const mz_uint8 s_tdefl_large_dist_sym[128] = {
2622 0, 0, 18, 19, 20, 20, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24,
2623 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26,
2624 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27,
2625 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
2626 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
2627 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
2628 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29};
2630static const mz_uint8 s_tdefl_large_dist_extra[128] = {
2631 0, 0, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11,
2632 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12,
2633 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
2634 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
2635 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
2636 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
2637 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13};
2642 mz_uint16 m_key, m_sym_index;
2647 mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2];
2650 for (i = 0; i < num_syms; i++) {
2651 mz_uint freq = pSyms0[i].m_key;
2652 hist[freq & 0xFF]++;
2653 hist[256 + ((freq >> 8) & 0xFF)]++;
2655 while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256]))
2657 for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8) {
2658 const mz_uint32 *pHist = &hist[pass << 8];
2659 mz_uint offsets[256], cur_ofs = 0;
2660 for (i = 0; i < 256; i++) {
2661 offsets[i] = cur_ofs;
2662 cur_ofs += pHist[i];
2664 for (i = 0; i < num_syms; i++)
2665 pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] =
2669 pCur_syms = pNew_syms;
2678static void tdefl_calculate_minimum_redundancy(
tdefl_sym_freq *A,
int n) {
2679 int root, leaf, next, avbl, used, dpth;
2686 A[0].m_key += A[1].m_key;
2689 for (next = 1; next < n - 1; next++) {
2690 if (leaf >= n || A[root].m_key < A[leaf].m_key) {
2691 A[next].m_key = A[root].m_key;
2692 A[root++].m_key = (mz_uint16)next;
2694 A[next].m_key = A[leaf++].m_key;
2695 if (leaf >= n || (root < next && A[root].m_key < A[leaf].m_key)) {
2696 A[next].m_key = (mz_uint16)(A[next].m_key + A[root].m_key);
2697 A[root++].m_key = (mz_uint16)next;
2699 A[next].m_key = (mz_uint16)(A[next].m_key + A[leaf++].m_key);
2702 for (next = n - 3; next >= 0; next--)
2703 A[next].m_key = A[A[next].m_key].m_key + 1;
2709 while (root >= 0 && (
int)A[root].m_key == dpth) {
2713 while (avbl > used) {
2714 A[next--].m_key = (mz_uint16)(dpth);
2724enum { TDEFL_MAX_SUPPORTED_HUFF_CODESIZE = 32 };
2725static void tdefl_huffman_enforce_max_code_size(
int *pNum_codes,
2727 int max_code_size) {
2729 mz_uint32 total = 0;
2730 if (code_list_len <= 1)
2732 for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++)
2733 pNum_codes[max_code_size] += pNum_codes[i];
2734 for (i = max_code_size; i > 0; i--)
2735 total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i));
2736 while (total != (1UL << max_code_size)) {
2737 pNum_codes[max_code_size]--;
2738 for (i = max_code_size - 1; i > 0; i--)
2739 if (pNum_codes[i]) {
2741 pNum_codes[i + 1] += 2;
2748static void tdefl_optimize_huffman_table(
tdefl_compressor *d,
int table_num,
2749 int table_len,
int code_size_limit,
2751 int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE];
2752 mz_uint next_code[TDEFL_MAX_SUPPORTED_HUFF_CODESIZE + 1];
2753 MZ_CLEAR_OBJ(num_codes);
2755 for (i = 0; i < table_len; i++)
2756 num_codes[d->m_huff_code_sizes[table_num][i]]++;
2758 tdefl_sym_freq syms0[TDEFL_MAX_HUFF_SYMBOLS], syms1[TDEFL_MAX_HUFF_SYMBOLS],
2760 int num_used_syms = 0;
2761 const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0];
2762 for (i = 0; i < table_len; i++)
2763 if (pSym_count[i]) {
2764 syms0[num_used_syms].m_key = (mz_uint16)pSym_count[i];
2765 syms0[num_used_syms++].m_sym_index = (mz_uint16)i;
2768 pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1);
2769 tdefl_calculate_minimum_redundancy(pSyms, num_used_syms);
2771 for (i = 0; i < num_used_syms; i++)
2772 num_codes[pSyms[i].m_key]++;
2774 tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms,
2777 MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]);
2778 MZ_CLEAR_OBJ(d->m_huff_codes[table_num]);
2779 for (i = 1, j = num_used_syms; i <= code_size_limit; i++)
2780 for (l = num_codes[i]; l > 0; l--)
2781 d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i);
2785 for (j = 0, i = 2; i <= code_size_limit; i++)
2786 next_code[i] = j = ((j + num_codes[i - 1]) << 1);
2788 for (i = 0; i < table_len; i++) {
2789 mz_uint rev_code = 0, code, code_size;
2790 if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0)
2792 code = next_code[code_size]++;
2793 for (l = code_size; l > 0; l--, code >>= 1)
2794 rev_code = (rev_code << 1) | (code & 1);
2795 d->m_huff_codes[table_num][i] = (mz_uint16)rev_code;
2799#define TDEFL_PUT_BITS(b, l) \
2803 MZ_ASSERT(bits <= ((1U << len) - 1U)); \
2804 d->m_bit_buffer |= (bits << d->m_bits_in); \
2805 d->m_bits_in += len; \
2806 while (d->m_bits_in >= 8) { \
2807 if (d->m_pOutput_buf < d->m_pOutput_buf_end) \
2808 *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \
2809 d->m_bit_buffer >>= 8; \
2810 d->m_bits_in -= 8; \
2815#define TDEFL_RLE_PREV_CODE_SIZE() \
2817 if (rle_repeat_count) { \
2818 if (rle_repeat_count < 3) { \
2819 d->m_huff_count[2][prev_code_size] = (mz_uint16)( \
2820 d->m_huff_count[2][prev_code_size] + rle_repeat_count); \
2821 while (rle_repeat_count--) \
2822 packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \
2824 d->m_huff_count[2][16] = (mz_uint16)(d->m_huff_count[2][16] + 1); \
2825 packed_code_sizes[num_packed_code_sizes++] = 16; \
2826 packed_code_sizes[num_packed_code_sizes++] = \
2827 (mz_uint8)(rle_repeat_count - 3); \
2829 rle_repeat_count = 0; \
2833#define TDEFL_RLE_ZERO_CODE_SIZE() \
2835 if (rle_z_count) { \
2836 if (rle_z_count < 3) { \
2837 d->m_huff_count[2][0] = \
2838 (mz_uint16)(d->m_huff_count[2][0] + rle_z_count); \
2839 while (rle_z_count--) \
2840 packed_code_sizes[num_packed_code_sizes++] = 0; \
2841 } else if (rle_z_count <= 10) { \
2842 d->m_huff_count[2][17] = (mz_uint16)(d->m_huff_count[2][17] + 1); \
2843 packed_code_sizes[num_packed_code_sizes++] = 17; \
2844 packed_code_sizes[num_packed_code_sizes++] = \
2845 (mz_uint8)(rle_z_count - 3); \
2847 d->m_huff_count[2][18] = (mz_uint16)(d->m_huff_count[2][18] + 1); \
2848 packed_code_sizes[num_packed_code_sizes++] = 18; \
2849 packed_code_sizes[num_packed_code_sizes++] = \
2850 (mz_uint8)(rle_z_count - 11); \
2856static mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = {
2857 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
2860 int num_lit_codes, num_dist_codes, num_bit_lengths;
2861 mz_uint i, total_code_sizes_to_pack, num_packed_code_sizes, rle_z_count,
2862 rle_repeat_count, packed_code_sizes_index;
2864 code_sizes_to_pack[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1],
2865 packed_code_sizes[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1],
2866 prev_code_size = 0xFF;
2868 d->m_huff_count[0][256] = 1;
2870 tdefl_optimize_huffman_table(d, 0, TDEFL_MAX_HUFF_SYMBOLS_0, 15, MZ_FALSE);
2871 tdefl_optimize_huffman_table(d, 1, TDEFL_MAX_HUFF_SYMBOLS_1, 15, MZ_FALSE);
2873 for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--)
2874 if (d->m_huff_code_sizes[0][num_lit_codes - 1])
2876 for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--)
2877 if (d->m_huff_code_sizes[1][num_dist_codes - 1])
2880 memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0],
2881 sizeof(mz_uint8) * num_lit_codes);
2882 memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0],
2883 sizeof(mz_uint8) * num_dist_codes);
2884 total_code_sizes_to_pack = num_lit_codes + num_dist_codes;
2885 num_packed_code_sizes = 0;
2887 rle_repeat_count = 0;
2889 memset(&d->m_huff_count[2][0], 0,
2890 sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2);
2891 for (i = 0; i < total_code_sizes_to_pack; i++) {
2892 mz_uint8 code_size = code_sizes_to_pack[i];
2894 TDEFL_RLE_PREV_CODE_SIZE();
2895 if (++rle_z_count == 138) {
2896 TDEFL_RLE_ZERO_CODE_SIZE();
2899 TDEFL_RLE_ZERO_CODE_SIZE();
2900 if (code_size != prev_code_size) {
2901 TDEFL_RLE_PREV_CODE_SIZE();
2902 d->m_huff_count[2][code_size] =
2903 (mz_uint16)(d->m_huff_count[2][code_size] + 1);
2904 packed_code_sizes[num_packed_code_sizes++] = code_size;
2905 }
else if (++rle_repeat_count == 6) {
2906 TDEFL_RLE_PREV_CODE_SIZE();
2909 prev_code_size = code_size;
2911 if (rle_repeat_count) {
2912 TDEFL_RLE_PREV_CODE_SIZE();
2914 TDEFL_RLE_ZERO_CODE_SIZE();
2917 tdefl_optimize_huffman_table(d, 2, TDEFL_MAX_HUFF_SYMBOLS_2, 7, MZ_FALSE);
2919 TDEFL_PUT_BITS(2, 2);
2921 TDEFL_PUT_BITS(num_lit_codes - 257, 5);
2922 TDEFL_PUT_BITS(num_dist_codes - 1, 5);
2924 for (num_bit_lengths = 18; num_bit_lengths >= 0; num_bit_lengths--)
2925 if (d->m_huff_code_sizes
2926 [2][s_tdefl_packed_code_size_syms_swizzle[num_bit_lengths]])
2928 num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1));
2929 TDEFL_PUT_BITS(num_bit_lengths - 4, 4);
2930 for (i = 0; (int)i < num_bit_lengths; i++)
2932 d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[i]], 3);
2934 for (packed_code_sizes_index = 0;
2935 packed_code_sizes_index < num_packed_code_sizes;) {
2936 mz_uint code = packed_code_sizes[packed_code_sizes_index++];
2937 MZ_ASSERT(code < TDEFL_MAX_HUFF_SYMBOLS_2);
2938 TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]);
2940 TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++],
2941 "\02\03\07"[code - 16]);
2947 mz_uint8 *p = &d->m_huff_code_sizes[0][0];
2949 for (i = 0; i <= 143; ++i)
2951 for (; i <= 255; ++i)
2953 for (; i <= 279; ++i)
2955 for (; i <= 287; ++i)
2958 memset(d->m_huff_code_sizes[1], 5, 32);
2960 tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE);
2961 tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE);
2963 TDEFL_PUT_BITS(1, 2);
2966static const mz_uint mz_bitmasks[17] = {
2967 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF,
2968 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF};
2970#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && \
2971 MINIZ_HAS_64BIT_REGISTERS
2974 mz_uint8 *pLZ_codes;
2975 mz_uint8 *pOutput_buf = d->m_pOutput_buf;
2976 mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf;
2977 mz_uint64 bit_buffer = d->m_bit_buffer;
2978 mz_uint bits_in = d->m_bits_in;
2980#define TDEFL_PUT_BITS_FAST(b, l) \
2982 bit_buffer |= (((mz_uint64)(b)) << bits_in); \
2987 for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end;
2990 flags = *pLZ_codes++ | 0x100;
2993 mz_uint s0, s1, n0, n1, sym, num_extra_bits;
2994 mz_uint match_len = pLZ_codes[0],
2995 match_dist = *(
const mz_uint16 *)(pLZ_codes + 1);
2998 MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
2999 TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][s_tdefl_len_sym[match_len]],
3000 d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
3001 TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]],
3002 s_tdefl_len_extra[match_len]);
3005 s0 = s_tdefl_small_dist_sym[match_dist & 511];
3006 n0 = s_tdefl_small_dist_extra[match_dist & 511];
3007 s1 = s_tdefl_large_dist_sym[match_dist >> 8];
3008 n1 = s_tdefl_large_dist_extra[match_dist >> 8];
3009 sym = (match_dist < 512) ? s0 : s1;
3010 num_extra_bits = (match_dist < 512) ? n0 : n1;
3012 MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
3013 TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym],
3014 d->m_huff_code_sizes[1][sym]);
3015 TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits],
3018 mz_uint lit = *pLZ_codes++;
3019 MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
3020 TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit],
3021 d->m_huff_code_sizes[0][lit]);
3023 if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) {
3026 MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
3027 TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit],
3028 d->m_huff_code_sizes[0][lit]);
3030 if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) {
3033 MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
3034 TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit],
3035 d->m_huff_code_sizes[0][lit]);
3040 if (pOutput_buf >= d->m_pOutput_buf_end)
3043 *(mz_uint64 *)pOutput_buf = bit_buffer;
3044 pOutput_buf += (bits_in >> 3);
3045 bit_buffer >>= (bits_in & ~7);
3049#undef TDEFL_PUT_BITS_FAST
3051 d->m_pOutput_buf = pOutput_buf;
3053 d->m_bit_buffer = 0;
3056 mz_uint32 n = MZ_MIN(bits_in, 16);
3057 TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n);
3062 TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
3064 return (d->m_pOutput_buf < d->m_pOutput_buf_end);
3069 mz_uint8 *pLZ_codes;
3072 for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf;
3075 flags = *pLZ_codes++ | 0x100;
3077 mz_uint sym, num_extra_bits;
3078 mz_uint match_len = pLZ_codes[0],
3079 match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8));
3082 MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
3083 TDEFL_PUT_BITS(d->m_huff_codes[0][s_tdefl_len_sym[match_len]],
3084 d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
3085 TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]],
3086 s_tdefl_len_extra[match_len]);
3088 if (match_dist < 512) {
3089 sym = s_tdefl_small_dist_sym[match_dist];
3090 num_extra_bits = s_tdefl_small_dist_extra[match_dist];
3092 sym = s_tdefl_large_dist_sym[match_dist >> 8];
3093 num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8];
3095 TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
3096 TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
3098 mz_uint lit = *pLZ_codes++;
3099 MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
3100 TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
3104 TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
3106 return (d->m_pOutput_buf < d->m_pOutput_buf_end);
3111static mz_bool tdefl_compress_block(
tdefl_compressor *d, mz_bool static_block) {
3113 tdefl_start_static_block(d);
3115 tdefl_start_dynamic_block(d);
3116 return tdefl_compress_lz_codes(d);
3120 mz_uint saved_bit_buf, saved_bits_in;
3121 mz_uint8 *pSaved_output_buf;
3122 mz_bool comp_block_succeeded = MZ_FALSE;
3123 int n, use_raw_block =
3124 ((d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS) != 0) &&
3125 (d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size;
3126 mz_uint8 *pOutput_buf_start =
3127 ((d->m_pPut_buf_func == NULL) &&
3128 ((*d->m_pOut_buf_size - d->m_out_buf_ofs) >= TDEFL_OUT_BUF_SIZE))
3129 ? ((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs)
3132 d->m_pOutput_buf = pOutput_buf_start;
3133 d->m_pOutput_buf_end = d->m_pOutput_buf + TDEFL_OUT_BUF_SIZE - 16;
3135 MZ_ASSERT(!d->m_output_flush_remaining);
3136 d->m_output_flush_ofs = 0;
3137 d->m_output_flush_remaining = 0;
3139 *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left);
3140 d->m_pLZ_code_buf -= (d->m_num_flags_left == 8);
3142 if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index)) {
3143 TDEFL_PUT_BITS(0x78, 8);
3144 TDEFL_PUT_BITS(0x01, 8);
3147 TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1);
3149 pSaved_output_buf = d->m_pOutput_buf;
3150 saved_bit_buf = d->m_bit_buffer;
3151 saved_bits_in = d->m_bits_in;
3154 comp_block_succeeded =
3155 tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) ||
3156 (d->m_total_lz_bytes < 48));
3160 if (((use_raw_block) ||
3161 ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >=
3162 d->m_total_lz_bytes))) &&
3163 ((d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size)) {
3165 d->m_pOutput_buf = pSaved_output_buf;
3166 d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
3167 TDEFL_PUT_BITS(0, 2);
3169 TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
3171 for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF) {
3172 TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16);
3174 for (i = 0; i < d->m_total_lz_bytes; ++i) {
3176 d->m_dict[(d->m_lz_code_buf_dict_pos + i) & TDEFL_LZ_DICT_SIZE_MASK],
3182 else if (!comp_block_succeeded) {
3183 d->m_pOutput_buf = pSaved_output_buf;
3184 d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
3185 tdefl_compress_block(d, MZ_TRUE);
3189 if (flush == TDEFL_FINISH) {
3191 TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
3193 if (d->m_flags & TDEFL_WRITE_ZLIB_HEADER) {
3194 mz_uint i, a = d->m_adler32;
3195 for (i = 0; i < 4; i++) {
3196 TDEFL_PUT_BITS((a >> 24) & 0xFF, 8);
3202 TDEFL_PUT_BITS(0, 3);
3204 TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
3206 for (i = 2; i; --i, z ^= 0xFFFF) {
3207 TDEFL_PUT_BITS(z & 0xFFFF, 16);
3212 MZ_ASSERT(d->m_pOutput_buf < d->m_pOutput_buf_end);
3214 memset(&d->m_huff_count[0][0], 0,
3215 sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
3216 memset(&d->m_huff_count[1][0], 0,
3217 sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
3219 d->m_pLZ_code_buf = d->m_lz_code_buf + 1;
3220 d->m_pLZ_flags = d->m_lz_code_buf;
3221 d->m_num_flags_left = 8;
3222 d->m_lz_code_buf_dict_pos += d->m_total_lz_bytes;
3223 d->m_total_lz_bytes = 0;
3226 if ((n = (
int)(d->m_pOutput_buf - pOutput_buf_start)) != 0) {
3227 if (d->m_pPut_buf_func) {
3228 *d->m_pIn_buf_size = d->m_pSrc - (
const mz_uint8 *)d->m_pIn_buf;
3229 if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user))
3230 return (d->m_prev_return_status = TDEFL_STATUS_PUT_BUF_FAILED);
3231 }
else if (pOutput_buf_start == d->m_output_buf) {
3232 int bytes_to_copy = (int)MZ_MIN(
3233 (
size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs));
3234 memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf,
3236 d->m_out_buf_ofs += bytes_to_copy;
3237 if ((n -= bytes_to_copy) != 0) {
3238 d->m_output_flush_ofs = bytes_to_copy;
3239 d->m_output_flush_remaining = n;
3242 d->m_out_buf_ofs += n;
3246 return d->m_output_flush_remaining;
3249#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
3250#define TDEFL_READ_UNALIGNED_WORD(p) ((p)[0] | (p)[1] << 8)
3251static MZ_FORCEINLINE
void
3252tdefl_find_match(
tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist,
3253 mz_uint max_match_len, mz_uint *pMatch_dist,
3254 mz_uint *pMatch_len) {
3255 mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK,
3256 match_len = *pMatch_len, probe_pos = pos, next_probe_pos,
3258 mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
3259 const mz_uint16 *s = (
const mz_uint16 *)(d->m_dict + pos), *p, *q;
3260 mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]),
3262 MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN);
3263 if (max_match_len <= match_len)
3267 if (--num_probes_left == 0)
3269#define TDEFL_PROBE \
3270 next_probe_pos = d->m_next[probe_pos]; \
3271 if ((!next_probe_pos) || \
3272 ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \
3274 probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
3275 if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) \
3283 q = (
const mz_uint16 *)(d->m_dict + probe_pos);
3289 }
while ((*(++p) == *(++q)) && (*(++p) == *(++q)) && (*(++p) == *(++q)) &&
3290 (*(++p) == *(++q)) && (--probe_len > 0));
3292 *pMatch_dist = dist;
3293 *pMatch_len = MZ_MIN(max_match_len, TDEFL_MAX_MATCH_LEN);
3295 }
else if ((probe_len = ((mz_uint)(p - s) * 2) +
3296 (mz_uint)(*(
const mz_uint8 *)p ==
3297 *(
const mz_uint8 *)q)) > match_len) {
3298 *pMatch_dist = dist;
3299 if ((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) ==
3302 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]);
3307static MZ_FORCEINLINE
void
3308tdefl_find_match(
tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist,
3309 mz_uint max_match_len, mz_uint *pMatch_dist,
3310 mz_uint *pMatch_len) {
3311 mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK,
3312 match_len = *pMatch_len, probe_pos = pos, next_probe_pos,
3314 mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
3315 const mz_uint8 *s = d->m_dict + pos, *p, *q;
3316 mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1];
3317 MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN);
3318 if (max_match_len <= match_len)
3322 if (--num_probes_left == 0)
3324#define TDEFL_PROBE \
3325 next_probe_pos = d->m_next[probe_pos]; \
3326 if ((!next_probe_pos) || \
3327 ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \
3329 probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
3330 if ((d->m_dict[probe_pos + match_len] == c0) && \
3331 (d->m_dict[probe_pos + match_len - 1] == c1)) \
3340 q = d->m_dict + probe_pos;
3341 for (probe_len = 0; probe_len < max_match_len; probe_len++)
3344 if (probe_len > match_len) {
3345 *pMatch_dist = dist;
3346 if ((*pMatch_len = match_len = probe_len) == max_match_len)
3348 c0 = d->m_dict[pos + match_len];
3349 c1 = d->m_dict[pos + match_len - 1];
3355#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
3360 mz_uint lookahead_pos = d->m_lookahead_pos,
3361 lookahead_size = d->m_lookahead_size, dict_size = d->m_dict_size,
3362 total_lz_bytes = d->m_total_lz_bytes,
3363 num_flags_left = d->m_num_flags_left;
3364 mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags;
3365 mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
3367 while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size))) {
3368 const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096;
3370 (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK;
3371 mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(
3372 d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size);
3373 d->m_src_buf_left -= num_bytes_to_process;
3374 lookahead_size += num_bytes_to_process;
3376 while (num_bytes_to_process) {
3377 mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process);
3378 memcpy(d->m_dict + dst_pos, d->m_pSrc, n);
3379 if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
3380 memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc,
3381 MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos));
3383 dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK;
3384 num_bytes_to_process -= n;
3387 dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size);
3388 if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE))
3391 while (lookahead_size >= 4) {
3392 mz_uint cur_match_dist, cur_match_len = 1;
3393 mz_uint8 *pCur_dict = d->m_dict + cur_pos;
3394 mz_uint first_trigram = (*(
const mz_uint32 *)pCur_dict) & 0xFFFFFF;
3396 (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) &
3397 TDEFL_LEVEL1_HASH_SIZE_MASK;
3398 mz_uint probe_pos = d->m_hash[hash];
3399 d->m_hash[hash] = (mz_uint16)lookahead_pos;
3401 if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <=
3404 *(d->m_dict + (probe_pos & TDEFL_LZ_DICT_SIZE_MASK)) |
3405 (*(d->m_dict + ((probe_pos & TDEFL_LZ_DICT_SIZE_MASK) + 1))
3407 (*(d->m_dict + ((probe_pos & TDEFL_LZ_DICT_SIZE_MASK) + 2))
3408 << 16)) == first_trigram)) {
3409 const mz_uint16 *p = (
const mz_uint16 *)pCur_dict;
3410 const mz_uint16 *q =
3411 (
const mz_uint16 *)(d->m_dict +
3412 (probe_pos & TDEFL_LZ_DICT_SIZE_MASK));
3413 mz_uint32 probe_len = 32;
3415 }
while ((*(++p) == *(++q)) && (*(++p) == *(++q)) &&
3416 (*(++p) == *(++q)) && (*(++p) == *(++q)) && (--probe_len > 0));
3417 cur_match_len = ((mz_uint)(p - (
const mz_uint16 *)pCur_dict) * 2) +
3418 (mz_uint)(*(
const mz_uint8 *)p == *(
const mz_uint8 *)q);
3420 cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0;
3422 if ((cur_match_len < TDEFL_MIN_MATCH_LEN) ||
3423 ((cur_match_len == TDEFL_MIN_MATCH_LEN) &&
3424 (cur_match_dist >= 8U * 1024U))) {
3426 *pLZ_code_buf++ = (mz_uint8)first_trigram;
3427 *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
3428 d->m_huff_count[0][(mz_uint8)first_trigram]++;
3431 cur_match_len = MZ_MIN(cur_match_len, lookahead_size);
3433 MZ_ASSERT((cur_match_len >= TDEFL_MIN_MATCH_LEN) &&
3434 (cur_match_dist >= 1) &&
3435 (cur_match_dist <= TDEFL_LZ_DICT_SIZE));
3439 pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN);
3440 *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist;
3442 *pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80);
3444 s0 = s_tdefl_small_dist_sym[cur_match_dist & 511];
3445 s1 = s_tdefl_large_dist_sym[cur_match_dist >> 8];
3446 d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++;
3448 d->m_huff_count[0][s_tdefl_len_sym[cur_match_len -
3449 TDEFL_MIN_MATCH_LEN]]++;
3452 *pLZ_code_buf++ = (mz_uint8)first_trigram;
3453 *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
3454 d->m_huff_count[0][(mz_uint8)first_trigram]++;
3457 if (--num_flags_left == 0) {
3459 pLZ_flags = pLZ_code_buf++;
3462 total_lz_bytes += cur_match_len;
3463 lookahead_pos += cur_match_len;
3464 dict_size = MZ_MIN(dict_size + cur_match_len, TDEFL_LZ_DICT_SIZE);
3465 cur_pos = (cur_pos + cur_match_len) & TDEFL_LZ_DICT_SIZE_MASK;
3466 MZ_ASSERT(lookahead_size >= cur_match_len);
3467 lookahead_size -= cur_match_len;
3469 if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) {
3471 d->m_lookahead_pos = lookahead_pos;
3472 d->m_lookahead_size = lookahead_size;
3473 d->m_dict_size = dict_size;
3474 d->m_total_lz_bytes = total_lz_bytes;
3475 d->m_pLZ_code_buf = pLZ_code_buf;
3476 d->m_pLZ_flags = pLZ_flags;
3477 d->m_num_flags_left = num_flags_left;
3478 if ((n = tdefl_flush_block(d, 0)) != 0)
3479 return (n < 0) ? MZ_FALSE : MZ_TRUE;
3480 total_lz_bytes = d->m_total_lz_bytes;
3481 pLZ_code_buf = d->m_pLZ_code_buf;
3482 pLZ_flags = d->m_pLZ_flags;
3483 num_flags_left = d->m_num_flags_left;
3487 while (lookahead_size) {
3488 mz_uint8 lit = d->m_dict[cur_pos];
3491 *pLZ_code_buf++ = lit;
3492 *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
3493 if (--num_flags_left == 0) {
3495 pLZ_flags = pLZ_code_buf++;
3498 d->m_huff_count[0][lit]++;
3501 dict_size = MZ_MIN(dict_size + 1, TDEFL_LZ_DICT_SIZE);
3502 cur_pos = (cur_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK;
3505 if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) {
3507 d->m_lookahead_pos = lookahead_pos;
3508 d->m_lookahead_size = lookahead_size;
3509 d->m_dict_size = dict_size;
3510 d->m_total_lz_bytes = total_lz_bytes;
3511 d->m_pLZ_code_buf = pLZ_code_buf;
3512 d->m_pLZ_flags = pLZ_flags;
3513 d->m_num_flags_left = num_flags_left;
3514 if ((n = tdefl_flush_block(d, 0)) != 0)
3515 return (n < 0) ? MZ_FALSE : MZ_TRUE;
3516 total_lz_bytes = d->m_total_lz_bytes;
3517 pLZ_code_buf = d->m_pLZ_code_buf;
3518 pLZ_flags = d->m_pLZ_flags;
3519 num_flags_left = d->m_num_flags_left;
3524 d->m_lookahead_pos = lookahead_pos;
3525 d->m_lookahead_size = lookahead_size;
3526 d->m_dict_size = dict_size;
3527 d->m_total_lz_bytes = total_lz_bytes;
3528 d->m_pLZ_code_buf = pLZ_code_buf;
3529 d->m_pLZ_flags = pLZ_flags;
3530 d->m_num_flags_left = num_flags_left;
3537 d->m_total_lz_bytes++;
3538 *d->m_pLZ_code_buf++ = lit;
3539 *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1);
3540 if (--d->m_num_flags_left == 0) {
3541 d->m_num_flags_left = 8;
3542 d->m_pLZ_flags = d->m_pLZ_code_buf++;
3544 d->m_huff_count[0][lit]++;
3547static MZ_FORCEINLINE
void
3548tdefl_record_match(
tdefl_compressor *d, mz_uint match_len, mz_uint match_dist) {
3551 MZ_ASSERT((match_len >= TDEFL_MIN_MATCH_LEN) && (match_dist >= 1) &&
3552 (match_dist <= TDEFL_LZ_DICT_SIZE));
3554 d->m_total_lz_bytes += match_len;
3556 d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN);
3559 d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF);
3560 d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8);
3561 d->m_pLZ_code_buf += 3;
3563 *d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80);
3564 if (--d->m_num_flags_left == 0) {
3565 d->m_num_flags_left = 8;
3566 d->m_pLZ_flags = d->m_pLZ_code_buf++;
3569 s0 = s_tdefl_small_dist_sym[match_dist & 511];
3570 s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127];
3571 d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++;
3573 if (match_len >= TDEFL_MIN_MATCH_LEN)
3574 d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++;
3578 const mz_uint8 *pSrc = d->m_pSrc;
3579 size_t src_buf_left = d->m_src_buf_left;
3580 tdefl_flush flush = d->m_flush;
3582 while ((src_buf_left) || ((flush) && (d->m_lookahead_size))) {
3583 mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos;
3586 if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1)) {
3587 mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) &
3588 TDEFL_LZ_DICT_SIZE_MASK,
3589 ins_pos = d->m_lookahead_pos + d->m_lookahead_size - 2;
3590 mz_uint hash = (d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK]
3591 << TDEFL_LZ_HASH_SHIFT) ^
3592 d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK];
3593 mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(
3594 src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size);
3595 const mz_uint8 *pSrc_end = pSrc + num_bytes_to_process;
3596 src_buf_left -= num_bytes_to_process;
3597 d->m_lookahead_size += num_bytes_to_process;
3598 while (pSrc != pSrc_end) {
3599 mz_uint8 c = *pSrc++;
3600 d->m_dict[dst_pos] = c;
3601 if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
3602 d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
3603 hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1);
3604 d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash];
3605 d->m_hash[hash] = (mz_uint16)(ins_pos);
3606 dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK;
3610 while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) {
3611 mz_uint8 c = *pSrc++;
3612 mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) &
3613 TDEFL_LZ_DICT_SIZE_MASK;
3615 d->m_dict[dst_pos] = c;
3616 if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
3617 d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
3618 if ((++d->m_lookahead_size + d->m_dict_size) >= TDEFL_MIN_MATCH_LEN) {
3619 mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2;
3620 mz_uint hash = ((d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK]
3621 << (TDEFL_LZ_HASH_SHIFT * 2)) ^
3622 (d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK]
3623 << TDEFL_LZ_HASH_SHIFT) ^
3625 (TDEFL_LZ_HASH_SIZE - 1);
3626 d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash];
3627 d->m_hash[hash] = (mz_uint16)(ins_pos);
3632 MZ_MIN(TDEFL_LZ_DICT_SIZE - d->m_lookahead_size, d->m_dict_size);
3633 if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN))
3640 d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1);
3641 cur_pos = d->m_lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
3642 if (d->m_flags & (TDEFL_RLE_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS)) {
3643 if ((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))) {
3644 mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK];
3646 while (cur_match_len < d->m_lookahead_size) {
3647 if (d->m_dict[cur_pos + cur_match_len] != c)
3651 if (cur_match_len < TDEFL_MIN_MATCH_LEN)
3657 tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size,
3658 d->m_lookahead_size, &cur_match_dist, &cur_match_len);
3660 if (((cur_match_len == TDEFL_MIN_MATCH_LEN) &&
3661 (cur_match_dist >= 8U * 1024U)) ||
3662 (cur_pos == cur_match_dist) ||
3663 ((d->m_flags & TDEFL_FILTER_MATCHES) && (cur_match_len <= 5))) {
3664 cur_match_dist = cur_match_len = 0;
3666 if (d->m_saved_match_len) {
3667 if (cur_match_len > d->m_saved_match_len) {
3668 tdefl_record_literal(d, (mz_uint8)d->m_saved_lit);
3669 if (cur_match_len >= 128) {
3670 tdefl_record_match(d, cur_match_len, cur_match_dist);
3671 d->m_saved_match_len = 0;
3672 len_to_move = cur_match_len;
3674 d->m_saved_lit = d->m_dict[cur_pos];
3675 d->m_saved_match_dist = cur_match_dist;
3676 d->m_saved_match_len = cur_match_len;
3679 tdefl_record_match(d, d->m_saved_match_len, d->m_saved_match_dist);
3680 len_to_move = d->m_saved_match_len - 1;
3681 d->m_saved_match_len = 0;
3683 }
else if (!cur_match_dist)
3684 tdefl_record_literal(d,
3685 d->m_dict[MZ_MIN(cur_pos,
sizeof(d->m_dict) - 1)]);
3686 else if ((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) ||
3687 (cur_match_len >= 128)) {
3688 tdefl_record_match(d, cur_match_len, cur_match_dist);
3689 len_to_move = cur_match_len;
3691 d->m_saved_lit = d->m_dict[MZ_MIN(cur_pos,
sizeof(d->m_dict) - 1)];
3692 d->m_saved_match_dist = cur_match_dist;
3693 d->m_saved_match_len = cur_match_len;
3696 d->m_lookahead_pos += len_to_move;
3697 MZ_ASSERT(d->m_lookahead_size >= len_to_move);
3698 d->m_lookahead_size -= len_to_move;
3699 d->m_dict_size = MZ_MIN(d->m_dict_size + len_to_move, TDEFL_LZ_DICT_SIZE);
3702 if ((d->m_pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) ||
3703 ((d->m_total_lz_bytes > 31 * 1024) &&
3704 (((((mz_uint)(d->m_pLZ_code_buf - d->m_lz_code_buf) * 115) >> 7) >=
3705 d->m_total_lz_bytes) ||
3706 (d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS)))) {
3709 d->m_src_buf_left = src_buf_left;
3710 if ((n = tdefl_flush_block(d, 0)) != 0)
3711 return (n < 0) ? MZ_FALSE : MZ_TRUE;
3716 d->m_src_buf_left = src_buf_left;
3721 if (d->m_pIn_buf_size) {
3722 *d->m_pIn_buf_size = d->m_pSrc - (
const mz_uint8 *)d->m_pIn_buf;
3725 if (d->m_pOut_buf_size) {
3726 size_t n = MZ_MIN(*d->m_pOut_buf_size - d->m_out_buf_ofs,
3727 d->m_output_flush_remaining);
3728 memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs,
3729 d->m_output_buf + d->m_output_flush_ofs, n);
3730 d->m_output_flush_ofs += (mz_uint)n;
3731 d->m_output_flush_remaining -= (mz_uint)n;
3732 d->m_out_buf_ofs += n;
3734 *d->m_pOut_buf_size = d->m_out_buf_ofs;
3737 return (d->m_finished && !d->m_output_flush_remaining) ? TDEFL_STATUS_DONE
3738 : TDEFL_STATUS_OKAY;
3742 size_t *pIn_buf_size,
void *pOut_buf,
3743 size_t *pOut_buf_size, tdefl_flush flush) {
3749 return TDEFL_STATUS_BAD_PARAM;
3752 d->m_pIn_buf = pIn_buf;
3753 d->m_pIn_buf_size = pIn_buf_size;
3754 d->m_pOut_buf = pOut_buf;
3755 d->m_pOut_buf_size = pOut_buf_size;
3756 d->m_pSrc = (
const mz_uint8 *)(pIn_buf);
3757 d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0;
3758 d->m_out_buf_ofs = 0;
3761 if (((d->m_pPut_buf_func != NULL) ==
3762 ((pOut_buf != NULL) || (pOut_buf_size != NULL))) ||
3763 (d->m_prev_return_status != TDEFL_STATUS_OKAY) ||
3764 (d->m_wants_to_finish && (flush != TDEFL_FINISH)) ||
3765 (pIn_buf_size && *pIn_buf_size && !pIn_buf) ||
3766 (pOut_buf_size && *pOut_buf_size && !pOut_buf)) {
3771 return (d->m_prev_return_status = TDEFL_STATUS_BAD_PARAM);
3773 d->m_wants_to_finish |= (flush == TDEFL_FINISH);
3775 if ((d->m_output_flush_remaining) || (d->m_finished))
3776 return (d->m_prev_return_status = tdefl_flush_output_buffer(d));
3778#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
3779 if (((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) &&
3780 ((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) &&
3781 ((d->m_flags & (TDEFL_FILTER_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS |
3782 TDEFL_RLE_MATCHES)) == 0)) {
3783 if (!tdefl_compress_fast(d))
3784 return d->m_prev_return_status;
3788 if (!tdefl_compress_normal(d))
3789 return d->m_prev_return_status;
3792 if ((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) &&
3795 (mz_uint32)mz_adler32(d->m_adler32, (
const mz_uint8 *)pIn_buf,
3796 d->m_pSrc - (
const mz_uint8 *)pIn_buf);
3798 if ((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) &&
3799 (!d->m_output_flush_remaining)) {
3800 if (tdefl_flush_block(d, flush) < 0)
3801 return d->m_prev_return_status;
3802 d->m_finished = (flush == TDEFL_FINISH);
3803 if (flush == TDEFL_FULL_FLUSH) {
3804 MZ_CLEAR_OBJ(d->m_hash);
3805 MZ_CLEAR_OBJ(d->m_next);
3810 return (d->m_prev_return_status = tdefl_flush_output_buffer(d));
3813tdefl_status tdefl_compress_buffer(
tdefl_compressor *d,
const void *pIn_buf,
3814 size_t in_buf_size, tdefl_flush flush) {
3815 MZ_ASSERT(d->m_pPut_buf_func);
3816 return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush);
3820 tdefl_put_buf_func_ptr pPut_buf_func,
3821 void *pPut_buf_user,
int flags) {
3822 d->m_pPut_buf_func = pPut_buf_func;
3823 d->m_pPut_buf_user = pPut_buf_user;
3824 d->m_flags = (mz_uint)(flags);
3825 d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3;
3826 d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0;
3827 d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3;
3828 if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG))
3829 MZ_CLEAR_OBJ(d->m_hash);
3830 d->m_lookahead_pos = d->m_lookahead_size = d->m_dict_size =
3831 d->m_total_lz_bytes = d->m_lz_code_buf_dict_pos = d->m_bits_in = 0;
3832 d->m_output_flush_ofs = d->m_output_flush_remaining = d->m_finished =
3833 d->m_block_index = d->m_bit_buffer = d->m_wants_to_finish = 0;
3834 d->m_pLZ_code_buf = d->m_lz_code_buf + 1;
3835 d->m_pLZ_flags = d->m_lz_code_buf;
3836 d->m_num_flags_left = 8;
3837 d->m_pOutput_buf = d->m_output_buf;
3838 d->m_pOutput_buf_end = d->m_output_buf;
3839 d->m_prev_return_status = TDEFL_STATUS_OKAY;
3840 d->m_saved_match_dist = d->m_saved_match_len = d->m_saved_lit = 0;
3842 d->m_pIn_buf = NULL;
3843 d->m_pOut_buf = NULL;
3844 d->m_pIn_buf_size = NULL;
3845 d->m_pOut_buf_size = NULL;
3846 d->m_flush = TDEFL_NO_FLUSH;
3848 d->m_src_buf_left = 0;
3849 d->m_out_buf_ofs = 0;
3850 memset(&d->m_huff_count[0][0], 0,
3851 sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
3852 memset(&d->m_huff_count[1][0], 0,
3853 sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
3854 return TDEFL_STATUS_OKAY;
3858 return d->m_prev_return_status;
3863mz_bool tdefl_compress_mem_to_output(
const void *pBuf,
size_t buf_len,
3864 tdefl_put_buf_func_ptr pPut_buf_func,
3865 void *pPut_buf_user,
int flags) {
3868 if (((buf_len) && (!pBuf)) || (!pPut_buf_func))
3873 succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags) ==
3876 succeeded && (tdefl_compress_buffer(pComp, pBuf, buf_len, TDEFL_FINISH) ==
3883 size_t m_size, m_capacity;
3885 mz_bool m_expandable;
3888static mz_bool tdefl_output_buffer_putter(
const void *pBuf,
int len,
3891 size_t new_size = p->m_size + len;
3892 if (new_size > p->m_capacity) {
3893 size_t new_capacity = p->m_capacity;
3895 if (!p->m_expandable)
3898 new_capacity = MZ_MAX(128U, new_capacity << 1U);
3899 }
while (new_size > new_capacity);
3900 pNew_buf = (mz_uint8 *)MZ_REALLOC(p->m_pBuf, new_capacity);
3903 p->m_pBuf = pNew_buf;
3904 p->m_capacity = new_capacity;
3906 memcpy((mz_uint8 *)p->m_pBuf + p->m_size, pBuf, len);
3907 p->m_size = new_size;
3911void *tdefl_compress_mem_to_heap(
const void *pSrc_buf,
size_t src_buf_len,
3912 size_t *pOut_len,
int flags) {
3914 MZ_CLEAR_OBJ(out_buf);
3919 out_buf.m_expandable = MZ_TRUE;
3920 if (!tdefl_compress_mem_to_output(
3921 pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags))
3923 *pOut_len = out_buf.m_size;
3924 return out_buf.m_pBuf;
3927size_t tdefl_compress_mem_to_mem(
void *pOut_buf,
size_t out_buf_len,
3928 const void *pSrc_buf,
size_t src_buf_len,
3931 MZ_CLEAR_OBJ(out_buf);
3934 out_buf.m_pBuf = (mz_uint8 *)pOut_buf;
3935 out_buf.m_capacity = out_buf_len;
3936 if (!tdefl_compress_mem_to_output(
3937 pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags))
3939 return out_buf.m_size;
3942#ifndef MINIZ_NO_ZLIB_APIS
3943static const mz_uint s_tdefl_num_probes[11] = {0, 1, 6, 32, 16, 32,
3944 128, 256, 512, 768, 1500};
3949mz_uint tdefl_create_comp_flags_from_zip_params(
int level,
int window_bits,
3951 mz_uint comp_flags =
3952 s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] |
3953 ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0);
3954 if (window_bits > 0)
3955 comp_flags |= TDEFL_WRITE_ZLIB_HEADER;
3958 comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS;
3959 else if (strategy == MZ_FILTERED)
3960 comp_flags |= TDEFL_FILTER_MATCHES;
3961 else if (strategy == MZ_HUFFMAN_ONLY)
3962 comp_flags &= ~TDEFL_MAX_PROBES_MASK;
3963 else if (strategy == MZ_FIXED)
3964 comp_flags |= TDEFL_FORCE_ALL_STATIC_BLOCKS;
3965 else if (strategy == MZ_RLE)
3966 comp_flags |= TDEFL_RLE_MATCHES;
3973#pragma warning(push)
3974#pragma warning(disable : 4204)
3984void *tdefl_write_image_to_png_file_in_memory_ex(
const void *pImage,
int w,
3985 int h,
int num_chans,
3987 mz_uint level, mz_bool flip) {
3990 static const mz_uint s_tdefl_png_num_probes[11] = {
3991 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500};
3995 int i, bpl = w * num_chans, y, z;
4000 MZ_CLEAR_OBJ(out_buf);
4001 out_buf.m_expandable = MZ_TRUE;
4002 out_buf.m_capacity = 57 + MZ_MAX(64, (1 + bpl) * h);
4003 if (NULL == (out_buf.m_pBuf = (mz_uint8 *)MZ_MALLOC(out_buf.m_capacity))) {
4008 for (z = 41; z; --z)
4009 tdefl_output_buffer_putter(&z, 1, &out_buf);
4011 tdefl_init(pComp, tdefl_output_buffer_putter, &out_buf,
4012 s_tdefl_png_num_probes[MZ_MIN(10, level)] |
4013 TDEFL_WRITE_ZLIB_HEADER);
4014 for (y = 0; y < h; ++y) {
4015 tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH);
4016 tdefl_compress_buffer(pComp,
4017 (mz_uint8 *)pImage + (flip ? (h - 1 - y) : y) * bpl,
4018 bpl, TDEFL_NO_FLUSH);
4020 if (tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) !=
4021 TDEFL_STATUS_DONE) {
4023 MZ_FREE(out_buf.m_pBuf);
4027 *pLen_out = out_buf.m_size - 41;
4029 static const mz_uint8 chans[] = {0x00, 0x00, 0x04, 0x02, 0x06};
4030 mz_uint8 pnghdr[41] = {0x89,
4063 (mz_uint8)(*pLen_out >> 24),
4064 (mz_uint8)(*pLen_out >> 16),
4065 (mz_uint8)(*pLen_out >> 8),
4066 (mz_uint8)*pLen_out,
4071 c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, pnghdr + 12, 17);
4072 for (i = 0; i < 4; ++i, c <<= 8)
4073 ((mz_uint8 *)(pnghdr + 29))[i] = (mz_uint8)(c >> 24);
4074 memcpy(out_buf.m_pBuf, pnghdr, 41);
4077 if (!tdefl_output_buffer_putter(
4078 "\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf)) {
4081 MZ_FREE(out_buf.m_pBuf);
4084 c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, out_buf.m_pBuf + 41 - 4,
4086 for (i = 0; i < 4; ++i, c <<= 8)
4087 (out_buf.m_pBuf + out_buf.m_size - 16)[i] = (mz_uint8)(c >> 24);
4091 return out_buf.m_pBuf;
4093void *tdefl_write_image_to_png_file_in_memory(
const void *pImage,
int w,
int h,
4094 int num_chans,
size_t *pLen_out) {
4098 return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans,
4099 pLen_out, 6, MZ_FALSE);
4108#ifndef MINIZ_NO_ARCHIVE_APIS
4110#ifdef MINIZ_NO_STDIO
4111#define MZ_FILE void *
4114#include <sys/stat.h>
4116#if defined(_MSC_VER) || defined(__MINGW32__)
4120static wchar_t *str2wstr(
const char *str) {
4121 int len = strlen(str) + 1;
4122 wchar_t *wstr =
static_cast<wchar_t*
>(malloc(len *
sizeof(
wchar_t)));
4123 MultiByteToWideChar(CP_UTF8, 0, str, len *
sizeof(
char), wstr, len);
4127static FILE *mz_fopen(
const char *pFilename,
const char *pMode) {
4128 wchar_t *wFilename = str2wstr(pFilename);
4129 wchar_t *wMode = str2wstr(pMode);
4130 FILE *pFile = _wfopen(wFilename, wMode);
4138static FILE *mz_freopen(
const char *pPath,
const char *pMode, FILE *pStream) {
4139 wchar_t *wPath = str2wstr(pPath);
4140 wchar_t *wMode = str2wstr(pMode);
4141 FILE *pFile = _wfreopen(wPath, wMode, pStream);
4149#ifndef MINIZ_NO_TIME
4150#include <sys/utime.h>
4153#define MZ_FOPEN mz_fopen
4154#define MZ_FCLOSE fclose
4155#define MZ_FREAD fread
4156#define MZ_FWRITE fwrite
4157#define MZ_FTELL64 _ftelli64
4158#define MZ_FSEEK64 _fseeki64
4159#define MZ_FILE_STAT_STRUCT _stat
4160#define MZ_FILE_STAT _stat
4161#define MZ_FFLUSH fflush
4162#define MZ_FREOPEN mz_freopen
4163#define MZ_DELETE_FILE remove
4164#elif defined(__MINGW32__)
4165#ifndef MINIZ_NO_TIME
4166#include <sys/utime.h>
4169#define MZ_FOPEN(f, m) mz_fopen
4170#define MZ_FCLOSE fclose
4171#define MZ_FREAD fread
4172#define MZ_FWRITE fwrite
4173#define MZ_FTELL64 ftell
4174#define MZ_FSEEK64 fseek
4175#define MZ_FILE_STAT_STRUCT _stat
4176#define MZ_FILE_STAT _stat
4177#define MZ_FFLUSH fflush
4178#define MZ_FREOPEN(f, m, s) mz_freopen
4179#define MZ_DELETE_FILE remove
4180#elif defined(__TINYC__)
4181#ifndef MINIZ_NO_TIME
4182#include <sys/utime.h>
4185#define MZ_FOPEN(f, m) fopen(f, m)
4186#define MZ_FCLOSE fclose
4187#define MZ_FREAD fread
4188#define MZ_FWRITE fwrite
4189#define MZ_FTELL64 ftell
4190#define MZ_FSEEK64 fseek
4191#define MZ_FILE_STAT_STRUCT stat
4192#define MZ_FILE_STAT stat
4193#define MZ_FFLUSH fflush
4194#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
4195#define MZ_DELETE_FILE remove
4196#elif defined(__GNUC__) && _LARGEFILE64_SOURCE
4197#ifndef MINIZ_NO_TIME
4201#define MZ_FOPEN(f, m) fopen64(f, m)
4202#define MZ_FCLOSE fclose
4203#define MZ_FREAD fread
4204#define MZ_FWRITE fwrite
4205#define MZ_FTELL64 ftello64
4206#define MZ_FSEEK64 fseeko64
4207#define MZ_FILE_STAT_STRUCT stat64
4208#define MZ_FILE_STAT stat64
4209#define MZ_FFLUSH fflush
4210#define MZ_FREOPEN(p, m, s) freopen64(p, m, s)
4211#define MZ_DELETE_FILE remove
4213#ifndef MINIZ_NO_TIME
4217#define MZ_FOPEN(f, m) fopen(f, m)
4218#define MZ_FCLOSE fclose
4219#define MZ_FREAD fread
4220#define MZ_FWRITE fwrite
4221#if _FILE_OFFSET_BITS == 64 || _POSIX_C_SOURCE >= 200112L
4222#define MZ_FTELL64 ftello
4223#define MZ_FSEEK64 fseeko
4225#define MZ_FTELL64 ftell
4226#define MZ_FSEEK64 fseek
4228#define MZ_FILE_STAT_STRUCT stat
4229#define MZ_FILE_STAT stat
4230#define MZ_FFLUSH fflush
4231#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
4232#define MZ_DELETE_FILE remove
4236#define MZ_TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c))
4243 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06054b50,
4244 MZ_ZIP_CENTRAL_DIR_HEADER_SIG = 0x02014b50,
4245 MZ_ZIP_LOCAL_DIR_HEADER_SIG = 0x04034b50,
4246 MZ_ZIP_LOCAL_DIR_HEADER_SIZE = 30,
4247 MZ_ZIP_CENTRAL_DIR_HEADER_SIZE = 46,
4248 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE = 22,
4251 MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06064b50,
4252 MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG = 0x07064b50,
4253 MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE = 56,
4254 MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE = 20,
4255 MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID = 0x0001,
4256 MZ_ZIP_DATA_DESCRIPTOR_ID = 0x08074b50,
4257 MZ_ZIP_DATA_DESCRIPTER_SIZE64 = 24,
4258 MZ_ZIP_DATA_DESCRIPTER_SIZE32 = 16,
4261 MZ_ZIP_CDH_SIG_OFS = 0,
4262 MZ_ZIP_CDH_VERSION_MADE_BY_OFS = 4,
4263 MZ_ZIP_CDH_VERSION_NEEDED_OFS = 6,
4264 MZ_ZIP_CDH_BIT_FLAG_OFS = 8,
4265 MZ_ZIP_CDH_METHOD_OFS = 10,
4266 MZ_ZIP_CDH_FILE_TIME_OFS = 12,
4267 MZ_ZIP_CDH_FILE_DATE_OFS = 14,
4268 MZ_ZIP_CDH_CRC32_OFS = 16,
4269 MZ_ZIP_CDH_COMPRESSED_SIZE_OFS = 20,
4270 MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS = 24,
4271 MZ_ZIP_CDH_FILENAME_LEN_OFS = 28,
4272 MZ_ZIP_CDH_EXTRA_LEN_OFS = 30,
4273 MZ_ZIP_CDH_COMMENT_LEN_OFS = 32,
4274 MZ_ZIP_CDH_DISK_START_OFS = 34,
4275 MZ_ZIP_CDH_INTERNAL_ATTR_OFS = 36,
4276 MZ_ZIP_CDH_EXTERNAL_ATTR_OFS = 38,
4277 MZ_ZIP_CDH_LOCAL_HEADER_OFS = 42,
4279 MZ_ZIP_LDH_SIG_OFS = 0,
4280 MZ_ZIP_LDH_VERSION_NEEDED_OFS = 4,
4281 MZ_ZIP_LDH_BIT_FLAG_OFS = 6,
4282 MZ_ZIP_LDH_METHOD_OFS = 8,
4283 MZ_ZIP_LDH_FILE_TIME_OFS = 10,
4284 MZ_ZIP_LDH_FILE_DATE_OFS = 12,
4285 MZ_ZIP_LDH_CRC32_OFS = 14,
4286 MZ_ZIP_LDH_COMPRESSED_SIZE_OFS = 18,
4287 MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS = 22,
4288 MZ_ZIP_LDH_FILENAME_LEN_OFS = 26,
4289 MZ_ZIP_LDH_EXTRA_LEN_OFS = 28,
4291 MZ_ZIP_ECDH_SIG_OFS = 0,
4292 MZ_ZIP_ECDH_NUM_THIS_DISK_OFS = 4,
4293 MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS = 6,
4294 MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 8,
4295 MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS = 10,
4296 MZ_ZIP_ECDH_CDIR_SIZE_OFS = 12,
4297 MZ_ZIP_ECDH_CDIR_OFS_OFS = 16,
4298 MZ_ZIP_ECDH_COMMENT_SIZE_OFS = 20,
4301 MZ_ZIP64_ECDL_SIG_OFS = 0,
4302 MZ_ZIP64_ECDL_NUM_DISK_CDIR_OFS = 4,
4303 MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS = 8,
4304 MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS = 16,
4307 MZ_ZIP64_ECDH_SIG_OFS = 0,
4308 MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS = 4,
4309 MZ_ZIP64_ECDH_VERSION_MADE_BY_OFS = 12,
4310 MZ_ZIP64_ECDH_VERSION_NEEDED_OFS = 14,
4311 MZ_ZIP64_ECDH_NUM_THIS_DISK_OFS = 16,
4312 MZ_ZIP64_ECDH_NUM_DISK_CDIR_OFS = 20,
4313 MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 24,
4314 MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS = 32,
4315 MZ_ZIP64_ECDH_CDIR_SIZE_OFS = 40,
4316 MZ_ZIP64_ECDH_CDIR_OFS_OFS = 48,
4317 MZ_ZIP_VERSION_MADE_BY_DOS_FILESYSTEM_ID = 0,
4318 MZ_ZIP_DOS_DIR_ATTRIBUTE_BITFLAG = 0x10,
4319 MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_IS_ENCRYPTED = 1,
4320 MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_COMPRESSED_PATCH_FLAG = 32,
4321 MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_USES_STRONG_ENCRYPTION = 64,
4322 MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_LOCAL_DIR_IS_MASKED = 8192,
4323 MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8 = 1 << 11
4328 size_t m_size, m_capacity;
4329 mz_uint m_element_size;
4338 uint32_t m_init_flags;
4347 mz_bool m_zip64_has_extended_info_fields;
4352 mz_uint64 m_file_archive_start_ofs;
4356 size_t m_mem_capacity;
4359#define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size) \
4360 (array_ptr)->m_element_size = element_size
4361#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) \
4362 ((element_type *)((array_ptr)->m_p))[index]
4364static MZ_FORCEINLINE
void mz_zip_array_clear(
mz_zip_archive *pZip,
4366 pZip->m_pFree(pZip->m_pAlloc_opaque, pArray->m_p);
4372 size_t min_new_capacity,
4375 size_t new_capacity = min_new_capacity;
4376 MZ_ASSERT(pArray->m_element_size);
4377 if (pArray->m_capacity >= min_new_capacity)
4380 new_capacity = MZ_MAX(1, pArray->m_capacity);
4381 while (new_capacity < min_new_capacity)
4384 if (NULL == (pNew_p = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pArray->m_p,
4385 pArray->m_element_size, new_capacity)))
4387 pArray->m_p = pNew_p;
4388 pArray->m_capacity = new_capacity;
4392static MZ_FORCEINLINE mz_bool mz_zip_array_reserve(
mz_zip_archive *pZip,
4394 size_t new_capacity,
4396 if (new_capacity > pArray->m_capacity) {
4397 if (!mz_zip_array_ensure_capacity(pZip, pArray, new_capacity, growing))
4403static MZ_FORCEINLINE mz_bool mz_zip_array_resize(
mz_zip_archive *pZip,
4407 if (new_size > pArray->m_capacity) {
4408 if (!mz_zip_array_ensure_capacity(pZip, pArray, new_size, growing))
4411 pArray->m_size = new_size;
4415static MZ_FORCEINLINE mz_bool mz_zip_array_ensure_room(
mz_zip_archive *pZip,
4418 return mz_zip_array_reserve(pZip, pArray, pArray->m_size + n, MZ_TRUE);
4421static MZ_FORCEINLINE mz_bool mz_zip_array_push_back(
mz_zip_archive *pZip,
4423 const void *pElements,
4430 size_t orig_size = pArray->m_size;
4431 if (!mz_zip_array_resize(pZip, pArray, orig_size + n, MZ_TRUE))
4433 memcpy((mz_uint8 *)pArray->m_p + orig_size * pArray->m_element_size,
4434 pElements, n * pArray->m_element_size);
4438#ifndef MINIZ_NO_TIME
4439static time_t mz_zip_dos_to_time_t(
int dos_time,
int dos_date) {
4441 memset(&tm, 0,
sizeof(tm));
4443 tm.tm_year = ((dos_date >> 9) & 127) + 1980 - 1900;
4444 tm.tm_mon = ((dos_date >> 5) & 15) - 1;
4445 tm.tm_mday = dos_date & 31;
4446 tm.tm_hour = (dos_time >> 11) & 31;
4447 tm.tm_min = (dos_time >> 5) & 63;
4448 tm.tm_sec = (dos_time << 1) & 62;
4452#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
4453static void mz_zip_time_t_to_dos_time(time_t time, mz_uint16 *pDOS_time,
4454 mz_uint16 *pDOS_date) {
4456 struct tm tm_struct;
4457 struct tm *tm = &tm_struct;
4458 errno_t err = localtime_s(tm, &time);
4465 struct tm *tm = localtime(&time);
4468 *pDOS_time = (mz_uint16)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) +
4469 ((tm->tm_sec) >> 1));
4470 *pDOS_date = (mz_uint16)(((tm->tm_year + 1900 - 1980) << 9) +
4471 ((tm->tm_mon + 1) << 5) + tm->tm_mday);
4475#ifndef MINIZ_NO_STDIO
4476#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
4477static mz_bool mz_zip_get_file_modified_time(
const char *pFilename,
4479 struct MZ_FILE_STAT_STRUCT file_stat;
4483 if (MZ_FILE_STAT(pFilename, &file_stat) != 0)
4486 *pTime = file_stat.st_mtime;
4492static mz_bool mz_zip_set_file_times(
const char *pFilename, time_t access_time,
4493 time_t modified_time) {
4496 memset(&t, 0,
sizeof(t));
4497 t.actime = access_time;
4498 t.modtime = modified_time;
4500 return !utime(pFilename, &t);
4505static MZ_FORCEINLINE mz_bool mz_zip_set_error(
mz_zip_archive *pZip,
4506 mz_zip_error err_num) {
4508 pZip->m_last_error = err_num;
4515 if ((!pZip) || (pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
4518 if (!pZip->m_pAlloc)
4519 pZip->m_pAlloc = def_alloc_func;
4521 pZip->m_pFree = def_free_func;
4522 if (!pZip->m_pRealloc)
4523 pZip->m_pRealloc = def_realloc_func;
4525 pZip->m_zip_mode = MZ_ZIP_MODE_READING;
4526 pZip->m_archive_size = 0;
4527 pZip->m_central_directory_file_ofs = 0;
4528 pZip->m_total_files = 0;
4534 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir,
4536 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets,
4538 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets,
4543static MZ_FORCEINLINE mz_bool
4544mz_zip_reader_filename_less(
const mz_zip_array *pCentral_dir_array,
4546 mz_uint l_index, mz_uint r_index) {
4547 const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(
4548 pCentral_dir_array, mz_uint8,
4549 MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32,
4552 const mz_uint8 *pR = &MZ_ZIP_ARRAY_ELEMENT(
4553 pCentral_dir_array, mz_uint8,
4554 MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, r_index));
4555 mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS),
4556 r_len = MZ_READ_LE16(pR + MZ_ZIP_CDH_FILENAME_LEN_OFS);
4557 mz_uint8 l = 0, r = 0;
4558 pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
4559 pR += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
4560 pE = pL + MZ_MIN(l_len, r_len);
4562 if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR)))
4567 return (pL == pE) ? (l_len < r_len) : (l < r);
4570#define MZ_SWAP_UINT32(a, b) \
4582mz_zip_reader_sort_central_dir_offsets_by_filename(
mz_zip_archive *pZip) {
4584 const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
4585 const mz_zip_array *pCentral_dir = &pState->m_central_dir;
4586 mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(
4587 &pState->m_sorted_central_dir_offsets, mz_uint32, 0);
4588 const int size = pZip->m_total_files;
4589 int start = (size - 2) >> 1, end;
4590 while (start >= 0) {
4591 int child, root = start;
4593 if ((child = (root << 1) + 1) >= size)
4596 (((child + 1) < size) &&
4597 (mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets,
4598 pIndices[child], pIndices[child + 1])));
4599 if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets,
4600 pIndices[root], pIndices[child]))
4602 MZ_SWAP_UINT32(pIndices[root], pIndices[child]);
4610 int child, root = 0;
4611 MZ_SWAP_UINT32(pIndices[end], pIndices[0]);
4613 if ((child = (root << 1) + 1) >= end)
4616 (((child + 1) < end) &&
4617 mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets,
4618 pIndices[child], pIndices[child + 1]));
4619 if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets,
4620 pIndices[root], pIndices[child]))
4622 MZ_SWAP_UINT32(pIndices[root], pIndices[child]);
4629static mz_bool mz_zip_reader_locate_header_sig(
mz_zip_archive *pZip,
4630 mz_uint32 record_sig,
4631 mz_uint32 record_size,
4633 mz_int64 cur_file_ofs;
4634 mz_uint32 buf_u32[4096 /
sizeof(mz_uint32)];
4635 mz_uint8 *pBuf = (mz_uint8 *)buf_u32;
4638 if (pZip->m_archive_size < record_size)
4643 MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)
sizeof(buf_u32), 0);
4646 n = (int)MZ_MIN(
sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs);
4648 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n)
4651 for (i = n - 4; i >= 0; --i) {
4652 mz_uint s = MZ_READ_LE32(pBuf + i);
4653 if (s == record_sig) {
4654 if ((pZip->m_archive_size - (cur_file_ofs + i)) >= record_size)
4666 if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >=
4667 (MZ_UINT16_MAX + record_size)))
4670 cur_file_ofs = MZ_MAX(cur_file_ofs - (
sizeof(buf_u32) - 3), 0);
4673 *pOfs = cur_file_ofs;
4677static mz_bool mz_zip_reader_read_central_dir(
mz_zip_archive *pZip,
4679 mz_uint cdir_size = 0, cdir_entries_on_this_disk = 0, num_this_disk = 0,
4680 cdir_disk_index = 0;
4681 mz_uint64 cdir_ofs = 0;
4682 mz_int64 cur_file_ofs = 0;
4685 mz_uint32 buf_u32[4096 /
sizeof(mz_uint32)];
4686 mz_uint8 *pBuf = (mz_uint8 *)buf_u32;
4687 mz_bool sort_central_dir =
4688 ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0);
4689 mz_uint32 zip64_end_of_central_dir_locator_u32
4690 [(MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE +
sizeof(mz_uint32) - 1) /
4692 mz_uint8 *pZip64_locator = (mz_uint8 *)zip64_end_of_central_dir_locator_u32;
4694 mz_uint32 zip64_end_of_central_dir_header_u32
4695 [(MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE +
sizeof(mz_uint32) - 1) /
4697 mz_uint8 *pZip64_end_of_central_dir =
4698 (mz_uint8 *)zip64_end_of_central_dir_header_u32;
4700 mz_uint64 zip64_end_of_central_dir_ofs = 0;
4704 if (pZip->m_archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
4705 return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
4707 if (!mz_zip_reader_locate_header_sig(
4708 pZip, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG,
4709 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE, &cur_file_ofs))
4710 return mz_zip_set_error(pZip, MZ_ZIP_FAILED_FINDING_CENTRAL_DIR);
4713 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf,
4714 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) !=
4715 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
4716 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
4718 if (MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) !=
4719 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG)
4720 return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
4722 if (cur_file_ofs >= (MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE +
4723 MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE)) {
4724 if (pZip->m_pRead(pZip->m_pIO_opaque,
4725 cur_file_ofs - MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE,
4727 MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) ==
4728 MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIZE) {
4729 if (MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_SIG_OFS) ==
4730 MZ_ZIP64_END_OF_CENTRAL_DIR_LOCATOR_SIG) {
4731 zip64_end_of_central_dir_ofs = MZ_READ_LE64(
4732 pZip64_locator + MZ_ZIP64_ECDL_REL_OFS_TO_ZIP64_ECDR_OFS);
4733 if (zip64_end_of_central_dir_ofs >
4734 (pZip->m_archive_size - MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE))
4735 return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
4737 if (pZip->m_pRead(pZip->m_pIO_opaque, zip64_end_of_central_dir_ofs,
4738 pZip64_end_of_central_dir,
4739 MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) ==
4740 MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE) {
4741 if (MZ_READ_LE32(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_SIG_OFS) ==
4742 MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIG) {
4743 pZip->m_pState->m_zip64 = MZ_TRUE;
4750 pZip->m_total_files = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS);
4751 cdir_entries_on_this_disk =
4752 MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS);
4753 num_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS);
4754 cdir_disk_index = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS);
4755 cdir_size = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_SIZE_OFS);
4756 cdir_ofs = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS);
4758 if (pZip->m_pState->m_zip64) {
4759 mz_uint32 zip64_total_num_of_disks =
4760 MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS);
4761 mz_uint64 zip64_cdir_total_entries = MZ_READ_LE64(
4762 pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_TOTAL_ENTRIES_OFS);
4763 mz_uint64 zip64_cdir_total_entries_on_this_disk = MZ_READ_LE64(
4764 pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS);
4765 mz_uint64 zip64_size_of_end_of_central_dir_record = MZ_READ_LE64(
4766 pZip64_end_of_central_dir + MZ_ZIP64_ECDH_SIZE_OF_RECORD_OFS);
4767 mz_uint64 zip64_size_of_central_directory =
4768 MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_SIZE_OFS);
4770 if (zip64_size_of_end_of_central_dir_record <
4771 (MZ_ZIP64_END_OF_CENTRAL_DIR_HEADER_SIZE - 12))
4772 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
4774 if (zip64_total_num_of_disks != 1U)
4775 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK);
4778 if (zip64_cdir_total_entries > MZ_UINT32_MAX)
4779 return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
4781 pZip->m_total_files = (mz_uint32)zip64_cdir_total_entries;
4783 if (zip64_cdir_total_entries_on_this_disk > MZ_UINT32_MAX)
4784 return mz_zip_set_error(pZip, MZ_ZIP_TOO_MANY_FILES);
4786 cdir_entries_on_this_disk =
4787 (mz_uint32)zip64_cdir_total_entries_on_this_disk;
4791 if (zip64_size_of_central_directory > MZ_UINT32_MAX)
4792 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_CDIR_SIZE);
4794 cdir_size = (mz_uint32)zip64_size_of_central_directory;
4796 num_this_disk = MZ_READ_LE32(pZip64_end_of_central_dir +
4797 MZ_ZIP64_ECDH_NUM_THIS_DISK_OFS);
4799 cdir_disk_index = MZ_READ_LE32(pZip64_end_of_central_dir +
4800 MZ_ZIP64_ECDH_NUM_DISK_CDIR_OFS);
4803 MZ_READ_LE64(pZip64_end_of_central_dir + MZ_ZIP64_ECDH_CDIR_OFS_OFS);
4806 if (pZip->m_total_files != cdir_entries_on_this_disk)
4807 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK);
4809 if (((num_this_disk | cdir_disk_index) != 0) &&
4810 ((num_this_disk != 1) || (cdir_disk_index != 1)))
4811 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK);
4813 if (cdir_size < pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)
4814 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
4816 if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size)
4817 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
4819 pZip->m_central_directory_file_ofs = cdir_ofs;
4821 if (pZip->m_total_files) {
4826 if ((!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir, cdir_size,
4828 (!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir_offsets,
4829 pZip->m_total_files, MZ_FALSE)))
4830 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
4832 if (sort_central_dir) {
4833 if (!mz_zip_array_resize(pZip,
4834 &pZip->m_pState->m_sorted_central_dir_offsets,
4835 pZip->m_total_files, MZ_FALSE))
4836 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
4839 if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs,
4840 pZip->m_pState->m_central_dir.m_p,
4841 cdir_size) != cdir_size)
4842 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
4846 p = (
const mz_uint8 *)pZip->m_pState->m_central_dir.m_p;
4847 for (n = cdir_size, i = 0; i < pZip->m_total_files; ++i) {
4848 mz_uint total_header_size, disk_index, bit_flags, filename_size,
4850 mz_uint64 comp_size, decomp_size, local_header_ofs;
4852 if ((n < MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) ||
4853 (MZ_READ_LE32(p) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG))
4854 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
4856 MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32,
4858 (mz_uint32)(p - (
const mz_uint8 *)pZip->m_pState->m_central_dir.m_p);
4860 if (sort_central_dir)
4861 MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_sorted_central_dir_offsets,
4864 comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
4865 decomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
4866 local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
4867 filename_size = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
4868 ext_data_size = MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS);
4870 if ((!pZip->m_pState->m_zip64_has_extended_info_fields) &&
4872 (MZ_MAX(MZ_MAX(comp_size, decomp_size), local_header_ofs) ==
4876 mz_uint32 extra_size_remaining = ext_data_size;
4878 if (extra_size_remaining) {
4879 const mz_uint8 *pExtra_data;
4882 if (MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + ext_data_size >
4884 buf = MZ_MALLOC(ext_data_size);
4886 return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
4888 if (pZip->m_pRead(pZip->m_pIO_opaque,
4889 cdir_ofs + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE +
4891 buf, ext_data_size) != ext_data_size) {
4893 return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
4896 pExtra_data = (mz_uint8 *)buf;
4898 pExtra_data = p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size;
4903 mz_uint32 field_data_size;
4905 if (extra_size_remaining < (
sizeof(mz_uint16) * 2)) {
4907 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
4910 field_id = MZ_READ_LE16(pExtra_data);
4911 field_data_size = MZ_READ_LE16(pExtra_data +
sizeof(mz_uint16));
4913 if ((field_data_size +
sizeof(mz_uint16) * 2) >
4914 extra_size_remaining) {
4916 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
4919 if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) {
4924 pZip->m_pState->m_zip64 = MZ_TRUE;
4925 pZip->m_pState->m_zip64_has_extended_info_fields = MZ_TRUE;
4929 pExtra_data +=
sizeof(mz_uint16) * 2 + field_data_size;
4930 extra_size_remaining =
4931 extra_size_remaining -
sizeof(mz_uint16) * 2 - field_data_size;
4932 }
while (extra_size_remaining);
4940 if ((comp_size != MZ_UINT32_MAX) && (decomp_size != MZ_UINT32_MAX)) {
4941 if (((!MZ_READ_LE32(p + MZ_ZIP_CDH_METHOD_OFS)) &&
4942 (decomp_size != comp_size)) ||
4943 (decomp_size && !comp_size))
4944 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
4947 disk_index = MZ_READ_LE16(p + MZ_ZIP_CDH_DISK_START_OFS);
4948 if ((disk_index == MZ_UINT16_MAX) ||
4949 ((disk_index != num_this_disk) && (disk_index != 1)))
4950 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_MULTIDISK);
4952 if (comp_size != MZ_UINT32_MAX) {
4953 if (((mz_uint64)MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS) +
4954 MZ_ZIP_LOCAL_DIR_HEADER_SIZE + comp_size) > pZip->m_archive_size)
4955 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
4958 bit_flags = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
4959 if (bit_flags & MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_LOCAL_DIR_IS_MASKED)
4960 return mz_zip_set_error(pZip, MZ_ZIP_UNSUPPORTED_ENCRYPTION);
4962 if ((total_header_size = MZ_ZIP_CENTRAL_DIR_HEADER_SIZE +
4963 MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) +
4964 MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS) +
4965 MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS)) >
4967 return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
4969 n -= total_header_size;
4970 p += total_header_size;
4974 if (sort_central_dir)
4975 mz_zip_reader_sort_central_dir_offsets_by_filename(pZip);
4982 if ((!pZip) || (!pZip->m_pRead))
4984 if (!mz_zip_reader_init_internal(pZip, flags))
4986 pZip->m_archive_size = size;
4987 if (!mz_zip_reader_read_central_dir(pZip, flags)) {
4988 mz_zip_reader_end(pZip);
4994static size_t mz_zip_mem_read_func(
void *pOpaque, mz_uint64 file_ofs,
4995 void *pBuf,
size_t n) {
4997 size_t s = (file_ofs >= pZip->m_archive_size)
4999 : (size_t)MZ_MIN(pZip->m_archive_size - file_ofs, n);
5000 memcpy(pBuf, (
const mz_uint8 *)pZip->m_pState->m_pMem + file_ofs, s);
5004mz_bool mz_zip_reader_init_mem(
mz_zip_archive *pZip,
const void *pMem,
5005 size_t size, mz_uint32 flags) {
5006 if (!mz_zip_reader_init_internal(pZip, flags))
5008 pZip->m_archive_size = size;
5009 pZip->m_pRead = mz_zip_mem_read_func;
5010 pZip->m_pIO_opaque = pZip;
5012 pZip->m_pState->m_pMem =
const_cast<void *
>(pMem);
5014 pZip->m_pState->m_pMem = (
void *)pMem;
5016 pZip->m_pState->m_mem_size = size;
5017 if (!mz_zip_reader_read_central_dir(pZip, flags)) {
5018 mz_zip_reader_end(pZip);
5024#ifndef MINIZ_NO_STDIO
5025static size_t mz_zip_file_read_func(
void *pOpaque, mz_uint64 file_ofs,
5026 void *pBuf,
size_t n) {
5028 mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
5029 if (((mz_int64)file_ofs < 0) ||
5030 (((cur_ofs != (mz_int64)file_ofs)) &&
5031 (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET))))
5033 return MZ_FREAD(pBuf, 1, n, pZip->m_pState->m_pFile);
5036mz_bool mz_zip_reader_init_file(
mz_zip_archive *pZip,
const char *pFilename,
5038 mz_uint64 file_size;
5039 MZ_FILE *pFile = MZ_FOPEN(pFilename,
"rb");
5042 if (MZ_FSEEK64(pFile, 0, SEEK_END)) {
5046 file_size = MZ_FTELL64(pFile);
5047 if (!mz_zip_reader_init_internal(pZip, flags)) {
5051 pZip->m_pRead = mz_zip_file_read_func;
5052 pZip->m_pIO_opaque = pZip;
5053 pZip->m_pState->m_pFile = pFile;
5054 pZip->m_archive_size = file_size;
5055 if (!mz_zip_reader_read_central_dir(pZip, flags)) {
5056 mz_zip_reader_end(pZip);
5064 return pZip ? pZip->m_total_files : 0;
5067static MZ_FORCEINLINE
const mz_uint8 *
5069 if ((!pZip) || (!pZip->m_pState) || (file_index >= pZip->m_total_files) ||
5070 (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
5072 return &MZ_ZIP_ARRAY_ELEMENT(
5073 &pZip->m_pState->m_central_dir, mz_uint8,
5074 MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32,
5079 mz_uint file_index) {
5081 const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
5084 m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
5085 return (m_bit_flag & 1);
5089 mz_uint file_index) {
5090 mz_uint filename_len, external_attr;
5091 const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
5096 filename_len = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
5098 if (*(p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_len - 1) ==
'/')
5107 external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS);
5108 if ((external_attr & 0x10) != 0)
5114mz_bool mz_zip_reader_file_stat(
mz_zip_archive *pZip, mz_uint file_index,
5117 const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
5118 if ((!p) || (!pStat))
5122 pStat->m_file_index = file_index;
5123 pStat->m_central_dir_ofs = MZ_ZIP_ARRAY_ELEMENT(
5124 &pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index);
5125 pStat->m_version_made_by = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS);
5126 pStat->m_version_needed = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_NEEDED_OFS);
5127 pStat->m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
5128 pStat->m_method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS);
5129#ifndef MINIZ_NO_TIME
5131 mz_zip_dos_to_time_t(MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_TIME_OFS),
5132 MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_DATE_OFS));
5134 pStat->m_crc32 = MZ_READ_LE32(p + MZ_ZIP_CDH_CRC32_OFS);
5135 pStat->m_comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
5136 pStat->m_uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
5137 pStat->m_internal_attr = MZ_READ_LE16(p + MZ_ZIP_CDH_INTERNAL_ATTR_OFS);
5138 pStat->m_external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS);
5139 pStat->m_local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
5142 n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
5143 n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE - 1);
5144 memcpy(pStat->m_filename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n);
5145 pStat->m_filename[n] =
'\0';
5147 n = MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS);
5148 n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE - 1);
5149 pStat->m_comment_size = n;
5150 memcpy(pStat->m_comment,
5151 p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE +
5152 MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) +
5153 MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS),
5155 pStat->m_comment[n] =
'\0';
5160mz_uint mz_zip_reader_get_filename(
mz_zip_archive *pZip, mz_uint file_index,
5161 char *pFilename, mz_uint filename_buf_size) {
5163 const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
5165 if (filename_buf_size)
5166 pFilename[0] =
'\0';
5169 n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
5170 if (filename_buf_size) {
5171 n = MZ_MIN(n, filename_buf_size - 1);
5172 memcpy(pFilename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n);
5173 pFilename[n] =
'\0';
5178static MZ_FORCEINLINE mz_bool mz_zip_reader_string_equal(
const char *pA,
5183 if (flags & MZ_ZIP_FLAG_CASE_SENSITIVE)
5184 return 0 == memcmp(pA, pB, len);
5185 for (i = 0; i < len; ++i)
5186 if (MZ_TOLOWER(pA[i]) != MZ_TOLOWER(pB[i]))
5191static MZ_FORCEINLINE
int
5192mz_zip_reader_filename_compare(
const mz_zip_array *pCentral_dir_array,
5194 mz_uint l_index,
const char *pR, mz_uint r_len) {
5195 const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(
5196 pCentral_dir_array, mz_uint8,
5197 MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32,
5200 mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS);
5201 mz_uint8 l = 0, r = 0;
5202 pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
5203 pE = pL + MZ_MIN(l_len, r_len);
5205 if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR)))
5210 return (pL == pE) ? (int)(l_len - r_len) : (l - r);
5213static int mz_zip_reader_locate_file_binary_search(
mz_zip_archive *pZip,
5214 const char *pFilename) {
5216 const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
5217 const mz_zip_array *pCentral_dir = &pState->m_central_dir;
5218 mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(
5219 &pState->m_sorted_central_dir_offsets, mz_uint32, 0);
5220 const int size = pZip->m_total_files;
5221 const mz_uint filename_len = (mz_uint)strlen(pFilename);
5222 int l = 0, h = size - 1;
5224 int m = (l + h) >> 1, file_index = pIndices[m],
5226 mz_zip_reader_filename_compare(pCentral_dir, pCentral_dir_offsets,
5227 file_index, pFilename, filename_len);
5238int mz_zip_reader_locate_file(
mz_zip_archive *pZip,
const char *pName,
5239 const char *pComment, mz_uint flags) {
5241 size_t name_len, comment_len;
5242 if ((!pZip) || (!pZip->m_pState) || (!pName) ||
5243 (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
5245 if (((flags & (MZ_ZIP_FLAG_IGNORE_PATH | MZ_ZIP_FLAG_CASE_SENSITIVE)) == 0) &&
5246 (!pComment) && (pZip->m_pState->m_sorted_central_dir_offsets.m_size))
5247 return mz_zip_reader_locate_file_binary_search(pZip, pName);
5248 name_len = strlen(pName);
5249 if (name_len > 0xFFFF)
5251 comment_len = pComment ? strlen(pComment) : 0;
5252 if (comment_len > 0xFFFF)
5254 for (file_index = 0; file_index < pZip->m_total_files; file_index++) {
5255 const mz_uint8 *pHeader = &MZ_ZIP_ARRAY_ELEMENT(
5256 &pZip->m_pState->m_central_dir, mz_uint8,
5257 MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32,
5259 mz_uint filename_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_FILENAME_LEN_OFS);
5260 const char *pFilename =
5261 (
const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
5262 if (filename_len < name_len)
5265 mz_uint file_extra_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_EXTRA_LEN_OFS),
5267 MZ_READ_LE16(pHeader + MZ_ZIP_CDH_COMMENT_LEN_OFS);
5268 const char *pFile_comment = pFilename + filename_len + file_extra_len;
5269 if ((file_comment_len != comment_len) ||
5270 (!mz_zip_reader_string_equal(pComment, pFile_comment,
5271 file_comment_len, flags)))
5274 if ((flags & MZ_ZIP_FLAG_IGNORE_PATH) && (filename_len)) {
5275 int ofs = filename_len - 1;
5277 if ((pFilename[ofs] ==
'/') || (pFilename[ofs] ==
'\\') ||
5278 (pFilename[ofs] ==
':'))
5280 }
while (--ofs >= 0);
5283 filename_len -= ofs;
5285 if ((filename_len == name_len) &&
5286 (mz_zip_reader_string_equal(pName, pFilename, filename_len, flags)))
5292mz_bool mz_zip_reader_extract_to_mem_no_alloc(
mz_zip_archive *pZip,
5293 mz_uint file_index,
void *pBuf,
5294 size_t buf_size, mz_uint flags,
5295 void *pUser_read_buf,
5296 size_t user_read_buf_size) {
5297 int status = TINFL_STATUS_DONE;
5298 mz_uint64 needed_size, cur_file_ofs, comp_remaining,
5299 out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail;
5303 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE +
sizeof(mz_uint32) - 1) /
5305 mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
5308 if ((buf_size) && (!pBuf))
5311 if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
5316 if (!file_stat.m_comp_size)
5323 if (mz_zip_reader_is_file_a_directory(pZip, file_index))
5327 if (file_stat.m_bit_flag & (1 | 32))
5331 if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) &&
5332 (file_stat.m_method != MZ_DEFLATED))
5336 needed_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size
5337 : file_stat.m_uncomp_size;
5338 if (buf_size < needed_size)
5342 cur_file_ofs = file_stat.m_local_header_ofs;
5343 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header,
5344 MZ_ZIP_LOCAL_DIR_HEADER_SIZE) !=
5345 MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
5347 if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
5350 cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE +
5351 MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) +
5352 MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
5353 if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
5356 if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) {
5358 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf,
5359 (
size_t)needed_size) != needed_size)
5361 return ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) != 0) ||
5362 (mz_crc32(MZ_CRC32_INIT, (
const mz_uint8 *)pBuf,
5363 (
size_t)file_stat.m_uncomp_size) == file_stat.m_crc32);
5368 tinfl_init(&inflator);
5370 if (pZip->m_pState->m_pMem) {
5372 pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
5373 read_buf_size = read_buf_avail = file_stat.m_comp_size;
5375 }
else if (pUser_read_buf) {
5377 if (!user_read_buf_size)
5379 pRead_buf = (mz_uint8 *)pUser_read_buf;
5380 read_buf_size = user_read_buf_size;
5382 comp_remaining = file_stat.m_comp_size;
5385 read_buf_size = MZ_MIN(file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE);
5386 if (((
sizeof(
size_t) ==
sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
5389 if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1,
5390 (
size_t)read_buf_size)))
5393 comp_remaining = file_stat.m_comp_size;
5398 out_buf_size = (size_t)(file_stat.m_uncomp_size - out_buf_ofs);
5399 if ((!read_buf_avail) && (!pZip->m_pState->m_pMem)) {
5400 read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
5401 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf,
5402 (
size_t)read_buf_avail) != read_buf_avail) {
5403 status = TINFL_STATUS_FAILED;
5406 cur_file_ofs += read_buf_avail;
5407 comp_remaining -= read_buf_avail;
5410 in_buf_size = (size_t)read_buf_avail;
5411 status = tinfl_decompress(
5412 &inflator, (mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size,
5413 (mz_uint8 *)pBuf, (mz_uint8 *)pBuf + out_buf_ofs, &out_buf_size,
5414 TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF |
5415 (comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0));
5416 read_buf_avail -= in_buf_size;
5417 read_buf_ofs += in_buf_size;
5418 out_buf_ofs += out_buf_size;
5419 }
while (status == TINFL_STATUS_NEEDS_MORE_INPUT);
5421 if (status == TINFL_STATUS_DONE) {
5423 if ((out_buf_ofs != file_stat.m_uncomp_size) ||
5424 (mz_crc32(MZ_CRC32_INIT, (
const mz_uint8 *)pBuf,
5425 (
size_t)file_stat.m_uncomp_size) != file_stat.m_crc32))
5426 status = TINFL_STATUS_FAILED;
5429 if ((!pZip->m_pState->m_pMem) && (!pUser_read_buf))
5430 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
5432 return status == TINFL_STATUS_DONE;
5435mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(
5436 mz_zip_archive *pZip,
const char *pFilename,
void *pBuf,
size_t buf_size,
5437 mz_uint flags,
void *pUser_read_buf,
size_t user_read_buf_size) {
5438 int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags);
5441 return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size,
5442 flags, pUser_read_buf,
5443 user_read_buf_size);
5446mz_bool mz_zip_reader_extract_to_mem(
mz_zip_archive *pZip, mz_uint file_index,
5447 void *pBuf,
size_t buf_size,
5449 return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size,
5454 const char *pFilename,
void *pBuf,
5455 size_t buf_size, mz_uint flags) {
5456 return mz_zip_reader_extract_file_to_mem_no_alloc(pZip, pFilename, pBuf,
5457 buf_size, flags, NULL, 0);
5460void *mz_zip_reader_extract_to_heap(
mz_zip_archive *pZip, mz_uint file_index,
5461 size_t *pSize, mz_uint flags) {
5462 mz_uint64 comp_size, uncomp_size, alloc_size;
5463 const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
5471 comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
5472 uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
5474 alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size;
5475 if (((
sizeof(
size_t) ==
sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
5478 (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (
size_t)alloc_size)))
5481 if (!mz_zip_reader_extract_to_mem(pZip, file_index, pBuf, (
size_t)alloc_size,
5483 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
5488 *pSize = (size_t)alloc_size;
5493 const char *pFilename,
size_t *pSize,
5495 int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags);
5496 if (file_index < 0) {
5501 return mz_zip_reader_extract_to_heap(pZip, file_index, pSize, flags);
5506 mz_file_write_func pCallback,
5507 void *pOpaque, mz_uint flags) {
5508 int status = TINFL_STATUS_DONE;
5509 mz_uint file_crc32 = MZ_CRC32_INIT;
5510 mz_uint64 read_buf_size, read_buf_ofs = 0, read_buf_avail, comp_remaining,
5511 out_buf_ofs = 0, cur_file_ofs;
5513 void *pRead_buf = NULL;
5514 void *pWrite_buf = NULL;
5516 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE +
sizeof(mz_uint32) - 1) /
5518 mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
5520 if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
5525 if (!file_stat.m_comp_size)
5532 if (mz_zip_reader_is_file_a_directory(pZip, file_index))
5536 if (file_stat.m_bit_flag & (1 | 32))
5540 if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) &&
5541 (file_stat.m_method != MZ_DEFLATED))
5545 cur_file_ofs = file_stat.m_local_header_ofs;
5546 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header,
5547 MZ_ZIP_LOCAL_DIR_HEADER_SIZE) !=
5548 MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
5550 if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
5553 cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE +
5554 MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) +
5555 MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
5556 if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
5561 if (pZip->m_pState->m_pMem) {
5562 pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
5563 read_buf_size = read_buf_avail = file_stat.m_comp_size;
5566 read_buf_size = MZ_MIN(file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE);
5567 if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1,
5568 (
size_t)read_buf_size)))
5571 comp_remaining = file_stat.m_comp_size;
5574 if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) {
5576 if (pZip->m_pState->m_pMem) {
5577 if (((
sizeof(
size_t) ==
sizeof(mz_uint32))) &&
5578 (file_stat.m_comp_size > 0xFFFFFFFF))
5581 if (pCallback(pOpaque, out_buf_ofs, pRead_buf,
5582 (
size_t)file_stat.m_comp_size) != file_stat.m_comp_size)
5583 status = TINFL_STATUS_FAILED;
5584 else if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
5586 (mz_uint32)mz_crc32(file_crc32, (
const mz_uint8 *)pRead_buf,
5587 (size_t)file_stat.m_comp_size);
5589 out_buf_ofs += file_stat.m_comp_size;
5592 while (comp_remaining) {
5593 read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
5594 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf,
5595 (
size_t)read_buf_avail) != read_buf_avail) {
5596 status = TINFL_STATUS_FAILED;
5600 if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
5601 file_crc32 = (mz_uint32)mz_crc32(
5602 file_crc32, (
const mz_uint8 *)pRead_buf, (size_t)read_buf_avail);
5604 if (pCallback(pOpaque, out_buf_ofs, pRead_buf,
5605 (
size_t)read_buf_avail) != read_buf_avail) {
5606 status = TINFL_STATUS_FAILED;
5609 cur_file_ofs += read_buf_avail;
5610 out_buf_ofs += read_buf_avail;
5611 comp_remaining -= read_buf_avail;
5616 tinfl_init(&inflator);
5618 if (NULL == (pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1,
5619 TINFL_LZ_DICT_SIZE)))
5620 status = TINFL_STATUS_FAILED;
5623 mz_uint8 *pWrite_buf_cur =
5624 (mz_uint8 *)pWrite_buf + (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
5627 TINFL_LZ_DICT_SIZE - (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
5628 if ((!read_buf_avail) && (!pZip->m_pState->m_pMem)) {
5629 read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
5630 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf,
5631 (
size_t)read_buf_avail) != read_buf_avail) {
5632 status = TINFL_STATUS_FAILED;
5635 cur_file_ofs += read_buf_avail;
5636 comp_remaining -= read_buf_avail;
5640 in_buf_size = (size_t)read_buf_avail;
5641 status = tinfl_decompress(
5642 &inflator, (
const mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size,
5643 (mz_uint8 *)pWrite_buf, pWrite_buf_cur, &out_buf_size,
5644 comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0);
5645 read_buf_avail -= in_buf_size;
5646 read_buf_ofs += in_buf_size;
5649 if (pCallback(pOpaque, out_buf_ofs, pWrite_buf_cur, out_buf_size) !=
5651 status = TINFL_STATUS_FAILED;
5655 (mz_uint32)mz_crc32(file_crc32, pWrite_buf_cur, out_buf_size);
5656 if ((out_buf_ofs += out_buf_size) > file_stat.m_uncomp_size) {
5657 status = TINFL_STATUS_FAILED;
5661 }
while ((status == TINFL_STATUS_NEEDS_MORE_INPUT) ||
5662 (status == TINFL_STATUS_HAS_MORE_OUTPUT));
5666 if ((status == TINFL_STATUS_DONE) &&
5667 (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))) {
5669 if ((out_buf_ofs != file_stat.m_uncomp_size) ||
5670 (file_crc32 != file_stat.m_crc32))
5671 status = TINFL_STATUS_FAILED;
5674 if (!pZip->m_pState->m_pMem)
5675 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
5677 pZip->m_pFree(pZip->m_pAlloc_opaque, pWrite_buf);
5679 return status == TINFL_STATUS_DONE;
5682mz_bool mz_zip_reader_extract_file_to_callback(
mz_zip_archive *pZip,
5683 const char *pFilename,
5684 mz_file_write_func pCallback,
5685 void *pOpaque, mz_uint flags) {
5686 int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags);
5689 return mz_zip_reader_extract_to_callback(pZip, file_index, pCallback, pOpaque,
5693#ifndef MINIZ_NO_STDIO
5694static size_t mz_zip_file_write_callback(
void *pOpaque, mz_uint64 ofs,
5695 const void *pBuf,
size_t n) {
5697 return MZ_FWRITE(pBuf, 1, n, (MZ_FILE *)pOpaque);
5700mz_bool mz_zip_reader_extract_to_file(
mz_zip_archive *pZip, mz_uint file_index,
5701 const char *pDst_filename,
5706 if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat))
5709 pFile = MZ_FOPEN(pDst_filename,
"wb");
5712 status = mz_zip_reader_extract_to_callback(
5713 pZip, file_index, mz_zip_file_write_callback, pFile, flags);
5714 if (MZ_FCLOSE(pFile) == EOF)
5716#ifndef MINIZ_NO_TIME
5718 mz_zip_set_file_times(pDst_filename, file_stat.m_time, file_stat.m_time);
5727 if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) ||
5728 (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
5732 pZip->m_pState = NULL;
5733 mz_zip_array_clear(pZip, &pState->m_central_dir);
5734 mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
5735 mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets);
5737#ifndef MINIZ_NO_STDIO
5738 if (pState->m_pFile) {
5739 MZ_FCLOSE(pState->m_pFile);
5740 pState->m_pFile = NULL;
5744 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
5746 pZip->m_zip_mode = MZ_ZIP_MODE_INVALID;
5751#ifndef MINIZ_NO_STDIO
5753 const char *pArchive_filename,
5754 const char *pDst_filename,
5757 mz_zip_reader_locate_file(pZip, pArchive_filename, NULL, flags);
5760 return mz_zip_reader_extract_to_file(pZip, file_index, pDst_filename, flags);
5766#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
5768static void mz_write_le16(mz_uint8 *p, mz_uint16 v) {
5770 p[1] = (mz_uint8)(v >> 8);
5772static void mz_write_le32(mz_uint8 *p, mz_uint32 v) {
5774 p[1] = (mz_uint8)(v >> 8);
5775 p[2] = (mz_uint8)(v >> 16);
5776 p[3] = (mz_uint8)(v >> 24);
5778#define MZ_WRITE_LE16(p, v) mz_write_le16((mz_uint8 *)(p), (mz_uint16)(v))
5779#define MZ_WRITE_LE32(p, v) mz_write_le32((mz_uint8 *)(p), (mz_uint32)(v))
5781mz_bool mz_zip_writer_init(
mz_zip_archive *pZip, mz_uint64 existing_size) {
5782 if ((!pZip) || (pZip->m_pState) || (!pZip->m_pWrite) ||
5783 (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
5786 if (pZip->m_file_offset_alignment) {
5788 if (pZip->m_file_offset_alignment & (pZip->m_file_offset_alignment - 1))
5792 if (!pZip->m_pAlloc)
5793 pZip->m_pAlloc = def_alloc_func;
5795 pZip->m_pFree = def_free_func;
5796 if (!pZip->m_pRealloc)
5797 pZip->m_pRealloc = def_realloc_func;
5799 pZip->m_zip_mode = MZ_ZIP_MODE_WRITING;
5800 pZip->m_archive_size = existing_size;
5801 pZip->m_central_directory_file_ofs = 0;
5802 pZip->m_total_files = 0;
5808 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir,
5810 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets,
5812 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets,
5817static size_t mz_zip_heap_write_func(
void *pOpaque, mz_uint64 file_ofs,
5818 const void *pBuf,
size_t n) {
5821 mz_uint64 new_size = MZ_MAX(file_ofs + n, pState->m_mem_size);
5824 ((
sizeof(
size_t) ==
sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF)))
5827 if (new_size > pState->m_mem_capacity) {
5829 size_t new_capacity = MZ_MAX(64, pState->m_mem_capacity);
5830 while (new_capacity < new_size)
5832 if (NULL == (pNew_block = pZip->m_pRealloc(
5833 pZip->m_pAlloc_opaque, pState->m_pMem, 1, new_capacity)))
5835 pState->m_pMem = pNew_block;
5836 pState->m_mem_capacity = new_capacity;
5838 memcpy((mz_uint8 *)pState->m_pMem + file_ofs, pBuf, n);
5839 pState->m_mem_size = (size_t)new_size;
5844 size_t size_to_reserve_at_beginning,
5845 size_t initial_allocation_size) {
5846 pZip->m_pWrite = mz_zip_heap_write_func;
5847 pZip->m_pIO_opaque = pZip;
5848 if (!mz_zip_writer_init(pZip, size_to_reserve_at_beginning))
5850 if (0 != (initial_allocation_size = MZ_MAX(initial_allocation_size,
5851 size_to_reserve_at_beginning))) {
5852 if (NULL == (pZip->m_pState->m_pMem = pZip->m_pAlloc(
5853 pZip->m_pAlloc_opaque, 1, initial_allocation_size))) {
5854 mz_zip_writer_end(pZip);
5857 pZip->m_pState->m_mem_capacity = initial_allocation_size;
5862#ifndef MINIZ_NO_STDIO
5863static size_t mz_zip_file_write_func(
void *pOpaque, mz_uint64 file_ofs,
5864 const void *pBuf,
size_t n) {
5866 mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
5867 if (((mz_int64)file_ofs < 0) ||
5868 (((cur_ofs != (mz_int64)file_ofs)) &&
5869 (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET))))
5871 return MZ_FWRITE(pBuf, 1, n, pZip->m_pState->m_pFile);
5874mz_bool mz_zip_writer_init_file(
mz_zip_archive *pZip,
const char *pFilename,
5875 mz_uint64 size_to_reserve_at_beginning) {
5877 pZip->m_pWrite = mz_zip_file_write_func;
5878 pZip->m_pIO_opaque = pZip;
5879 if (!mz_zip_writer_init(pZip, size_to_reserve_at_beginning))
5881 if (NULL == (pFile = MZ_FOPEN(pFilename,
"wb"))) {
5882 mz_zip_writer_end(pZip);
5885 pZip->m_pState->m_pFile = pFile;
5886 if (size_to_reserve_at_beginning) {
5887 mz_uint64 cur_ofs = 0;
5891 size_t n = (size_t)MZ_MIN(
sizeof(buf), size_to_reserve_at_beginning);
5892 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_ofs, buf, n) != n) {
5893 mz_zip_writer_end(pZip);
5897 size_to_reserve_at_beginning -= n;
5898 }
while (size_to_reserve_at_beginning);
5905 const char *pFilename) {
5907 if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
5911 if ((pZip->m_total_files == 0xFFFF) ||
5912 ((pZip->m_archive_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE +
5913 MZ_ZIP_LOCAL_DIR_HEADER_SIZE) > 0xFFFFFFFF))
5916 pState = pZip->m_pState;
5918 if (pState->m_pFile) {
5919#ifdef MINIZ_NO_STDIO
5924 if (pZip->m_pIO_opaque != pZip)
5928 pZip->m_pWrite = mz_zip_file_write_func;
5930 (pState->m_pFile = MZ_FREOPEN(pFilename,
"r+b", pState->m_pFile))) {
5933 mz_zip_reader_end(pZip);
5937 }
else if (pState->m_pMem) {
5940 if (pZip->m_pIO_opaque != pZip)
5942 pState->m_mem_capacity = pState->m_mem_size;
5943 pZip->m_pWrite = mz_zip_heap_write_func;
5947 else if (!pZip->m_pWrite)
5952 pZip->m_archive_size = pZip->m_central_directory_file_ofs;
5953 pZip->m_zip_mode = MZ_ZIP_MODE_WRITING;
5954 pZip->m_central_directory_file_ofs = 0;
5959mz_bool mz_zip_writer_add_mem(
mz_zip_archive *pZip,
const char *pArchive_name,
5960 const void *pBuf,
size_t buf_size,
5961 mz_uint level_and_flags) {
5962 return mz_zip_writer_add_mem_ex(pZip, pArchive_name, pBuf, buf_size, NULL, 0,
5963 level_and_flags, 0, 0);
5968 mz_uint64 m_cur_archive_file_ofs;
5969 mz_uint64 m_comp_size;
5972static mz_bool mz_zip_writer_add_put_buf_callback(
const void *pBuf,
int len,
5975 if ((
int)pState->m_pZip->m_pWrite(pState->m_pZip->m_pIO_opaque,
5976 pState->m_cur_archive_file_ofs, pBuf,
5979 pState->m_cur_archive_file_ofs += len;
5980 pState->m_comp_size += len;
5984static mz_bool mz_zip_writer_create_local_dir_header(
5986 mz_uint16 extra_size, mz_uint64 uncomp_size, mz_uint64 comp_size,
5987 mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags,
5988 mz_uint16 dos_time, mz_uint16 dos_date) {
5990 memset(pDst, 0, MZ_ZIP_LOCAL_DIR_HEADER_SIZE);
5991 MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_SIG_OFS, MZ_ZIP_LOCAL_DIR_HEADER_SIG);
5992 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_VERSION_NEEDED_OFS, method ? 20 : 0);
5993 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_BIT_FLAG_OFS, bit_flags);
5994 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_METHOD_OFS, method);
5995 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_TIME_OFS, dos_time);
5996 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_DATE_OFS, dos_date);
5997 MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_CRC32_OFS, uncomp_crc32);
5998 MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS, comp_size);
5999 MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS, uncomp_size);
6000 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILENAME_LEN_OFS, filename_size);
6001 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_EXTRA_LEN_OFS, extra_size);
6005static mz_bool mz_zip_writer_create_central_dir_header(
6007 mz_uint16 extra_size, mz_uint16 comment_size, mz_uint64 uncomp_size,
6008 mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method,
6009 mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date,
6010 mz_uint64 local_header_ofs, mz_uint32 ext_attributes) {
6012 mz_uint16 version_made_by = 10 * MZ_VER_MAJOR + MZ_VER_MINOR;
6013 version_made_by |= (MZ_PLATFORM << 8);
6015 memset(pDst, 0, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE);
6016 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_SIG_OFS, MZ_ZIP_CENTRAL_DIR_HEADER_SIG);
6017 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_VERSION_MADE_BY_OFS, version_made_by);
6018 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_VERSION_NEEDED_OFS, method ? 20 : 0);
6019 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_BIT_FLAG_OFS, bit_flags);
6020 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_METHOD_OFS, method);
6021 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_TIME_OFS, dos_time);
6022 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_DATE_OFS, dos_date);
6023 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_CRC32_OFS, uncomp_crc32);
6024 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS, comp_size);
6025 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS, uncomp_size);
6026 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILENAME_LEN_OFS, filename_size);
6027 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_EXTRA_LEN_OFS, extra_size);
6028 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_COMMENT_LEN_OFS, comment_size);
6029 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS, ext_attributes);
6030 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_LOCAL_HEADER_OFS, local_header_ofs);
6034static mz_bool mz_zip_writer_add_to_central_dir(
6035 mz_zip_archive *pZip,
const char *pFilename, mz_uint16 filename_size,
6036 const void *pExtra, mz_uint16 extra_size,
const void *pComment,
6037 mz_uint16 comment_size, mz_uint64 uncomp_size, mz_uint64 comp_size,
6038 mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags,
6039 mz_uint16 dos_time, mz_uint16 dos_date, mz_uint64 local_header_ofs,
6040 mz_uint32 ext_attributes) {
6042 mz_uint32 central_dir_ofs = (mz_uint32)pState->m_central_dir.m_size;
6043 size_t orig_central_dir_size = pState->m_central_dir.m_size;
6044 mz_uint8 central_dir_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE];
6047 if ((local_header_ofs > 0xFFFFFFFF) ||
6048 (((mz_uint64)pState->m_central_dir.m_size +
6049 MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + extra_size +
6050 comment_size) > 0xFFFFFFFF))
6053 if (!mz_zip_writer_create_central_dir_header(
6054 pZip, central_dir_header, filename_size, extra_size, comment_size,
6055 uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time,
6056 dos_date, local_header_ofs, ext_attributes))
6059 if ((!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_dir_header,
6060 MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) ||
6061 (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pFilename,
6063 (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pExtra,
6065 (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pComment,
6067 (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets,
6068 ¢ral_dir_ofs, 1))) {
6070 mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size,
6078static mz_bool mz_zip_writer_validate_archive_name(
const char *pArchive_name) {
6082 if (*pArchive_name ==
'/')
6084 while (*pArchive_name) {
6085 if ((*pArchive_name ==
'\\') || (*pArchive_name ==
':'))
6093mz_zip_writer_compute_padding_needed_for_file_alignment(
mz_zip_archive *pZip) {
6095 if (!pZip->m_file_offset_alignment)
6097 n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1));
6098 return (pZip->m_file_offset_alignment - n) &
6099 (pZip->m_file_offset_alignment - 1);
6103 mz_uint64 cur_file_ofs, mz_uint32 n) {
6105 memset(buf, 0, MZ_MIN(
sizeof(buf), n));
6107 mz_uint32 s = MZ_MIN(
sizeof(buf), n);
6108 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_file_ofs, buf, s) != s)
6117 const char *pArchive_name,
const void *pBuf,
6118 size_t buf_size,
const void *pComment,
6119 mz_uint16 comment_size,
6120 mz_uint level_and_flags, mz_uint64 uncomp_size,
6121 mz_uint32 uncomp_crc32) {
6122 mz_uint32 ext_attributes = 0;
6123 mz_uint16 method = 0, dos_time = 0, dos_date = 0;
6124 mz_uint level, num_alignment_padding_bytes;
6125 mz_uint64 local_dir_header_ofs, cur_archive_file_ofs, comp_size = 0;
6126 size_t archive_name_size;
6127 mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
6129 mz_bool store_data_uncompressed;
6132 if ((
int)level_and_flags < 0)
6133 level_and_flags = MZ_DEFAULT_LEVEL;
6134 level = level_and_flags & 0xF;
6135 store_data_uncompressed =
6136 ((!level) || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA));
6138 if ((!pZip) || (!pZip->m_pState) ||
6139 (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || ((buf_size) && (!pBuf)) ||
6140 (!pArchive_name) || ((comment_size) && (!pComment)) ||
6141 (pZip->m_total_files == 0xFFFF) || (level > MZ_UBER_COMPRESSION))
6144 local_dir_header_ofs = cur_archive_file_ofs = pZip->m_archive_size;
6145 pState = pZip->m_pState;
6147 if ((!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (uncomp_size))
6150 if ((buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF))
6152 if (!mz_zip_writer_validate_archive_name(pArchive_name))
6155#ifndef MINIZ_NO_TIME
6159 mz_zip_time_t_to_dos_time(cur_time, &dos_time, &dos_date);
6163 archive_name_size = strlen(pArchive_name);
6164 if (archive_name_size > 0xFFFF)
6167 num_alignment_padding_bytes =
6168 mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
6171 if ((pZip->m_total_files == 0xFFFF) ||
6172 ((pZip->m_archive_size + num_alignment_padding_bytes +
6173 MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE +
6174 comment_size + archive_name_size) > 0xFFFFFFFF))
6177 if ((archive_name_size) && (pArchive_name[archive_name_size - 1] ==
'/')) {
6179 ext_attributes |= 0x10;
6181 if ((buf_size) || (uncomp_size))
6188 if ((!mz_zip_array_ensure_room(pZip, &pState->m_central_dir,
6189 MZ_ZIP_CENTRAL_DIR_HEADER_SIZE +
6190 archive_name_size + comment_size)) ||
6191 (!mz_zip_array_ensure_room(pZip, &pState->m_central_dir_offsets, 1)))
6194 if ((!store_data_uncompressed) && (buf_size)) {
6200 if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs,
6201 num_alignment_padding_bytes +
6202 sizeof(local_dir_header))) {
6203 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6206 local_dir_header_ofs += num_alignment_padding_bytes;
6207 if (pZip->m_file_offset_alignment) {
6208 MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) ==
6211 cur_archive_file_ofs +=
6212 num_alignment_padding_bytes +
sizeof(local_dir_header);
6214 MZ_CLEAR_OBJ(local_dir_header);
6215 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name,
6216 archive_name_size) != archive_name_size) {
6217 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6220 cur_archive_file_ofs += archive_name_size;
6222 if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) {
6224 (mz_uint32)mz_crc32(MZ_CRC32_INIT, (
const mz_uint8 *)pBuf, buf_size);
6225 uncomp_size = buf_size;
6226 if (uncomp_size <= 3) {
6228 store_data_uncompressed = MZ_TRUE;
6232 if (store_data_uncompressed) {
6233 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pBuf,
6234 buf_size) != buf_size) {
6235 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6239 cur_archive_file_ofs += buf_size;
6240 comp_size = buf_size;
6242 if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)
6243 method = MZ_DEFLATED;
6244 }
else if (buf_size) {
6247 state.m_pZip = pZip;
6248 state.m_cur_archive_file_ofs = cur_archive_file_ofs;
6249 state.m_comp_size = 0;
6251 if ((tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state,
6252 tdefl_create_comp_flags_from_zip_params(
6253 level, -15, MZ_DEFAULT_STRATEGY)) !=
6254 TDEFL_STATUS_OKAY) ||
6255 (tdefl_compress_buffer(pComp, pBuf, buf_size, TDEFL_FINISH) !=
6256 TDEFL_STATUS_DONE)) {
6257 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6261 comp_size = state.m_comp_size;
6262 cur_archive_file_ofs = state.m_cur_archive_file_ofs;
6264 method = MZ_DEFLATED;
6267 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6271 if ((comp_size > 0xFFFFFFFF) || (cur_archive_file_ofs > 0xFFFFFFFF))
6274 if (!mz_zip_writer_create_local_dir_header(
6275 pZip, local_dir_header, (mz_uint16)archive_name_size, 0, uncomp_size,
6276 comp_size, uncomp_crc32, method, 0, dos_time, dos_date))
6279 if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header,
6280 sizeof(local_dir_header)) !=
sizeof(local_dir_header))
6283 if (!mz_zip_writer_add_to_central_dir(
6284 pZip, pArchive_name, (mz_uint16)archive_name_size, NULL, 0, pComment,
6285 comment_size, uncomp_size, comp_size, uncomp_crc32, method, 0,
6286 dos_time, dos_date, local_dir_header_ofs, ext_attributes))
6289 pZip->m_total_files++;
6290 pZip->m_archive_size = cur_archive_file_ofs;
6295#ifndef MINIZ_NO_STDIO
6296mz_bool mz_zip_writer_add_file(
mz_zip_archive *pZip,
const char *pArchive_name,
6297 const char *pSrc_filename,
const void *pComment,
6298 mz_uint16 comment_size, mz_uint level_and_flags,
6299 mz_uint32 ext_attributes) {
6300 mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes;
6301 mz_uint16 method = 0, dos_time = 0, dos_date = 0;
6302#ifndef MINIZ_NO_TIME
6303 time_t file_modified_time;
6306 mz_uint64 local_dir_header_ofs, cur_archive_file_ofs, uncomp_size = 0,
6308 size_t archive_name_size;
6309 mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
6310 MZ_FILE *pSrc_file = NULL;
6312 if ((
int)level_and_flags < 0)
6313 level_and_flags = MZ_DEFAULT_LEVEL;
6314 level = level_and_flags & 0xF;
6316 if ((!pZip) || (!pZip->m_pState) ||
6317 (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) ||
6318 ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION))
6321 local_dir_header_ofs = cur_archive_file_ofs = pZip->m_archive_size;
6323 if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)
6325 if (!mz_zip_writer_validate_archive_name(pArchive_name))
6328 archive_name_size = strlen(pArchive_name);
6329 if (archive_name_size > 0xFFFF)
6332 num_alignment_padding_bytes =
6333 mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
6336 if ((pZip->m_total_files == 0xFFFF) ||
6337 ((pZip->m_archive_size + num_alignment_padding_bytes +
6338 MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE +
6339 comment_size + archive_name_size) > 0xFFFFFFFF))
6342#ifndef MINIZ_NO_TIME
6343 memset(&file_modified_time, 0,
sizeof(file_modified_time));
6344 if (!mz_zip_get_file_modified_time(pSrc_filename, &file_modified_time))
6346 mz_zip_time_t_to_dos_time(file_modified_time, &dos_time, &dos_date);
6349 pSrc_file = MZ_FOPEN(pSrc_filename,
"rb");
6352 MZ_FSEEK64(pSrc_file, 0, SEEK_END);
6353 uncomp_size = MZ_FTELL64(pSrc_file);
6354 MZ_FSEEK64(pSrc_file, 0, SEEK_SET);
6356 if (uncomp_size > 0xFFFFFFFF) {
6358 MZ_FCLOSE(pSrc_file);
6361 if (uncomp_size <= 3)
6364 if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs,
6365 num_alignment_padding_bytes +
6366 sizeof(local_dir_header))) {
6367 MZ_FCLOSE(pSrc_file);
6370 local_dir_header_ofs += num_alignment_padding_bytes;
6371 if (pZip->m_file_offset_alignment) {
6372 MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) ==
6375 cur_archive_file_ofs +=
6376 num_alignment_padding_bytes +
sizeof(local_dir_header);
6378 MZ_CLEAR_OBJ(local_dir_header);
6379 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name,
6380 archive_name_size) != archive_name_size) {
6381 MZ_FCLOSE(pSrc_file);
6384 cur_archive_file_ofs += archive_name_size;
6387 mz_uint64 uncomp_remaining = uncomp_size;
6389 pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, MZ_ZIP_MAX_IO_BUF_SIZE);
6391 MZ_FCLOSE(pSrc_file);
6396 while (uncomp_remaining) {
6397 mz_uint n = (mz_uint)MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE, uncomp_remaining);
6398 if ((MZ_FREAD(pRead_buf, 1, n, pSrc_file) != n) ||
6399 (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf,
6401 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6402 MZ_FCLOSE(pSrc_file);
6406 (mz_uint32)mz_crc32(uncomp_crc32, (
const mz_uint8 *)pRead_buf, n);
6407 uncomp_remaining -= n;
6408 cur_archive_file_ofs += n;
6410 comp_size = uncomp_size;
6412 mz_bool result = MZ_FALSE;
6417 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6418 MZ_FCLOSE(pSrc_file);
6422 state.m_pZip = pZip;
6423 state.m_cur_archive_file_ofs = cur_archive_file_ofs;
6424 state.m_comp_size = 0;
6426 if (tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state,
6427 tdefl_create_comp_flags_from_zip_params(
6428 level, -15, MZ_DEFAULT_STRATEGY)) !=
6429 TDEFL_STATUS_OKAY) {
6430 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6431 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6432 MZ_FCLOSE(pSrc_file);
6437 size_t in_buf_size =
6438 (mz_uint32)MZ_MIN(uncomp_remaining, MZ_ZIP_MAX_IO_BUF_SIZE);
6439 tdefl_status status;
6441 if (MZ_FREAD(pRead_buf, 1, in_buf_size, pSrc_file) != in_buf_size)
6444 uncomp_crc32 = (mz_uint32)mz_crc32(
6445 uncomp_crc32, (
const mz_uint8 *)pRead_buf, in_buf_size);
6446 uncomp_remaining -= in_buf_size;
6448 status = tdefl_compress_buffer(pComp, pRead_buf, in_buf_size,
6449 uncomp_remaining ? TDEFL_NO_FLUSH
6451 if (status == TDEFL_STATUS_DONE) {
6454 }
else if (status != TDEFL_STATUS_OKAY)
6458 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
6461 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6462 MZ_FCLOSE(pSrc_file);
6466 comp_size = state.m_comp_size;
6467 cur_archive_file_ofs = state.m_cur_archive_file_ofs;
6469 method = MZ_DEFLATED;
6472 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
6475 MZ_FCLOSE(pSrc_file);
6479 if ((comp_size > 0xFFFFFFFF) || (cur_archive_file_ofs > 0xFFFFFFFF))
6482 if (!mz_zip_writer_create_local_dir_header(
6483 pZip, local_dir_header, (mz_uint16)archive_name_size, 0, uncomp_size,
6484 comp_size, uncomp_crc32, method, 0, dos_time, dos_date))
6487 if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header,
6488 sizeof(local_dir_header)) !=
sizeof(local_dir_header))
6491 if (!mz_zip_writer_add_to_central_dir(
6492 pZip, pArchive_name, (mz_uint16)archive_name_size, NULL, 0, pComment,
6493 comment_size, uncomp_size, comp_size, uncomp_crc32, method, 0,
6494 dos_time, dos_date, local_dir_header_ofs, ext_attributes))
6497 pZip->m_total_files++;
6498 pZip->m_archive_size = cur_archive_file_ofs;
6506 mz_uint file_index) {
6507 mz_uint n, bit_flags, num_alignment_padding_bytes;
6508 mz_uint64 comp_bytes_remaining, local_dir_header_ofs;
6509 mz_uint64 cur_src_file_ofs, cur_dst_file_ofs;
6511 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE +
sizeof(mz_uint32) - 1) /
6513 mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
6514 mz_uint8 central_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE];
6515 size_t orig_central_dir_size;
6518 const mz_uint8 *pSrc_central_header;
6520 if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING))
6523 (pSrc_central_header = mz_zip_reader_get_cdh(pSource_zip, file_index)))
6525 pState = pZip->m_pState;
6527 num_alignment_padding_bytes =
6528 mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
6531 if ((pZip->m_total_files == 0xFFFF) ||
6532 ((pZip->m_archive_size + num_alignment_padding_bytes +
6533 MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) >
6538 MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
6539 cur_dst_file_ofs = pZip->m_archive_size;
6541 if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs,
6542 pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) !=
6543 MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
6545 if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
6547 cur_src_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE;
6549 if (!mz_zip_writer_write_zeros(pZip, cur_dst_file_ofs,
6550 num_alignment_padding_bytes))
6552 cur_dst_file_ofs += num_alignment_padding_bytes;
6553 local_dir_header_ofs = cur_dst_file_ofs;
6554 if (pZip->m_file_offset_alignment) {
6555 MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) ==
6559 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pLocal_header,
6560 MZ_ZIP_LOCAL_DIR_HEADER_SIZE) !=
6561 MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
6563 cur_dst_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE;
6565 n = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) +
6566 MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
6567 comp_bytes_remaining =
6568 n + MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
6571 (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1,
6572 (
size_t)MZ_MAX(
sizeof(mz_uint32) * 4,
6573 MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE,
6574 comp_bytes_remaining)))))
6577 while (comp_bytes_remaining) {
6578 n = (mz_uint)MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE, comp_bytes_remaining);
6579 if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf,
6581 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
6584 cur_src_file_ofs += n;
6586 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n) {
6587 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
6590 cur_dst_file_ofs += n;
6592 comp_bytes_remaining -= n;
6595 bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS);
6596 if (bit_flags & 8) {
6598 if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf,
6599 sizeof(mz_uint32) * 4) !=
sizeof(mz_uint32) * 4) {
6600 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
6604 n =
sizeof(mz_uint32) * ((MZ_READ_LE32(pBuf) == 0x08074b50) ? 4 : 3);
6605 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n) {
6606 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
6611 cur_dst_file_ofs += n;
6613 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
6616 if (cur_dst_file_ofs > 0xFFFFFFFF)
6619 orig_central_dir_size = pState->m_central_dir.m_size;
6621 memcpy(central_header, pSrc_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE);
6622 MZ_WRITE_LE32(central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS,
6623 local_dir_header_ofs);
6624 if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_header,
6625 MZ_ZIP_CENTRAL_DIR_HEADER_SIZE))
6628 n = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_FILENAME_LEN_OFS) +
6629 MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS) +
6630 MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_COMMENT_LEN_OFS);
6631 if (!mz_zip_array_push_back(
6632 pZip, &pState->m_central_dir,
6633 pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n)) {
6634 mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size,
6639 if (pState->m_central_dir.m_size > 0xFFFFFFFF)
6641 n = (mz_uint32)orig_central_dir_size;
6642 if (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &n, 1)) {
6643 mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size,
6648 pZip->m_total_files++;
6649 pZip->m_archive_size = cur_dst_file_ofs;
6656 mz_uint64 central_dir_ofs, central_dir_size;
6657 mz_uint8 hdr[MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE];
6659 if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING))
6662 pState = pZip->m_pState;
6665 if ((pZip->m_total_files > 0xFFFF) ||
6666 ((pZip->m_archive_size + pState->m_central_dir.m_size +
6667 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF))
6670 central_dir_ofs = 0;
6671 central_dir_size = 0;
6672 if (pZip->m_total_files) {
6674 central_dir_ofs = pZip->m_archive_size;
6675 central_dir_size = pState->m_central_dir.m_size;
6676 pZip->m_central_directory_file_ofs = central_dir_ofs;
6677 if (pZip->m_pWrite(pZip->m_pIO_opaque, central_dir_ofs,
6678 pState->m_central_dir.m_p,
6679 (
size_t)central_dir_size) != central_dir_size)
6681 pZip->m_archive_size += central_dir_size;
6686 MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_SIG_OFS,
6687 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG);
6688 MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS,
6689 pZip->m_total_files);
6690 MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS, pZip->m_total_files);
6691 MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_SIZE_OFS, central_dir_size);
6692 MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_OFS_OFS, central_dir_ofs);
6694 if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr,
6695 sizeof(hdr)) !=
sizeof(hdr))
6697#ifndef MINIZ_NO_STDIO
6698 if ((pState->m_pFile) && (MZ_FFLUSH(pState->m_pFile) == EOF))
6702 pZip->m_archive_size +=
sizeof(hdr);
6704 pZip->m_zip_mode = MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED;
6708mz_bool mz_zip_writer_finalize_heap_archive(
mz_zip_archive *pZip,
void **pBuf,
6710 if ((!pZip) || (!pZip->m_pState) || (!pBuf) || (!pSize))
6712 if (pZip->m_pWrite != mz_zip_heap_write_func)
6714 if (!mz_zip_writer_finalize_archive(pZip))
6717 *pBuf = pZip->m_pState->m_pMem;
6718 *pSize = pZip->m_pState->m_mem_size;
6719 pZip->m_pState->m_pMem = NULL;
6720 pZip->m_pState->m_mem_size = pZip->m_pState->m_mem_capacity = 0;
6726 mz_bool status = MZ_TRUE;
6727 if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) ||
6728 ((pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) &&
6729 (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED)))
6732 pState = pZip->m_pState;
6733 pZip->m_pState = NULL;
6734 mz_zip_array_clear(pZip, &pState->m_central_dir);
6735 mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
6736 mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets);
6738#ifndef MINIZ_NO_STDIO
6739 if (pState->m_pFile) {
6740 MZ_FCLOSE(pState->m_pFile);
6741 pState->m_pFile = NULL;
6745 if ((pZip->m_pWrite == mz_zip_heap_write_func) && (pState->m_pMem)) {
6746 pZip->m_pFree(pZip->m_pAlloc_opaque, pState->m_pMem);
6747 pState->m_pMem = NULL;
6750 pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
6751 pZip->m_zip_mode = MZ_ZIP_MODE_INVALID;
6755#ifndef MINIZ_NO_STDIO
6756mz_bool mz_zip_add_mem_to_archive_file_in_place(
6757 const char *pZip_filename,
const char *pArchive_name,
const void *pBuf,
6758 size_t buf_size,
const void *pComment, mz_uint16 comment_size,
6759 mz_uint level_and_flags) {
6760 mz_bool status, created_new_archive = MZ_FALSE;
6762 struct MZ_FILE_STAT_STRUCT file_stat;
6763 MZ_CLEAR_OBJ(zip_archive);
6764 if ((
int)level_and_flags < 0)
6765 level_and_flags = MZ_DEFAULT_LEVEL;
6766 if ((!pZip_filename) || (!pArchive_name) || ((buf_size) && (!pBuf)) ||
6767 ((comment_size) && (!pComment)) ||
6768 ((level_and_flags & 0xF) > MZ_UBER_COMPRESSION))
6770 if (!mz_zip_writer_validate_archive_name(pArchive_name))
6772 if (MZ_FILE_STAT(pZip_filename, &file_stat) != 0) {
6774 if (!mz_zip_writer_init_file(&zip_archive, pZip_filename, 0))
6776 created_new_archive = MZ_TRUE;
6779 if (!mz_zip_reader_init_file(&zip_archive, pZip_filename,
6781 MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY))
6783 if (!mz_zip_writer_init_from_reader(&zip_archive, pZip_filename)) {
6784 mz_zip_reader_end(&zip_archive);
6789 mz_zip_writer_add_mem_ex(&zip_archive, pArchive_name, pBuf, buf_size,
6790 pComment, comment_size, level_and_flags, 0, 0);
6793 if (!mz_zip_writer_finalize_archive(&zip_archive))
6795 if (!mz_zip_writer_end(&zip_archive))
6797 if ((!status) && (created_new_archive)) {
6799 int ignoredStatus = MZ_DELETE_FILE(pZip_filename);
6800 (void)ignoredStatus;
6805void *mz_zip_extract_archive_file_to_heap(
const char *pZip_filename,
6806 const char *pArchive_name,
6807 size_t *pSize, mz_uint flags) {
6815 if ((!pZip_filename) || (!pArchive_name))
6818 MZ_CLEAR_OBJ(zip_archive);
6819 if (!mz_zip_reader_init_file(&zip_archive, pZip_filename,
6821 MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY))
6824 if ((file_index = mz_zip_reader_locate_file(&zip_archive, pArchive_name, NULL,
6826 p = mz_zip_reader_extract_to_heap(&zip_archive, file_index, pSize, flags);
6828 mz_zip_reader_end(&zip_archive);