/ miniz_win32.h
miniz_win32.h
1 /* miniz.c v1.11 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing 2 See "unlicense" statement at the end of this file. 3 Rich Geldreich <richgel99@gmail.com>, last updated May 27, 2011 4 Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt 5 6 Most API's defined in miniz.c are optional. For example, to disable the archive related functions just define 7 MINIZ_NO_ARCHIVE_APIS, or to get rid of all stdio usage define MINIZ_NO_STDIO (see the list below for more macros). 8 9 * Change History 10 May 15, v1.09 - Initial stable release. 11 May 27, v1.10 - Substantial compressor optimizations: 12 Level 1 is now ~4x faster than before. The L1 compressor's throughput now varies between 70-110MB/sec. on a 13 Core i7 (actual throughput varies depending on the type of data, and x64 vs. x86). 14 Improved baseline L2-L9 compression perf. Also, greatly improved compression perf. issues on some file types. 15 Refactored the compression code for better readability and maintainability. 16 Added level 10 compression level (L10 has slightly better ratio than level 9, but could have a potentially large 17 drop in throughput on some files). 18 May 28, v1.11 - Added statement from unlicense.org 19 20 * Deflate/Inflate implementation notes: 21 22 Compression: Use the "tdefl" API's. The compressor supports raw, static, and dynamic blocks, lazy or 23 greedy parsing, match length filtering, RLE-only, and Huffman-only streams. It performs and compresses 24 approximately as well as zlib. 25 26 Decompression: Use the "tinfl" API's. The entire decompressor is implemented as a single function 27 coroutine: see tinfl_decompress(). It supports decompression into a 32KB wrapping buffer or into a memory 28 block large enough to hold the entire file. 29 30 The low-level tdefl/tinfl API's do not make any use of dynamic memory allocation. 31 32 * zlib-style API notes: 33 34 miniz.c implements a fairly large subset of zlib. There's enough functionality present for it to be a drop-in 35 zlib replacement in many apps: 36 The z_stream struct, optional memory allocation callbacks 37 deflateInit/deflateInit2/deflate/deflateReset/deflateEnd/deflateBound 38 inflateInit/inflateInit2/inflate/inflateEnd 39 compress, compress2, compressBound, uncompress 40 CRC-32, Adler-32 41 Supports raw deflate streams or standard zlib streams with adler-32 checking. 42 43 Limitations: 44 The callback API's are not implemented yet. No support for gzip headers or zlib static dictionaries. 45 I've tried to closely emulate zlib's various flavors of stream flushing and return status codes, but 46 there are no guarantees that miniz.c pulls this off perfectly. 47 48 * PNG writing: See the tdefl_write_image_to_png_file_in_memory() function, originally written by 49 Alex Evans. Supports 1-4 bytes/pixel images. 50 51 * ZIP archive API notes: 52 53 The ZIP archive API's where designed with simplicity and efficiency in mind, with just enough abstraction to 54 get the job done with minimal fuss. There are simple API's to retrieve file information, read files from 55 existing archives, create new archives, append new files to existing archives, or clone archive data from 56 one archive to another. It supports archives located in memory or the heap, on disk (using stdio.h), 57 or you can specify custom file read/write callbacks. 58 59 - Archive reading: Just call this function to read a single file from a disk archive: 60 61 void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, 62 size_t *pSize, mz_uint zip_flags); 63 64 For more complex cases, use the "mz_zip_reader" functions. Upon opening an archive, the entire central 65 directory is located and read as-is into memory, and subsequent file access only occurs when reading individual files. 66 67 - Archives file scanning: The simple way is to use this function to scan a loaded archive for a specific file: 68 69 int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags); 70 71 The locate operation can optionally check file comments too, which (as one example) can be used to identify 72 multiple versions of the same file in an archive. This function uses a simple linear search through the central 73 directory, so it's not very fast. 74 75 Alternately, you can iterate through all the files in an archive (using mz_zip_reader_get_num_files()) and 76 retrieve detailed info on each file by calling mz_zip_reader_file_stat(). 77 78 - Archive creation: Use the "mz_zip_writer" functions. The ZIP writer immediately writes compressed file data 79 to disk and builds an exact image of the central directory in memory. The central directory image is written 80 all at once at the end of the archive file when the archive is finalized. 81 82 The archive writer can optionally align each file's local header and file data to any power of 2 alignment, 83 which can be useful when the archive will be read from optical media. Also, the writer supports placing 84 arbitrary data blobs at the very beginning of ZIP archives. Archives written using either feature are still 85 readable by any ZIP tool. 86 87 - Archive appending: The simple way to add a single file to an archive is to call this function: 88 89 mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, 90 const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags); 91 92 The archive will be created if it doesn't already exist, otherwise it'll be appended to. 93 Note the appending is done in-place and is not an atomic operation, so if something goes wrong 94 during the operation it's possible the archive could be left without a central directory (although the local 95 file headers and file data will be fine, so the archive will be recoverable). 96 97 For more complex archive modification scenarios: 98 1. The safest way is to use a mz_zip_reader to read the existing archive, cloning only those bits you want to 99 preserve into a new archive using using the mz_zip_writer_add_from_zip_reader() function (which compiles the 100 compressed file data as-is). When you're done, delete the old archive and rename the newly written archive, and 101 you're done. This is safe but requires a bunch of temporary disk space or heap memory. 102 103 2. Or, you can convert an mz_zip_reader in-place to an mz_zip_writer using mz_zip_writer_init_from_reader(), 104 append new files as needed, then finalize the archive which will write an updated central directory to the 105 original archive. (This is basically what mz_zip_add_mem_to_archive_file_in_place() does.) There's a 106 possibility that the archive's central directory could be lost with this method if anything goes wrong, though. 107 108 - ZIP archive support limitations: 109 No zip64 or spanning support. Extraction functions can only handle unencrypted, stored or deflated files. 110 Requires streams capable of seeking. 111 112 * This is a header file library, like stb_image.c. To get only a header file, either cut and paste the 113 below header, or create miniz.h, #define MINIZ_HEADER_FILE_ONLY, and then include miniz.c from it. 114 115 * Important: For best perf. be sure to customize the below macros for your target platform: 116 #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1 117 #define MINIZ_LITTLE_ENDIAN 1 118 #define MINIZ_HAS_64BIT_REGISTERS 1 119 */ 120 121 #ifndef MINIZ_HEADER_INCLUDED 122 #define MINIZ_HEADER_INCLUDED 123 124 #include <stdlib.h> 125 126 // Defines to completely disable specific portions of miniz.c: 127 // If all macros here are defined the only functionality remaining will be CRC-32, adler-32, tinfl, and tdefl. 128 129 // Define MINIZ_NO_STDIO to disable all usage and any functions which rely on stdio for file I/O. 130 //#define MINIZ_NO_STDIO 131 132 // If MINIZ_NO_TIME is specified then the ZIP archive functions will not be able to get the current time, or 133 // get/set file times. 134 #define MINIZ_NO_TIME 135 136 // Define MINIZ_NO_ARCHIVE_APIS to disable all ZIP archive API's. 137 //#define MINIZ_NO_ARCHIVE_APIS 138 139 // Define MINIZ_NO_ARCHIVE_APIS to disable all writing related ZIP archive API's. 140 #define MINIZ_NO_ARCHIVE_WRITING_APIS 141 142 // Define MINIZ_NO_ZLIB_APIS to remove all ZLIB-style compression/decompression API's. 143 //#define MINIZ_NO_ZLIB_APIS 144 145 // Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent conflicts against stock zlib. 146 //#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES 147 148 // Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc. 149 // Note if MINIZ_NO_MALLOC is defined then the user must always provide custom user alloc/free/realloc 150 // callbacks to the zlib and archive API's, and a few stand-alone helper API's which don't provide custom user 151 // functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work. 152 //#define MINIZ_NO_MALLOC 153 154 #if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__) 155 // MINIZ_X86_OR_X64_CPU is only used to help set the below macros. 156 #define MINIZ_X86_OR_X64_CPU 1 157 #endif 158 159 #if (__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU 160 // Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. 161 #define MINIZ_LITTLE_ENDIAN 1 162 #endif 163 164 #if MINIZ_X86_OR_X64_CPU 165 // Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient integer loads and stores from unaligned addresses. 166 #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1 167 #endif 168 169 #if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) || defined(__ia64__) || defined(__x86_64__) 170 // Set MINIZ_HAS_64BIT_REGISTERS to 1 if operations on 64-bit integers are reasonably fast (and don't involve compiler generated calls to helper functions). 171 #define MINIZ_HAS_64BIT_REGISTERS 1 172 #endif 173 174 #ifdef __cplusplus 175 extern "C" { 176 #endif 177 178 // ------------------- zlib-style API Definitions. 179 180 // For more compatibility with zlib, miniz.c uses unsigned long for some parameters/struct members. 181 typedef unsigned long mz_ulong; 182 183 // Heap allocation callbacks. 184 // Note that mz_alloc_func parameter types purpsosely differ from zlib's: items/size is size_t, not unsigned long. 185 typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size); 186 typedef void (*mz_free_func)(void *opaque, void *address); 187 typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size); 188 189 #define MZ_ADLER32_INIT (1) 190 // mz_adler32() returns the initial adler-32 value to use when called with ptr==NULL. 191 mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len); 192 193 #define MZ_CRC32_INIT (0) 194 // mz_crc32() returns the initial CRC-32 value to use when called with ptr==NULL. 195 mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len); 196 197 // Compression strategies. 198 enum { MZ_DEFAULT_STRATEGY = 0, MZ_FILTERED = 1, MZ_HUFFMAN_ONLY = 2, MZ_RLE = 3, MZ_FIXED = 4 }; 199 200 // Method 201 #define MZ_DEFLATED 8 202 203 #ifndef MINIZ_NO_ZLIB_APIS 204 205 #define MZ_VERSION "9.1.11" 206 #define MZ_VERNUM 0x91B0 207 #define MZ_VER_MAJOR 9 208 #define MZ_VER_MINOR 1 209 #define MZ_VER_REVISION 11 210 #define MZ_VER_SUBREVISION 0 211 212 // Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The other stuff is for advanced use. 213 enum { MZ_NO_FLUSH = 0, MZ_PARTIAL_FLUSH = 1, MZ_SYNC_FLUSH = 2, MZ_FULL_FLUSH = 3, MZ_FINISH = 4, MZ_BLOCK = 5 }; 214 215 // Return status codes. MZ_PARAM_ERROR is non-standard. 216 enum { MZ_OK = 0, MZ_STREAM_END = 1, MZ_NEED_DICT = 2, MZ_ERRNO = -1, MZ_STREAM_ERROR = -2, MZ_DATA_ERROR = -3, MZ_MEM_ERROR = -4, MZ_BUF_ERROR = -5, MZ_VERSION_ERROR = -6, MZ_PARAM_ERROR = -10000 }; 217 218 // Compression levels. 219 enum { MZ_NO_COMPRESSION = 0, MZ_BEST_SPEED = 1, MZ_BEST_COMPRESSION = 9, MZ_DEFAULT_COMPRESSION = -1 }; 220 221 // Window bits 222 #define MZ_DEFAULT_WINDOW_BITS 15 223 224 struct mz_internal_state; 225 226 // Compression/decompression stream struct. 227 typedef struct mz_stream_s 228 { 229 const unsigned char *next_in; // pointer to next byte to read 230 unsigned int avail_in; // number of bytes available at next_in 231 mz_ulong total_in; // total number of bytes consumed so far 232 233 unsigned char *next_out; // pointer to next byte to write 234 unsigned int avail_out; // number of bytes that can be written to next_out 235 mz_ulong total_out; // total number of bytes produced so far 236 237 char *msg; // error msg (unused) 238 struct mz_internal_state *state; // internal state, allocated by zalloc/zfree 239 240 mz_alloc_func zalloc; // optional heap allocation function (defaults to malloc) 241 mz_free_func zfree; // optional heap free function (defaults to free) 242 void *opaque; // heap alloc function user pointer 243 244 int data_type; // data_type (unused) 245 mz_ulong adler; // adler32 of the source or uncompressed data 246 mz_ulong reserved; // not used 247 } mz_stream; 248 249 typedef mz_stream *mz_streamp; 250 251 // Returns the version string of miniz.c. 252 const char *mz_version(void); 253 254 // mz_deflateInit() initializes a compressor with default options: 255 // Parameters: 256 // pStream must point to an initialized mz_stream struct. 257 // level must be between [MZ_NO_COMPRESSION, MZ_BEST_COMPRESSION]. 258 // level 1 enables a specially optimized compression function that's been optimized purely for performance, not ratio. 259 // (This special func. is currently only enabled when MINIZ_USE_UNALIGNED_LOADS_AND_STORES and MINIZ_LITTLE_ENDIAN are defined.) 260 // Return values: 261 // MZ_OK on success. 262 // MZ_STREAM_ERROR if the stream is bogus. 263 // MZ_PARAM_ERROR if the input parameters are bogus. 264 // MZ_MEM_ERROR on out of memory. 265 int mz_deflateInit(mz_streamp pStream, int level); 266 267 // mz_deflateInit2() is like mz_deflate(), except with more control: 268 // Additional parameters: 269 // method must be MZ_DEFLATED 270 // window_bits must be MZ_DEFAULT_WINDOW_BITS (to wrap the deflate stream with zlib header/adler-32 footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate/no header or footer) 271 // mem_level must be between [1, 9] (it's checked but ignored by miniz.c) 272 int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy); 273 274 // Quickly resets a compressor without having to reallocate anything. Same as calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2(). 275 int mz_deflateReset(mz_streamp pStream); 276 277 // mz_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible. 278 // Parameters: 279 // pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. 280 // flush may be MZ_NO_FLUSH, MZ_PARTIAL_FLUSH/MZ_SYNC_FLUSH, MZ_FULL_FLUSH, or MZ_FINISH. 281 // Return values: 282 // MZ_OK on success (when flushing, or if more input is needed but not available, and/or there's more output to be written but the output buffer is full). 283 // MZ_STREAM_END if all input has been consumed and all output bytes have been written. Don't call mz_deflate() on the stream anymore. 284 // MZ_STREAM_ERROR if the stream is bogus. 285 // MZ_PARAM_ERROR if one of the parameters is invalid. 286 // MZ_BUF_ERROR if no forward progress is possible because the input and/or output buffers are empty. (Fill up the input buffer or free up some output space and try again.) 287 int mz_deflate(mz_streamp pStream, int flush); 288 289 // mz_deflateEnd() deinitializes a compressor: 290 // Return values: 291 // MZ_OK on success. 292 // MZ_STREAM_ERROR if the stream is bogus. 293 int mz_deflateEnd(mz_streamp pStream); 294 295 // mz_deflateBound() returns a (very) conservative upper bound on the amount of data that could be generated by deflate(), assuming flush is set to only MZ_NO_FLUSH or MZ_FINISH. 296 mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len); 297 298 // Single-call compression functions mz_compress() and mz_compress2(): 299 // Returns MZ_OK on success, or one of the error codes from mz_deflate() on failure. 300 int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len); 301 int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level); 302 303 // mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress(). 304 mz_ulong mz_compressBound(mz_ulong source_len); 305 306 // Initializes a decompressor. 307 int mz_inflateInit(mz_streamp pStream); 308 309 // mz_inflateInit2() is like mz_inflateInit() with an additional option that controls the window size and whether or not the stream has been wrapped with a zlib header/footer: 310 // window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate). 311 int mz_inflateInit2(mz_streamp pStream, int window_bits); 312 313 // Decompresses the input stream to the output, consuming only as much of the input as needed, and writing as much to the output as possible. 314 // Parameters: 315 // pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. 316 // flush may be MZ_NO_FLUSH, MZ_SYNC_FLUSH, or MZ_FINISH. 317 // On the first call, if flush is MZ_FINISH it's assumed the input and output buffers are both sized large enough to decompress the entire stream in a single call (this is slightly faster). 318 // MZ_FINISH implies that there are no more source bytes available beside what's already in the input buffer, and that the output buffer is large enough to hold the rest of the decompressed data. 319 // Return values: 320 // MZ_OK on success. Either more input is needed but not available, and/or there's more output to be written but the output buffer is full. 321 // MZ_STREAM_END if all needed input has been consumed and all output bytes have been written. For zlib streams, the adler-32 of the decompressed data has also been verified. 322 // MZ_STREAM_ERROR if the stream is bogus. 323 // MZ_DATA_ERROR if the deflate stream is invalid. 324 // MZ_PARAM_ERROR if one of the parameters is invalid. 325 // MZ_BUF_ERROR if no forward progress is possible because the input buffer is empty but the inflater needs more input to continue, or if the output buffer is not large enough. Call mz_inflate() again 326 // with more input data, or with more room in the output buffer (except when using single call decompression, described above). 327 int mz_inflate(mz_streamp pStream, int flush); 328 329 // Deinitializes a decompressor. 330 int mz_inflateEnd(mz_streamp pStream); 331 332 // Single-call decompression. 333 // Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure. 334 int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len); 335 336 // Returns a string description of the specified error code, or NULL if the error code is invalid. 337 const char *mz_error(int err); 338 339 // Redefine zlib-compatible names to miniz equivalents, so miniz.c can be used as a drop-in replacement for the subset of zlib that miniz.c supports. 340 // Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project. 341 #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES 342 typedef unsigned char Byte; 343 typedef unsigned int uInt; 344 typedef mz_ulong uLong; 345 typedef Byte Bytef; 346 typedef uInt uIntf; 347 typedef char charf; 348 typedef int intf; 349 typedef void *voidpf; 350 typedef uLong uLongf; 351 typedef void *voidp; 352 typedef void *const voidpc; 353 #define Z_NULL 0 354 #define Z_NO_FLUSH MZ_NO_FLUSH 355 #define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH 356 #define Z_SYNC_FLUSH MZ_SYNC_FLUSH 357 #define Z_FULL_FLUSH MZ_FULL_FLUSH 358 #define Z_FINISH MZ_FINISH 359 #define Z_BLOCK MZ_BLOCK 360 #define Z_OK MZ_OK 361 #define Z_STREAM_END MZ_STREAM_END 362 #define Z_NEED_DICT MZ_NEED_DICT 363 #define Z_ERRNO MZ_ERRNO 364 #define Z_STREAM_ERROR MZ_STREAM_ERROR 365 #define Z_DATA_ERROR MZ_DATA_ERROR 366 #define Z_MEM_ERROR MZ_MEM_ERROR 367 #define Z_BUF_ERROR MZ_BUF_ERROR 368 #define Z_VERSION_ERROR MZ_VERSION_ERROR 369 #define Z_PARAM_ERROR MZ_PARAM_ERROR 370 #define Z_NO_COMPRESSION MZ_NO_COMPRESSION 371 #define Z_BEST_SPEED MZ_BEST_SPEED 372 #define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION 373 #define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION 374 #define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY 375 #define Z_FILTERED MZ_FILTERED 376 #define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY 377 #define Z_RLE MZ_RLE 378 #define Z_FIXED MZ_FIXED 379 #define Z_DEFLATED MZ_DEFLATED 380 #define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS 381 #define alloc_func mz_alloc_func 382 #define free_func mz_free_func 383 #define internal_state mz_internal_state 384 #define z_stream mz_stream 385 #define deflateInit mz_deflateInit 386 #define deflateInit2 mz_deflateInit2 387 #define deflateReset mz_deflateReset 388 #define deflate mz_deflate 389 #define deflateEnd mz_deflateEnd 390 #define deflateBound mz_deflateBound 391 #define compress mz_compress 392 #define compress2 mz_compress2 393 #define compressBound mz_compressBound 394 #define inflateInit mz_inflateInit 395 #define inflateInit2 mz_inflateInit2 396 #define inflate mz_inflate 397 #define inflateEnd mz_inflateEnd 398 #define uncompress mz_uncompress 399 #define crc32 mz_crc32 400 #define adler32 mz_adler32 401 #define MAX_WBITS 15 402 #define MAX_MEM_LEVEL 9 403 #define zError mz_error 404 #define ZLIB_VERSION MZ_VERSION 405 #define ZLIB_VERNUM MZ_VERNUM 406 #define ZLIB_VER_MAJOR MZ_VER_MAJOR 407 #define ZLIB_VER_MINOR MZ_VER_MINOR 408 #define ZLIB_VER_REVISION MZ_VER_REVISION 409 #define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION 410 #define zlibVersion mz_version 411 #define zlib_version mz_version() 412 #endif // #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES 413 414 #endif // MINIZ_NO_ZLIB_APIS 415 416 // ------------------- Types and macros 417 418 typedef unsigned char mz_uint8; 419 typedef signed short mz_int16; 420 typedef unsigned short mz_uint16; 421 typedef unsigned int mz_uint32; 422 typedef unsigned int mz_uint; 423 typedef long long mz_int64; 424 typedef unsigned long long mz_uint64; 425 typedef int mz_bool; 426 427 #define MZ_FALSE (0) 428 #define MZ_TRUE (1) 429 430 // Works around MSVC's spammy "warning C4127: conditional expression is constant" message. 431 #define MZ_MACRO_END while (0, 0) 432 433 // ------------------- ZIP archive reading/writing 434 435 #ifndef MINIZ_NO_ARCHIVE_APIS 436 437 enum 438 { 439 MZ_ZIP_MAX_IO_BUF_SIZE = 64*1024, 440 MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE = 260, 441 MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE = 256 442 }; 443 444 typedef struct 445 { 446 mz_uint32 m_file_index; 447 mz_uint32 m_central_dir_ofs; 448 mz_uint16 m_version_made_by; 449 mz_uint16 m_version_needed; 450 mz_uint16 m_bit_flag; 451 mz_uint16 m_method; 452 #ifndef MINIZ_NO_TIME 453 time_t m_time; 454 #endif 455 mz_uint32 m_crc32; 456 mz_uint64 m_comp_size; 457 mz_uint64 m_uncomp_size; 458 mz_uint16 m_internal_attr; 459 mz_uint32 m_external_attr; 460 mz_uint64 m_local_header_ofs; 461 mz_uint32 m_comment_size; 462 char m_filename[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE]; 463 char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE]; 464 } mz_zip_archive_file_stat; 465 466 typedef size_t (*mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n); 467 typedef size_t (*mz_file_write_func)(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n); 468 469 struct mz_zip_internal_state_tag; 470 typedef struct mz_zip_internal_state_tag mz_zip_internal_state; 471 472 typedef enum 473 { 474 MZ_ZIP_MODE_INVALID = 0, 475 MZ_ZIP_MODE_READING = 1, 476 MZ_ZIP_MODE_WRITING = 2, 477 MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3 478 } mz_zip_mode; 479 480 typedef struct 481 { 482 mz_uint64 m_archive_size; 483 mz_uint64 m_central_directory_file_ofs; 484 mz_uint m_total_files; 485 mz_zip_mode m_zip_mode; 486 487 mz_uint m_file_offset_alignment; 488 489 mz_alloc_func m_pAlloc; 490 mz_free_func m_pFree; 491 mz_realloc_func m_pRealloc; 492 void *m_pAlloc_opaque; 493 494 mz_file_read_func m_pRead; 495 mz_file_write_func m_pWrite; 496 void *m_pIO_opaque; 497 498 mz_zip_internal_state *m_pState; 499 500 } mz_zip_archive; 501 502 typedef enum 503 { 504 MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100, 505 MZ_ZIP_FLAG_IGNORE_PATH = 0x0200, 506 MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400, 507 MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY = 0x0800 508 } mz_zip_flags; 509 510 // ZIP archive reading 511 512 // Inits a ZIP archive reader. 513 // These functions read and validate the archive's central directory. 514 mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint32 flags); 515 mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint32 flags); 516 517 #ifndef MINIZ_NO_STDIO 518 mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags); 519 #endif 520 521 // Returns the total number of files in the archive. 522 mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip); 523 524 // Returns detailed information about an archive file entry. 525 mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat); 526 527 // Determines if an archive file entry is a directory entry. 528 mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index); 529 mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index); 530 531 // Retrieves the filename of an archive file entry. 532 // Returns the number of bytes written to pFilename, or if filename_buf_size is 0 this function returns the number of bytes needed to fully store the filename. 533 mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size); 534 535 // Attempts to locates a file in the archive's central directory. 536 // Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH 537 // Returns -1 if the file cannot be found. 538 int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags); 539 540 // Extracts a archive file to a memory buffer using no memory allocation. 541 mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size); 542 mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size); 543 544 // Extracts a archive file to a memory buffer. 545 mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags); 546 mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags); 547 548 // Extracts a archive file to a dynamically allocated heap buffer. 549 void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags); 550 void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags); 551 552 // Extracts a archive file using a callback function to output the file's data. 553 mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags); 554 mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags); 555 556 #ifndef MINIZ_NO_STDIO 557 // Extracts a archive file to a disk file and sets its last accessed and modified times. 558 // This function only extracts files, not archive directory records. 559 mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags); 560 mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags); 561 #endif 562 563 // Ends archive reading, freeing all allocations, and closing the input archive file if mz_zip_reader_init_file() was used. 564 mz_bool mz_zip_reader_end(mz_zip_archive *pZip); 565 566 // ZIP archive writing 567 568 #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS 569 570 // Inits a ZIP archive writer. 571 mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size); 572 mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size); 573 574 #ifndef MINIZ_NO_STDIO 575 mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning); 576 #endif 577 578 // Converts a ZIP archive reader object into a writer object, to allow efficient in-place file appends to occur on an existing archive. 579 // For archives opened using mz_zip_reader_init_file, pFilename must be the archive's filename so it can be reopened for writing. If the file can't be reopened, mz_zip_reader_end() will be called. 580 // For archives opened using mz_zip_reader_init_mem, the memory block must be growable using the realloc callback (which defaults to realloc unless you've overridden it). 581 // Finally, for archives opened using mz_zip_reader_init, the mz_zip_archive's user provided m_pWrite function cannot be NULL. 582 // Note: In-place archive modification is not recommended unless you know what you're doing, because if execution stops or something goes wrong before 583 // the archive is finalized the file's central directory will be hosed. 584 mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename); 585 586 // Adds the contents of a memory buffer to an archive. These functions record the current local time into the archive. 587 // To add a directory entry, call this method with an archive name ending in a forwardslash with empty buffer. 588 mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags); 589 mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32); 590 591 #ifndef MINIZ_NO_STDIO 592 // Adds the contents of a disk file to an archive. This function also records the disk file's modified time into the archive. 593 mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags); 594 #endif 595 596 // Adds a file to an archive by fully cloning the data from another archive. 597 // This function fully clones the source file's compressed data (no recompression), along with its full filename, extra data, and comment fields. 598 mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint file_index); 599 600 // Finalizes the archive by writing the central directory records followed by the end of central directory record. 601 // After an archive is finalized, the only valid call on the mz_zip_archive struct is mz_zip_writer_end(). 602 // An archive must be manually finalized by calling this function for it to be valid. 603 mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip); 604 mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **pBuf, size_t *pSize); 605 606 // Ends archive writing, freeing all allocations, and closing the output file if mz_zip_writer_init_file() was used. 607 // Note for the archive to be valid, it must have been finalized before ending. 608 mz_bool mz_zip_writer_end(mz_zip_archive *pZip); 609 610 // Misc. high-level helper functions: 611 612 // mz_zip_add_mem_to_archive_file_in_place() efficiently (but not atomically) appends a memory blob to a ZIP archive. 613 mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags); 614 615 // Reads a single file from an archive into a heap block. 616 // Returns NULL on failure. 617 void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint zip_flags); 618 619 #endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS 620 621 #endif // #ifndef MINIZ_NO_ARCHIVE_APIS 622 623 // ------------------- Low-level Decompression API Definitions 624 625 // Decompression flags. 626 enum 627 { 628 TINFL_FLAG_PARSE_ZLIB_HEADER = 1, 629 TINFL_FLAG_HAS_MORE_INPUT = 2, 630 TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4, 631 TINFL_FLAG_COMPUTE_ADLER32 = 8 632 }; 633 634 // High level decompression functions: 635 // tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block allocated via malloc(). 636 // On entry: 637 // pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data to decompress. 638 // On return: 639 // Function returns a pointer to the decompressed data, or NULL on failure. 640 // *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data. 641 // The caller must free() the returned block when it's no longer needed. 642 void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags); 643 644 // tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory. 645 // Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success. 646 #define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1)) 647 size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags); 648 649 // tinfl_decompress_mem_to_callback() decompresses a block in memory to an internal 32KB buffer, and a user provided callback function will be called to flush the buffer. 650 // Returns 1 on success or 0 on failure. 651 typedef int (*tinfl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser); 652 int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); 653 654 struct tinfl_decompressor_tag; typedef struct tinfl_decompressor_tag tinfl_decompressor; 655 656 // Max size of LZ dictionary. 657 #define TINFL_LZ_DICT_SIZE 32768 658 659 // Return status. 660 typedef enum 661 { 662 TINFL_STATUS_BAD_PARAM = -3, 663 TINFL_STATUS_ADLER32_MISMATCH = -2, 664 TINFL_STATUS_FAILED = -1, 665 TINFL_STATUS_DONE = 0, 666 TINFL_STATUS_NEEDS_MORE_INPUT = 1, 667 TINFL_STATUS_HAS_MORE_OUTPUT = 2 668 } tinfl_status; 669 670 // Initializes the decompressor to its initial state. 671 #define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END 672 #define tinfl_get_adler32(r) (r)->m_check_adler32 673 674 // Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability. 675 // This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output. 676 tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags); 677 678 // Internal/private bits follow. 679 enum 680 { 681 TINFL_MAX_HUFF_TABLES = 3, TINFL_MAX_HUFF_SYMBOLS_0 = 288, TINFL_MAX_HUFF_SYMBOLS_1 = 32, TINFL_MAX_HUFF_SYMBOLS_2 = 19, 682 TINFL_FAST_LOOKUP_BITS = 10, TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS 683 }; 684 685 typedef struct 686 { 687 mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0]; 688 mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2]; 689 } tinfl_huff_table; 690 691 #if MINIZ_HAS_64BIT_REGISTERS 692 #define TINFL_USE_64BIT_BITBUF 1 693 #endif 694 695 #if TINFL_USE_64BIT_BITBUF 696 typedef mz_uint64 tinfl_bit_buf_t; 697 #define TINFL_BITBUF_SIZE (64) 698 #else 699 typedef mz_uint32 tinfl_bit_buf_t; 700 #define TINFL_BITBUF_SIZE (32) 701 #endif 702 703 struct tinfl_decompressor_tag 704 { 705 mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES]; 706 tinfl_bit_buf_t m_bit_buf; 707 size_t m_dist_from_out_buf_start; 708 tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES]; 709 mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137]; 710 }; 711 712 // ------------------- Low-level Compression API Definitions 713 714 // Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly slower, and raw/dynamic blocks will be output more frequently). 715 #define TDEFL_LESS_MEMORY 0 716 717 // Compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search): 718 // TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap compression), 4095=Huffman+LZ (slowest/best compression). 719 enum 720 { 721 TDEFL_HUFFMAN_ONLY = 0, TDEFL_DEFAULT_MAX_PROBES = 128, TDEFL_MAX_PROBES_MASK = 0xFFF 722 }; 723 // TDEFL_WRITE_ZLIB_HEADER: If set, the compressor outputs a zlib header before the deflate data, and the Adler-32 of the source data at the end. Otherwise, you'll get raw deflate data. 724 // TDEFL_COMPUTE_ADLER32: Always compute the adler-32 of the input data (even when not writing zlib headers). 725 // TDEFL_GREEDY_PARSING_FLAG: Set to use faster greedy parsing, instead of more efficient lazy parsing. 726 // TDEFL_NONDETERMINISTIC_PARSING_FLAG: Enable to decrease the compressor's initialization time to the minimum, but the output may vary from run to run given the same input (depending on the contents of memory). 727 // TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables. 728 enum 729 { 730 TDEFL_WRITE_ZLIB_HEADER = 0x01000, 731 TDEFL_COMPUTE_ADLER32 = 0x02000, 732 TDEFL_GREEDY_PARSING_FLAG = 0x04000, 733 TDEFL_NONDETERMINISTIC_PARSING_FLAG = 0x08000, 734 TDEFL_RLE_MATCHES = 0x10000, 735 TDEFL_FILTER_MATCHES = 0x20000, 736 TDEFL_FORCE_ALL_STATIC_BLOCKS = 0x40000, 737 TDEFL_FORCE_ALL_RAW_BLOCKS = 0x80000 738 }; 739 740 // High level compression functions: 741 // tdefl_compress_mem_to_heap() compresses a block in memory to a heap block allocated via malloc(). 742 // On entry: 743 // pSrc_buf, src_buf_len: Pointer and size of source block to compress. 744 // flags: The max match finder probes (default is 128) logically OR'd against the above flags. Higher probes are slower but improve compression. 745 // On return: 746 // Function returns a pointer to the compressed data, or NULL on failure. 747 // *pOut_len will be set to the compressed data's size, which could be larger than src_buf_len on uncompressible data. 748 // The caller must free() the returned block when it's no longer needed. 749 void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags); 750 751 // tdefl_compress_mem_to_mem() compresses a block in memory to another block in memory. 752 // Returns 0 on failure. 753 size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags); 754 755 // Compresses an image to a compressed PNG file in memory. 756 // On entry: 757 // pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4. 758 // On return: 759 // Function returns a pointer to the compressed data, or NULL on failure. 760 // *pLen_out will be set to the size of the PNG image file. 761 // The caller must free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed. 762 void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out); 763 764 // Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time. 765 typedef mz_bool (*tdefl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser); 766 767 // tdefl_compress_mem_to_output() compresses a block to an output stream. The above helpers use this function internally. 768 mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); 769 770 enum { TDEFL_MAX_HUFF_TABLES = 3, TDEFL_MAX_HUFF_SYMBOLS_0 = 288, TDEFL_MAX_HUFF_SYMBOLS_1 = 32, TDEFL_MAX_HUFF_SYMBOLS_2 = 19, TDEFL_LZ_DICT_SIZE = 32768, TDEFL_LZ_DICT_SIZE_MASK = TDEFL_LZ_DICT_SIZE - 1, TDEFL_MIN_MATCH_LEN = 3, TDEFL_MAX_MATCH_LEN = 258 }; 771 772 // TDEFL_OUT_BUF_SIZE MUST be large enough to hold a single entire compressed output block (using static/fixed Huffman codes). 773 #if TDEFL_LESS_MEMORY 774 enum { TDEFL_LZ_CODE_BUF_SIZE = 24 * 1024, TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13 ) / 10, TDEFL_MAX_HUFF_SYMBOLS = 288, TDEFL_LZ_HASH_BITS = 12, TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS }; 775 #else 776 enum { TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024, TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13 ) / 10, TDEFL_MAX_HUFF_SYMBOLS = 288, TDEFL_LZ_HASH_BITS = 15, TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS }; 777 #endif 778 779 // The low-level tdefl functions below may be used directly if the above helper functions aren't flexible enough. The low-level functions don't make any heap allocations, unlike the above helper functions. 780 typedef enum 781 { 782 TDEFL_STATUS_BAD_PARAM = -2, 783 TDEFL_STATUS_PUT_BUF_FAILED = -1, 784 TDEFL_STATUS_OKAY = 0, 785 TDEFL_STATUS_DONE = 1, 786 } tdefl_status; 787 788 // Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums 789 typedef enum 790 { 791 TDEFL_NO_FLUSH = 0, 792 TDEFL_SYNC_FLUSH = 2, 793 TDEFL_FULL_FLUSH = 3, 794 TDEFL_FINISH = 4 795 } tdefl_flush; 796 797 typedef struct 798 { 799 tdefl_put_buf_func_ptr m_pPut_buf_func; 800 void *m_pPut_buf_user; 801 mz_uint m_flags, m_max_probes[2]; 802 int m_greedy_parsing; 803 mz_uint m_adler32, m_lookahead_pos, m_lookahead_size, m_dict_size; 804 mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end; 805 mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in, m_bit_buffer; 806 mz_uint m_saved_match_dist, m_saved_match_len, m_saved_lit, m_output_flush_ofs, m_output_flush_remaining, m_finished, m_block_index, m_wants_to_finish; 807 tdefl_status m_prev_return_status; 808 const void *m_pIn_buf; 809 void *m_pOut_buf; 810 size_t *m_pIn_buf_size, *m_pOut_buf_size; 811 tdefl_flush m_flush; 812 const mz_uint8 *m_pSrc; 813 size_t m_src_buf_left, m_out_buf_ofs; 814 mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE + TDEFL_MAX_MATCH_LEN - 1]; 815 mz_uint16 m_huff_count[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; 816 mz_uint16 m_huff_codes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; 817 mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; 818 mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE]; 819 mz_uint16 m_next[TDEFL_LZ_DICT_SIZE]; 820 mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE]; 821 mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE]; 822 } tdefl_compressor; 823 824 // Initializes the compressor. 825 tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); 826 827 // Compresses a block of data, consuming as much of the input as possible, and writing as much compressed data as possible. 828 tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush); 829 // tdefl_compress_buffer() is only usable when the tdefl_init() is called with a valid tdefl_put_buf_func_ptr. 830 // tdefl_compress_buffer() always consumes the entire input buffer. 831 tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush); 832 833 tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d); 834 mz_uint32 tdefl_get_adler32(tdefl_compressor *d); 835 836 // Create tdefl_compress() flags given zlib-style compression parameters. 837 // level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files) 838 // window_bits may be -15 (raw deflate) or 15 (zlib) 839 // strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED 840 mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy); 841 842 #ifdef __cplusplus 843 } 844 #endif 845 846 #endif // MINIZ_HEADER_INCLUDED 847 848 // ------------------- End of Header: Implementation follows. (If you only want the header, define MINIZ_HEADER_FILE_ONLY.) 849 850 #ifndef MINIZ_HEADER_FILE_ONLY 851 852 typedef unsigned char mz_validate_uint16[sizeof(mz_uint16)==2 ? 1 : -1]; 853 typedef unsigned char mz_validate_uint32[sizeof(mz_uint32)==4 ? 1 : -1]; 854 typedef unsigned char mz_validate_uint64[sizeof(mz_uint64)==8 ? 1 : -1]; 855 856 #include <string.h> 857 #include <assert.h> 858 859 #define MZ_ASSERT(x) assert(x) 860 861 #ifdef MINIZ_NO_MALLOC 862 #define MZ_MALLOC(x) NULL 863 #define MZ_FREE(x) x, ((void)0) 864 #define MZ_REALLOC(p, x) NULL 865 #else 866 #define MZ_MALLOC(x) malloc(x) 867 #define MZ_FREE(x) free(x) 868 #define MZ_REALLOC(p, x) realloc(p, x) 869 #endif 870 871 #define MZ_MAX(a,b) (((a)>(b))?(a):(b)) 872 #define MZ_MIN(a,b) (((a)<(b))?(a):(b)) 873 #define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj)) 874 875 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN 876 #define MZ_READ_LE16(p) *((const mz_uint16 *)(p)) 877 #define MZ_READ_LE32(p) *((const mz_uint32 *)(p)) 878 #else 879 #define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U)) 880 #define MZ_READ_LE32(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U)) 881 #endif 882 883 #if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__MINGW64__) && !defined(__forceinline) 884 #ifdef __cplusplus 885 #define __forceinline inline 886 #else 887 #define __forceinline inline 888 #endif 889 #endif 890 891 #ifdef __cplusplus 892 extern "C" { 893 #endif 894 895 // ------------------- zlib-style API's 896 897 static void *def_alloc_func(void *opaque, size_t items, size_t size) { (void)opaque; return MZ_MALLOC(items * size); } 898 static void def_free_func(void *opaque, void *address) { (void)opaque, MZ_FREE(address); } 899 static void *def_realloc_func(void *opaque, void *address, size_t items, size_t size) { (void)opaque; return MZ_REALLOC(address, items * size); } 900 901 mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len) 902 { 903 mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16); size_t block_len = buf_len % 5552; 904 if (!ptr) return MZ_ADLER32_INIT; 905 while (buf_len) { 906 for (i = 0; i + 7 < block_len; i += 8, ptr += 8) { 907 s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1; 908 s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1; 909 } 910 for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1; 911 s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552; 912 } 913 return (s2 << 16) + s1; 914 } 915 916 // Karl Malbrain's compact CRC-32. See "A compact CCITT crc16 and crc32 C implementation that balances processor cache usage against speed": http://www.geocities.com/malbrain/ 917 mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len) 918 { 919 static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, 920 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c }; 921 if (!ptr) return MZ_CRC32_INIT; 922 crc = ~crc; while (buf_len--) { mz_uint8 b = *ptr++; crc = (crc >> 4) ^ s_crc32[(crc & 0xF) ^ (b & 0xF)]; crc = (crc >> 4) ^ s_crc32[(crc & 0xF) ^ (b >> 4)]; } return ~crc; 923 } 924 925 #ifndef MINIZ_NO_ZLIB_APIS 926 927 const char *mz_version(void) 928 { 929 return MZ_VERSION; 930 } 931 932 int mz_deflateInit(mz_streamp pStream, int level) 933 { 934 return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY); 935 } 936 937 int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy) 938 { 939 tdefl_compressor *pComp; 940 mz_uint comp_flags = TDEFL_COMPUTE_ADLER32 | tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy); 941 942 if (!pStream) return MZ_STREAM_ERROR; 943 if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) || ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS))) return MZ_PARAM_ERROR; 944 945 pStream->data_type = 0; 946 pStream->adler = MZ_ADLER32_INIT; 947 pStream->msg = NULL; 948 pStream->reserved = 0; 949 pStream->total_in = 0; 950 pStream->total_out = 0; 951 if (!pStream->zalloc) pStream->zalloc = def_alloc_func; 952 if (!pStream->zfree) pStream->zfree = def_free_func; 953 954 pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, sizeof(tdefl_compressor)); 955 if (!pComp) 956 return MZ_MEM_ERROR; 957 958 pStream->state = (struct mz_internal_state *)pComp; 959 960 if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY) 961 { 962 mz_deflateEnd(pStream); 963 return MZ_PARAM_ERROR; 964 } 965 966 return MZ_OK; 967 } 968 969 int mz_deflateReset(mz_streamp pStream) 970 { 971 if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree)) return MZ_STREAM_ERROR; 972 pStream->total_in = pStream->total_out = 0; 973 tdefl_init((tdefl_compressor*)pStream->state, NULL, NULL, ((tdefl_compressor*)pStream->state)->m_flags); 974 return MZ_OK; 975 } 976 977 int mz_deflate(mz_streamp pStream, int flush) 978 { 979 size_t in_bytes, out_bytes; 980 mz_ulong orig_total_in, orig_total_out; 981 int mz_status = MZ_OK; 982 983 if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || (!pStream->next_out)) return MZ_STREAM_ERROR; 984 if (!pStream->avail_out) return MZ_BUF_ERROR; 985 986 if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH; 987 988 if (((tdefl_compressor*)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE) 989 return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR; 990 991 orig_total_in = pStream->total_in; orig_total_out = pStream->total_out; 992 for ( ; ; ) 993 { 994 tdefl_status defl_status; 995 in_bytes = pStream->avail_in; out_bytes = pStream->avail_out; 996 997 defl_status = tdefl_compress((tdefl_compressor*)pStream->state, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, (tdefl_flush)flush); 998 pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; 999 pStream->total_in += (mz_uint)in_bytes; pStream->adler = tdefl_get_adler32((tdefl_compressor*)pStream->state); 1000 1001 pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes; 1002 pStream->total_out += (mz_uint)out_bytes; 1003 1004 if (defl_status < 0) 1005 { 1006 mz_status = MZ_STREAM_ERROR; 1007 break; 1008 } 1009 else if (defl_status == TDEFL_STATUS_DONE) 1010 { 1011 mz_status = MZ_STREAM_END; 1012 break; 1013 } 1014 else if (!pStream->avail_out) 1015 break; 1016 else if ((!pStream->avail_in) && (flush != MZ_FINISH)) 1017 { 1018 if ((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out)) 1019 break; 1020 return MZ_BUF_ERROR; // Can't make forward progress without some input. 1021 } 1022 } 1023 return mz_status; 1024 } 1025 1026 int mz_deflateEnd(mz_streamp pStream) 1027 { 1028 if (!pStream) return MZ_STREAM_ERROR; 1029 if (pStream->state) 1030 { 1031 pStream->zfree(pStream->opaque, pStream->state); 1032 pStream->state = NULL; 1033 } 1034 return MZ_OK; 1035 } 1036 1037 mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len) 1038 { 1039 pStream; 1040 // This is really over conservative. (And lame, but it's actually pretty tricky to compute a true upper bound given the way tdefl's blocking works.) 1041 return MZ_MAX(128 + (source_len * 110) / 100, 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5); 1042 } 1043 1044 int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level) 1045 { 1046 int status; 1047 mz_stream stream; 1048 memset(&stream, 0, sizeof(stream)); 1049 1050 // In case mz_ulong is 64-bits (argh I hate longs). 1051 if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR; 1052 1053 stream.next_in = pSource; 1054 stream.avail_in = (mz_uint32)source_len; 1055 stream.next_out = pDest; 1056 stream.avail_out = (mz_uint32)*pDest_len; 1057 1058 status = mz_deflateInit(&stream, level); 1059 if (status != MZ_OK) return status; 1060 1061 status = mz_deflate(&stream, MZ_FINISH); 1062 if (status != MZ_STREAM_END) 1063 { 1064 mz_deflateEnd(&stream); 1065 return (status == MZ_OK) ? MZ_BUF_ERROR : status; 1066 } 1067 1068 *pDest_len = stream.total_out; 1069 return mz_deflateEnd(&stream); 1070 } 1071 1072 int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len) 1073 { 1074 return mz_compress2(pDest, pDest_len, pSource, source_len, MZ_DEFAULT_COMPRESSION); 1075 } 1076 1077 mz_ulong mz_compressBound(mz_ulong source_len) 1078 { 1079 return mz_deflateBound(NULL, source_len); 1080 } 1081 1082 typedef struct 1083 { 1084 tinfl_decompressor m_decomp; 1085 mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed; int m_window_bits; 1086 mz_uint8 m_dict[TINFL_LZ_DICT_SIZE]; 1087 tinfl_status m_last_status; 1088 } inflate_state; 1089 1090 int mz_inflateInit2(mz_streamp pStream, int window_bits) 1091 { 1092 inflate_state *pDecomp; 1093 if (!pStream) return MZ_STREAM_ERROR; 1094 if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)) return MZ_PARAM_ERROR; 1095 1096 pStream->data_type = 0; 1097 pStream->adler = 0; 1098 pStream->msg = NULL; 1099 pStream->total_in = 0; 1100 pStream->total_out = 0; 1101 pStream->reserved = 0; 1102 if (!pStream->zalloc) pStream->zalloc = def_alloc_func; 1103 if (!pStream->zfree) pStream->zfree = def_free_func; 1104 1105 pDecomp = (inflate_state*)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state)); 1106 if (!pDecomp) return MZ_MEM_ERROR; 1107 1108 pStream->state = (struct mz_internal_state *)pDecomp; 1109 1110 tinfl_init(&pDecomp->m_decomp); 1111 pDecomp->m_dict_ofs = 0; 1112 pDecomp->m_dict_avail = 0; 1113 pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT; 1114 pDecomp->m_first_call = 1; 1115 pDecomp->m_has_flushed = 0; 1116 pDecomp->m_window_bits = window_bits; 1117 1118 return MZ_OK; 1119 } 1120 1121 int mz_inflateInit(mz_streamp pStream) 1122 { 1123 return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS); 1124 } 1125 1126 int mz_inflate(mz_streamp pStream, int flush) 1127 { 1128 inflate_state* pState; 1129 mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32; 1130 size_t in_bytes, out_bytes, orig_avail_in; 1131 tinfl_status status; 1132 1133 if ((!pStream) || (!pStream->state)) return MZ_STREAM_ERROR; 1134 if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH; 1135 if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH)) return MZ_STREAM_ERROR; 1136 1137 pState = (inflate_state*)pStream->state; 1138 if (pState->m_window_bits > 0) decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER; 1139 orig_avail_in = pStream->avail_in; 1140 1141 first_call = pState->m_first_call; pState->m_first_call = 0; 1142 if (pState->m_last_status < 0) return MZ_DATA_ERROR; 1143 1144 if (pState->m_has_flushed && (flush != MZ_FINISH)) return MZ_STREAM_ERROR; 1145 pState->m_has_flushed |= (flush == MZ_FINISH); 1146 1147 if ((flush == MZ_FINISH) && (first_call)) 1148 { 1149 // MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file. 1150 decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF; 1151 in_bytes = pStream->avail_in; out_bytes = pStream->avail_out; 1152 status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags); 1153 pState->m_last_status = status; 1154 pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; pStream->total_in += (mz_uint)in_bytes; 1155 pStream->adler = tinfl_get_adler32(&pState->m_decomp); 1156 pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes; pStream->total_out += (mz_uint)out_bytes; 1157 1158 if (status < 0) 1159 return MZ_DATA_ERROR; 1160 else if (status != TINFL_STATUS_DONE) 1161 { 1162 pState->m_last_status = TINFL_STATUS_FAILED; 1163 return MZ_BUF_ERROR; 1164 } 1165 return MZ_STREAM_END; 1166 } 1167 // flush != MZ_FINISH then we must assume there's more input. 1168 if (flush != MZ_FINISH) decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT; 1169 1170 if (pState->m_dict_avail) 1171 { 1172 n = MZ_MIN(pState->m_dict_avail, pStream->avail_out); 1173 memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n); 1174 pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n; 1175 pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1); 1176 return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK; 1177 } 1178 1179 for ( ; ; ) 1180 { 1181 in_bytes = pStream->avail_in; 1182 out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs; 1183 1184 status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict, pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags); 1185 pState->m_last_status = status; 1186 1187 pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; 1188 pStream->total_in += (mz_uint)in_bytes; pStream->adler = tinfl_get_adler32(&pState->m_decomp); 1189 1190 pState->m_dict_avail = (mz_uint)out_bytes; 1191 1192 n = MZ_MIN(pState->m_dict_avail, pStream->avail_out); 1193 memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n); 1194 pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n; 1195 pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1); 1196 1197 if (status < 0) 1198 return MZ_DATA_ERROR; // Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well). 1199 else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in)) 1200 return MZ_BUF_ERROR; // Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH. 1201 else if (flush == MZ_FINISH) 1202 { 1203 // The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH. 1204 if (status == TINFL_STATUS_DONE) 1205 return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END; 1206 // status here must be TINFL_STATUS_HAS_MORE_OUTPUT, which means there's at least 1 more byte on the way. If there's no more room left in the output buffer then something is wrong. 1207 else if (!pStream->avail_out) 1208 return MZ_BUF_ERROR; 1209 } 1210 else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail)) 1211 break; 1212 } 1213 1214 return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK; 1215 } 1216 1217 int mz_inflateEnd(mz_streamp pStream) 1218 { 1219 if (!pStream) 1220 return MZ_STREAM_ERROR; 1221 if (pStream->state) 1222 { 1223 pStream->zfree(pStream->opaque, pStream->state); 1224 pStream->state = NULL; 1225 } 1226 return MZ_OK; 1227 } 1228 1229 int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len) 1230 { 1231 mz_stream stream; 1232 int status; 1233 memset(&stream, 0, sizeof(stream)); 1234 1235 // In case mz_ulong is 64-bits (argh I hate longs). 1236 if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR; 1237 1238 stream.next_in = pSource; 1239 stream.avail_in = (mz_uint32)source_len; 1240 stream.next_out = pDest; 1241 stream.avail_out = (mz_uint32)*pDest_len; 1242 1243 status = mz_inflateInit(&stream); 1244 if (status != MZ_OK) 1245 return status; 1246 1247 status = mz_inflate(&stream, MZ_FINISH); 1248 if (status != MZ_STREAM_END) 1249 { 1250 mz_inflateEnd(&stream); 1251 return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status; 1252 } 1253 *pDest_len = stream.total_out; 1254 1255 return mz_inflateEnd(&stream); 1256 } 1257 1258 const char *mz_error(int err) 1259 { 1260 static struct { int m_err; const char *m_pDesc; } s_error_descs[] = 1261 { 1262 { MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" }, 1263 { MZ_DATA_ERROR, "data error" }, { MZ_MEM_ERROR, "out of memory" }, { MZ_BUF_ERROR, "buf error" }, { MZ_VERSION_ERROR, "version error" }, { MZ_PARAM_ERROR, "parameter error" } 1264 }; 1265 mz_uint i; for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i) if (s_error_descs[i].m_err == err) return s_error_descs[i].m_pDesc; 1266 return NULL; 1267 } 1268 1269 #endif //MINIZ_NO_ZLIB_APIS 1270 1271 // ------------------- Low-level Decompression (completely independent from all compression API's) 1272 1273 #define TINFL_MEMCPY(d, s, l) memcpy(d, s, l) 1274 #define TINFL_MEMSET(p, c, l) memset(p, c, l) 1275 1276 #define TINFL_CR_BEGIN switch(r->m_state) { case 0: 1277 #define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END 1278 #define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END 1279 #define TINFL_CR_FINISH } 1280 1281 // TODO: If the caller has indicated that there's no more input, and we attempt to read beyond the input buf, then something is wrong with the input because the inflator never 1282 // reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of the stream with 0's in this scenario. 1283 #define TINFL_GET_BYTE(state_index, c) do { \ 1284 if (pIn_buf_cur >= pIn_buf_end) { \ 1285 for ( ; ; ) { \ 1286 if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \ 1287 TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \ 1288 if (pIn_buf_cur < pIn_buf_end) { \ 1289 c = *pIn_buf_cur++; \ 1290 break; \ 1291 } \ 1292 } else { \ 1293 c = 0; \ 1294 break; \ 1295 } \ 1296 } \ 1297 } else c = *pIn_buf_cur++; } MZ_MACRO_END 1298 1299 #define TINFL_NEED_BITS(state_index, n) do { mz_uint c; TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; } while (num_bits < (mz_uint)(n)) 1300 #define TINFL_SKIP_BITS(state_index, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END 1301 #define TINFL_GET_BITS(state_index, b, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } b = bit_buf & ((1 << (n)) - 1); bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END 1302 1303 // TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2. 1304 // It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a 1305 // Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the 1306 // bit buffer contains >=15 bits (deflate's max. Huffman code size). 1307 #define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \ 1308 do { \ 1309 temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \ 1310 if (temp >= 0) { \ 1311 code_len = temp >> 9; \ 1312 if ((code_len) && (num_bits >= code_len)) \ 1313 break; \ 1314 } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \ 1315 code_len = TINFL_FAST_LOOKUP_BITS; \ 1316 do { \ 1317 temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \ 1318 } while ((temp < 0) && (num_bits >= (code_len + 1))); if (temp >= 0) break; \ 1319 } TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; \ 1320 } while (num_bits < 15); 1321 1322 // TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex than you would initially expect because the zlib API expects the decompressor to never read 1323 // beyond the final byte of the deflate stream. (In other words, when this macro wants to read another byte from the input, it REALLY needs another byte in order to fully 1324 // decode the next Huffman code.) Handling this properly is particularly important on raw deflate (non-zlib) streams, which aren't followed by a byte aligned adler-32. 1325 // The slow path is only executed at the very end of the input buffer. 1326 #define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \ 1327 int temp; mz_uint code_len, c; \ 1328 if (num_bits < 15) { \ 1329 if ((pIn_buf_end - pIn_buf_cur) < 2) { \ 1330 TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \ 1331 } else { \ 1332 bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); pIn_buf_cur += 2; num_bits += 16; \ 1333 } \ 1334 } \ 1335 if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \ 1336 code_len = temp >> 9, temp &= 511; \ 1337 else { \ 1338 code_len = TINFL_FAST_LOOKUP_BITS; do { temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; } while (temp < 0); \ 1339 } sym = temp; bit_buf >>= code_len; num_bits -= code_len; } MZ_MACRO_END 1340 1341 tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags) 1342 { 1343 static const int s_length_base[31] = { 3,4,5,6,7,8,9,10,11,13, 15,17,19,23,27,31,35,43,51,59, 67,83,99,115,131,163,195,227,258,0,0 }; 1344 static const int s_length_extra[31]= { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; 1345 static const int s_dist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; 1346 static const int s_dist_extra[32] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; 1347 static const mz_uint8 s_length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; 1348 static const int s_min_table_sizes[3] = { 257, 1, 4 }; 1349 1350 tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; tinfl_bit_buf_t bit_buf; 1351 const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size; 1352 mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size; 1353 size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t)-1 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, dist_from_out_buf_start; 1354 1355 // Ensure the output buffer's size is a power of 2, unless the output buffer is large enough to hold the entire output file (in which case it doesn't matter). 1356 if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start)) { *pIn_buf_size = *pOut_buf_size = 0; return TINFL_STATUS_BAD_PARAM; } 1357 1358 num_bits = r->m_num_bits; bit_buf = r->m_bit_buf; dist = r->m_dist; counter = r->m_counter; num_extra = r->m_num_extra; dist_from_out_buf_start = r->m_dist_from_out_buf_start; 1359 TINFL_CR_BEGIN 1360 1361 bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0; r->m_z_adler32 = r->m_check_adler32 = 1; 1362 if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) 1363 { 1364 TINFL_GET_BYTE(1, r->m_zhdr0); TINFL_GET_BYTE(2, r->m_zhdr1); 1365 counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8)); 1366 if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1U << (8U + (r->m_zhdr0 >> 4))))); 1367 if (counter) { TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); } 1368 } 1369 1370 do 1371 { 1372 TINFL_GET_BITS(3, r->m_final, 3); r->m_type = r->m_final >> 1; 1373 if (r->m_type == 0) 1374 { 1375 TINFL_SKIP_BITS(5, num_bits & 7); 1376 for (counter = 0; counter < 4; ++counter) { if (num_bits) TINFL_GET_BITS(6, r->m_raw_header[counter], 8); else TINFL_GET_BYTE(7, r->m_raw_header[counter]); } 1377 if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) != (mz_uint)(0xFFFF ^ (r->m_raw_header[2] | (r->m_raw_header[3] << 8)))) { TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED); } 1378 while ((counter) && (num_bits)) 1379 { 1380 TINFL_GET_BITS(51, dist, 8); 1381 while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT); } 1382 *pOut_buf_cur++ = (mz_uint8)dist; 1383 counter--; 1384 } 1385 while (counter) 1386 { 1387 size_t n; while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); } 1388 while (pIn_buf_cur >= pIn_buf_end) 1389 { 1390 if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) 1391 { 1392 TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT); 1393 } 1394 else 1395 { 1396 TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED); 1397 } 1398 } 1399 n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter); 1400 TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); pIn_buf_cur += n; pOut_buf_cur += n; counter -= (mz_uint)n; 1401 } 1402 } 1403 else if (r->m_type == 3) 1404 { 1405 TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED); 1406 } 1407 else 1408 { 1409 if (r->m_type == 1) 1410 { 1411 mz_uint8 *p = r->m_tables[0].m_code_size; mz_uint i; 1412 r->m_table_sizes[0] = 288; r->m_table_sizes[1] = 32; TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32); 1413 for ( i = 0; i <= 143; ++i) *p++ = 8; for ( ; i <= 255; ++i) *p++ = 9; for ( ; i <= 279; ++i) *p++ = 7; for ( ; i <= 287; ++i) *p++ = 8; 1414 } 1415 else 1416 { 1417 for (counter = 0; counter < 3; counter++) { TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); r->m_table_sizes[counter] += s_min_table_sizes[counter]; } 1418 MZ_CLEAR_OBJ(r->m_tables[2].m_code_size); for (counter = 0; counter < r->m_table_sizes[2]; counter++) { mz_uint s; TINFL_GET_BITS(14, s, 3); r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; } 1419 r->m_table_sizes[2] = 19; 1420 } 1421 for ( ; (int)r->m_type >= 0; r->m_type--) 1422 { 1423 int tree_next, tree_cur; tinfl_huff_table *pTable; 1424 mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; pTable = &r->m_tables[r->m_type]; MZ_CLEAR_OBJ(total_syms); MZ_CLEAR_OBJ(pTable->m_look_up); MZ_CLEAR_OBJ(pTable->m_tree); 1425 for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) total_syms[pTable->m_code_size[i]]++; 1426 used_syms = 0, total = 0; next_code[0] = next_code[1] = 0; 1427 for (i = 1; i <= 15; ++i) { used_syms += total_syms[i]; next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); } 1428 if ((65536 != total) && (used_syms > 1)) 1429 { 1430 TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED); 1431 } 1432 for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index) 1433 { 1434 mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index]; if (!code_size) continue; 1435 cur_code = next_code[code_size]++; for (l = code_size; l > 0; l--, cur_code >>= 1) rev_code = (rev_code << 1) | (cur_code & 1); 1436 if (code_size <= TINFL_FAST_LOOKUP_BITS) { mz_int16 k = (mz_int16)((code_size << 9) | sym_index); while (rev_code < TINFL_FAST_LOOKUP_SIZE) { pTable->m_look_up[rev_code] = k; rev_code += (1 << code_size); } continue; } 1437 if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) { pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } 1438 rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1); 1439 for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--) 1440 { 1441 tree_cur -= ((rev_code >>= 1) & 1); 1442 if (!pTable->m_tree[-tree_cur - 1]) { pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } else tree_cur = pTable->m_tree[-tree_cur - 1]; 1443 } 1444 tree_cur -= ((rev_code >>= 1) & 1); pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index; 1445 } 1446 if (r->m_type == 2) 1447 { 1448 for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]); ) 1449 { 1450 mz_uint s; TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); if (dist < 16) { r->m_len_codes[counter++] = (mz_uint8)dist; continue; } 1451 if ((dist == 16) && (!counter)) 1452 { 1453 TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED); 1454 } 1455 num_extra = "\02\03\07"[dist - 16]; TINFL_GET_BITS(18, s, num_extra); s += "\03\03\013"[dist - 16]; 1456 TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s); counter += s; 1457 } 1458 if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter) 1459 { 1460 TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED); 1461 } 1462 TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]); TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]); 1463 } 1464 } 1465 for ( ; ; ) 1466 { 1467 mz_uint8 *pSrc; 1468 for ( ; ; ) 1469 { 1470 if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2)) 1471 { 1472 TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]); 1473 if (counter >= 256) 1474 break; 1475 while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT); } 1476 *pOut_buf_cur++ = (mz_uint8)counter; 1477 } 1478 else 1479 { 1480 int sym2; mz_uint code_len; 1481 #if TINFL_USE_64BIT_BITBUF 1482 if (num_bits < 30) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits); pIn_buf_cur += 4; num_bits += 32; } 1483 #else 1484 if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; } 1485 #endif 1486 if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) 1487 code_len = sym2 >> 9; 1488 else 1489 { 1490 code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0); 1491 } 1492 counter = sym2; bit_buf >>= code_len; num_bits -= code_len; 1493 if (counter & 256) 1494 break; 1495 1496 #if !TINFL_USE_64BIT_BITBUF 1497 if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; } 1498 #endif 1499 if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) 1500 code_len = sym2 >> 9; 1501 else 1502 { 1503 code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0); 1504 } 1505 bit_buf >>= code_len; num_bits -= code_len; 1506 1507 pOut_buf_cur[0] = (mz_uint8)counter; 1508 if (sym2 & 256) 1509 { 1510 pOut_buf_cur++; 1511 counter = sym2; 1512 break; 1513 } 1514 pOut_buf_cur[1] = (mz_uint8)sym2; 1515 pOut_buf_cur += 2; 1516 } 1517 } 1518 if ((counter &= 511) == 256) break; 1519 1520 num_extra = s_length_extra[counter - 257]; counter = s_length_base[counter - 257]; 1521 if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(25, extra_bits, num_extra); counter += extra_bits; } 1522 1523 TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]); 1524 num_extra = s_dist_extra[dist]; dist = s_dist_base[dist]; 1525 if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(27, extra_bits, num_extra); dist += extra_bits; } 1526 1527 dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start; 1528 if ((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) 1529 { 1530 TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED); 1531 } 1532 1533 pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask); 1534 1535 if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end) 1536 { 1537 while (counter--) 1538 { 1539 while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT); } 1540 *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask]; 1541 } 1542 continue; 1543 } 1544 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1545 else if ((counter >= 9) && (counter <= dist)) 1546 { 1547 const mz_uint8 *pSrc_end = pSrc + (counter & ~7); 1548 do 1549 { 1550 ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0]; 1551 ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1]; 1552 pOut_buf_cur += 8; 1553 } while ((pSrc += 8) < pSrc_end); 1554 if ((counter &= 7) < 3) 1555 { 1556 if (counter) 1557 { 1558 pOut_buf_cur[0] = pSrc[0]; 1559 if (counter > 1) 1560 pOut_buf_cur[1] = pSrc[1]; 1561 pOut_buf_cur += counter; 1562 } 1563 continue; 1564 } 1565 } 1566 #endif 1567 do 1568 { 1569 pOut_buf_cur[0] = pSrc[0]; 1570 pOut_buf_cur[1] = pSrc[1]; 1571 pOut_buf_cur[2] = pSrc[2]; 1572 pOut_buf_cur += 3; pSrc += 3; 1573 } while ((int)(counter -= 3) > 2); 1574 if ((int)counter > 0) 1575 { 1576 pOut_buf_cur[0] = pSrc[0]; 1577 if ((int)counter > 1) 1578 pOut_buf_cur[1] = pSrc[1]; 1579 pOut_buf_cur += counter; 1580 } 1581 } 1582 } 1583 } while (!(r->m_final & 1)); 1584 if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) 1585 { 1586 TINFL_SKIP_BITS(32, num_bits & 7); for (counter = 0; counter < 4; ++counter) { mz_uint s; if (num_bits) TINFL_GET_BITS(41, s, 8); else TINFL_GET_BYTE(42, s); r->m_z_adler32 = (r->m_z_adler32 << 8) | s; } 1587 } 1588 TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE); 1589 TINFL_CR_FINISH 1590 1591 common_exit: 1592 r->m_num_bits = num_bits; r->m_bit_buf = bit_buf; r->m_dist = dist; r->m_counter = counter; r->m_num_extra = num_extra; r->m_dist_from_out_buf_start = dist_from_out_buf_start; 1593 *pIn_buf_size = pIn_buf_cur - pIn_buf_next; *pOut_buf_size = pOut_buf_cur - pOut_buf_next; 1594 if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0)) 1595 { 1596 const mz_uint8 *ptr = pOut_buf_next; size_t buf_len = *pOut_buf_size; 1597 mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16; size_t block_len = buf_len % 5552; 1598 while (buf_len) 1599 { 1600 for (i = 0; i + 7 < block_len; i += 8, ptr += 8) 1601 { 1602 s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1; 1603 s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1; 1604 } 1605 for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1; 1606 s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552; 1607 } 1608 r->m_check_adler32 = (s2 << 16) + s1; if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32)) status = TINFL_STATUS_ADLER32_MISMATCH; 1609 } 1610 return status; 1611 } 1612 1613 // Higher level helper functions. 1614 void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags) 1615 { 1616 tinfl_decompressor decomp; void *pBuf = NULL, *pNew_buf; size_t src_buf_ofs = 0, out_buf_capacity = 0; 1617 *pOut_len = 0; 1618 tinfl_init(&decomp); 1619 for ( ; ; ) 1620 { 1621 size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity; 1622 tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf + src_buf_ofs, &src_buf_size, (mz_uint8*)pBuf, pBuf ? (mz_uint8*)pBuf + *pOut_len : NULL, &dst_buf_size, 1623 (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); 1624 if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT)) 1625 { 1626 MZ_FREE(pBuf); *pOut_len = 0; return NULL; 1627 } 1628 src_buf_ofs += src_buf_size; 1629 *pOut_len += dst_buf_size; 1630 if (status == TINFL_STATUS_DONE) break; 1631 new_out_buf_capacity = out_buf_capacity * 2; if (new_out_buf_capacity < 128) new_out_buf_capacity = 128; 1632 pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity); 1633 if (!pNew_buf) 1634 { 1635 MZ_FREE(pBuf); *pOut_len = 0; return NULL; 1636 } 1637 pBuf = pNew_buf; out_buf_capacity = new_out_buf_capacity; 1638 } 1639 return pBuf; 1640 } 1641 1642 size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags) 1643 { 1644 tinfl_decompressor decomp; tinfl_status status; tinfl_init(&decomp); 1645 status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf, &src_buf_len, (mz_uint8*)pOut_buf, (mz_uint8*)pOut_buf, &out_buf_len, (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); 1646 return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len; 1647 } 1648 1649 int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) 1650 { 1651 int result = 0; 1652 tinfl_decompressor decomp; 1653 mz_uint8 *pDict = (mz_uint8*)MZ_MALLOC(TINFL_LZ_DICT_SIZE); size_t in_buf_ofs = 0, dict_ofs = 0; 1654 if (!pDict) 1655 return TINFL_STATUS_FAILED; 1656 tinfl_init(&decomp); 1657 for ( ; ; ) 1658 { 1659 size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs; 1660 tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size, 1661 (flags & ~(TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))); 1662 in_buf_ofs += in_buf_size; 1663 if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user))) 1664 break; 1665 if (status != TINFL_STATUS_HAS_MORE_OUTPUT) 1666 { 1667 result = (status == TINFL_STATUS_DONE); 1668 break; 1669 } 1670 dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1); 1671 } 1672 MZ_FREE(pDict); 1673 *pIn_buf_size = in_buf_ofs; 1674 return result; 1675 } 1676 1677 // ------------------- Low-level Compression (independent from all decompression API's) 1678 1679 // Purposely making these tables static for faster init and thread safety. 1680 static const mz_uint16 s_tdefl_len_sym[256] = { 1681 257,258,259,260,261,262,263,264,265,265,266,266,267,267,268,268,269,269,269,269,270,270,270,270,271,271,271,271,272,272,272,272, 1682 273,273,273,273,273,273,273,273,274,274,274,274,274,274,274,274,275,275,275,275,275,275,275,275,276,276,276,276,276,276,276,276, 1683 277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278, 1684 279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280, 1685 281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281, 1686 282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282, 1687 283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283, 1688 284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,285 }; 1689 1690 static const mz_uint8 s_tdefl_len_extra[256] = { 1691 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, 1692 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 1693 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 1694 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0 }; 1695 1696 static const mz_uint8 s_tdefl_small_dist_sym[512] = { 1697 0,1,2,3,4,4,5,5,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11, 1698 11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13, 1699 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14, 1700 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, 1701 14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, 1702 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16, 1703 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 1704 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, 1705 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,17,17,17,17,17, 1706 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, 1707 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, 1708 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17 }; 1709 1710 static const mz_uint8 s_tdefl_small_dist_extra[512] = { 1711 0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5, 1712 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 1713 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 1714 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,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,7,7,7,7,7,7,7, 1715 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,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,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 1716 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,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,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 1717 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,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,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 1718 7,7,7,7,7,7,7,7 }; 1719 1720 static const mz_uint8 s_tdefl_large_dist_sym[128] = { 1721 0,0,18,19,20,20,21,21,22,22,22,22,23,23,23,23,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26, 1722 26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28, 1723 28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29 }; 1724 1725 static const mz_uint8 s_tdefl_large_dist_extra[128] = { 1726 0,0,8,8,9,9,9,9,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, 1727 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, 1728 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13 }; 1729 1730 // Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted values. 1731 typedef struct { mz_uint16 m_key, m_sym_index; } tdefl_sym_freq; 1732 static tdefl_sym_freq* tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq* pSyms0, tdefl_sym_freq* pSyms1) 1733 { 1734 mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2]; tdefl_sym_freq* pCur_syms = pSyms0, *pNew_syms = pSyms1; MZ_CLEAR_OBJ(hist); 1735 for (i = 0; i < num_syms; i++) { mz_uint freq = pSyms0[i].m_key; hist[freq & 0xFF]++; hist[256 + ((freq >> 8) & 0xFF)]++; } 1736 while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256])) total_passes--; 1737 for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8) 1738 { 1739 const mz_uint32* pHist = &hist[pass << 8]; 1740 mz_uint offsets[256], cur_ofs = 0; 1741 for (i = 0; i < 256; i++) { offsets[i] = cur_ofs; cur_ofs += pHist[i]; } 1742 for (i = 0; i < num_syms; i++) pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = pCur_syms[i]; 1743 { tdefl_sym_freq* t = pCur_syms; pCur_syms = pNew_syms; pNew_syms = t; } 1744 } 1745 return pCur_syms; 1746 } 1747 1748 // tdefl_calculate_minimum_redundancy() originally written by: Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996. 1749 static void tdefl_calculate_minimum_redundancy(tdefl_sym_freq *A, int n) 1750 { 1751 int root, leaf, next, avbl, used, dpth; 1752 if (n==0) return; else if (n==1) { A[0].m_key = 1; return; } 1753 A[0].m_key += A[1].m_key; root = 0; leaf = 2; 1754 for (next=1; next < n-1; next++) 1755 { 1756 if (leaf>=n || A[root].m_key<A[leaf].m_key) { A[next].m_key = A[root].m_key; A[root++].m_key = (mz_uint16)next; } else A[next].m_key = A[leaf++].m_key; 1757 if (leaf>=n || (root<next && A[root].m_key<A[leaf].m_key)) { A[next].m_key = (mz_uint16)(A[next].m_key + A[root].m_key); A[root++].m_key = (mz_uint16)next; } else A[next].m_key = (mz_uint16)(A[next].m_key + A[leaf++].m_key); 1758 } 1759 A[n-2].m_key = 0; for (next=n-3; next>=0; next--) A[next].m_key = A[A[next].m_key].m_key+1; 1760 avbl = 1; used = dpth = 0; root = n-2; next = n-1; 1761 while (avbl>0) 1762 { 1763 while (root>=0 && (int)A[root].m_key==dpth) { used++; root--; } 1764 while (avbl>used) { A[next--].m_key = (mz_uint16)(dpth); avbl--; } 1765 avbl = 2*used; dpth++; used = 0; 1766 } 1767 } 1768 1769 // Limits canonical Huffman code table's max code size. 1770 enum { TDEFL_MAX_SUPPORTED_HUFF_CODESIZE = 32 }; 1771 static void tdefl_huffman_enforce_max_code_size(int *pNum_codes, int code_list_len, int max_code_size) 1772 { 1773 int i; mz_uint32 total = 0; if (code_list_len <= 1) return; 1774 for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++) pNum_codes[max_code_size] += pNum_codes[i]; 1775 for (i = max_code_size; i > 0; i--) total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i)); 1776 while (total != (1UL << max_code_size)) 1777 { 1778 pNum_codes[max_code_size]--; 1779 for (i = max_code_size - 1; i > 0; i--) if (pNum_codes[i]) { pNum_codes[i]--; pNum_codes[i + 1] += 2; break; } 1780 total--; 1781 } 1782 } 1783 1784 static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int table_len, int code_size_limit, int static_table) 1785 { 1786 int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE]; mz_uint next_code[TDEFL_MAX_SUPPORTED_HUFF_CODESIZE + 1]; MZ_CLEAR_OBJ(num_codes); 1787 if (static_table) 1788 { 1789 for (i = 0; i < table_len; i++) num_codes[d->m_huff_code_sizes[table_num][i]]++; 1790 } 1791 else 1792 { 1793 tdefl_sym_freq syms0[TDEFL_MAX_HUFF_SYMBOLS], syms1[TDEFL_MAX_HUFF_SYMBOLS], *pSyms; 1794 int num_used_syms = 0; 1795 const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0]; 1796 for (i = 0; i < table_len; i++) if (pSym_count[i]) { syms0[num_used_syms].m_key = (mz_uint16)pSym_count[i]; syms0[num_used_syms++].m_sym_index = (mz_uint16)i; } 1797 1798 pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1); tdefl_calculate_minimum_redundancy(pSyms, num_used_syms); 1799 1800 for (i = 0; i < num_used_syms; i++) num_codes[pSyms[i].m_key]++; 1801 1802 tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, code_size_limit); 1803 1804 MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]); MZ_CLEAR_OBJ(d->m_huff_codes[table_num]); 1805 for (i = 1, j = num_used_syms; i <= code_size_limit; i++) 1806 for (l = num_codes[i]; l > 0; l--) d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i); 1807 } 1808 1809 next_code[1] = 0; for (j = 0, i = 2; i <= code_size_limit; i++) next_code[i] = j = ((j + num_codes[i - 1]) << 1); 1810 1811 for (i = 0; i < table_len; i++) 1812 { 1813 mz_uint rev_code = 0, code, code_size; if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0) continue; 1814 code = next_code[code_size]++; for (l = code_size; l > 0; l--, code >>= 1) rev_code = (rev_code << 1) | (code & 1); 1815 d->m_huff_codes[table_num][i] = (mz_uint16)rev_code; 1816 } 1817 } 1818 1819 #define TDEFL_PUT_BITS(b, l) do { \ 1820 mz_uint bits = b; mz_uint len = l; MZ_ASSERT(bits <= ((1U << len) - 1U)); \ 1821 d->m_bit_buffer |= (bits << d->m_bits_in); d->m_bits_in += len; \ 1822 while (d->m_bits_in >= 8) { \ 1823 if (d->m_pOutput_buf < d->m_pOutput_buf_end) \ 1824 *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \ 1825 d->m_bit_buffer >>= 8; \ 1826 d->m_bits_in -= 8; \ 1827 } \ 1828 } MZ_MACRO_END 1829 1830 #define TDEFL_RLE_PREV_CODE_SIZE() { if (rle_repeat_count) { \ 1831 if (rle_repeat_count < 3) { \ 1832 d->m_huff_count[2][prev_code_size] = (mz_uint16)(d->m_huff_count[2][prev_code_size] + rle_repeat_count); \ 1833 while (rle_repeat_count--) packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \ 1834 } else { \ 1835 d->m_huff_count[2][16] = (mz_uint16)(d->m_huff_count[2][16] + 1); packed_code_sizes[num_packed_code_sizes++] = 16; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_repeat_count - 3); \ 1836 } rle_repeat_count = 0; } } 1837 1838 #define TDEFL_RLE_ZERO_CODE_SIZE() { if (rle_z_count) { \ 1839 if (rle_z_count < 3) { \ 1840 d->m_huff_count[2][0] = (mz_uint16)(d->m_huff_count[2][0] + rle_z_count); while (rle_z_count--) packed_code_sizes[num_packed_code_sizes++] = 0; \ 1841 } else if (rle_z_count <= 10) { \ 1842 d->m_huff_count[2][17] = (mz_uint16)(d->m_huff_count[2][17] + 1); packed_code_sizes[num_packed_code_sizes++] = 17; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 3); \ 1843 } else { \ 1844 d->m_huff_count[2][18] = (mz_uint16)(d->m_huff_count[2][18] + 1); packed_code_sizes[num_packed_code_sizes++] = 18; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 11); \ 1845 } rle_z_count = 0; } } 1846 1847 static mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; 1848 1849 static void tdefl_start_dynamic_block(tdefl_compressor *d) 1850 { 1851 int num_lit_codes, num_dist_codes, num_bit_lengths; mz_uint i, total_code_sizes_to_pack, num_packed_code_sizes, rle_z_count, rle_repeat_count, packed_code_sizes_index; 1852 mz_uint8 code_sizes_to_pack[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], packed_code_sizes[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], prev_code_size = 0xFF; 1853 1854 d->m_huff_count[0][256] = 1; 1855 1856 tdefl_optimize_huffman_table(d, 0, TDEFL_MAX_HUFF_SYMBOLS_0, 15, MZ_FALSE); 1857 tdefl_optimize_huffman_table(d, 1, TDEFL_MAX_HUFF_SYMBOLS_1, 15, MZ_FALSE); 1858 1859 for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--) if (d->m_huff_code_sizes[0][num_lit_codes - 1]) break; 1860 for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--) if (d->m_huff_code_sizes[1][num_dist_codes - 1]) break; 1861 1862 memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes); 1863 memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0], num_dist_codes); 1864 total_code_sizes_to_pack = num_lit_codes + num_dist_codes; num_packed_code_sizes = 0; rle_z_count = 0; rle_repeat_count = 0; 1865 1866 memset(&d->m_huff_count[2][0], 0, sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2); 1867 for (i = 0; i < total_code_sizes_to_pack; i++) 1868 { 1869 mz_uint8 code_size = code_sizes_to_pack[i]; 1870 if (!code_size) 1871 { 1872 TDEFL_RLE_PREV_CODE_SIZE(); 1873 if (++rle_z_count == 138) { TDEFL_RLE_ZERO_CODE_SIZE(); } 1874 } 1875 else 1876 { 1877 TDEFL_RLE_ZERO_CODE_SIZE(); 1878 if (code_size != prev_code_size) 1879 { 1880 TDEFL_RLE_PREV_CODE_SIZE(); 1881 d->m_huff_count[2][code_size] = (mz_uint16)(d->m_huff_count[2][code_size] + 1); packed_code_sizes[num_packed_code_sizes++] = code_size; 1882 } 1883 else if (++rle_repeat_count == 6) 1884 { 1885 TDEFL_RLE_PREV_CODE_SIZE(); 1886 } 1887 } 1888 prev_code_size = code_size; 1889 } 1890 if (rle_repeat_count) { TDEFL_RLE_PREV_CODE_SIZE(); } else { TDEFL_RLE_ZERO_CODE_SIZE(); } 1891 1892 tdefl_optimize_huffman_table(d, 2, TDEFL_MAX_HUFF_SYMBOLS_2, 7, MZ_FALSE); 1893 1894 TDEFL_PUT_BITS(2, 2); 1895 1896 TDEFL_PUT_BITS(num_lit_codes - 257, 5); 1897 TDEFL_PUT_BITS(num_dist_codes - 1, 5); 1898 1899 for (num_bit_lengths = 18; num_bit_lengths >= 0; num_bit_lengths--) if (d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[num_bit_lengths]]) break; 1900 num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1)); TDEFL_PUT_BITS(num_bit_lengths - 4, 4); 1901 for (i = 0; (int)i < num_bit_lengths; i++) TDEFL_PUT_BITS(d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[i]], 3); 1902 1903 for (packed_code_sizes_index = 0; packed_code_sizes_index < num_packed_code_sizes; ) 1904 { 1905 mz_uint code = packed_code_sizes[packed_code_sizes_index++]; MZ_ASSERT(code < TDEFL_MAX_HUFF_SYMBOLS_2); 1906 TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]); 1907 if (code >= 16) TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++], "\02\03\07"[code - 16]); 1908 } 1909 } 1910 1911 static void tdefl_start_static_block(tdefl_compressor *d) 1912 { 1913 mz_uint i; 1914 mz_uint8 *p = &d->m_huff_code_sizes[0][0]; 1915 1916 for (i = 0; i <= 143; ++i) *p++ = 8; 1917 for ( ; i <= 255; ++i) *p++ = 9; 1918 for ( ; i <= 279; ++i) *p++ = 7; 1919 for ( ; i <= 287; ++i) *p++ = 8; 1920 1921 memset(d->m_huff_code_sizes[1], 5, 32); 1922 1923 tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE); 1924 tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE); 1925 1926 TDEFL_PUT_BITS(1, 2); 1927 } 1928 1929 static const mz_uint mz_bitmasks[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF }; 1930 1931 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS 1932 static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) 1933 { 1934 mz_uint flags; 1935 mz_uint8 *pLZ_codes; 1936 mz_uint8 *pOutput_buf = d->m_pOutput_buf; 1937 mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf; 1938 mz_uint64 bit_buffer = d->m_bit_buffer; 1939 mz_uint bits_in = d->m_bits_in; 1940 1941 #define TDEFL_PUT_BITS_FAST(b, l) { bit_buffer |= (((mz_uint64)(b)) << bits_in); bits_in += (l); } 1942 1943 flags = 1; 1944 for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end; flags >>= 1) 1945 { 1946 if (flags == 1) 1947 flags = *pLZ_codes++ | 0x100; 1948 1949 if (flags & 1) 1950 { 1951 mz_uint s0, s1, n0, n1, sym, num_extra_bits; 1952 mz_uint match_len = pLZ_codes[0], match_dist = *(const mz_uint16 *)(pLZ_codes + 1); pLZ_codes += 3; 1953 1954 MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); 1955 TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); 1956 TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]); 1957 1958 // This sequence coaxes MSVC into using cmov's vs. jmp's. 1959 s0 = s_tdefl_small_dist_sym[match_dist & 511]; 1960 n0 = s_tdefl_small_dist_extra[match_dist & 511]; 1961 s1 = s_tdefl_large_dist_sym[match_dist >> 8]; 1962 n1 = s_tdefl_large_dist_extra[match_dist >> 8]; 1963 sym = (match_dist < 512) ? s0 : s1; 1964 num_extra_bits = (match_dist < 512) ? n0 : n1; 1965 1966 MZ_ASSERT(d->m_huff_code_sizes[1][sym]); 1967 TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]); 1968 TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits); 1969 } 1970 else 1971 { 1972 mz_uint lit = *pLZ_codes++; 1973 MZ_ASSERT(d->m_huff_code_sizes[0][lit]); 1974 TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); 1975 1976 if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) 1977 { 1978 flags >>= 1; 1979 lit = *pLZ_codes++; 1980 MZ_ASSERT(d->m_huff_code_sizes[0][lit]); 1981 TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); 1982 1983 if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) 1984 { 1985 flags >>= 1; 1986 lit = *pLZ_codes++; 1987 MZ_ASSERT(d->m_huff_code_sizes[0][lit]); 1988 TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); 1989 } 1990 } 1991 } 1992 1993 if (pOutput_buf >= d->m_pOutput_buf_end) 1994 return MZ_FALSE; 1995 1996 *(mz_uint64*)pOutput_buf = bit_buffer; 1997 pOutput_buf += (bits_in >> 3); 1998 bit_buffer >>= (bits_in & ~7); 1999 bits_in &= 7; 2000 } 2001 2002 #undef TDEFL_PUT_BITS_FAST 2003 2004 d->m_pOutput_buf = pOutput_buf; 2005 d->m_bits_in = 0; 2006 d->m_bit_buffer = 0; 2007 2008 while (bits_in) 2009 { 2010 mz_uint32 n = MZ_MIN(bits_in, 16); 2011 TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n); 2012 bit_buffer >>= n; 2013 bits_in -= n; 2014 } 2015 2016 TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]); 2017 2018 return (d->m_pOutput_buf < d->m_pOutput_buf_end); 2019 } 2020 #else 2021 static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) 2022 { 2023 mz_uint flags; 2024 mz_uint8 *pLZ_codes; 2025 2026 flags = 1; 2027 for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf; flags >>= 1) 2028 { 2029 if (flags == 1) 2030 flags = *pLZ_codes++ | 0x100; 2031 if (flags & 1) 2032 { 2033 mz_uint sym, num_extra_bits; 2034 mz_uint match_len = pLZ_codes[0], match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8)); pLZ_codes += 3; 2035 2036 MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); 2037 TDEFL_PUT_BITS(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); 2038 TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]); 2039 2040 if (match_dist < 512) 2041 { 2042 sym = s_tdefl_small_dist_sym[match_dist]; num_extra_bits = s_tdefl_small_dist_extra[match_dist]; 2043 } 2044 else 2045 { 2046 sym = s_tdefl_large_dist_sym[match_dist >> 8]; num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8]; 2047 } 2048 MZ_ASSERT(d->m_huff_code_sizes[1][sym]); 2049 TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]); 2050 TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits); 2051 } 2052 else 2053 { 2054 mz_uint lit = *pLZ_codes++; 2055 MZ_ASSERT(d->m_huff_code_sizes[0][lit]); 2056 TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); 2057 } 2058 } 2059 2060 TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]); 2061 2062 return (d->m_pOutput_buf < d->m_pOutput_buf_end); 2063 } 2064 #endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS 2065 2066 static mz_bool tdefl_compress_block(tdefl_compressor *d, mz_bool static_block) 2067 { 2068 if (static_block) 2069 tdefl_start_static_block(d); 2070 else 2071 tdefl_start_dynamic_block(d); 2072 return tdefl_compress_lz_codes(d); 2073 } 2074 2075 static int tdefl_flush_block(tdefl_compressor *d, int flush) 2076 { 2077 mz_uint saved_bit_buf, saved_bits_in; 2078 mz_uint8 *pSaved_output_buf; 2079 mz_bool comp_block_succeeded = MZ_FALSE; 2080 int n, use_raw_block = ((d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS) != 0) && (d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size; 2081 mz_uint8 *pOutput_buf_start = ((d->m_pPut_buf_func == NULL) && ((*d->m_pOut_buf_size - d->m_out_buf_ofs) >= TDEFL_OUT_BUF_SIZE)) ? ((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs) : d->m_output_buf; 2082 2083 d->m_pOutput_buf = pOutput_buf_start; 2084 d->m_pOutput_buf_end = d->m_pOutput_buf + TDEFL_OUT_BUF_SIZE - 16; 2085 2086 MZ_ASSERT(!d->m_output_flush_remaining); 2087 d->m_output_flush_ofs = 0; 2088 d->m_output_flush_remaining = 0; 2089 2090 *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left); 2091 d->m_pLZ_code_buf -= (d->m_num_flags_left == 8); 2092 2093 if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index)) 2094 { 2095 TDEFL_PUT_BITS(0x78, 8); TDEFL_PUT_BITS(0x01, 8); 2096 } 2097 2098 TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1); 2099 2100 pSaved_output_buf = d->m_pOutput_buf; saved_bit_buf = d->m_bit_buffer; saved_bits_in = d->m_bits_in; 2101 2102 if (!use_raw_block) 2103 comp_block_succeeded = tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || (d->m_total_lz_bytes < 48)); 2104 2105 // If the block gets expanded, forget the current contents of the output buffer and send a raw block instead. 2106 if ( ((use_raw_block) || ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >= d->m_total_lz_bytes))) && 2107 ((d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size) ) 2108 { 2109 mz_uint i; d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in; 2110 TDEFL_PUT_BITS(0, 2); 2111 if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); } 2112 for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF) 2113 { 2114 TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16); 2115 } 2116 for (i = 0; i < d->m_total_lz_bytes; ++i) 2117 { 2118 TDEFL_PUT_BITS(d->m_dict[(d->m_lz_code_buf_dict_pos + i) & TDEFL_LZ_DICT_SIZE_MASK], 8); 2119 } 2120 } 2121 // Check for the extremely unlikely (if not impossible) case of the compressed block not fitting into the output buffer when using dynamic codes. 2122 else if (!comp_block_succeeded) 2123 { 2124 d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in; 2125 tdefl_compress_block(d, MZ_TRUE); 2126 } 2127 2128 if (flush) 2129 { 2130 if (flush == TDEFL_FINISH) 2131 { 2132 if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); } 2133 if (d->m_flags & TDEFL_WRITE_ZLIB_HEADER) { mz_uint i, a = d->m_adler32; for (i = 0; i < 4; i++) { TDEFL_PUT_BITS((a >> 24) & 0xFF, 8); a <<= 8; } } 2134 } 2135 else 2136 { 2137 mz_uint i, z = 0; TDEFL_PUT_BITS(0, 3); if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); } for (i = 2; i; --i, z ^= 0xFFFF) { TDEFL_PUT_BITS(z & 0xFFFF, 16); } 2138 } 2139 } 2140 2141 MZ_ASSERT(d->m_pOutput_buf < d->m_pOutput_buf_end); 2142 2143 memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0); 2144 memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1); 2145 2146 d->m_pLZ_code_buf = d->m_lz_code_buf + 1; d->m_pLZ_flags = d->m_lz_code_buf; d->m_num_flags_left = 8; d->m_lz_code_buf_dict_pos += d->m_total_lz_bytes; d->m_total_lz_bytes = 0; d->m_block_index++; 2147 2148 if ((n = (int)(d->m_pOutput_buf - pOutput_buf_start)) != 0) 2149 { 2150 if (d->m_pPut_buf_func) 2151 { 2152 *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf; 2153 if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user)) 2154 return (d->m_prev_return_status = TDEFL_STATUS_PUT_BUF_FAILED); 2155 } 2156 else if (pOutput_buf_start == d->m_output_buf) 2157 { 2158 int bytes_to_copy = (int)MZ_MIN((size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs)); 2159 memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf, bytes_to_copy); 2160 d->m_out_buf_ofs += bytes_to_copy; 2161 if ((n -= bytes_to_copy) != 0) 2162 { 2163 d->m_output_flush_ofs = bytes_to_copy; 2164 d->m_output_flush_remaining = n; 2165 } 2166 } 2167 else 2168 { 2169 d->m_out_buf_ofs += n; 2170 } 2171 } 2172 2173 return d->m_output_flush_remaining; 2174 } 2175 2176 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES 2177 #define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16*)(p) 2178 static inline void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len) 2179 2180 { 2181 mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len; 2182 mz_uint num_probes_left = d->m_max_probes[match_len >= 32]; 2183 const mz_uint16 *s = (const mz_uint16*)(d->m_dict + pos), *p, *q; 2184 mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]), s01 = TDEFL_READ_UNALIGNED_WORD(s); 2185 MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return; 2186 for ( ; ; ) 2187 { 2188 for ( ; ; ) 2189 { 2190 if (--num_probes_left == 0) return; 2191 #define TDEFL_PROBE \ 2192 next_probe_pos = d->m_next[probe_pos]; \ 2193 if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \ 2194 probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \ 2195 if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) break; 2196 TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE; 2197 } 2198 if (!dist) break; q = (const mz_uint16*)(d->m_dict + probe_pos); if (TDEFL_READ_UNALIGNED_WORD(q) != s01) continue; p = s; probe_len = 32; 2199 do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && 2200 (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0) ); 2201 if (!probe_len) 2202 { 2203 *pMatch_dist = dist; *pMatch_len = MZ_MIN(max_match_len, TDEFL_MAX_MATCH_LEN); break; 2204 } 2205 else if ((probe_len = ((mz_uint)(p - s) * 2) + (mz_uint)(*(const mz_uint8*)p == *(const mz_uint8*)q)) > match_len) 2206 { 2207 *pMatch_dist = dist; if ((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) == max_match_len) break; 2208 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]); 2209 } 2210 } 2211 } 2212 #else 2213 static inline void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len) 2214 { 2215 mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len; 2216 mz_uint num_probes_left = d->m_max_probes[match_len >= 32]; 2217 const mz_uint8 *s = d->m_dict + pos, *p, *q; 2218 mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1]; 2219 MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return; 2220 for ( ; ; ) 2221 { 2222 for ( ; ; ) 2223 { 2224 if (--num_probes_left == 0) return; 2225 #define TDEFL_PROBE \ 2226 next_probe_pos = d->m_next[probe_pos]; \ 2227 if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \ 2228 probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \ 2229 if ((d->m_dict[probe_pos + match_len] == c0) && (d->m_dict[probe_pos + match_len - 1] == c1)) break; 2230 TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE; 2231 } 2232 if (!dist) break; p = s; q = d->m_dict + probe_pos; for (probe_len = 0; probe_len < max_match_len; probe_len++) if (*p++ != *q++) break; 2233 if (probe_len > match_len) 2234 { 2235 *pMatch_dist = dist; if ((*pMatch_len = match_len = probe_len) == max_match_len) return; 2236 c0 = d->m_dict[pos + match_len]; c1 = d->m_dict[pos + match_len - 1]; 2237 } 2238 } 2239 } 2240 #endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES 2241 2242 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN 2243 static mz_bool tdefl_compress_fast(tdefl_compressor *d) 2244 { 2245 // Faster, minimally featured LZRW1-style match+parse loop with better register utilization. Intended for applications where raw throughput is valued more highly than ratio. 2246 mz_uint lookahead_pos = d->m_lookahead_pos, lookahead_size = d->m_lookahead_size, dict_size = d->m_dict_size, total_lz_bytes = d->m_total_lz_bytes, num_flags_left = d->m_num_flags_left; 2247 mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags; 2248 mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK; 2249 2250 while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size))) 2251 { 2252 const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096; 2253 mz_uint dst_pos = (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK; 2254 mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size); 2255 d->m_src_buf_left -= num_bytes_to_process; 2256 lookahead_size += num_bytes_to_process; 2257 2258 while (num_bytes_to_process) 2259 { 2260 mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process); 2261 memcpy(d->m_dict + dst_pos, d->m_pSrc, n); 2262 if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) 2263 memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc, MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos)); 2264 d->m_pSrc += n; 2265 dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK; 2266 num_bytes_to_process -= n; 2267 } 2268 2269 dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size); 2270 if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE)) break; 2271 2272 while (lookahead_size >= 4) 2273 { 2274 mz_uint cur_match_dist, cur_match_len = 1; 2275 mz_uint8 *pCur_dict = d->m_dict + cur_pos; 2276 mz_uint first_trigram = (*(const mz_uint32 *)pCur_dict) & 0xFFFFFF; 2277 mz_uint hash = (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) & TDEFL_LEVEL1_HASH_SIZE_MASK; 2278 mz_uint probe_pos = d->m_hash[hash]; 2279 d->m_hash[hash] = (mz_uint16)lookahead_pos; 2280 2281 if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <= dict_size) && ((*(const mz_uint32 *)(d->m_dict + (probe_pos &= TDEFL_LZ_DICT_SIZE_MASK)) & 0xFFFFFF) == first_trigram)) 2282 { 2283 const mz_uint16 *p = (const mz_uint16 *)pCur_dict; 2284 const mz_uint16 *q = (const mz_uint16 *)(d->m_dict + probe_pos); 2285 mz_uint32 probe_len = 32; 2286 do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && 2287 (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0) ); 2288 cur_match_len = ((mz_uint)(p - (const mz_uint16 *)pCur_dict) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q); 2289 if (!probe_len) 2290 cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0; 2291 2292 if ((cur_match_len < TDEFL_MIN_MATCH_LEN) || ((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U*1024U))) 2293 { 2294 cur_match_len = 1; 2295 *pLZ_code_buf++ = (mz_uint8)first_trigram; 2296 *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); 2297 d->m_huff_count[0][(mz_uint8)first_trigram]++; 2298 } 2299 else 2300 { 2301 mz_uint32 s0, s1; 2302 cur_match_len = MZ_MIN(cur_match_len, lookahead_size); 2303 2304 MZ_ASSERT((cur_match_len >= TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 1) && (cur_match_dist <= TDEFL_LZ_DICT_SIZE)); 2305 2306 cur_match_dist--; 2307 2308 pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN); 2309 *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist; 2310 pLZ_code_buf += 3; 2311 *pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80); 2312 2313 s0 = s_tdefl_small_dist_sym[cur_match_dist & 511]; 2314 s1 = s_tdefl_large_dist_sym[cur_match_dist >> 8]; 2315 d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++; 2316 2317 d->m_huff_count[0][s_tdefl_len_sym[cur_match_len - TDEFL_MIN_MATCH_LEN]]++; 2318 } 2319 } 2320 else 2321 { 2322 *pLZ_code_buf++ = (mz_uint8)first_trigram; 2323 *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); 2324 d->m_huff_count[0][(mz_uint8)first_trigram]++; 2325 } 2326 2327 if (--num_flags_left == 0) { num_flags_left = 8; pLZ_flags = pLZ_code_buf++; } 2328 2329 total_lz_bytes += cur_match_len; 2330 lookahead_pos += cur_match_len; 2331 dict_size = MZ_MIN(dict_size + cur_match_len, TDEFL_LZ_DICT_SIZE); 2332 cur_pos = (cur_pos + cur_match_len) & TDEFL_LZ_DICT_SIZE_MASK; 2333 MZ_ASSERT(lookahead_size >= cur_match_len); 2334 lookahead_size -= cur_match_len; 2335 2336 if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) 2337 { 2338 int n; 2339 d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size; 2340 d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left; 2341 if ((n = tdefl_flush_block(d, 0)) != 0) 2342 return (n < 0) ? MZ_FALSE : MZ_TRUE; 2343 total_lz_bytes = d->m_total_lz_bytes; pLZ_code_buf = d->m_pLZ_code_buf; pLZ_flags = d->m_pLZ_flags; num_flags_left = d->m_num_flags_left; 2344 } 2345 } 2346 2347 while (lookahead_size) 2348 { 2349 mz_uint8 lit = d->m_dict[cur_pos]; 2350 2351 total_lz_bytes++; 2352 *pLZ_code_buf++ = lit; 2353 *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); 2354 if (--num_flags_left == 0) { num_flags_left = 8; pLZ_flags = pLZ_code_buf++; } 2355 2356 d->m_huff_count[0][lit]++; 2357 2358 lookahead_pos++; 2359 dict_size = MZ_MIN(dict_size + 1, TDEFL_LZ_DICT_SIZE); 2360 cur_pos = (cur_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; 2361 lookahead_size--; 2362 2363 if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) 2364 { 2365 int n; 2366 d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size; 2367 d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left; 2368 if ((n = tdefl_flush_block(d, 0)) != 0) 2369 return (n < 0) ? MZ_FALSE : MZ_TRUE; 2370 total_lz_bytes = d->m_total_lz_bytes; pLZ_code_buf = d->m_pLZ_code_buf; pLZ_flags = d->m_pLZ_flags; num_flags_left = d->m_num_flags_left; 2371 } 2372 } 2373 } 2374 2375 d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size; 2376 d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left; 2377 return MZ_TRUE; 2378 } 2379 #endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN 2380 2381 static inline void tdefl_record_literal(tdefl_compressor *d, mz_uint8 lit) 2382 { 2383 d->m_total_lz_bytes++; 2384 *d->m_pLZ_code_buf++ = lit; 2385 *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1); if (--d->m_num_flags_left == 0) { d->m_num_flags_left = 8; d->m_pLZ_flags = d->m_pLZ_code_buf++; } 2386 d->m_huff_count[0][lit]++; 2387 } 2388 2389 static inline void tdefl_record_match(tdefl_compressor *d, mz_uint match_len, mz_uint match_dist) 2390 { 2391 mz_uint32 s0, s1; 2392 2393 MZ_ASSERT((match_len >= TDEFL_MIN_MATCH_LEN) && (match_dist >= 1) && (match_dist <= TDEFL_LZ_DICT_SIZE)); 2394 2395 d->m_total_lz_bytes += match_len; 2396 2397 d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN); 2398 2399 match_dist -= 1; 2400 d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF); 2401 d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8); d->m_pLZ_code_buf += 3; 2402 2403 *d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80); if (--d->m_num_flags_left == 0) { d->m_num_flags_left = 8; d->m_pLZ_flags = d->m_pLZ_code_buf++; } 2404 2405 s0 = s_tdefl_small_dist_sym[match_dist & 511]; s1 = s_tdefl_large_dist_sym[match_dist >> 8]; 2406 d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++; 2407 2408 d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++; 2409 } 2410 2411 static mz_bool tdefl_compress_normal(tdefl_compressor *d) 2412 { 2413 const mz_uint8 *pSrc = d->m_pSrc; size_t src_buf_left = d->m_src_buf_left; 2414 tdefl_flush flush = d->m_flush; 2415 2416 while ((src_buf_left) || ((flush) && (d->m_lookahead_size))) 2417 { 2418 mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos; 2419 // Update dictionary and hash chains. Keeps the lookahead size equal to TDEFL_MAX_MATCH_LEN. 2420 if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1)) 2421 { 2422 mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK, ins_pos = d->m_lookahead_pos + d->m_lookahead_size - 2; 2423 mz_uint hash = (d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK]; 2424 mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size); 2425 const mz_uint8 *pSrc_end = pSrc + num_bytes_to_process; 2426 src_buf_left -= num_bytes_to_process; 2427 d->m_lookahead_size += num_bytes_to_process; 2428 while (pSrc != pSrc_end) 2429 { 2430 mz_uint8 c = *pSrc++; d->m_dict[dst_pos] = c; if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c; 2431 hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1); 2432 d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; d->m_hash[hash] = (mz_uint16)(ins_pos); 2433 dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; ins_pos++; 2434 } 2435 } 2436 else 2437 { 2438 while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) 2439 { 2440 mz_uint8 c = *pSrc++; 2441 mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK; 2442 src_buf_left--; 2443 d->m_dict[dst_pos] = c; 2444 if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) 2445 d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c; 2446 if ((++d->m_lookahead_size + d->m_dict_size) >= TDEFL_MIN_MATCH_LEN) 2447 { 2448 mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2; 2449 mz_uint hash = ((d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << (TDEFL_LZ_HASH_SHIFT * 2)) ^ (d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1); 2450 d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; d->m_hash[hash] = (mz_uint16)(ins_pos); 2451 } 2452 } 2453 } 2454 d->m_dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - d->m_lookahead_size, d->m_dict_size); 2455 if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) 2456 break; 2457 2458 // Simple lazy/greedy parsing state machine. 2459 len_to_move = 1; cur_match_dist = 0; cur_match_len = d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1); cur_pos = d->m_lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK; 2460 if (d->m_flags & (TDEFL_RLE_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS)) 2461 { 2462 if ((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))) 2463 { 2464 mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK]; 2465 cur_match_len = 0; while (cur_match_len < d->m_lookahead_size) { if (d->m_dict[cur_pos + cur_match_len] != c) break; cur_match_len++; } 2466 if (cur_match_len < TDEFL_MIN_MATCH_LEN) cur_match_len = 0; else cur_match_dist = 1; 2467 } 2468 } 2469 else 2470 { 2471 tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size, d->m_lookahead_size, &cur_match_dist, &cur_match_len); 2472 } 2473 if (((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U*1024U)) || (cur_pos == cur_match_dist) || ((d->m_flags & TDEFL_FILTER_MATCHES) && (cur_match_len <= 5))) 2474 { 2475 cur_match_dist = cur_match_len = 0; 2476 } 2477 if (d->m_saved_match_len) 2478 { 2479 if (cur_match_len > d->m_saved_match_len) 2480 { 2481 tdefl_record_literal(d, (mz_uint8)d->m_saved_lit); 2482 if (cur_match_len >= 128) 2483 { 2484 tdefl_record_match(d, cur_match_len, cur_match_dist); 2485 d->m_saved_match_len = 0; len_to_move = cur_match_len; 2486 } 2487 else 2488 { 2489 d->m_saved_lit = d->m_dict[cur_pos]; d->m_saved_match_dist = cur_match_dist; d->m_saved_match_len = cur_match_len; 2490 } 2491 } 2492 else 2493 { 2494 tdefl_record_match(d, d->m_saved_match_len, d->m_saved_match_dist); 2495 len_to_move = d->m_saved_match_len - 1; d->m_saved_match_len = 0; 2496 } 2497 } 2498 else if (!cur_match_dist) 2499 tdefl_record_literal(d, d->m_dict[cur_pos]); 2500 else if ((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) || (cur_match_len >= 128)) 2501 { 2502 tdefl_record_match(d, cur_match_len, cur_match_dist); 2503 len_to_move = cur_match_len; 2504 } 2505 else 2506 { 2507 d->m_saved_lit = d->m_dict[cur_pos]; d->m_saved_match_dist = cur_match_dist; d->m_saved_match_len = cur_match_len; 2508 } 2509 // Move the lookahead forward by len_to_move bytes. 2510 d->m_lookahead_pos += len_to_move; 2511 MZ_ASSERT(d->m_lookahead_size >= len_to_move); 2512 d->m_lookahead_size -= len_to_move; 2513 d->m_dict_size = MZ_MIN(d->m_dict_size + len_to_move, TDEFL_LZ_DICT_SIZE); 2514 // Check if it's time to flush the current LZ codes to the internal output buffer. 2515 if ( (d->m_pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) || 2516 ( (d->m_total_lz_bytes > 31*1024) && (((((mz_uint)(d->m_pLZ_code_buf - d->m_lz_code_buf) * 115) >> 7) >= d->m_total_lz_bytes) || (d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))) ) 2517 { 2518 int n; 2519 d->m_pSrc = pSrc; d->m_src_buf_left = src_buf_left; 2520 if ((n = tdefl_flush_block(d, 0)) != 0) 2521 return (n < 0) ? MZ_FALSE : MZ_TRUE; 2522 } 2523 } 2524 2525 d->m_pSrc = pSrc; d->m_src_buf_left = src_buf_left; 2526 return MZ_TRUE; 2527 } 2528 2529 static tdefl_status tdefl_flush_output_buffer(tdefl_compressor *d) 2530 { 2531 if (d->m_pIn_buf_size) 2532 { 2533 *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf; 2534 } 2535 2536 if (d->m_pOut_buf_size) 2537 { 2538 size_t n = MZ_MIN(*d->m_pOut_buf_size - d->m_out_buf_ofs, d->m_output_flush_remaining); 2539 memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf + d->m_output_flush_ofs, n); 2540 d->m_output_flush_ofs += (mz_uint)n; 2541 d->m_output_flush_remaining -= (mz_uint)n; 2542 d->m_out_buf_ofs += n; 2543 2544 *d->m_pOut_buf_size = d->m_out_buf_ofs; 2545 } 2546 2547 return (d->m_finished && !d->m_output_flush_remaining) ? TDEFL_STATUS_DONE : TDEFL_STATUS_OKAY; 2548 } 2549 2550 tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush) 2551 { 2552 if (!d) 2553 { 2554 if (pIn_buf_size) *pIn_buf_size = 0; 2555 if (pOut_buf_size) *pOut_buf_size = 0; 2556 return TDEFL_STATUS_BAD_PARAM; 2557 } 2558 2559 d->m_pIn_buf = pIn_buf; d->m_pIn_buf_size = pIn_buf_size; 2560 d->m_pOut_buf = pOut_buf; d->m_pOut_buf_size = pOut_buf_size; 2561 d->m_pSrc = (const mz_uint8 *)(pIn_buf); d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0; 2562 d->m_out_buf_ofs = 0; 2563 d->m_flush = flush; 2564 2565 if ( ((d->m_pPut_buf_func != NULL) == ((pOut_buf != NULL) || (pOut_buf_size != NULL))) || (d->m_prev_return_status != TDEFL_STATUS_OKAY) || 2566 (d->m_wants_to_finish && (flush != TDEFL_FINISH)) || (pIn_buf_size && *pIn_buf_size && !pIn_buf) || (pOut_buf_size && *pOut_buf_size && !pOut_buf) ) 2567 { 2568 if (pIn_buf_size) *pIn_buf_size = 0; 2569 if (pOut_buf_size) *pOut_buf_size = 0; 2570 return (d->m_prev_return_status = TDEFL_STATUS_BAD_PARAM); 2571 } 2572 d->m_wants_to_finish |= (flush == TDEFL_FINISH); 2573 2574 if ((d->m_output_flush_remaining) || (d->m_finished)) 2575 return (d->m_prev_return_status = tdefl_flush_output_buffer(d)); 2576 2577 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN 2578 if (((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) && 2579 ((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) && 2580 ((d->m_flags & (TDEFL_FILTER_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS | TDEFL_RLE_MATCHES)) == 0)) 2581 { 2582 if (!tdefl_compress_fast(d)) 2583 return d->m_prev_return_status; 2584 } 2585 else 2586 #endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN 2587 { 2588 if (!tdefl_compress_normal(d)) 2589 return d->m_prev_return_status; 2590 } 2591 2592 if ((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) && (pIn_buf)) 2593 d->m_adler32 = (mz_uint32)mz_adler32(d->m_adler32, (const mz_uint8 *)pIn_buf, d->m_pSrc - (const mz_uint8 *)pIn_buf); 2594 2595 if ((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) && (!d->m_output_flush_remaining)) 2596 { 2597 if (tdefl_flush_block(d, flush) < 0) 2598 return d->m_prev_return_status; 2599 d->m_finished = (flush == TDEFL_FINISH); 2600 if (flush == TDEFL_FULL_FLUSH) { MZ_CLEAR_OBJ(d->m_hash); MZ_CLEAR_OBJ(d->m_next); d->m_dict_size = 0; } 2601 } 2602 2603 return (d->m_prev_return_status = tdefl_flush_output_buffer(d)); 2604 } 2605 2606 tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush) 2607 { 2608 MZ_ASSERT(d->m_pPut_buf_func); return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush); 2609 } 2610 2611 tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) 2612 { 2613 d->m_pPut_buf_func = pPut_buf_func; d->m_pPut_buf_user = pPut_buf_user; 2614 d->m_flags = (mz_uint)(flags); d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3; d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0; 2615 d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3; 2616 if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG)) MZ_CLEAR_OBJ(d->m_hash); 2617 d->m_lookahead_pos = d->m_lookahead_size = d->m_dict_size = d->m_total_lz_bytes = d->m_lz_code_buf_dict_pos = d->m_bits_in = 0; 2618 d->m_output_flush_ofs = d->m_output_flush_remaining = d->m_finished = d->m_block_index = d->m_bit_buffer = d->m_wants_to_finish = 0; 2619 d->m_pLZ_code_buf = d->m_lz_code_buf + 1; d->m_pLZ_flags = d->m_lz_code_buf; d->m_num_flags_left = 8; 2620 d->m_pOutput_buf = d->m_output_buf; d->m_pOutput_buf_end = d->m_output_buf; d->m_prev_return_status = TDEFL_STATUS_OKAY; 2621 d->m_saved_match_dist = d->m_saved_match_len = d->m_saved_lit = 0; d->m_adler32 = 1; 2622 d->m_pIn_buf = NULL; d->m_pOut_buf = NULL; 2623 d->m_pIn_buf_size = NULL; d->m_pOut_buf_size = NULL; 2624 d->m_flush = TDEFL_NO_FLUSH; d->m_pSrc = NULL; d->m_src_buf_left = 0; d->m_out_buf_ofs = 0; 2625 memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0); 2626 memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1); 2627 return TDEFL_STATUS_OKAY; 2628 } 2629 2630 tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d) 2631 { 2632 return d->m_prev_return_status; 2633 } 2634 2635 mz_uint32 tdefl_get_adler32(tdefl_compressor *d) 2636 { 2637 return d->m_adler32; 2638 } 2639 2640 mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) 2641 { 2642 tdefl_compressor *pComp; mz_bool succeeded; if (((buf_len) && (!pBuf)) || (!pPut_buf_func)) return MZ_FALSE; 2643 pComp = (tdefl_compressor*)MZ_MALLOC(sizeof(tdefl_compressor)); if (!pComp) return MZ_FALSE; 2644 succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags) == TDEFL_STATUS_OKAY); 2645 succeeded = succeeded && (tdefl_compress_buffer(pComp, pBuf, buf_len, TDEFL_FINISH) == TDEFL_STATUS_DONE); 2646 MZ_FREE(pComp); return succeeded; 2647 } 2648 2649 typedef struct 2650 { 2651 size_t m_size, m_capacity; 2652 mz_uint8 *m_pBuf; 2653 mz_bool m_expandable; 2654 } tdefl_output_buffer; 2655 2656 static mz_bool tdefl_output_buffer_putter(const void *pBuf, int len, void *pUser) 2657 { 2658 tdefl_output_buffer *p = (tdefl_output_buffer *)pUser; 2659 size_t new_size = p->m_size + len; 2660 if (new_size > p->m_capacity) 2661 { 2662 size_t new_capacity = p->m_capacity; mz_uint8 *pNew_buf; if (!p->m_expandable) return MZ_FALSE; 2663 do { new_capacity = MZ_MAX(128U, new_capacity << 1U); } while (new_size > new_capacity); 2664 pNew_buf = (mz_uint8*)MZ_REALLOC(p->m_pBuf, new_capacity); if (!pNew_buf) return MZ_FALSE; 2665 p->m_pBuf = pNew_buf; p->m_capacity = new_capacity; 2666 } 2667 memcpy((mz_uint8*)p->m_pBuf + p->m_size, pBuf, len); p->m_size = new_size; 2668 return MZ_TRUE; 2669 } 2670 2671 void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags) 2672 { 2673 tdefl_output_buffer out_buf; MZ_CLEAR_OBJ(out_buf); 2674 if (!pOut_len) return MZ_FALSE; else *pOut_len = 0; 2675 out_buf.m_expandable = MZ_TRUE; 2676 if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) return NULL; 2677 *pOut_len = out_buf.m_size; return out_buf.m_pBuf; 2678 } 2679 2680 size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags) 2681 { 2682 tdefl_output_buffer out_buf; MZ_CLEAR_OBJ(out_buf); 2683 if (!pOut_buf) return 0; 2684 out_buf.m_pBuf = (mz_uint8*)pOut_buf; out_buf.m_capacity = out_buf_len; 2685 if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) return 0; 2686 return out_buf.m_size; 2687 } 2688 2689 static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 }; 2690 2691 // level may actually range from [0,10] (10 is a "hidden" max level, where we want a bit more compression and it's fine if throughput to fall off a cliff on some files). 2692 mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy) 2693 { 2694 mz_uint comp_flags = s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : 6] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0); 2695 if (window_bits > 0) comp_flags |= TDEFL_WRITE_ZLIB_HEADER; 2696 2697 if (!level) comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS; 2698 else if (strategy == MZ_FILTERED) comp_flags |= TDEFL_FILTER_MATCHES; 2699 else if (strategy == MZ_HUFFMAN_ONLY) comp_flags &= ~TDEFL_MAX_PROBES_MASK; 2700 else if (strategy == MZ_FIXED) comp_flags |= TDEFL_FORCE_ALL_STATIC_BLOCKS; 2701 else if (strategy == MZ_RLE) comp_flags |= TDEFL_RLE_MATCHES; 2702 2703 return comp_flags; 2704 } 2705 2706 #ifdef _MSC_VER 2707 #pragma warning (push) 2708 #pragma warning (disable:4204) // nonstandard extension used : non-constant aggregate initializer (also supported by GNU C and C99, so no big deal) 2709 #endif 2710 2711 // Simple PNG writer function by Alex Evans, 2011. Released into the public domain: https://gist.github.com/908299, more context at 2712 // http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/. 2713 void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out) 2714 { 2715 tdefl_compressor *pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); tdefl_output_buffer out_buf; int i, bpl = w * num_chans, y, z; mz_uint32 c; *pLen_out = 0; 2716 if (!pComp) return NULL; 2717 MZ_CLEAR_OBJ(out_buf); out_buf.m_expandable = MZ_TRUE; out_buf.m_capacity = 57+MZ_MAX(64, (1+bpl)*h); if (NULL == (out_buf.m_pBuf = (mz_uint8*)MZ_MALLOC(out_buf.m_capacity))) { MZ_FREE(pComp); return NULL; } 2718 // write dummy header 2719 for (z = 41; z; --z) tdefl_output_buffer_putter(&z, 1, &out_buf); 2720 // compress image data 2721 tdefl_init(pComp, tdefl_output_buffer_putter, &out_buf, TDEFL_DEFAULT_MAX_PROBES | TDEFL_WRITE_ZLIB_HEADER); 2722 for (y = 0; y < h; ++y) { tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH); tdefl_compress_buffer(pComp, (mz_uint8*)pImage + y * bpl, bpl, TDEFL_NO_FLUSH); } 2723 if (tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) != TDEFL_STATUS_DONE) { MZ_FREE(pComp); MZ_FREE(out_buf.m_pBuf); return NULL; } 2724 // write real header 2725 *pLen_out = out_buf.m_size-41; 2726 { 2727 mz_uint8 pnghdr[41]={0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52, 2728 0,0,(mz_uint8)(w>>8),(mz_uint8)w,0,0,(mz_uint8)(h>>8),(mz_uint8)h,8,"\0\0\04\02\06"[num_chans],0,0,0,0,0,0,0, 2729 (mz_uint8)(*pLen_out>>24),(mz_uint8)(*pLen_out>>16),(mz_uint8)(*pLen_out>>8),(mz_uint8)*pLen_out,0x49,0x44,0x41,0x54}; 2730 c=(mz_uint32)mz_crc32(MZ_CRC32_INIT,pnghdr+12,17); for (i=0; i<4; ++i, c<<=8) ((mz_uint8*)(pnghdr+29))[i]=(mz_uint8)(c>>24); 2731 memcpy(out_buf.m_pBuf, pnghdr, 41); 2732 } 2733 // write footer (IDAT CRC-32, followed by IEND chunk) 2734 if (!tdefl_output_buffer_putter("\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf)) { *pLen_out = 0; MZ_FREE(pComp); MZ_FREE(out_buf.m_pBuf); return NULL; } 2735 c = (mz_uint32)mz_crc32(MZ_CRC32_INIT,out_buf.m_pBuf+41-4, *pLen_out+4); for (i=0; i<4; ++i, c<<=8) (out_buf.m_pBuf+out_buf.m_size-16)[i] = (mz_uint8)(c >> 24); 2736 // compute final size of file, grab compressed data buffer and return 2737 *pLen_out += 57; MZ_FREE(pComp); return out_buf.m_pBuf; 2738 } 2739 2740 #ifdef _MSC_VER 2741 #pragma warning (pop) 2742 #endif 2743 2744 // ------------------- .ZIP archive reading 2745 2746 #ifndef MINIZ_NO_ARCHIVE_APIS 2747 2748 #ifndef MINIZ_NO_TIME 2749 #include <time.h> 2750 #endif 2751 2752 #ifdef MINIZ_NO_STDIO 2753 #define MZ_FILE void * 2754 #else 2755 #include <stdio.h> 2756 #include <sys/stat.h> 2757 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) 2758 #include <sys/utime.h> 2759 #define MZ_FILE FILE 2760 #define MZ_FOPEN fopen 2761 #define MZ_FCLOSE fclose 2762 #define MZ_FREAD fread 2763 #define MZ_FWRITE fwrite 2764 #define MZ_FTELL64 ftell 2765 #define MZ_FSEEK64 fseek 2766 #define MZ_FILE_STAT_STRUCT _stat 2767 #define MZ_FILE_STAT _stat 2768 #define MZ_FFLUSH fflush 2769 #define MZ_FREOPEN freopen 2770 #define MZ_DELETE_FILE remove 2771 #else 2772 #include <utime.h> 2773 #define MZ_FILE FILE 2774 #define MZ_FOPEN fopen 2775 #define MZ_FCLOSE fclose 2776 #define MZ_FREAD fread 2777 #define MZ_FWRITE fwrite 2778 #define MZ_FTELL64 ftello 2779 #define MZ_FSEEK64 fseeko 2780 #define MZ_FILE_STAT_STRUCT stat 2781 #define MZ_FILE_STAT stat 2782 #define MZ_FFLUSH fflush 2783 #define MZ_FREOPEN freopen 2784 #define MZ_DELETE_FILE remove 2785 #endif // #ifdef _MSC_VER 2786 #endif // #ifdef MINIZ_NO_STDIO 2787 2788 #define MZ_TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c)) 2789 2790 // Various ZIP archive enums. To completely avoid cross platform compiler alignment and platform endian issues, miniz.c doesn't use structs for any of this stuff. 2791 enum 2792 { 2793 // ZIP archive identifiers and record sizes 2794 MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06054b50, MZ_ZIP_CENTRAL_DIR_HEADER_SIG = 0x02014b50, MZ_ZIP_LOCAL_DIR_HEADER_SIG = 0x04034b50, 2795 MZ_ZIP_LOCAL_DIR_HEADER_SIZE = 30, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE = 46, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE = 22, 2796 // Central directory header record offsets 2797 MZ_ZIP_CDH_SIG_OFS = 0, MZ_ZIP_CDH_VERSION_MADE_BY_OFS = 4, MZ_ZIP_CDH_VERSION_NEEDED_OFS = 6, MZ_ZIP_CDH_BIT_FLAG_OFS = 8, 2798 MZ_ZIP_CDH_METHOD_OFS = 10, MZ_ZIP_CDH_FILE_TIME_OFS = 12, MZ_ZIP_CDH_FILE_DATE_OFS = 14, MZ_ZIP_CDH_CRC32_OFS = 16, 2799 MZ_ZIP_CDH_COMPRESSED_SIZE_OFS = 20, MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS = 24, MZ_ZIP_CDH_FILENAME_LEN_OFS = 28, MZ_ZIP_CDH_EXTRA_LEN_OFS = 30, 2800 MZ_ZIP_CDH_COMMENT_LEN_OFS = 32, MZ_ZIP_CDH_DISK_START_OFS = 34, MZ_ZIP_CDH_INTERNAL_ATTR_OFS = 36, MZ_ZIP_CDH_EXTERNAL_ATTR_OFS = 38, MZ_ZIP_CDH_LOCAL_HEADER_OFS = 42, 2801 // Local directory header offsets 2802 MZ_ZIP_LDH_SIG_OFS = 0, MZ_ZIP_LDH_VERSION_NEEDED_OFS = 4, MZ_ZIP_LDH_BIT_FLAG_OFS = 6, MZ_ZIP_LDH_METHOD_OFS = 8, MZ_ZIP_LDH_FILE_TIME_OFS = 10, 2803 MZ_ZIP_LDH_FILE_DATE_OFS = 12, MZ_ZIP_LDH_CRC32_OFS = 14, MZ_ZIP_LDH_COMPRESSED_SIZE_OFS = 18, MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS = 22, 2804 MZ_ZIP_LDH_FILENAME_LEN_OFS = 26, MZ_ZIP_LDH_EXTRA_LEN_OFS = 28, 2805 // End of central directory offsets 2806 MZ_ZIP_ECDH_SIG_OFS = 0, MZ_ZIP_ECDH_NUM_THIS_DISK_OFS = 4, MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS = 6, MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 8, 2807 MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS = 10, MZ_ZIP_ECDH_CDIR_SIZE_OFS = 12, MZ_ZIP_ECDH_CDIR_OFS_OFS = 16, MZ_ZIP_ECDH_COMMENT_SIZE_OFS = 20, 2808 }; 2809 2810 typedef struct 2811 { 2812 void *m_p; 2813 size_t m_size, m_capacity; 2814 mz_uint m_element_size; 2815 } mz_zip_array; 2816 2817 struct mz_zip_internal_state_tag 2818 { 2819 mz_zip_array m_central_dir; 2820 mz_zip_array m_central_dir_offsets; 2821 mz_zip_array m_sorted_central_dir_offsets; 2822 MZ_FILE *m_pFile; 2823 void *m_pMem; 2824 size_t m_mem_size; 2825 size_t m_mem_capacity; 2826 }; 2827 2828 #define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size) (array_ptr)->m_element_size = element_size 2829 #define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) ((element_type *)((array_ptr)->m_p))[index] 2830 2831 static inline void mz_zip_array_clear(mz_zip_archive *pZip, mz_zip_array *pArray) 2832 { 2833 pZip->m_pFree(pZip->m_pAlloc_opaque, pArray->m_p); 2834 memset(pArray, 0, sizeof(mz_zip_array)); 2835 } 2836 2837 static mz_bool mz_zip_array_ensure_capacity(mz_zip_archive *pZip, mz_zip_array *pArray, size_t min_new_capacity, mz_uint growing) 2838 { 2839 void *pNew_p; size_t new_capacity = min_new_capacity; MZ_ASSERT(pArray->m_element_size); if (pArray->m_capacity >= min_new_capacity) return MZ_TRUE; 2840 if (growing) { new_capacity = MZ_MAX(1, pArray->m_capacity); while (new_capacity < min_new_capacity) new_capacity *= 2; } 2841 if (NULL == (pNew_p = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pArray->m_p, pArray->m_element_size, new_capacity))) return MZ_FALSE; 2842 pArray->m_p = pNew_p; pArray->m_capacity = new_capacity; 2843 return MZ_TRUE; 2844 } 2845 2846 static inline mz_bool mz_zip_array_reserve(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_capacity, mz_uint growing) 2847 { 2848 if (new_capacity > pArray->m_capacity) { if (!mz_zip_array_ensure_capacity(pZip, pArray, new_capacity, growing)) return MZ_FALSE; } 2849 return MZ_TRUE; 2850 } 2851 2852 static inline mz_bool mz_zip_array_resize(mz_zip_archive *pZip, mz_zip_array *pArray, size_t new_size, mz_uint growing) 2853 { 2854 if (new_size > pArray->m_capacity) { if (!mz_zip_array_ensure_capacity(pZip, pArray, new_size, growing)) return MZ_FALSE; } 2855 pArray->m_size = new_size; 2856 return MZ_TRUE; 2857 } 2858 2859 static inline mz_bool mz_zip_array_ensure_room(mz_zip_archive *pZip, mz_zip_array *pArray, size_t n) 2860 { 2861 return mz_zip_array_reserve(pZip, pArray, pArray->m_size + n, MZ_TRUE); 2862 } 2863 2864 static inline mz_bool mz_zip_array_push_back(mz_zip_archive *pZip, mz_zip_array *pArray, const void *pElements, size_t n) 2865 { 2866 size_t orig_size = pArray->m_size; if (!mz_zip_array_resize(pZip, pArray, orig_size + n, MZ_TRUE)) return MZ_FALSE; 2867 memcpy((mz_uint8*)pArray->m_p + orig_size * pArray->m_element_size, pElements, n * pArray->m_element_size); 2868 return MZ_TRUE; 2869 } 2870 2871 #ifndef MINIZ_NO_TIME 2872 static time_t mz_zip_dos_to_time_t(int dos_time, int dos_date) 2873 { 2874 struct tm tm; 2875 memset(&tm, 0, sizeof(tm)); tm.tm_isdst = -1; 2876 tm.tm_year = ((dos_date >> 9) & 127) + 1980 - 1900; tm.tm_mon = ((dos_date >> 5) & 15) - 1; tm.tm_mday = dos_date & 31; 2877 tm.tm_hour = (dos_time >> 11) & 31; tm.tm_min = (dos_time >> 5) & 63; tm.tm_sec = (dos_time << 1) & 62; 2878 return mktime(&tm); 2879 } 2880 2881 static void mz_zip_time_to_dos_time(time_t time, mz_uint16 *pDOS_time, mz_uint16 *pDOS_date) 2882 { 2883 struct tm *tm = localtime(&time); 2884 *pDOS_time = (mz_uint16)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) + ((tm->tm_sec) >> 1)); 2885 *pDOS_date = (mz_uint16)(((tm->tm_year + 1900 - 1980) << 9) + ((tm->tm_mon + 1) << 5) + tm->tm_mday); 2886 } 2887 #endif 2888 2889 #ifndef MINIZ_NO_STDIO 2890 static mz_bool mz_zip_get_file_modified_time(const char *pFilename, mz_uint16 *pDOS_time, mz_uint16 *pDOS_date) 2891 { 2892 #ifdef MINIZ_NO_TIME 2893 (void)pFilename; *pDOS_date = *pDOS_time = 0; 2894 #else 2895 struct MZ_FILE_STAT_STRUCT file_stat; if (MZ_FILE_STAT(pFilename, &file_stat) != 0) return MZ_FALSE; 2896 mz_zip_time_to_dos_time(file_stat.st_mtime, pDOS_time, pDOS_date); 2897 #endif // #ifdef MINIZ_NO_TIME 2898 return MZ_TRUE; 2899 } 2900 2901 static mz_bool mz_zip_set_file_times(const char *pFilename, time_t access_time, time_t modified_time) 2902 { 2903 #ifndef MINIZ_NO_TIME 2904 struct utimbuf t; t.actime = access_time; t.modtime = modified_time; 2905 return !utime(pFilename, &t); 2906 #else 2907 pFilename, access_time, modified_time; 2908 return MZ_TRUE; 2909 #endif // #ifndef MINIZ_NO_TIME 2910 } 2911 #endif 2912 2913 static mz_bool mz_zip_reader_init_internal(mz_zip_archive *pZip, mz_uint32 flags) 2914 { 2915 (void)flags; 2916 if ((!pZip) || (pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID)) 2917 return MZ_FALSE; 2918 2919 if (!pZip->m_pAlloc) pZip->m_pAlloc = def_alloc_func; 2920 if (!pZip->m_pFree) pZip->m_pFree = def_free_func; 2921 if (!pZip->m_pRealloc) pZip->m_pRealloc = def_realloc_func; 2922 2923 pZip->m_zip_mode = MZ_ZIP_MODE_READING; 2924 pZip->m_archive_size = 0; 2925 pZip->m_central_directory_file_ofs = 0; 2926 pZip->m_total_files = 0; 2927 2928 if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state)))) 2929 return MZ_FALSE; 2930 memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state)); 2931 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, sizeof(mz_uint8)); 2932 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, sizeof(mz_uint32)); 2933 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, sizeof(mz_uint32)); 2934 return MZ_TRUE; 2935 } 2936 2937 static inline mz_bool mz_zip_reader_filename_less(const mz_zip_array *pCentral_dir_array, const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, mz_uint r_index) 2938 { 2939 const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE; 2940 const mz_uint8 *pR = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, r_index)); 2941 mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS), r_len = MZ_READ_LE16(pR + MZ_ZIP_CDH_FILENAME_LEN_OFS); 2942 mz_uint8 l = 0, r = 0; 2943 pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; pR += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; 2944 pE = pL + MZ_MIN(l_len, r_len); 2945 while (pL < pE) 2946 { 2947 if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR))) 2948 break; 2949 pL++; pR++; 2950 } 2951 return (pL == pE) ? (l_len < r_len) : (l < r); 2952 } 2953 2954 #define MZ_SWAP_UINT32(a, b) do { mz_uint32 t = a; a = b; b = t; } MZ_MACRO_END 2955 2956 // Heap sort of lowercased filenames, used to help accelerate plain central directory searches by mz_zip_reader_locate_file(). (Could also use qsort(), but it could allocate memory.) 2957 static void mz_zip_reader_sort_central_dir_offsets_by_filename(mz_zip_archive *pZip) 2958 { 2959 mz_zip_internal_state *pState = pZip->m_pState; 2960 const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets; 2961 const mz_zip_array *pCentral_dir = &pState->m_central_dir; 2962 mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0); 2963 const int size = pZip->m_total_files; 2964 int start = (size - 2) >> 1, end; 2965 while (start >= 0) 2966 { 2967 int child, root = start; 2968 for ( ; ; ) 2969 { 2970 if ((child = (root << 1) + 1) >= size) 2971 break; 2972 child += (((child + 1) < size) && (mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1]))); 2973 if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child])) 2974 break; 2975 MZ_SWAP_UINT32(pIndices[root], pIndices[child]); root = child; 2976 } 2977 start--; 2978 } 2979 2980 end = size - 1; 2981 while (end > 0) 2982 { 2983 int child, root = 0; 2984 MZ_SWAP_UINT32(pIndices[end], pIndices[0]); 2985 for ( ; ; ) 2986 { 2987 if ((child = (root << 1) + 1) >= end) 2988 break; 2989 child += (((child + 1) < end) && mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[child], pIndices[child + 1])); 2990 if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets, pIndices[root], pIndices[child])) 2991 break; 2992 MZ_SWAP_UINT32(pIndices[root], pIndices[child]); root = child; 2993 } 2994 end--; 2995 } 2996 } 2997 2998 static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint32 flags) 2999 { 3000 mz_uint i, n, cdir_size, num_this_disk, cdir_disk_index; 3001 mz_uint64 cdir_ofs; 3002 mz_int64 cur_file_ofs; 3003 const mz_uint8 *p; 3004 mz_uint32 buf_u32[4096 / sizeof(mz_uint32)]; mz_uint8 *pBuf = (mz_uint8 *)buf_u32; 3005 // Basic sanity checks - reject files which are too small, and check the first 4 bytes of the file to make sure a local header is there. 3006 if (pZip->m_archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) 3007 return MZ_FALSE; 3008 // Find the end of central directory record by scanning the file from the end towards the beginning. 3009 cur_file_ofs = MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)sizeof(buf_u32), 0); 3010 for ( ; ; ) 3011 { 3012 int i, n = (int)MZ_MIN(sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs); 3013 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n) 3014 return MZ_FALSE; 3015 for (i = n - 4; i >= 0; --i) 3016 if (MZ_READ_LE32(pBuf + i) == MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) 3017 break; 3018 if (i >= 0) 3019 { 3020 cur_file_ofs += i; 3021 break; 3022 } 3023 if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >= (0xFFFF + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE))) 3024 return MZ_FALSE; 3025 cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0); 3026 } 3027 // Read and verify the end of central directory record. 3028 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) 3029 return MZ_FALSE; 3030 if ((MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) != MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) || 3031 ((pZip->m_total_files = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS)) != MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS))) 3032 return MZ_FALSE; 3033 3034 num_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS); 3035 cdir_disk_index = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS); 3036 if (((num_this_disk | cdir_disk_index) != 0) && ((num_this_disk != 1) || (cdir_disk_index != 1))) 3037 return MZ_FALSE; 3038 3039 if ((cdir_size = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_SIZE_OFS)) < pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) 3040 return MZ_FALSE; 3041 3042 cdir_ofs = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS); 3043 if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size) 3044 return MZ_FALSE; 3045 3046 pZip->m_central_directory_file_ofs = cdir_ofs; 3047 3048 if (pZip->m_total_files) 3049 { 3050 // Read the entire central directory into a heap block, and allocate another heap block to hold the unsorted central dir file record offsets, and another to hold the sorted indices. 3051 if ((!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir, cdir_size, MZ_FALSE)) || 3052 (!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir_offsets, pZip->m_total_files, MZ_FALSE)) || 3053 (!mz_zip_array_resize(pZip, &pZip->m_pState->m_sorted_central_dir_offsets, pZip->m_total_files, MZ_FALSE))) 3054 return MZ_FALSE; 3055 if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs, pZip->m_pState->m_central_dir.m_p, cdir_size) != cdir_size) 3056 return MZ_FALSE; 3057 3058 // Now create an index into the central directory file records, do some basic sanity checking on each record, and check for zip64 entries (which are not yet supported). 3059 p = (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p; 3060 for (n = cdir_size, i = 0; i < pZip->m_total_files; ++i) 3061 { 3062 mz_uint total_header_size, comp_size, decomp_size, disk_index; 3063 if ((n < MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) || (MZ_READ_LE32(p) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG)) 3064 return MZ_FALSE; 3065 MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, i) = (mz_uint32)(p - (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p); 3066 MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_sorted_central_dir_offsets, mz_uint32, i) = i; 3067 comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); 3068 decomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS); 3069 if (((!MZ_READ_LE32(p + MZ_ZIP_CDH_METHOD_OFS)) && (decomp_size != comp_size)) || (decomp_size && !comp_size) || (decomp_size == 0xFFFFFFFF) || (comp_size == 0xFFFFFFFF)) 3070 return MZ_FALSE; 3071 disk_index = MZ_READ_LE16(p + MZ_ZIP_CDH_DISK_START_OFS); 3072 if ((disk_index != num_this_disk) && (disk_index != 1)) 3073 return MZ_FALSE; 3074 if (((mz_uint64)MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS) + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + comp_size) > pZip->m_archive_size) 3075 return MZ_FALSE; 3076 if ((total_header_size = MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS)) > n) 3077 return MZ_FALSE; 3078 n -= total_header_size; p += total_header_size; 3079 } 3080 } 3081 3082 if ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0) 3083 mz_zip_reader_sort_central_dir_offsets_by_filename(pZip); 3084 3085 return MZ_TRUE; 3086 } 3087 3088 mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint32 flags) 3089 { 3090 if ((!pZip) || (!pZip->m_pRead)) 3091 return MZ_FALSE; 3092 if (!mz_zip_reader_init_internal(pZip, flags)) 3093 return MZ_FALSE; 3094 pZip->m_archive_size = size; 3095 if (!mz_zip_reader_read_central_dir(pZip, flags)) 3096 { 3097 mz_zip_reader_end(pZip); 3098 return MZ_FALSE; 3099 } 3100 return MZ_TRUE; 3101 } 3102 3103 static size_t mz_zip_mem_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n) 3104 { 3105 mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; 3106 size_t s = (file_ofs >= pZip->m_archive_size) ? 0 : (size_t)MZ_MIN(pZip->m_archive_size - file_ofs, n); 3107 memcpy(pBuf, (const mz_uint8 *)pZip->m_pState->m_pMem + file_ofs, s); 3108 return s; 3109 } 3110 3111 mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint32 flags) 3112 { 3113 if (!mz_zip_reader_init_internal(pZip, flags)) 3114 return MZ_FALSE; 3115 pZip->m_archive_size = size; 3116 pZip->m_pRead = mz_zip_mem_read_func; 3117 pZip->m_pIO_opaque = pZip; 3118 pZip->m_pState->m_pMem = (void *)pMem; 3119 pZip->m_pState->m_mem_size = size; 3120 if (!mz_zip_reader_read_central_dir(pZip, flags)) 3121 { 3122 mz_zip_reader_end(pZip); 3123 return MZ_FALSE; 3124 } 3125 return MZ_TRUE; 3126 } 3127 3128 #ifndef MINIZ_NO_STDIO 3129 static size_t mz_zip_file_read_func(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n) 3130 { 3131 mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; 3132 mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile); 3133 if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET)))) 3134 return 0; 3135 return MZ_FREAD(pBuf, 1, n, pZip->m_pState->m_pFile); 3136 } 3137 3138 mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags) 3139 { 3140 mz_uint64 file_size; 3141 MZ_FILE *pFile = MZ_FOPEN(pFilename, "rb"); 3142 if (!pFile) 3143 return MZ_FALSE; 3144 if (MZ_FSEEK64(pFile, 0, SEEK_END)) 3145 return MZ_FALSE; 3146 file_size = MZ_FTELL64(pFile); 3147 if (!mz_zip_reader_init_internal(pZip, flags)) 3148 { 3149 MZ_FCLOSE(pFile); 3150 return MZ_FALSE; 3151 } 3152 pZip->m_pRead = mz_zip_file_read_func; 3153 pZip->m_pIO_opaque = pZip; 3154 pZip->m_pState->m_pFile = pFile; 3155 pZip->m_archive_size = file_size; 3156 if (!mz_zip_reader_read_central_dir(pZip, flags)) 3157 { 3158 mz_zip_reader_end(pZip); 3159 return MZ_FALSE; 3160 } 3161 return MZ_TRUE; 3162 } 3163 #endif // #ifndef MINIZ_NO_STDIO 3164 3165 mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip) 3166 { 3167 return pZip ? pZip->m_total_files : 0; 3168 } 3169 3170 static inline const mz_uint8 *mz_zip_reader_get_cdh(mz_zip_archive *pZip, mz_uint file_index) 3171 { 3172 if ((!pZip) || (!pZip->m_pState) || (file_index >= pZip->m_total_files) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) 3173 return NULL; 3174 return &MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index)); 3175 } 3176 3177 mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index) 3178 { 3179 mz_uint m_bit_flag; 3180 const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index); 3181 if (!p) 3182 return MZ_FALSE; 3183 m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS); 3184 return (m_bit_flag & 1); 3185 } 3186 3187 mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index) 3188 { 3189 mz_uint filename_len, internal_attr, external_attr; 3190 const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index); 3191 if (!p) 3192 return MZ_FALSE; 3193 3194 internal_attr = MZ_READ_LE16(p + MZ_ZIP_CDH_INTERNAL_ATTR_OFS); 3195 external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS); 3196 if ((!internal_attr) && ((external_attr & 0x10) != 0)) 3197 return MZ_TRUE; 3198 3199 filename_len = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); 3200 if (filename_len) 3201 { 3202 if (*(p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_len - 1) == '/') 3203 return MZ_TRUE; 3204 } 3205 3206 return MZ_FALSE; 3207 } 3208 3209 mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat) 3210 { 3211 mz_uint n; 3212 const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index); 3213 if ((!p) || (!pStat)) 3214 return MZ_FALSE; 3215 3216 // Unpack the central directory record. 3217 pStat->m_file_index = file_index; 3218 pStat->m_central_dir_ofs = MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index); 3219 pStat->m_version_made_by = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS); 3220 pStat->m_version_needed = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_NEEDED_OFS); 3221 pStat->m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS); 3222 pStat->m_method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS); 3223 #ifndef MINIZ_NO_TIME 3224 pStat->m_time = mz_zip_dos_to_time_t(MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_TIME_OFS), MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_DATE_OFS)); 3225 #endif 3226 pStat->m_crc32 = MZ_READ_LE32(p + MZ_ZIP_CDH_CRC32_OFS); 3227 pStat->m_comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); 3228 pStat->m_uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS); 3229 pStat->m_internal_attr = MZ_READ_LE16(p + MZ_ZIP_CDH_INTERNAL_ATTR_OFS); 3230 pStat->m_external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS); 3231 pStat->m_local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS); 3232 3233 // Copy as much of the filename and comment as possible. 3234 n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE - 1); 3235 memcpy(pStat->m_filename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n); pStat->m_filename[n] = '\0'; 3236 3237 n = MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS); n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE - 1); 3238 pStat->m_comment_size = n; 3239 memcpy(pStat->m_comment, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS), n); pStat->m_comment[n] = '\0'; 3240 3241 return MZ_TRUE; 3242 } 3243 3244 mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size) 3245 { 3246 mz_uint n; 3247 const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index); 3248 if (!p) { if (filename_buf_size) pFilename[0] = '\0'; return 0; } 3249 n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS); 3250 if (filename_buf_size) 3251 { 3252 n = MZ_MIN(n, filename_buf_size - 1); 3253 memcpy(pFilename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n); 3254 pFilename[n] = '\0'; 3255 } 3256 return n + 1; 3257 } 3258 3259 static inline mz_bool mz_zip_reader_string_equal(const char *pA, const char *pB, mz_uint len, mz_uint flags) 3260 { 3261 mz_uint i; 3262 if (flags & MZ_ZIP_FLAG_CASE_SENSITIVE) 3263 return 0 == memcmp(pA, pB, len); 3264 for (i = 0; i < len; ++i) 3265 if (MZ_TOLOWER(pA[i]) != MZ_TOLOWER(pB[i])) 3266 return MZ_FALSE; 3267 return MZ_TRUE; 3268 } 3269 3270 static inline int mz_zip_reader_filename_compare(const mz_zip_array *pCentral_dir_array, const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, const char *pR, mz_uint r_len) 3271 { 3272 const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_array, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, l_index)), *pE; 3273 mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS); 3274 mz_uint8 l = 0, r = 0; 3275 pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; 3276 pE = pL + MZ_MIN(l_len, r_len); 3277 while (pL < pE) 3278 { 3279 if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR))) 3280 break; 3281 pL++; pR++; 3282 } 3283 return (pL == pE) ? (int)(l_len - r_len) : (l - r); 3284 } 3285 3286 static int mz_zip_reader_locate_file_binary_search(mz_zip_archive *pZip, const char *pFilename) 3287 { 3288 mz_zip_internal_state *pState = pZip->m_pState; 3289 const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets; 3290 const mz_zip_array *pCentral_dir = &pState->m_central_dir; 3291 mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(&pState->m_sorted_central_dir_offsets, mz_uint32, 0); 3292 const int size = pZip->m_total_files; 3293 const mz_uint filename_len = (mz_uint)strlen(pFilename); 3294 int l = 0, h = size - 1; 3295 while (l <= h) 3296 { 3297 int m = (l + h) >> 1, file_index = pIndices[m], comp = mz_zip_reader_filename_compare(pCentral_dir, pCentral_dir_offsets, file_index, pFilename, filename_len); 3298 if (!comp) 3299 return file_index; 3300 else if (comp < 0) 3301 l = m + 1; 3302 else 3303 h = m - 1; 3304 } 3305 return -1; 3306 } 3307 3308 int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags) 3309 { 3310 mz_uint file_index; size_t name_len, comment_len; 3311 if ((!pZip) || (!pZip->m_pState) || (!pName) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) 3312 return -1; 3313 if (((flags & (MZ_ZIP_FLAG_IGNORE_PATH | MZ_ZIP_FLAG_CASE_SENSITIVE)) == 0) && (!pComment) && (pZip->m_pState->m_sorted_central_dir_offsets.m_p)) 3314 return mz_zip_reader_locate_file_binary_search(pZip, pName); 3315 name_len = strlen(pName); if (name_len > 0xFFFF) return -1; 3316 comment_len = pComment ? strlen(pComment) : 0; if (comment_len > 0xFFFF) return -1; 3317 for (file_index = 0; file_index < pZip->m_total_files; file_index++) 3318 { 3319 const mz_uint8 *pHeader = &MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir, mz_uint8, MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index)); 3320 mz_uint filename_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_FILENAME_LEN_OFS); 3321 const char *pFilename = (const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE; 3322 if (filename_len < name_len) 3323 continue; 3324 if (comment_len) 3325 { 3326 mz_uint file_extra_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_EXTRA_LEN_OFS), file_comment_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_COMMENT_LEN_OFS); 3327 const char *pFile_comment = pFilename + filename_len + file_extra_len; 3328 if ((file_comment_len != comment_len) || (!mz_zip_reader_string_equal(pComment, pFile_comment, file_comment_len, flags))) 3329 continue; 3330 } 3331 if ((flags & MZ_ZIP_FLAG_IGNORE_PATH) && (filename_len)) 3332 { 3333 int ofs = filename_len - 1; 3334 do 3335 { 3336 if ((pFilename[ofs] == '/') || (pFilename[ofs] == '\\') || (pFilename[ofs] == ':')) 3337 break; 3338 } while (--ofs >= 0); 3339 ofs++; 3340 pFilename += ofs; filename_len -= ofs; 3341 } 3342 if ((filename_len == name_len) && (mz_zip_reader_string_equal(pName, pFilename, filename_len, flags))) 3343 return file_index; 3344 } 3345 return -1; 3346 } 3347 3348 mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size) 3349 { 3350 int status = TINFL_STATUS_DONE; 3351 mz_uint64 needed_size, cur_file_ofs, comp_remaining, out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail; 3352 mz_zip_archive_file_stat file_stat; 3353 void *pRead_buf; 3354 mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; 3355 tinfl_decompressor inflator; 3356 3357 if ((buf_size) && (!pBuf)) 3358 return MZ_FALSE; 3359 3360 if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) 3361 return MZ_FALSE; 3362 3363 if (!file_stat.m_comp_size) 3364 return MZ_TRUE; 3365 3366 // Encryption and patch files are not supported. 3367 if (file_stat.m_bit_flag & (1 | 32)) 3368 return MZ_FALSE; 3369 3370 // This function only supports stored and deflate. 3371 if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED)) 3372 return MZ_FALSE; 3373 3374 // Ensure supplied output buffer is large enough. 3375 needed_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size : file_stat.m_uncomp_size; 3376 if (buf_size < needed_size) 3377 return MZ_FALSE; 3378 3379 // Read and parse the local directory entry. 3380 cur_file_ofs = file_stat.m_local_header_ofs; 3381 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) 3382 return MZ_FALSE; 3383 if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) 3384 return MZ_FALSE; 3385 3386 cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); 3387 if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size) 3388 return MZ_FALSE; 3389 3390 if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) 3391 { 3392 // The file is stored or the caller has requested the compressed data. 3393 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, (size_t)needed_size) != needed_size) 3394 return MZ_FALSE; 3395 return ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) != 0) || (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) == file_stat.m_crc32); 3396 } 3397 3398 // Decompress the file either directly from memory or from a file input buffer. 3399 tinfl_init(&inflator); 3400 3401 if (pZip->m_pState->m_pMem) 3402 { 3403 // Read directly from the archive in memory. 3404 pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs; 3405 read_buf_size = read_buf_avail = file_stat.m_comp_size; 3406 comp_remaining = 0; 3407 } 3408 else if (pUser_read_buf) 3409 { 3410 // Use a user provided read buffer. 3411 if (!user_read_buf_size) 3412 return MZ_FALSE; 3413 pRead_buf = (mz_uint8 *)pUser_read_buf; 3414 read_buf_size = user_read_buf_size; 3415 read_buf_avail = 0; 3416 comp_remaining = file_stat.m_uncomp_size; 3417 } 3418 else 3419 { 3420 // Temporarily allocate a read buffer. 3421 read_buf_size = MZ_MIN(file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE); 3422 if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF)) 3423 return MZ_FALSE; 3424 if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size))) 3425 return MZ_FALSE; 3426 read_buf_avail = 0; 3427 comp_remaining = file_stat.m_comp_size; 3428 } 3429 3430 do 3431 { 3432 size_t in_buf_size, out_buf_size = (size_t)(file_stat.m_uncomp_size - out_buf_ofs); 3433 if ((!read_buf_avail) && (!pZip->m_pState->m_pMem)) 3434 { 3435 read_buf_avail = MZ_MIN(read_buf_size, comp_remaining); 3436 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail) 3437 { 3438 status = TINFL_STATUS_FAILED; 3439 break; 3440 } 3441 cur_file_ofs += read_buf_avail; 3442 comp_remaining -= read_buf_avail; 3443 read_buf_ofs = 0; 3444 } 3445 in_buf_size = (size_t)read_buf_avail; 3446 status = tinfl_decompress(&inflator, (mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pBuf, (mz_uint8 *)pBuf + out_buf_ofs, &out_buf_size, TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF | (comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0)); 3447 read_buf_avail -= in_buf_size; 3448 read_buf_ofs += in_buf_size; 3449 out_buf_ofs += out_buf_size; 3450 } while (status == TINFL_STATUS_NEEDS_MORE_INPUT); 3451 3452 if (status == TINFL_STATUS_DONE) 3453 { 3454 // Make sure the entire file was decompressed, and check its CRC. 3455 if ((out_buf_ofs != file_stat.m_uncomp_size) || (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32)) 3456 status = TINFL_STATUS_FAILED; 3457 } 3458 3459 if ((!pZip->m_pState->m_pMem) && (!pUser_read_buf)) 3460 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); 3461 3462 return status == TINFL_STATUS_DONE; 3463 } 3464 3465 mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size) 3466 { 3467 int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags); 3468 if (file_index < 0) 3469 return MZ_FALSE; 3470 return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, pUser_read_buf, user_read_buf_size); 3471 } 3472 3473 mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags) 3474 { 3475 return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size, flags, NULL, 0); 3476 } 3477 3478 mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags) 3479 { 3480 return mz_zip_reader_extract_file_to_mem_no_alloc(pZip, pFilename, pBuf, buf_size, flags, NULL, 0); 3481 } 3482 3483 void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags) 3484 { 3485 mz_uint64 comp_size, uncomp_size, alloc_size; 3486 const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index); 3487 void *pBuf; 3488 3489 if (pSize) 3490 *pSize = 0; 3491 if (!p) 3492 return NULL; 3493 3494 comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); 3495 uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS); 3496 3497 alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size; 3498 if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF)) 3499 return NULL; 3500 if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size))) 3501 return NULL; 3502 3503 if (!mz_zip_reader_extract_to_mem(pZip, file_index, pBuf, (size_t)alloc_size, flags)) 3504 { 3505 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); 3506 return NULL; 3507 } 3508 3509 if (pSize) *pSize = (size_t)alloc_size; 3510 return pBuf; 3511 } 3512 3513 void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags) 3514 { 3515 int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags); 3516 if (file_index < 0) 3517 { 3518 if (pSize) *pSize = 0; 3519 return MZ_FALSE; 3520 } 3521 return mz_zip_reader_extract_to_heap(pZip, file_index, pSize, flags); 3522 } 3523 3524 mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags) 3525 { 3526 int status = TINFL_STATUS_DONE; mz_uint file_crc32 = MZ_CRC32_INIT; 3527 mz_uint64 read_buf_size, read_buf_ofs = 0, read_buf_avail, comp_remaining, out_buf_ofs = 0, cur_file_ofs; 3528 mz_zip_archive_file_stat file_stat; 3529 void *pRead_buf = NULL; void *pWrite_buf = NULL; 3530 mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; 3531 3532 if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) 3533 return MZ_FALSE; 3534 3535 if (!file_stat.m_comp_size) 3536 return MZ_TRUE; 3537 3538 // Encryption and patch files are not supported. 3539 if (file_stat.m_bit_flag & (1 | 32)) 3540 return MZ_FALSE; 3541 3542 // This function only supports stored and deflate. 3543 if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) && (file_stat.m_method != MZ_DEFLATED)) 3544 return MZ_FALSE; 3545 3546 // Read and parse the local directory entry. 3547 cur_file_ofs = file_stat.m_local_header_ofs; 3548 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) 3549 return MZ_FALSE; 3550 if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) 3551 return MZ_FALSE; 3552 3553 cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); 3554 if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size) 3555 return MZ_FALSE; 3556 3557 // Decompress the file either directly from memory or from a file input buffer. 3558 if (pZip->m_pState->m_pMem) 3559 { 3560 pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs; 3561 read_buf_size = read_buf_avail = file_stat.m_comp_size; 3562 comp_remaining = 0; 3563 } 3564 else 3565 { 3566 read_buf_size = MZ_MIN(file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE); 3567 if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)read_buf_size))) 3568 return MZ_FALSE; 3569 read_buf_avail = 0; 3570 comp_remaining = file_stat.m_comp_size; 3571 } 3572 3573 if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) 3574 { 3575 // The file is stored or the caller has requested the compressed data. 3576 if (pZip->m_pState->m_pMem) 3577 { 3578 if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (file_stat.m_comp_size > 0xFFFFFFFF)) 3579 return MZ_FALSE; 3580 if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)file_stat.m_comp_size) != file_stat.m_comp_size) 3581 status = TINFL_STATUS_FAILED; 3582 else if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) 3583 file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)file_stat.m_comp_size); 3584 cur_file_ofs += file_stat.m_comp_size; 3585 out_buf_ofs += file_stat.m_comp_size; 3586 comp_remaining = 0; 3587 } 3588 else 3589 { 3590 while (comp_remaining) 3591 { 3592 read_buf_avail = MZ_MIN(read_buf_size, comp_remaining); 3593 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail) 3594 { 3595 status = TINFL_STATUS_FAILED; 3596 break; 3597 } 3598 3599 if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) 3600 file_crc32 = (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf, (size_t)read_buf_avail); 3601 3602 if (pCallback(pOpaque, out_buf_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail) 3603 { 3604 status = TINFL_STATUS_FAILED; 3605 break; 3606 } 3607 cur_file_ofs += read_buf_avail; 3608 out_buf_ofs += read_buf_avail; 3609 comp_remaining -= read_buf_avail; 3610 } 3611 } 3612 } 3613 else 3614 { 3615 tinfl_decompressor inflator; 3616 tinfl_init(&inflator); 3617 3618 if (NULL == (pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, TINFL_LZ_DICT_SIZE))) 3619 status = TINFL_STATUS_FAILED; 3620 else 3621 { 3622 do 3623 { 3624 mz_uint8 *pWrite_buf_cur = (mz_uint8 *)pWrite_buf + (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1)); 3625 size_t in_buf_size, out_buf_size = TINFL_LZ_DICT_SIZE - (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1)); 3626 if ((!read_buf_avail) && (!pZip->m_pState->m_pMem)) 3627 { 3628 read_buf_avail = MZ_MIN(read_buf_size, comp_remaining); 3629 if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf, (size_t)read_buf_avail) != read_buf_avail) 3630 { 3631 status = TINFL_STATUS_FAILED; 3632 break; 3633 } 3634 cur_file_ofs += read_buf_avail; 3635 comp_remaining -= read_buf_avail; 3636 read_buf_ofs = 0; 3637 } 3638 3639 in_buf_size = (size_t)read_buf_avail; 3640 status = tinfl_decompress(&inflator, (const mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size, (mz_uint8 *)pWrite_buf, pWrite_buf_cur, &out_buf_size, comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0); 3641 read_buf_avail -= in_buf_size; 3642 read_buf_ofs += in_buf_size; 3643 3644 if (out_buf_size) 3645 { 3646 if (pCallback(pOpaque, out_buf_ofs, pWrite_buf_cur, out_buf_size) != out_buf_size) 3647 { 3648 status = TINFL_STATUS_FAILED; 3649 break; 3650 } 3651 file_crc32 = (mz_uint32)mz_crc32(file_crc32, pWrite_buf_cur, out_buf_size); 3652 if ((out_buf_ofs += out_buf_size) > file_stat.m_uncomp_size) 3653 { 3654 status = TINFL_STATUS_FAILED; 3655 break; 3656 } 3657 } 3658 } while ((status == TINFL_STATUS_NEEDS_MORE_INPUT) || (status == TINFL_STATUS_HAS_MORE_OUTPUT)); 3659 } 3660 } 3661 3662 if ((status == TINFL_STATUS_DONE) && (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))) 3663 { 3664 // Make sure the entire file was decompressed, and check its CRC. 3665 if ((out_buf_ofs != file_stat.m_uncomp_size) || (file_crc32 != file_stat.m_crc32)) 3666 status = TINFL_STATUS_FAILED; 3667 } 3668 3669 if (!pZip->m_pState->m_pMem) 3670 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); 3671 if (pWrite_buf) 3672 pZip->m_pFree(pZip->m_pAlloc_opaque, pWrite_buf); 3673 3674 return status == TINFL_STATUS_DONE; 3675 } 3676 3677 mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags) 3678 { 3679 int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags); 3680 if (file_index < 0) 3681 return MZ_FALSE; 3682 return mz_zip_reader_extract_to_callback(pZip, file_index, pCallback, pOpaque, flags); 3683 } 3684 3685 #ifndef MINIZ_NO_STDIO 3686 static size_t mz_zip_file_write_callback(void *pOpaque, mz_uint64 ofs, const void *pBuf, size_t n) 3687 { 3688 (void)ofs; return MZ_FWRITE(pBuf, 1, n, (MZ_FILE*)pOpaque); 3689 } 3690 3691 mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags) 3692 { 3693 mz_bool status; 3694 mz_zip_archive_file_stat file_stat; 3695 MZ_FILE *pFile; 3696 if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) 3697 return MZ_FALSE; 3698 pFile = MZ_FOPEN(pDst_filename, "wb"); 3699 if (!pFile) 3700 return MZ_FALSE; 3701 status = mz_zip_reader_extract_to_callback(pZip, file_index, mz_zip_file_write_callback, pFile, flags); 3702 if (MZ_FCLOSE(pFile) == EOF) 3703 return MZ_FALSE; 3704 #ifndef MINIZ_NO_TIME 3705 if (status) 3706 mz_zip_set_file_times(pDst_filename, file_stat.m_time, file_stat.m_time); 3707 #endif 3708 return status; 3709 } 3710 #endif // #ifndef MINIZ_NO_STDIO 3711 3712 mz_bool mz_zip_reader_end(mz_zip_archive *pZip) 3713 { 3714 if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) 3715 return MZ_FALSE; 3716 3717 if (pZip->m_pState) 3718 { 3719 mz_zip_internal_state *pState = pZip->m_pState; pZip->m_pState = NULL; 3720 mz_zip_array_clear(pZip, &pState->m_central_dir); 3721 mz_zip_array_clear(pZip, &pState->m_central_dir_offsets); 3722 mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets); 3723 3724 #ifndef MINIZ_NO_STDIO 3725 if (pState->m_pFile) 3726 { 3727 MZ_FCLOSE(pState->m_pFile); 3728 pState->m_pFile = NULL; 3729 } 3730 #endif // #ifndef MINIZ_NO_STDIO 3731 3732 pZip->m_pFree(pZip->m_pAlloc_opaque, pState); 3733 } 3734 pZip->m_zip_mode = MZ_ZIP_MODE_INVALID; 3735 3736 return MZ_TRUE; 3737 } 3738 3739 mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags) 3740 { 3741 int file_index = mz_zip_reader_locate_file(pZip, pArchive_filename, NULL, flags); 3742 if (file_index < 0) 3743 return MZ_FALSE; 3744 return mz_zip_reader_extract_to_file(pZip, file_index, pDst_filename, flags); 3745 } 3746 3747 // ------------------- .ZIP archive writing 3748 3749 #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS 3750 3751 static void mz_write_le16(mz_uint8 *p, mz_uint16 v) { p[0] = (mz_uint8)v; p[1] = (mz_uint8)(v >> 8); } 3752 static void mz_write_le32(mz_uint8 *p, mz_uint32 v) { p[0] = (mz_uint8)v; p[1] = (mz_uint8)(v >> 8); p[2] = (mz_uint8)(v >> 16); p[3] = (mz_uint8)(v >> 24); } 3753 #define MZ_WRITE_LE16(p, v) mz_write_le16((mz_uint8 *)(p), (mz_uint16)(v)) 3754 #define MZ_WRITE_LE32(p, v) mz_write_le32((mz_uint8 *)(p), (mz_uint32)(v)) 3755 3756 mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size) 3757 { 3758 if ((!pZip) || (pZip->m_pState) || (!pZip->m_pWrite) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID)) 3759 return MZ_FALSE; 3760 3761 if (pZip->m_file_offset_alignment) 3762 { 3763 // Ensure user specified file offset alignment is a power of 2. 3764 if (pZip->m_file_offset_alignment & (pZip->m_file_offset_alignment - 1)) 3765 return MZ_FALSE; 3766 } 3767 3768 if (!pZip->m_pAlloc) pZip->m_pAlloc = def_alloc_func; 3769 if (!pZip->m_pFree) pZip->m_pFree = def_free_func; 3770 if (!pZip->m_pRealloc) pZip->m_pRealloc = def_realloc_func; 3771 3772 pZip->m_zip_mode = MZ_ZIP_MODE_WRITING; 3773 pZip->m_archive_size = existing_size; 3774 pZip->m_central_directory_file_ofs = 0; 3775 pZip->m_total_files = 0; 3776 3777 if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state)))) 3778 return MZ_FALSE; 3779 memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state)); 3780 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir, sizeof(mz_uint8)); 3781 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets, sizeof(mz_uint32)); 3782 MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets, sizeof(mz_uint32)); 3783 return MZ_TRUE; 3784 } 3785 3786 static size_t mz_zip_heap_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n) 3787 { 3788 mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; 3789 mz_zip_internal_state *pState = pZip->m_pState; 3790 mz_uint64 new_size = MZ_MAX(file_ofs + n, pState->m_mem_size); 3791 if ((!n) || ((0, sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF))) 3792 return 0; 3793 if (new_size > pState->m_mem_capacity) 3794 { 3795 void *pNew_block; 3796 size_t new_capacity = MZ_MAX(64, pState->m_mem_capacity); while (new_capacity < new_size) new_capacity *= 2; 3797 if (NULL == (pNew_block = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pState->m_pMem, 1, new_capacity))) 3798 return 0; 3799 pState->m_pMem = pNew_block; pState->m_mem_capacity = new_capacity; 3800 } 3801 memcpy((mz_uint8 *)pState->m_pMem + file_ofs, pBuf, n); 3802 pState->m_mem_size = (size_t)new_size; 3803 return n; 3804 } 3805 3806 mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size) 3807 { 3808 pZip->m_pWrite = mz_zip_heap_write_func; 3809 pZip->m_pIO_opaque = pZip; 3810 if (!mz_zip_writer_init(pZip, size_to_reserve_at_beginning)) 3811 return MZ_FALSE; 3812 if (0 != (initial_allocation_size = MZ_MAX(initial_allocation_size, size_to_reserve_at_beginning))) 3813 { 3814 if (NULL == (pZip->m_pState->m_pMem = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, initial_allocation_size))) 3815 { 3816 mz_zip_writer_end(pZip); 3817 return MZ_FALSE; 3818 } 3819 pZip->m_pState->m_mem_capacity = initial_allocation_size; 3820 } 3821 return MZ_TRUE; 3822 } 3823 3824 #ifndef MINIZ_NO_STDIO 3825 static size_t mz_zip_file_write_func(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n) 3826 { 3827 mz_zip_archive *pZip = (mz_zip_archive *)pOpaque; 3828 mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile); 3829 if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET)))) 3830 return 0; 3831 return MZ_FWRITE(pBuf, 1, n, pZip->m_pState->m_pFile); 3832 } 3833 3834 mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning) 3835 { 3836 MZ_FILE *pFile; 3837 pZip->m_pWrite = mz_zip_file_write_func; 3838 pZip->m_pIO_opaque = pZip; 3839 if (!mz_zip_writer_init(pZip, size_to_reserve_at_beginning)) 3840 return MZ_FALSE; 3841 if (NULL == (pFile = MZ_FOPEN(pFilename, "wb"))) 3842 { 3843 mz_zip_writer_end(pZip); 3844 return MZ_FALSE; 3845 } 3846 pZip->m_pState->m_pFile = pFile; 3847 if (size_to_reserve_at_beginning) 3848 { 3849 mz_uint64 cur_ofs = 0; char buf[4096]; MZ_CLEAR_OBJ(buf); 3850 do 3851 { 3852 size_t n = (size_t)MZ_MIN(sizeof(buf), size_to_reserve_at_beginning); 3853 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_ofs, buf, n) != n) 3854 { 3855 mz_zip_writer_end(pZip); 3856 return MZ_FALSE; 3857 } 3858 cur_ofs += n; size_to_reserve_at_beginning -= n; 3859 } while (size_to_reserve_at_beginning); 3860 } 3861 return MZ_TRUE; 3862 } 3863 #endif // #ifndef MINIZ_NO_STDIO 3864 3865 mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename) 3866 { 3867 mz_zip_internal_state *pState; 3868 if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING)) 3869 return MZ_FALSE; 3870 // No sense in trying to write to an archive that's already at the support max size 3871 if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + MZ_ZIP_LOCAL_DIR_HEADER_SIZE) > 0xFFFFFFFF)) 3872 return MZ_FALSE; 3873 3874 pState = pZip->m_pState; 3875 3876 if (pState->m_pFile) 3877 { 3878 #ifdef MINIZ_NO_STDIO 3879 pFilename; return MZ_FALSE; 3880 #else 3881 // Archive is being read from stdio - try to reopen as writable. 3882 if (pZip->m_pIO_opaque != pZip) 3883 return MZ_FALSE; 3884 if (!pFilename) 3885 return MZ_FALSE; 3886 pZip->m_pWrite = mz_zip_file_write_func; 3887 if (NULL == (pState->m_pFile = MZ_FREOPEN(pFilename, "r+b", pState->m_pFile))) 3888 { 3889 // The mz_zip_archive is now in a bogus state because pState->m_pFile is NULL, so just close it. 3890 mz_zip_reader_end(pZip); 3891 return MZ_FALSE; 3892 } 3893 #endif // #ifdef MINIZ_NO_STDIO 3894 } 3895 else if (pState->m_pMem) 3896 { 3897 // Archive lives in a memory block. Assume it's from the heap that we can resize using the realloc callback. 3898 if (pZip->m_pIO_opaque != pZip) 3899 return MZ_FALSE; 3900 pState->m_mem_capacity = pState->m_mem_size; 3901 pZip->m_pWrite = mz_zip_heap_write_func; 3902 } 3903 // Archive is being read via a user provided read function - make sure the user has specified a write function too. 3904 else if (!pZip->m_pWrite) 3905 return MZ_FALSE; 3906 3907 // Start writing new files at the archive's current central directory location. 3908 pZip->m_archive_size = pZip->m_central_directory_file_ofs; 3909 pZip->m_zip_mode = MZ_ZIP_MODE_WRITING; 3910 pZip->m_central_directory_file_ofs = 0; 3911 3912 return MZ_TRUE; 3913 } 3914 3915 mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags) 3916 { 3917 return mz_zip_writer_add_mem_ex(pZip, pArchive_name, pBuf, buf_size, NULL, 0, level_and_flags, 0, 0); 3918 } 3919 3920 typedef struct 3921 { 3922 mz_zip_archive *m_pZip; 3923 mz_uint64 m_cur_archive_file_ofs; 3924 mz_uint64 m_comp_size; 3925 } mz_zip_writer_add_state; 3926 3927 static mz_bool mz_zip_writer_add_put_buf_callback(const void* pBuf, int len, void *pUser) 3928 { 3929 mz_zip_writer_add_state *pState = (mz_zip_writer_add_state *)pUser; 3930 if ((int)pState->m_pZip->m_pWrite(pState->m_pZip->m_pIO_opaque, pState->m_cur_archive_file_ofs, pBuf, len) != len) 3931 return MZ_FALSE; 3932 pState->m_cur_archive_file_ofs += len; 3933 pState->m_comp_size += len; 3934 return MZ_TRUE; 3935 } 3936 3937 static mz_bool mz_zip_writer_create_local_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, mz_uint16 extra_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date) 3938 { 3939 (void)pZip; 3940 memset(pDst, 0, MZ_ZIP_LOCAL_DIR_HEADER_SIZE); 3941 MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_SIG_OFS, MZ_ZIP_LOCAL_DIR_HEADER_SIG); 3942 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_VERSION_NEEDED_OFS, method ? 20 : 0); 3943 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_BIT_FLAG_OFS, bit_flags); 3944 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_METHOD_OFS, method); 3945 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_TIME_OFS, dos_time); 3946 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_DATE_OFS, dos_date); 3947 MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_CRC32_OFS, uncomp_crc32); 3948 MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS, comp_size); 3949 MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS, uncomp_size); 3950 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILENAME_LEN_OFS, filename_size); 3951 MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_EXTRA_LEN_OFS, extra_size); 3952 return MZ_TRUE; 3953 } 3954 3955 static mz_bool mz_zip_writer_create_central_dir_header(mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size, mz_uint16 extra_size, mz_uint16 comment_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, mz_uint64 local_header_ofs, mz_uint32 ext_attributes) 3956 { 3957 (void)pZip; 3958 memset(pDst, 0, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE); 3959 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_SIG_OFS, MZ_ZIP_CENTRAL_DIR_HEADER_SIG); 3960 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_VERSION_NEEDED_OFS, method ? 20 : 0); 3961 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_BIT_FLAG_OFS, bit_flags); 3962 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_METHOD_OFS, method); 3963 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_TIME_OFS, dos_time); 3964 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_DATE_OFS, dos_date); 3965 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_CRC32_OFS, uncomp_crc32); 3966 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS, comp_size); 3967 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS, uncomp_size); 3968 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILENAME_LEN_OFS, filename_size); 3969 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_EXTRA_LEN_OFS, extra_size); 3970 MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_COMMENT_LEN_OFS, comment_size); 3971 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS, ext_attributes); 3972 MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_LOCAL_HEADER_OFS, local_header_ofs); 3973 return MZ_TRUE; 3974 } 3975 3976 static mz_bool mz_zip_writer_add_to_central_dir(mz_zip_archive *pZip, const char *pFilename, mz_uint16 filename_size, const void *pExtra, mz_uint16 extra_size, const void *pComment, mz_uint16 comment_size, mz_uint64 uncomp_size, mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date, mz_uint64 local_header_ofs, mz_uint32 ext_attributes) 3977 { 3978 mz_zip_internal_state *pState = pZip->m_pState; 3979 mz_uint32 central_dir_ofs = (mz_uint32)pState->m_central_dir.m_size; 3980 size_t orig_central_dir_size = pState->m_central_dir.m_size; 3981 mz_uint8 central_dir_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE]; 3982 3983 // No zip64 support yet 3984 if ((local_header_ofs > 0xFFFFFFFF) || (((mz_uint64)pState->m_central_dir.m_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + extra_size + comment_size) > 0xFFFFFFFF)) 3985 return MZ_FALSE; 3986 3987 if (!mz_zip_writer_create_central_dir_header(pZip, central_dir_header, filename_size, extra_size, comment_size, uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time, dos_date, local_header_ofs, ext_attributes)) 3988 return MZ_FALSE; 3989 3990 if ((!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_dir_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) || 3991 (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pFilename, filename_size)) || 3992 (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pExtra, extra_size)) || 3993 (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pComment, comment_size)) || 3994 (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, ¢ral_dir_ofs, 1))) 3995 { 3996 // Try to push the central directory array back into its original state. 3997 mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); 3998 return MZ_FALSE; 3999 } 4000 4001 return MZ_TRUE; 4002 } 4003 4004 static mz_bool mz_zip_writer_validate_archive_name(const char *pArchive_name) 4005 { 4006 // Basic ZIP archive filename validity checks: Valid filenames cannot start with a forward slash, cannot contain a drive letter, and cannot use DOS-style backward slashes. 4007 if (*pArchive_name == '/') 4008 return MZ_FALSE; 4009 while (*pArchive_name) 4010 { 4011 if ((*pArchive_name == '\\') || (*pArchive_name == ':')) 4012 return MZ_FALSE; 4013 pArchive_name++; 4014 } 4015 return MZ_TRUE; 4016 } 4017 4018 static mz_uint mz_zip_writer_compute_padding_needed_for_file_alignment(mz_zip_archive *pZip) 4019 { 4020 mz_uint32 n; 4021 if (!pZip->m_file_offset_alignment) 4022 return 0; 4023 n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1)); 4024 return (pZip->m_file_offset_alignment - n) & (pZip->m_file_offset_alignment - 1); 4025 } 4026 4027 static mz_bool mz_zip_writer_write_zeros(mz_zip_archive *pZip, mz_uint64 cur_file_ofs, mz_uint32 n) 4028 { 4029 char buf[4096]; 4030 memset(buf, 0, MZ_MIN(sizeof(buf), n)); 4031 while (n) 4032 { 4033 mz_uint32 s = MZ_MIN(sizeof(buf), n); 4034 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_file_ofs, buf, s) != s) 4035 return MZ_FALSE; 4036 cur_file_ofs += s; n -= s; 4037 } 4038 return MZ_TRUE; 4039 } 4040 4041 mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_uint64 uncomp_size, mz_uint32 uncomp_crc32) 4042 { 4043 mz_uint16 method = 0, dos_time = 0, dos_date = 0; 4044 mz_uint level = level_and_flags & 0xF, ext_attributes = 0, num_alignment_padding_bytes; 4045 mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, comp_size = 0; 4046 size_t archive_name_size; 4047 mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; 4048 tdefl_compressor *pComp = NULL; 4049 mz_bool store_data_uncompressed = ((!level) || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)); 4050 mz_zip_internal_state *pState; 4051 4052 if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || ((buf_size) && (!pBuf)) || (!pArchive_name) || ((comment_size) && (!pComment)) || (pZip->m_total_files == 0xFFFF) || (level > 10)) 4053 return MZ_FALSE; 4054 4055 pState = pZip->m_pState; 4056 4057 if ((!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (uncomp_size)) 4058 return MZ_FALSE; 4059 // No zip64 support yet 4060 if ((buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF)) 4061 return MZ_FALSE; 4062 if (!mz_zip_writer_validate_archive_name(pArchive_name)) 4063 return MZ_FALSE; 4064 4065 #ifndef MINIZ_NO_TIME 4066 { 4067 time_t cur_time; time(&cur_time); 4068 mz_zip_time_to_dos_time(cur_time, &dos_time, &dos_date); 4069 } 4070 #endif // #ifndef MINIZ_NO_TIME 4071 4072 archive_name_size = strlen(pArchive_name); 4073 if (archive_name_size > 0xFFFF) 4074 return MZ_FALSE; 4075 4076 num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip); 4077 4078 // no zip64 support yet 4079 if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + comment_size + archive_name_size) > 0xFFFFFFFF)) 4080 return MZ_FALSE; 4081 4082 if ((archive_name_size) && (pArchive_name[archive_name_size - 1] == '/')) 4083 { 4084 // Set DOS Subdirectory attribute bit. 4085 ext_attributes |= 0x10; 4086 // Subdirectories cannot contain data. 4087 if ((buf_size) || (uncomp_size)) 4088 return MZ_FALSE; 4089 } 4090 4091 // Try to do any allocations before writing to the archive, so if an allocation fails the file remains unmodified. (A good idea if we're doing an in-place modification.) 4092 if ((!mz_zip_array_ensure_room(pZip, &pState->m_central_dir, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size)) || (!mz_zip_array_ensure_room(pZip, &pState->m_central_dir_offsets, 1))) 4093 return MZ_FALSE; 4094 4095 if ((!store_data_uncompressed) && (buf_size)) 4096 { 4097 if (NULL == (pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor)))) 4098 return MZ_FALSE; 4099 } 4100 4101 if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes + sizeof(local_dir_header))) 4102 { 4103 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); 4104 return MZ_FALSE; 4105 } 4106 local_dir_header_ofs += num_alignment_padding_bytes; 4107 if (pZip->m_file_offset_alignment) { MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); } 4108 cur_archive_file_ofs += num_alignment_padding_bytes + sizeof(local_dir_header); 4109 4110 MZ_CLEAR_OBJ(local_dir_header); 4111 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size) 4112 { 4113 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); 4114 return MZ_FALSE; 4115 } 4116 cur_archive_file_ofs += archive_name_size; 4117 4118 if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) 4119 { 4120 uncomp_crc32 = (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8*)pBuf, buf_size); 4121 uncomp_size = buf_size; 4122 if (uncomp_size <= 3) 4123 { 4124 level = 0; 4125 store_data_uncompressed = MZ_TRUE; 4126 } 4127 } 4128 4129 if (store_data_uncompressed) 4130 { 4131 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pBuf, buf_size) != buf_size) 4132 { 4133 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); 4134 return MZ_FALSE; 4135 } 4136 4137 cur_archive_file_ofs += buf_size; 4138 comp_size = buf_size; 4139 4140 if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA) 4141 method = MZ_DEFLATED; 4142 } 4143 else if (buf_size) 4144 { 4145 mz_zip_writer_add_state state; 4146 4147 state.m_pZip = pZip; 4148 state.m_cur_archive_file_ofs = cur_archive_file_ofs; 4149 state.m_comp_size = 0; 4150 4151 if ((tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY) || 4152 (tdefl_compress_buffer(pComp, pBuf, buf_size, TDEFL_FINISH) != TDEFL_STATUS_DONE)) 4153 { 4154 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); 4155 return MZ_FALSE; 4156 } 4157 4158 comp_size = state.m_comp_size; 4159 cur_archive_file_ofs = state.m_cur_archive_file_ofs; 4160 4161 method = MZ_DEFLATED; 4162 } 4163 4164 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); 4165 pComp = NULL; 4166 4167 // no zip64 support yet 4168 if ((comp_size > 0xFFFFFFFF) || (cur_archive_file_ofs > 0xFFFFFFFF)) 4169 return MZ_FALSE; 4170 4171 if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, 0, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date)) 4172 return MZ_FALSE; 4173 4174 if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) 4175 return MZ_FALSE; 4176 4177 if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, NULL, 0, pComment, comment_size, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date, local_dir_header_ofs, ext_attributes)) 4178 return MZ_FALSE; 4179 4180 pZip->m_total_files++; 4181 pZip->m_archive_size = cur_archive_file_ofs; 4182 4183 return MZ_TRUE; 4184 } 4185 4186 #ifndef MINIZ_NO_STDIO 4187 mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags) 4188 { 4189 mz_uint uncomp_crc32 = MZ_CRC32_INIT, level = level_and_flags & 0xF, num_alignment_padding_bytes; 4190 mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0; 4191 mz_uint64 local_dir_header_ofs = pZip->m_archive_size, cur_archive_file_ofs = pZip->m_archive_size, uncomp_size = 0, comp_size = 0; 4192 size_t archive_name_size; 4193 mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE]; 4194 MZ_FILE *pSrc_file = NULL; 4195 4196 if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) || ((comment_size) && (!pComment)) || (level > 10)) 4197 return MZ_FALSE; 4198 if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA) 4199 return MZ_FALSE; 4200 if (!mz_zip_writer_validate_archive_name(pArchive_name)) 4201 return MZ_FALSE; 4202 4203 archive_name_size = strlen(pArchive_name); 4204 if (archive_name_size > 0xFFFF) 4205 return MZ_FALSE; 4206 4207 num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip); 4208 4209 // no zip64 support yet 4210 if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + comment_size + archive_name_size) > 0xFFFFFFFF)) 4211 return MZ_FALSE; 4212 4213 if (!mz_zip_get_file_modified_time(pSrc_filename, &dos_time, &dos_date)) 4214 return MZ_FALSE; 4215 4216 pSrc_file = MZ_FOPEN(pSrc_filename, "rb"); 4217 if (!pSrc_file) 4218 return MZ_FALSE; 4219 MZ_FSEEK64(pSrc_file, 0, SEEK_END); 4220 uncomp_size = MZ_FTELL64(pSrc_file); 4221 MZ_FSEEK64(pSrc_file, 0, SEEK_SET); 4222 4223 if (uncomp_size > 0xFFFFFFFF) 4224 { 4225 // No zip64 support yet 4226 MZ_FCLOSE(pSrc_file); 4227 return MZ_FALSE; 4228 } 4229 if (uncomp_size <= 3) 4230 level = 0; 4231 4232 if (!mz_zip_writer_write_zeros(pZip, cur_archive_file_ofs, num_alignment_padding_bytes + sizeof(local_dir_header))) 4233 return MZ_FALSE; 4234 local_dir_header_ofs += num_alignment_padding_bytes; 4235 if (pZip->m_file_offset_alignment) { MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); } 4236 cur_archive_file_ofs += num_alignment_padding_bytes + sizeof(local_dir_header); 4237 4238 MZ_CLEAR_OBJ(local_dir_header); 4239 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name, archive_name_size) != archive_name_size) 4240 { 4241 MZ_FCLOSE(pSrc_file); 4242 return MZ_FALSE; 4243 } 4244 cur_archive_file_ofs += archive_name_size; 4245 4246 if (uncomp_size) 4247 { 4248 mz_uint64 uncomp_remaining = uncomp_size; 4249 void *pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, MZ_ZIP_MAX_IO_BUF_SIZE); 4250 if (!pRead_buf) 4251 { 4252 MZ_FCLOSE(pSrc_file); 4253 return MZ_FALSE; 4254 } 4255 4256 if (!level) 4257 { 4258 while (uncomp_remaining) 4259 { 4260 mz_uint n = (mz_uint)MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE, uncomp_remaining); 4261 if ((MZ_FREAD(pRead_buf, 1, n, pSrc_file) != n) || (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf, n) != n)) 4262 { 4263 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); 4264 MZ_FCLOSE(pSrc_file); 4265 return MZ_FALSE; 4266 } 4267 uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n); 4268 uncomp_remaining -= n; 4269 cur_archive_file_ofs += n; 4270 } 4271 comp_size = uncomp_size; 4272 } 4273 else 4274 { 4275 mz_bool result = MZ_FALSE; 4276 mz_zip_writer_add_state state; 4277 tdefl_compressor *pComp = (tdefl_compressor *)pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor)); 4278 if (!pComp) 4279 { 4280 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); 4281 MZ_FCLOSE(pSrc_file); 4282 return MZ_FALSE; 4283 } 4284 4285 state.m_pZip = pZip; 4286 state.m_cur_archive_file_ofs = cur_archive_file_ofs; 4287 state.m_comp_size = 0; 4288 4289 if (tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state, tdefl_create_comp_flags_from_zip_params(level, -15, MZ_DEFAULT_STRATEGY)) != TDEFL_STATUS_OKAY) 4290 { 4291 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); 4292 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); 4293 MZ_FCLOSE(pSrc_file); 4294 return MZ_FALSE; 4295 } 4296 4297 for ( ; ; ) 4298 { 4299 size_t in_buf_size = (mz_uint32)MZ_MIN(uncomp_remaining, MZ_ZIP_MAX_IO_BUF_SIZE); 4300 tdefl_status status; 4301 4302 if (MZ_FREAD(pRead_buf, 1, in_buf_size, pSrc_file) != in_buf_size) 4303 break; 4304 4305 uncomp_crc32 = (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, in_buf_size); 4306 uncomp_remaining -= in_buf_size; 4307 4308 status = tdefl_compress_buffer(pComp, pRead_buf, in_buf_size, uncomp_remaining ? TDEFL_NO_FLUSH : TDEFL_FINISH); 4309 if (status == TDEFL_STATUS_DONE) 4310 { 4311 result = MZ_TRUE; 4312 break; 4313 } 4314 else if (status != TDEFL_STATUS_OKAY) 4315 break; 4316 } 4317 4318 pZip->m_pFree(pZip->m_pAlloc_opaque, pComp); 4319 4320 if (!result) 4321 { 4322 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); 4323 MZ_FCLOSE(pSrc_file); 4324 return MZ_FALSE; 4325 } 4326 4327 comp_size = state.m_comp_size; 4328 cur_archive_file_ofs = state.m_cur_archive_file_ofs; 4329 4330 method = MZ_DEFLATED; 4331 } 4332 4333 pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf); 4334 } 4335 4336 MZ_FCLOSE(pSrc_file); pSrc_file = NULL; 4337 4338 // no zip64 support yet 4339 if ((comp_size > 0xFFFFFFFF) || (cur_archive_file_ofs > 0xFFFFFFFF)) 4340 return MZ_FALSE; 4341 4342 if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, 0, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date)) 4343 return MZ_FALSE; 4344 4345 if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header, sizeof(local_dir_header)) != sizeof(local_dir_header)) 4346 return MZ_FALSE; 4347 4348 if (!mz_zip_writer_add_to_central_dir(pZip, pArchive_name, (mz_uint16)archive_name_size, NULL, 0, pComment, comment_size, uncomp_size, comp_size, uncomp_crc32, method, 0, dos_time, dos_date, local_dir_header_ofs, ext_attributes)) 4349 return MZ_FALSE; 4350 4351 pZip->m_total_files++; 4352 pZip->m_archive_size = cur_archive_file_ofs; 4353 4354 return MZ_TRUE; 4355 } 4356 #endif // #ifndef MINIZ_NO_STDIO 4357 4358 mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint file_index) 4359 { 4360 mz_uint n, bit_flags, num_alignment_padding_bytes; 4361 mz_uint64 comp_bytes_remaining, local_dir_header_ofs; 4362 mz_uint64 cur_src_file_ofs, cur_dst_file_ofs; 4363 mz_uint32 local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) / sizeof(mz_uint32)]; mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32; 4364 mz_uint8 central_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE]; 4365 size_t orig_central_dir_size; 4366 mz_zip_internal_state *pState; 4367 void *pBuf; const mz_uint8 *pSrc_central_header; 4368 4369 if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING)) 4370 return MZ_FALSE; 4371 if (NULL == (pSrc_central_header = mz_zip_reader_get_cdh(pSource_zip, file_index))) 4372 return MZ_FALSE; 4373 pState = pZip->m_pState; 4374 4375 num_alignment_padding_bytes = mz_zip_writer_compute_padding_needed_for_file_alignment(pZip); 4376 4377 // no zip64 support yet 4378 if ((pZip->m_total_files == 0xFFFF) || ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF)) 4379 return MZ_FALSE; 4380 4381 cur_src_file_ofs = MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS); 4382 cur_dst_file_ofs = pZip->m_archive_size; 4383 4384 if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) 4385 return MZ_FALSE; 4386 if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG) 4387 return MZ_FALSE; 4388 cur_src_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE; 4389 4390 if (!mz_zip_writer_write_zeros(pZip, cur_dst_file_ofs, num_alignment_padding_bytes)) 4391 return MZ_FALSE; 4392 cur_dst_file_ofs += num_alignment_padding_bytes; 4393 local_dir_header_ofs = cur_dst_file_ofs; 4394 if (pZip->m_file_offset_alignment) { MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) == 0); } 4395 4396 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) != MZ_ZIP_LOCAL_DIR_HEADER_SIZE) 4397 return MZ_FALSE; 4398 cur_dst_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE; 4399 4400 n = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS); 4401 comp_bytes_remaining = n + MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS); 4402 4403 if (NULL == (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)MZ_MAX(sizeof(mz_uint32) * 4, MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE, comp_bytes_remaining))))) 4404 return MZ_FALSE; 4405 4406 while (comp_bytes_remaining) 4407 { 4408 n = (mz_uint)MZ_MIN(MZ_ZIP_MAX_IO_BUF_SIZE, comp_bytes_remaining); 4409 if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, n) != n) 4410 { 4411 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); 4412 return MZ_FALSE; 4413 } 4414 cur_src_file_ofs += n; 4415 4416 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n) 4417 { 4418 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); 4419 return MZ_FALSE; 4420 } 4421 cur_dst_file_ofs += n; 4422 4423 comp_bytes_remaining -= n; 4424 } 4425 4426 bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS); 4427 if (bit_flags & 8) 4428 { 4429 // Copy data descriptor 4430 if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, sizeof(mz_uint32) * 4) != sizeof(mz_uint32) * 4) 4431 { 4432 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); 4433 return MZ_FALSE; 4434 } 4435 4436 n = sizeof(mz_uint32) * ((MZ_READ_LE32(pBuf) == 0x08074b50) ? 4 : 3); 4437 if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n) 4438 { 4439 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); 4440 return MZ_FALSE; 4441 } 4442 4443 cur_src_file_ofs += n; 4444 cur_dst_file_ofs += n; 4445 } 4446 pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); 4447 4448 // no zip64 support yet 4449 if (cur_dst_file_ofs > 0xFFFFFFFF) 4450 return MZ_FALSE; 4451 4452 orig_central_dir_size = pState->m_central_dir.m_size; 4453 4454 memcpy(central_header, pSrc_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE); 4455 MZ_WRITE_LE32(central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS, local_dir_header_ofs); 4456 if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) 4457 return MZ_FALSE; 4458 4459 n = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_FILENAME_LEN_OFS) + MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS) + MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_COMMENT_LEN_OFS); 4460 if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n)) 4461 { 4462 mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); 4463 return MZ_FALSE; 4464 } 4465 4466 if (pState->m_central_dir.m_size > 0xFFFFFFFF) 4467 return MZ_FALSE; 4468 n = (mz_uint32)pState->m_central_dir.m_size; 4469 if (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &n, 1)) 4470 { 4471 mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size, MZ_FALSE); 4472 return MZ_FALSE; 4473 } 4474 4475 pZip->m_total_files++; 4476 pZip->m_archive_size = cur_dst_file_ofs; 4477 4478 return MZ_TRUE; 4479 } 4480 4481 mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip) 4482 { 4483 mz_zip_internal_state *pState; 4484 mz_uint64 central_dir_ofs, central_dir_size; 4485 mz_uint8 hdr[MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE]; 4486 4487 if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING)) 4488 return MZ_FALSE; 4489 4490 pState = pZip->m_pState; 4491 4492 // no zip64 support yet 4493 if ((pZip->m_total_files > 0xFFFF) || ((pZip->m_archive_size + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF)) 4494 return MZ_FALSE; 4495 4496 central_dir_ofs = 0; 4497 central_dir_size = 0; 4498 if (pZip->m_total_files) 4499 { 4500 // Write central directory 4501 central_dir_ofs = pZip->m_archive_size; 4502 central_dir_size = pState->m_central_dir.m_size; 4503 pZip->m_central_directory_file_ofs = central_dir_ofs; 4504 if (pZip->m_pWrite(pZip->m_pIO_opaque, central_dir_ofs, pState->m_central_dir.m_p, (size_t)central_dir_size) != central_dir_size) 4505 return MZ_FALSE; 4506 pZip->m_archive_size += central_dir_size; 4507 } 4508 4509 // Write end of central directory record 4510 MZ_CLEAR_OBJ(hdr); 4511 MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_SIG_OFS, MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG); 4512 MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS, pZip->m_total_files); 4513 MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS, pZip->m_total_files); 4514 MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_SIZE_OFS, central_dir_size); 4515 MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_OFS_OFS, central_dir_ofs); 4516 4517 if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr, sizeof(hdr)) != sizeof(hdr)) 4518 return MZ_FALSE; 4519 #ifndef MINIZ_NO_STDIO 4520 if ((pState->m_pFile) && (MZ_FFLUSH(pState->m_pFile) == EOF)) 4521 return MZ_FALSE; 4522 #endif // #ifndef MINIZ_NO_STDIO 4523 4524 pZip->m_archive_size += sizeof(hdr); 4525 4526 pZip->m_zip_mode = MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED; 4527 return MZ_TRUE; 4528 } 4529 4530 mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **pBuf, size_t *pSize) 4531 { 4532 if ((!pZip) || (!pZip->m_pState) || (!pBuf) || (!pSize)) 4533 return MZ_FALSE; 4534 if (pZip->m_pWrite != mz_zip_heap_write_func) 4535 return MZ_FALSE; 4536 if (!mz_zip_writer_finalize_archive(pZip)) 4537 return MZ_FALSE; 4538 4539 *pBuf = pZip->m_pState->m_pMem; 4540 *pSize = pZip->m_pState->m_mem_size; 4541 pZip->m_pState->m_pMem = NULL; 4542 pZip->m_pState->m_mem_size = pZip->m_pState->m_mem_capacity = 0; 4543 return MZ_TRUE; 4544 } 4545 4546 mz_bool mz_zip_writer_end(mz_zip_archive *pZip) 4547 { 4548 mz_zip_internal_state *pState; 4549 mz_bool status = MZ_TRUE; 4550 if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) || ((pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) && (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED))) 4551 return MZ_FALSE; 4552 4553 pState = pZip->m_pState; 4554 pZip->m_pState = NULL; 4555 mz_zip_array_clear(pZip, &pState->m_central_dir); 4556 mz_zip_array_clear(pZip, &pState->m_central_dir_offsets); 4557 mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets); 4558 4559 #ifndef MINIZ_NO_STDIO 4560 if (pState->m_pFile) 4561 { 4562 MZ_FCLOSE(pState->m_pFile); 4563 pState->m_pFile = NULL; 4564 } 4565 #endif // #ifndef MINIZ_NO_STDIO 4566 4567 if ((pZip->m_pWrite == mz_zip_heap_write_func) && (pState->m_pMem)) 4568 { 4569 pZip->m_pFree(pZip->m_pAlloc_opaque, pState->m_pMem); 4570 pState->m_pMem = NULL; 4571 } 4572 4573 pZip->m_pFree(pZip->m_pAlloc_opaque, pState); 4574 pZip->m_zip_mode = MZ_ZIP_MODE_INVALID; 4575 return status; 4576 } 4577 4578 #ifndef MINIZ_NO_STDIO 4579 mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags) 4580 { 4581 mz_bool status, created_new_archive = MZ_FALSE; 4582 mz_zip_archive zip_archive; 4583 struct MZ_FILE_STAT_STRUCT file_stat; 4584 MZ_CLEAR_OBJ(zip_archive); 4585 if ((!pZip_filename) || (!pArchive_name) || ((buf_size) && (!pBuf)) || ((comment_size) && (!pComment)) || ((level_and_flags & 0xF) > 9)) 4586 return MZ_FALSE; 4587 if (!mz_zip_writer_validate_archive_name(pArchive_name)) 4588 return MZ_FALSE; 4589 if (MZ_FILE_STAT(pZip_filename, &file_stat) != 0) 4590 { 4591 // Create a new archive. 4592 if (!mz_zip_writer_init_file(&zip_archive, pZip_filename, 0)) 4593 return MZ_FALSE; 4594 created_new_archive = MZ_TRUE; 4595 } 4596 else 4597 { 4598 // Append to an existing archive. 4599 if (!mz_zip_reader_init_file(&zip_archive, pZip_filename, level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY)) 4600 return MZ_FALSE; 4601 if (!mz_zip_writer_init_from_reader(&zip_archive, pZip_filename)) 4602 { 4603 mz_zip_reader_end(&zip_archive); 4604 return MZ_FALSE; 4605 } 4606 } 4607 status = mz_zip_writer_add_mem_ex(&zip_archive, pArchive_name, pBuf, buf_size, pComment, comment_size, level_and_flags, 0, 0); 4608 // Always finalize, even if adding failed for some reason, so we have a valid central directory. (This may not always succeed, but we can try.) 4609 status = status && mz_zip_writer_finalize_archive(&zip_archive); 4610 status = status && mz_zip_writer_end(&zip_archive); 4611 if ((!status) && (created_new_archive)) 4612 { 4613 // It's a new archive and something went wrong, so just delete it. 4614 MZ_DELETE_FILE(pZip_filename); 4615 } 4616 return status; 4617 } 4618 4619 void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags) 4620 { 4621 int file_index; 4622 mz_zip_archive zip_archive; 4623 void *p = NULL; 4624 4625 if (pSize) 4626 *pSize = 0; 4627 4628 if ((!pZip_filename) || (!pArchive_name)) 4629 return NULL; 4630 4631 MZ_CLEAR_OBJ(zip_archive); 4632 if (!mz_zip_reader_init_file(&zip_archive, pZip_filename, flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY)) 4633 return NULL; 4634 4635 if ((file_index = mz_zip_reader_locate_file(&zip_archive, pArchive_name, NULL, flags)) >= 0) 4636 p = mz_zip_reader_extract_to_heap(&zip_archive, file_index, pSize, flags); 4637 4638 mz_zip_reader_end(&zip_archive); 4639 return p; 4640 } 4641 4642 #endif // #ifndef MINIZ_NO_STDIO 4643 4644 #endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS 4645 4646 #endif // #ifndef MINIZ_NO_ARCHIVE_APIS 4647 4648 #ifdef __cplusplus 4649 } 4650 #endif 4651 4652 #endif // MINIZ_HEADER_FILE_ONLY 4653 4654 /* 4655 This is free and unencumbered software released into the public domain. 4656 4657 Anyone is free to copy, modify, publish, use, compile, sell, or 4658 distribute this software, either in source code form or as a compiled 4659 binary, for any purpose, commercial or non-commercial, and by any 4660 means. 4661 4662 In jurisdictions that recognize copyright laws, the author or authors 4663 of this software dedicate any and all copyright interest in the 4664 software to the public domain. We make this dedication for the benefit 4665 of the public at large and to the detriment of our heirs and 4666 successors. We intend this dedication to be an overt act of 4667 relinquishment in perpetuity of all present and future rights to this 4668 software under copyright law. 4669 4670 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 4671 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 4672 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 4673 IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 4674 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 4675 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 4676 OTHER DEALINGS IN THE SOFTWARE. 4677 4678 For more information, please refer to <http://unlicense.org/> 4679 */