• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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