on 5f6e310 help sign in
602 lines 23 kB history raw
1/**************************************************************************
2 *
3 * Copyright 2013-2014 RAD Game Tools and Valve Software
4 * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 *
25 **************************************************************************/
27#include "miniz.h"
29typedef unsigned char mz_validate_uint16[sizeof(mz_uint16) == 2 ? 1 : -1];
30typedef unsigned char mz_validate_uint32[sizeof(mz_uint32) == 4 ? 1 : -1];
31typedef unsigned char mz_validate_uint64[sizeof(mz_uint64) == 8 ? 1 : -1];
33#ifdef __cplusplus
34extern "C" {
35#endif
37/* ------------------- zlib-style API's */
39mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len)
41 mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16);
42 size_t block_len = buf_len % 5552;
43 if (!ptr)
44 return MZ_ADLER32_INIT;
45 while (buf_len)
46 {
47 for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
48 {
49 s1 += ptr[0], s2 += s1;
50 s1 += ptr[1], s2 += s1;
51 s1 += ptr[2], s2 += s1;
52 s1 += ptr[3], s2 += s1;
53 s1 += ptr[4], s2 += s1;
54 s1 += ptr[5], s2 += s1;
55 s1 += ptr[6], s2 += s1;
56 s1 += ptr[7], s2 += s1;
57 }
58 for (; i < block_len; ++i)
59 s1 += *ptr++, s2 += s1;
60 s1 %= 65521U, s2 %= 65521U;
61 buf_len -= block_len;
62 block_len = 5552;
63 }
64 return (s2 << 16) + s1;
67/* 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/ */
68#if 0
69 mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
70 {
71 static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
72 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c };
73 mz_uint32 crcu32 = (mz_uint32)crc;
74 if (!ptr)
75 return MZ_CRC32_INIT;
76 crcu32 = ~crcu32;
77 while (buf_len--)
78 {
79 mz_uint8 b = *ptr++;
80 crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)];
81 crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)];
82 }
83 return ~crcu32;
84 }
85#else
86/* Faster, but larger CPU cache footprint.
87 */
88mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
90 static const mz_uint32 s_crc_table[256] =
91 {
92 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535,
93 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
94 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D,
95 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
96 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4,
97 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
98 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC,
99 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
100 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB,
101 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
102 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB,
103 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
104 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA,
105 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE,
106 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A,
107 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
108 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409,
109 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
110 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739,
111 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
112 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268,
113 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0,
114 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8,
115 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
116 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF,
117 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
118 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7,
119 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
120 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE,
121 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
122 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6,
123 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
124 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D,
125 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
126 0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605,
127 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
128 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
129 };
131 mz_uint32 crc32 = (mz_uint32)crc ^ 0xFFFFFFFF;
132 const mz_uint8 *pByte_buf = (const mz_uint8 *)ptr;
134 while (buf_len >= 4)
135 {
136 crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF];
137 crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[1]) & 0xFF];
138 crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[2]) & 0xFF];
139 crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[3]) & 0xFF];
140 pByte_buf += 4;
141 buf_len -= 4;
142 }
144 while (buf_len)
145 {
146 crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF];
147 ++pByte_buf;
148 --buf_len;
149 }
151 return ~crc32;
153#endif
155void mz_free(void *p)
157 MZ_FREE(p);
160void *miniz_def_alloc_func(void *opaque, size_t items, size_t size)
162 (void)opaque, (void)items, (void)size;
163 return MZ_MALLOC(items * size);
165void miniz_def_free_func(void *opaque, void *address)
167 (void)opaque, (void)address;
168 MZ_FREE(address);
170void *miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size)
172 (void)opaque, (void)address, (void)items, (void)size;
173 return MZ_REALLOC(address, items * size);
176const char *mz_version(void)
178 return MZ_VERSION;
181#ifndef MINIZ_NO_ZLIB_APIS
183int mz_deflateInit(mz_streamp pStream, int level)
185 return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY);
188int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy)
190 tdefl_compressor *pComp;
191 mz_uint comp_flags = TDEFL_COMPUTE_ADLER32 | tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy);
193 if (!pStream)
194 return MZ_STREAM_ERROR;
195 if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) || ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)))
196 return MZ_PARAM_ERROR;
198 pStream->data_type = 0;
199 pStream->adler = MZ_ADLER32_INIT;
200 pStream->msg = NULL;
201 pStream->reserved = 0;
202 pStream->total_in = 0;
203 pStream->total_out = 0;
204 if (!pStream->zalloc)
205 pStream->zalloc = miniz_def_alloc_func;
206 if (!pStream->zfree)
207 pStream->zfree = miniz_def_free_func;
209 pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, sizeof(tdefl_compressor));
210 if (!pComp)
211 return MZ_MEM_ERROR;
213 pStream->state = (struct mz_internal_state *)pComp;
215 if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY)
216 {
217 mz_deflateEnd(pStream);
218 return MZ_PARAM_ERROR;
219 }
221 return MZ_OK;
224int mz_deflateReset(mz_streamp pStream)
226 if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree))
227 return MZ_STREAM_ERROR;
228 pStream->total_in = pStream->total_out = 0;
229 tdefl_init((tdefl_compressor *)pStream->state, NULL, NULL, ((tdefl_compressor *)pStream->state)->m_flags);
230 return MZ_OK;
233int mz_deflate(mz_streamp pStream, int flush)
235 size_t in_bytes, out_bytes;
236 mz_ulong orig_total_in, orig_total_out;
237 int mz_status = MZ_OK;
239 if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || (!pStream->next_out))
240 return MZ_STREAM_ERROR;
241 if (!pStream->avail_out)
242 return MZ_BUF_ERROR;
244 if (flush == MZ_PARTIAL_FLUSH)
245 flush = MZ_SYNC_FLUSH;
247 if (((tdefl_compressor *)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE)
248 return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR;
250 orig_total_in = pStream->total_in;
251 orig_total_out = pStream->total_out;
252 for (;;)
253 {
254 tdefl_status defl_status;
255 in_bytes = pStream->avail_in;
256 out_bytes = pStream->avail_out;
258 defl_status = tdefl_compress((tdefl_compressor *)pStream->state, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, (tdefl_flush)flush);
259 pStream->next_in += (mz_uint)in_bytes;
260 pStream->avail_in -= (mz_uint)in_bytes;
261 pStream->total_in += (mz_uint)in_bytes;
262 pStream->adler = tdefl_get_adler32((tdefl_compressor *)pStream->state);
264 pStream->next_out += (mz_uint)out_bytes;
265 pStream->avail_out -= (mz_uint)out_bytes;
266 pStream->total_out += (mz_uint)out_bytes;
268 if (defl_status < 0)
269 {
270 mz_status = MZ_STREAM_ERROR;
271 break;
272 }
273 else if (defl_status == TDEFL_STATUS_DONE)
274 {
275 mz_status = MZ_STREAM_END;
276 break;
277 }
278 else if (!pStream->avail_out)
279 break;
280 else if ((!pStream->avail_in) && (flush != MZ_FINISH))
281 {
282 if ((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out))
283 break;
284 return MZ_BUF_ERROR; /* Can't make forward progress without some input.
285 */
286 }
287 }
288 return mz_status;
291int mz_deflateEnd(mz_streamp pStream)
293 if (!pStream)
294 return MZ_STREAM_ERROR;
295 if (pStream->state)
296 {
297 pStream->zfree(pStream->opaque, pStream->state);
298 pStream->state = NULL;
299 }
300 return MZ_OK;
303mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len)
305 (void)pStream;
306 /* 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.) */
307 return MZ_MAX(128 + (source_len * 110) / 100, 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5);
310int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level)
312 int status;
313 mz_stream stream;
314 memset(&stream, 0, sizeof(stream));
316 /* In case mz_ulong is 64-bits (argh I hate longs). */
317 if ((source_len | *pDest_len) > 0xFFFFFFFFU)
318 return MZ_PARAM_ERROR;
320 stream.next_in = pSource;
321 stream.avail_in = (mz_uint32)source_len;
322 stream.next_out = pDest;
323 stream.avail_out = (mz_uint32)*pDest_len;
325 status = mz_deflateInit(&stream, level);
326 if (status != MZ_OK)
327 return status;
329 status = mz_deflate(&stream, MZ_FINISH);
330 if (status != MZ_STREAM_END)
331 {
332 mz_deflateEnd(&stream);
333 return (status == MZ_OK) ? MZ_BUF_ERROR : status;
334 }
336 *pDest_len = stream.total_out;
337 return mz_deflateEnd(&stream);
340int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
342 return mz_compress2(pDest, pDest_len, pSource, source_len, MZ_DEFAULT_COMPRESSION);
345mz_ulong mz_compressBound(mz_ulong source_len)
347 return mz_deflateBound(NULL, source_len);
350typedef struct
352 tinfl_decompressor m_decomp;
353 mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed;
354 int m_window_bits;
355 mz_uint8 m_dict[TINFL_LZ_DICT_SIZE];
356 tinfl_status m_last_status;
357} inflate_state;
359int mz_inflateInit2(mz_streamp pStream, int window_bits)
361 inflate_state *pDecomp;
362 if (!pStream)
363 return MZ_STREAM_ERROR;
364 if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS))
365 return MZ_PARAM_ERROR;
367 pStream->data_type = 0;
368 pStream->adler = 0;
369 pStream->msg = NULL;
370 pStream->total_in = 0;
371 pStream->total_out = 0;
372 pStream->reserved = 0;
373 if (!pStream->zalloc)
374 pStream->zalloc = miniz_def_alloc_func;
375 if (!pStream->zfree)
376 pStream->zfree = miniz_def_free_func;
378 pDecomp = (inflate_state *)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state));
379 if (!pDecomp)
380 return MZ_MEM_ERROR;
382 pStream->state = (struct mz_internal_state *)pDecomp;
384 tinfl_init(&pDecomp->m_decomp);
385 pDecomp->m_dict_ofs = 0;
386 pDecomp->m_dict_avail = 0;
387 pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
388 pDecomp->m_first_call = 1;
389 pDecomp->m_has_flushed = 0;
390 pDecomp->m_window_bits = window_bits;
392 return MZ_OK;
395int mz_inflateInit(mz_streamp pStream)
397 return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS);
400int mz_inflate(mz_streamp pStream, int flush)
402 inflate_state *pState;
403 mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32;
404 size_t in_bytes, out_bytes, orig_avail_in;
405 tinfl_status status;
407 if ((!pStream) || (!pStream->state))
408 return MZ_STREAM_ERROR;
409 if (flush == MZ_PARTIAL_FLUSH)
410 flush = MZ_SYNC_FLUSH;
411 if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH))
412 return MZ_STREAM_ERROR;
414 pState = (inflate_state *)pStream->state;
415 if (pState->m_window_bits > 0)
416 decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER;
417 orig_avail_in = pStream->avail_in;
419 first_call = pState->m_first_call;
420 pState->m_first_call = 0;
421 if (pState->m_last_status < 0)
422 return MZ_DATA_ERROR;
424 if (pState->m_has_flushed && (flush != MZ_FINISH))
425 return MZ_STREAM_ERROR;
426 pState->m_has_flushed |= (flush == MZ_FINISH);
428 if ((flush == MZ_FINISH) && (first_call))
429 {
430 /* MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file. */
431 decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF;
432 in_bytes = pStream->avail_in;
433 out_bytes = pStream->avail_out;
434 status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags);
435 pState->m_last_status = status;
436 pStream->next_in += (mz_uint)in_bytes;
437 pStream->avail_in -= (mz_uint)in_bytes;
438 pStream->total_in += (mz_uint)in_bytes;
439 pStream->adler = tinfl_get_adler32(&pState->m_decomp);
440 pStream->next_out += (mz_uint)out_bytes;
441 pStream->avail_out -= (mz_uint)out_bytes;
442 pStream->total_out += (mz_uint)out_bytes;
444 if (status < 0)
445 return MZ_DATA_ERROR;
446 else if (status != TINFL_STATUS_DONE)
447 {
448 pState->m_last_status = TINFL_STATUS_FAILED;
449 return MZ_BUF_ERROR;
450 }
451 return MZ_STREAM_END;
452 }
453 /* flush != MZ_FINISH then we must assume there's more input. */
454 if (flush != MZ_FINISH)
455 decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT;
457 if (pState->m_dict_avail)
458 {
459 n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
460 memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
461 pStream->next_out += n;
462 pStream->avail_out -= n;
463 pStream->total_out += n;
464 pState->m_dict_avail -= n;
465 pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
466 return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
467 }
469 for (;;)
470 {
471 in_bytes = pStream->avail_in;
472 out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs;
474 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);
475 pState->m_last_status = status;
477 pStream->next_in += (mz_uint)in_bytes;
478 pStream->avail_in -= (mz_uint)in_bytes;
479 pStream->total_in += (mz_uint)in_bytes;
480 pStream->adler = tinfl_get_adler32(&pState->m_decomp);
482 pState->m_dict_avail = (mz_uint)out_bytes;
484 n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
485 memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
486 pStream->next_out += n;
487 pStream->avail_out -= n;
488 pStream->total_out += n;
489 pState->m_dict_avail -= n;
490 pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
492 if (status < 0)
493 return MZ_DATA_ERROR; /* Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well). */
494 else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in))
495 return MZ_BUF_ERROR; /* Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH. */
496 else if (flush == MZ_FINISH)
497 {
498 /* The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH. */
499 if (status == TINFL_STATUS_DONE)
500 return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END;
501 /* 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. */
502 else if (!pStream->avail_out)
503 return MZ_BUF_ERROR;
504 }
505 else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail))
506 break;
507 }
509 return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
512int mz_inflateEnd(mz_streamp pStream)
514 if (!pStream)
515 return MZ_STREAM_ERROR;
516 if (pStream->state)
517 {
518 pStream->zfree(pStream->opaque, pStream->state);
519 pStream->state = NULL;
520 }
521 return MZ_OK;
524int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
526 mz_stream stream;
527 int status;
528 memset(&stream, 0, sizeof(stream));
530 /* In case mz_ulong is 64-bits (argh I hate longs). */
531 if ((source_len | *pDest_len) > 0xFFFFFFFFU)
532 return MZ_PARAM_ERROR;
534 stream.next_in = pSource;
535 stream.avail_in = (mz_uint32)source_len;
536 stream.next_out = pDest;
537 stream.avail_out = (mz_uint32)*pDest_len;
539 status = mz_inflateInit(&stream);
540 if (status != MZ_OK)
541 return status;
543 status = mz_inflate(&stream, MZ_FINISH);
544 if (status != MZ_STREAM_END)
545 {
546 mz_inflateEnd(&stream);
547 return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status;
548 }
549 *pDest_len = stream.total_out;
551 return mz_inflateEnd(&stream);
554const char *mz_error(int err)
556 static struct
557 {
558 int m_err;
559 const char *m_pDesc;
560 } s_error_descs[] =
561 {
562 { MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" }, { 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" }
563 };
564 mz_uint i;
565 for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i)
566 if (s_error_descs[i].m_err == err)
567 return s_error_descs[i].m_pDesc;
568 return NULL;
571#endif /*MINIZ_NO_ZLIB_APIS */
573#ifdef __cplusplus
575#endif
577/*
578 This is free and unencumbered software released into the public domain.
580 Anyone is free to copy, modify, publish, use, compile, sell, or
581 distribute this software, either in source code form or as a compiled
582 binary, for any purpose, commercial or non-commercial, and by any
583 means.
585 In jurisdictions that recognize copyright laws, the author or authors
586 of this software dedicate any and all copyright interest in the
587 software to the public domain. We make this dedication for the benefit
588 of the public at large and to the detriment of our heirs and
589 successors. We intend this dedication to be an overt act of
590 relinquishment in perpetuity of all present and future rights to this
591 software under copyright law.
593 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
594 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
595 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
596 IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
597 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
598 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
599 OTHER DEALINGS IN THE SOFTWARE.
601 For more information, please refer to <http://unlicense.org/>
602*/