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 **************************************************************************/
26
27 #include "miniz.h"
28
29 typedef unsigned char mz_validate_uint16[sizeof(mz_uint16) == 2 ? 1 : -1];
30 typedef unsigned char mz_validate_uint32[sizeof(mz_uint32) == 4 ? 1 : -1];
31 typedef unsigned char mz_validate_uint64[sizeof(mz_uint64) == 8 ? 1 : -1];
32
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36
37 /* ------------------- zlib-style API's */
38
mz_adler32(mz_ulong adler,const unsigned char * ptr,size_t buf_len)39 mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len)
40 {
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;
65 }
66
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 */
mz_crc32(mz_ulong crc,const mz_uint8 * ptr,size_t buf_len)88 mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
89 {
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 };
130
131 mz_uint32 crc32 = (mz_uint32)crc ^ 0xFFFFFFFF;
132 const mz_uint8 *pByte_buf = (const mz_uint8 *)ptr;
133
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 }
143
144 while (buf_len)
145 {
146 crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF];
147 ++pByte_buf;
148 --buf_len;
149 }
150
151 return ~crc32;
152 }
153 #endif
154
mz_free(void * p)155 void mz_free(void *p)
156 {
157 MZ_FREE(p);
158 }
159
miniz_def_alloc_func(void * opaque,size_t items,size_t size)160 void *miniz_def_alloc_func(void *opaque, size_t items, size_t size)
161 {
162 (void)opaque, (void)items, (void)size;
163 return MZ_MALLOC(items * size);
164 }
miniz_def_free_func(void * opaque,void * address)165 void miniz_def_free_func(void *opaque, void *address)
166 {
167 (void)opaque, (void)address;
168 MZ_FREE(address);
169 }
miniz_def_realloc_func(void * opaque,void * address,size_t items,size_t size)170 void *miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size)
171 {
172 (void)opaque, (void)address, (void)items, (void)size;
173 return MZ_REALLOC(address, items * size);
174 }
175
mz_version(void)176 const char *mz_version(void)
177 {
178 return MZ_VERSION;
179 }
180
181 #ifndef MINIZ_NO_ZLIB_APIS
182
mz_deflateInit(mz_streamp pStream,int level)183 int mz_deflateInit(mz_streamp pStream, int level)
184 {
185 return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY);
186 }
187
mz_deflateInit2(mz_streamp pStream,int level,int method,int window_bits,int mem_level,int strategy)188 int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy)
189 {
190 tdefl_compressor *pComp;
191 mz_uint comp_flags = TDEFL_COMPUTE_ADLER32 | tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy);
192
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;
197
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;
208
209 pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, sizeof(tdefl_compressor));
210 if (!pComp)
211 return MZ_MEM_ERROR;
212
213 pStream->state = (struct mz_internal_state *)pComp;
214
215 if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY)
216 {
217 mz_deflateEnd(pStream);
218 return MZ_PARAM_ERROR;
219 }
220
221 return MZ_OK;
222 }
223
mz_deflateReset(mz_streamp pStream)224 int mz_deflateReset(mz_streamp pStream)
225 {
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;
231 }
232
mz_deflate(mz_streamp pStream,int flush)233 int mz_deflate(mz_streamp pStream, int flush)
234 {
235 size_t in_bytes, out_bytes;
236 mz_ulong orig_total_in, orig_total_out;
237 int mz_status = MZ_OK;
238
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;
243
244 if (flush == MZ_PARTIAL_FLUSH)
245 flush = MZ_SYNC_FLUSH;
246
247 if (((tdefl_compressor *)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE)
248 return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR;
249
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;
257
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);
263
264 pStream->next_out += (mz_uint)out_bytes;
265 pStream->avail_out -= (mz_uint)out_bytes;
266 pStream->total_out += (mz_uint)out_bytes;
267
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;
289 }
290
mz_deflateEnd(mz_streamp pStream)291 int mz_deflateEnd(mz_streamp pStream)
292 {
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;
301 }
302
mz_deflateBound(mz_streamp pStream,mz_ulong source_len)303 mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len)
304 {
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);
308 }
309
mz_compress2(unsigned char * pDest,mz_ulong * pDest_len,const unsigned char * pSource,mz_ulong source_len,int level)310 int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level)
311 {
312 int status;
313 mz_stream stream;
314 memset(&stream, 0, sizeof(stream));
315
316 /* In case mz_ulong is 64-bits (argh I hate longs). */
317 if ((source_len | *pDest_len) > 0xFFFFFFFFU)
318 return MZ_PARAM_ERROR;
319
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;
324
325 status = mz_deflateInit(&stream, level);
326 if (status != MZ_OK)
327 return status;
328
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 }
335
336 *pDest_len = stream.total_out;
337 return mz_deflateEnd(&stream);
338 }
339
mz_compress(unsigned char * pDest,mz_ulong * pDest_len,const unsigned char * pSource,mz_ulong source_len)340 int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
341 {
342 return mz_compress2(pDest, pDest_len, pSource, source_len, MZ_DEFAULT_COMPRESSION);
343 }
344
mz_compressBound(mz_ulong source_len)345 mz_ulong mz_compressBound(mz_ulong source_len)
346 {
347 return mz_deflateBound(NULL, source_len);
348 }
349
350 typedef struct
351 {
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;
358
mz_inflateInit2(mz_streamp pStream,int window_bits)359 int mz_inflateInit2(mz_streamp pStream, int window_bits)
360 {
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;
366
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;
377
378 pDecomp = (inflate_state *)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state));
379 if (!pDecomp)
380 return MZ_MEM_ERROR;
381
382 pStream->state = (struct mz_internal_state *)pDecomp;
383
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;
391
392 return MZ_OK;
393 }
394
mz_inflateInit(mz_streamp pStream)395 int mz_inflateInit(mz_streamp pStream)
396 {
397 return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS);
398 }
399
mz_inflateReset(mz_streamp pStream)400 int mz_inflateReset(mz_streamp pStream)
401 {
402 inflate_state *pDecomp;
403 if (!pStream)
404 return MZ_STREAM_ERROR;
405
406 pStream->data_type = 0;
407 pStream->adler = 0;
408 pStream->msg = NULL;
409 pStream->total_in = 0;
410 pStream->total_out = 0;
411 pStream->reserved = 0;
412
413 pDecomp = (inflate_state *)pStream->state;
414
415 tinfl_init(&pDecomp->m_decomp);
416 pDecomp->m_dict_ofs = 0;
417 pDecomp->m_dict_avail = 0;
418 pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
419 pDecomp->m_first_call = 1;
420 pDecomp->m_has_flushed = 0;
421 /* pDecomp->m_window_bits = window_bits */;
422
423 return MZ_OK;
424 }
425
mz_inflate(mz_streamp pStream,int flush)426 int mz_inflate(mz_streamp pStream, int flush)
427 {
428 inflate_state *pState;
429 mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32;
430 size_t in_bytes, out_bytes, orig_avail_in;
431 tinfl_status status;
432
433 if ((!pStream) || (!pStream->state))
434 return MZ_STREAM_ERROR;
435 if (flush == MZ_PARTIAL_FLUSH)
436 flush = MZ_SYNC_FLUSH;
437 if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH))
438 return MZ_STREAM_ERROR;
439
440 pState = (inflate_state *)pStream->state;
441 if (pState->m_window_bits > 0)
442 decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER;
443 orig_avail_in = pStream->avail_in;
444
445 first_call = pState->m_first_call;
446 pState->m_first_call = 0;
447 if (pState->m_last_status < 0)
448 return MZ_DATA_ERROR;
449
450 if (pState->m_has_flushed && (flush != MZ_FINISH))
451 return MZ_STREAM_ERROR;
452 pState->m_has_flushed |= (flush == MZ_FINISH);
453
454 if ((flush == MZ_FINISH) && (first_call))
455 {
456 /* MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file. */
457 decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF;
458 in_bytes = pStream->avail_in;
459 out_bytes = pStream->avail_out;
460 status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags);
461 pState->m_last_status = status;
462 pStream->next_in += (mz_uint)in_bytes;
463 pStream->avail_in -= (mz_uint)in_bytes;
464 pStream->total_in += (mz_uint)in_bytes;
465 pStream->adler = tinfl_get_adler32(&pState->m_decomp);
466 pStream->next_out += (mz_uint)out_bytes;
467 pStream->avail_out -= (mz_uint)out_bytes;
468 pStream->total_out += (mz_uint)out_bytes;
469
470 if (status < 0)
471 return MZ_DATA_ERROR;
472 else if (status != TINFL_STATUS_DONE)
473 {
474 pState->m_last_status = TINFL_STATUS_FAILED;
475 return MZ_BUF_ERROR;
476 }
477 return MZ_STREAM_END;
478 }
479 /* flush != MZ_FINISH then we must assume there's more input. */
480 if (flush != MZ_FINISH)
481 decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT;
482
483 if (pState->m_dict_avail)
484 {
485 n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
486 memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
487 pStream->next_out += n;
488 pStream->avail_out -= n;
489 pStream->total_out += n;
490 pState->m_dict_avail -= n;
491 pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
492 return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
493 }
494
495 for (;;)
496 {
497 in_bytes = pStream->avail_in;
498 out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs;
499
500 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);
501 pState->m_last_status = status;
502
503 pStream->next_in += (mz_uint)in_bytes;
504 pStream->avail_in -= (mz_uint)in_bytes;
505 pStream->total_in += (mz_uint)in_bytes;
506 pStream->adler = tinfl_get_adler32(&pState->m_decomp);
507
508 pState->m_dict_avail = (mz_uint)out_bytes;
509
510 n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
511 memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
512 pStream->next_out += n;
513 pStream->avail_out -= n;
514 pStream->total_out += n;
515 pState->m_dict_avail -= n;
516 pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
517
518 if (status < 0)
519 return MZ_DATA_ERROR; /* Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well). */
520 else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in))
521 return MZ_BUF_ERROR; /* Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH. */
522 else if (flush == MZ_FINISH)
523 {
524 /* The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH. */
525 if (status == TINFL_STATUS_DONE)
526 return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END;
527 /* 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. */
528 else if (!pStream->avail_out)
529 return MZ_BUF_ERROR;
530 }
531 else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail))
532 break;
533 }
534
535 return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
536 }
537
mz_inflateEnd(mz_streamp pStream)538 int mz_inflateEnd(mz_streamp pStream)
539 {
540 if (!pStream)
541 return MZ_STREAM_ERROR;
542 if (pStream->state)
543 {
544 pStream->zfree(pStream->opaque, pStream->state);
545 pStream->state = NULL;
546 }
547 return MZ_OK;
548 }
549
mz_uncompress(unsigned char * pDest,mz_ulong * pDest_len,const unsigned char * pSource,mz_ulong source_len)550 int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
551 {
552 mz_stream stream;
553 int status;
554 memset(&stream, 0, sizeof(stream));
555
556 /* In case mz_ulong is 64-bits (argh I hate longs). */
557 if ((source_len | *pDest_len) > 0xFFFFFFFFU)
558 return MZ_PARAM_ERROR;
559
560 stream.next_in = pSource;
561 stream.avail_in = (mz_uint32)source_len;
562 stream.next_out = pDest;
563 stream.avail_out = (mz_uint32)*pDest_len;
564
565 status = mz_inflateInit(&stream);
566 if (status != MZ_OK)
567 return status;
568
569 status = mz_inflate(&stream, MZ_FINISH);
570 if (status != MZ_STREAM_END)
571 {
572 mz_inflateEnd(&stream);
573 return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status;
574 }
575 *pDest_len = stream.total_out;
576
577 return mz_inflateEnd(&stream);
578 }
579
mz_error(int err)580 const char *mz_error(int err)
581 {
582 static struct
583 {
584 int m_err;
585 const char *m_pDesc;
586 } s_error_descs[] =
587 {
588 { 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" }
589 };
590 mz_uint i;
591 for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i)
592 if (s_error_descs[i].m_err == err)
593 return s_error_descs[i].m_pDesc;
594 return NULL;
595 }
596
597 #endif /*MINIZ_NO_ZLIB_APIS */
598
599 #ifdef __cplusplus
600 }
601 #endif
602
603 /*
604 This is free and unencumbered software released into the public domain.
605
606 Anyone is free to copy, modify, publish, use, compile, sell, or
607 distribute this software, either in source code form or as a compiled
608 binary, for any purpose, commercial or non-commercial, and by any
609 means.
610
611 In jurisdictions that recognize copyright laws, the author or authors
612 of this software dedicate any and all copyright interest in the
613 software to the public domain. We make this dedication for the benefit
614 of the public at large and to the detriment of our heirs and
615 successors. We intend this dedication to be an overt act of
616 relinquishment in perpetuity of all present and future rights to this
617 software under copyright law.
618
619 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
620 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
621 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
622 IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
623 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
624 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
625 OTHER DEALINGS IN THE SOFTWARE.
626
627 For more information, please refer to <http://unlicense.org/>
628 */
629