1 /*--------------------------------------------------------------------*/
2 /*--- Tiny zlib decompressor tinfl.c ---*/
3 /*--------------------------------------------------------------------*/
5 /* tinfl.c v1.11 - public domain inflate with zlib header parsing/adler32
6 checking (inflate-only subset of miniz.c)
8 Rich Geldreich <richgel99@gmail.com>, last updated May 20, 2011
10 Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt
11 and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
13 The original file has been modified in order to be a part of Valgrind
14 project, a dynamic binary instrumentation framework.
15 RT-RK Institute for Computer Based Systems, 2016 (mips-valgrind@rt-rk.com)
17 This program is free software; you can redistribute it and/or
18 modify it under the terms of the GNU General Public License as
19 published by the Free Software Foundation; either version 2 of the
20 License, or (at your option) any later version.
22 This program is distributed in the hope that it will be useful, but
23 WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 General Public License for more details.
27 You should have received a copy of the GNU General Public License
28 along with this program; if not, write to the Free Software
29 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
32 The GNU General Public License is contained in the file COPYING.
35 #ifndef TINFL_HEADER_INCLUDED
36 #define TINFL_HEADER_INCLUDED
38 /* The entire decompressor coroutine is implemented in tinfl_decompress().
39 The other functions are optional high-level helpers. */
41 #include "pub_core_basics.h"
43 typedef UChar mz_uint8
;
44 typedef Short mz_int16
;
45 typedef UShort mz_uint16
;
46 typedef UInt mz_uint32
;
48 typedef ULong mz_uint64
;
50 #if defined(VGA_x86) || defined(VGA_amd64)
51 // Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 if integer loads and stores to
52 // unaligned addresses are acceptable on the target platform (slightly faster).
53 #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
56 #define MINIZ_LITTLE_ENDIAN ( defined(VG_LITTLEENDIAN) )
57 #define MINIZ_HAS_64BIT_REGISTERS ( VG_WORDSIZE == 8 )
59 // Works around MSVC's spammy "warning C4127: conditional expression is
62 #define MZ_MACRO_END while (0, 0)
64 #define MZ_MACRO_END while (0)
67 /* Decompression flags used by tinfl_decompress().
69 TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and
70 ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the
71 input is a raw deflate stream.
73 TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available
74 beyond the end of the supplied input buffer. If clear, the input buffer
75 contains all remaining input.
77 TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large
78 enough to hold the entire decompressed stream. If clear, the output buffer
79 is at least the size of the dictionary (typically 32KB).
81 TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the
87 TINFL_FLAG_PARSE_ZLIB_HEADER
= 1,
88 TINFL_FLAG_HAS_MORE_INPUT
= 2,
89 TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF
= 4,
90 TINFL_FLAG_COMPUTE_ADLER32
= 8
93 // High level decompression functions:
94 // tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block allocated via malloc().
96 // pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data to decompress.
98 // Function returns a pointer to the decompressed data, or NULL on failure.
99 // *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data.
100 // The caller must free() the returned block when it's no longer needed.
101 void *tinfl_decompress_mem_to_heap(const void *pSrc_buf
, SizeT src_buf_len
, SizeT
*pOut_len
, int flags
);
103 // tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory.
104 // Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success.
105 #define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((SizeT)(-1))
106 SizeT
tinfl_decompress_mem_to_mem(void *pOut_buf
, SizeT out_buf_len
, const void *pSrc_buf
, SizeT src_buf_len
, int flags
);
108 // 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.
109 // Returns 1 on success or 0 on failure.
110 typedef int (*tinfl_put_buf_func_ptr
)(const void* pBuf
, int len
, void *pUser
);
111 int tinfl_decompress_mem_to_callback(const void *pIn_buf
, SizeT
*pIn_buf_size
, tinfl_put_buf_func_ptr pPut_buf_func
, void *pPut_buf_user
, int flags
);
113 struct tinfl_decompressor_tag
; typedef struct tinfl_decompressor_tag tinfl_decompressor
;
115 // Max size of LZ dictionary.
116 #define TINFL_LZ_DICT_SIZE 32768
121 TINFL_STATUS_BAD_PARAM
= -3,
122 TINFL_STATUS_ADLER32_MISMATCH
= -2,
123 TINFL_STATUS_FAILED
= -1,
124 TINFL_STATUS_DONE
= 0,
125 TINFL_STATUS_NEEDS_MORE_INPUT
= 1,
126 TINFL_STATUS_HAS_MORE_OUTPUT
= 2
129 // Initializes the decompressor to its initial state.
130 #define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END
131 #define tinfl_get_adler32(r) (r)->m_check_adler32
133 // 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.
134 // 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.
135 tinfl_status
tinfl_decompress(tinfl_decompressor
*r
, const mz_uint8
*pIn_buf_next
, SizeT
*pIn_buf_size
, mz_uint8
*pOut_buf_start
, mz_uint8
*pOut_buf_next
, SizeT
*pOut_buf_size
, const mz_uint32 decomp_flags
);
137 // Internal/private bits follow.
140 TINFL_MAX_HUFF_TABLES
= 3, TINFL_MAX_HUFF_SYMBOLS_0
= 288, TINFL_MAX_HUFF_SYMBOLS_1
= 32, TINFL_MAX_HUFF_SYMBOLS_2
= 19,
141 TINFL_FAST_LOOKUP_BITS
= 10, TINFL_FAST_LOOKUP_SIZE
= 1 << TINFL_FAST_LOOKUP_BITS
146 mz_uint8 m_code_size
[TINFL_MAX_HUFF_SYMBOLS_0
];
147 mz_int16 m_look_up
[TINFL_FAST_LOOKUP_SIZE
], m_tree
[TINFL_MAX_HUFF_SYMBOLS_0
* 2];
150 #if MINIZ_HAS_64BIT_REGISTERS
151 #define TINFL_USE_64BIT_BITBUF 1
154 #if TINFL_USE_64BIT_BITBUF
155 typedef mz_uint64 tinfl_bit_buf_t
;
156 #define TINFL_BITBUF_SIZE (64)
158 typedef mz_uint32 tinfl_bit_buf_t
;
159 #define TINFL_BITBUF_SIZE (32)
162 struct tinfl_decompressor_tag
164 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
];
165 tinfl_bit_buf_t m_bit_buf
;
166 SizeT m_dist_from_out_buf_start
;
167 tinfl_huff_table m_tables
[TINFL_MAX_HUFF_TABLES
];
168 mz_uint8 m_raw_header
[4], m_len_codes
[TINFL_MAX_HUFF_SYMBOLS_0
+ TINFL_MAX_HUFF_SYMBOLS_1
+ 137];
171 #endif // #ifdef TINFL_HEADER_INCLUDED
173 // ------------------- End of Header: Implementation follows. (If you only want the header, define MINIZ_HEADER_FILE_ONLY.)
175 #ifndef TINFL_HEADER_FILE_ONLY
177 #include "pub_core_mallocfree.h"
178 #include "pub_core_libcbase.h"
180 #define MZ_MAX(a,b) (((a)>(b))?(a):(b))
181 #define MZ_MIN(a,b) (((a)<(b))?(a):(b))
182 #define MZ_CLEAR_OBJ(obj) VG_(memset)(&(obj), 0, sizeof(obj))
184 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
185 #define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
186 #define MZ_READ_LE32(p) *((const mz_uint32 *)(p))
188 #define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U))
189 #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))
192 #define TINFL_MEMCPY(d, s, l) VG_(memcpy)(d, s, l)
193 #define TINFL_MEMSET(p, c, l) VG_(memset)(p, c, l)
195 #define TINFL_CR_BEGIN switch(r->m_state) { case 0:
196 #define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END
197 #define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END
198 #define TINFL_CR_FINISH }
200 // 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
201 // reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of the stream with 0's in this scenario.
202 #define TINFL_GET_BYTE(state_index, c) do { \
203 if (pIn_buf_cur >= pIn_buf_end) { \
205 if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \
206 TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \
207 if (pIn_buf_cur < pIn_buf_end) { \
208 c = *pIn_buf_cur++; \
216 } else c = *pIn_buf_cur++; } MZ_MACRO_END
218 #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))
219 #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
220 #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
222 // TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2.
223 // 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
224 // 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
225 // bit buffer contains >=15 bits (deflate's max. Huffman code size).
226 #define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \
228 temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
230 code_len = temp >> 9; \
231 if ((code_len) && (num_bits >= code_len)) \
233 } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \
234 code_len = TINFL_FAST_LOOKUP_BITS; \
236 temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
237 } while ((temp < 0) && (num_bits >= (code_len + 1))); if (temp >= 0) break; \
238 } TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; \
239 } while (num_bits < 15);
241 // 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
242 // 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
243 // 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.
244 // The slow path is only executed at the very end of the input buffer.
245 #define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \
246 int temp; mz_uint code_len, c; \
247 if (num_bits < 15) { \
248 if ((pIn_buf_end - pIn_buf_cur) < 2) { \
249 TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
251 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; \
254 if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
255 code_len = temp >> 9, temp &= 511; \
257 code_len = TINFL_FAST_LOOKUP_BITS; do { temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; } while (temp < 0); \
258 } sym = temp; bit_buf >>= code_len; num_bits -= code_len; } MZ_MACRO_END
260 tinfl_status
tinfl_decompress(tinfl_decompressor
*r
, const mz_uint8
*pIn_buf_next
, SizeT
*pIn_buf_size
, mz_uint8
*pOut_buf_start
, mz_uint8
*pOut_buf_next
, SizeT
*pOut_buf_size
, const mz_uint32 decomp_flags
)
262 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 };
263 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 };
264 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};
265 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};
266 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 };
267 static const int s_min_table_sizes
[3] = { 257, 1, 4 };
269 tinfl_status status
= TINFL_STATUS_FAILED
; mz_uint32 num_bits
, dist
, counter
, num_extra
; tinfl_bit_buf_t bit_buf
;
270 const mz_uint8
*pIn_buf_cur
= pIn_buf_next
, *const pIn_buf_end
= pIn_buf_next
+ *pIn_buf_size
;
271 mz_uint8
*pOut_buf_cur
= pOut_buf_next
, *const pOut_buf_end
= pOut_buf_next
+ *pOut_buf_size
;
272 SizeT out_buf_size_mask
= (decomp_flags
& TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF
) ? (SizeT
)-1 : ((pOut_buf_next
- pOut_buf_start
) + *pOut_buf_size
) - 1, dist_from_out_buf_start
;
274 // 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).
275 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
; }
277 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
;
280 bit_buf
= num_bits
= dist
= counter
= num_extra
= r
->m_zhdr0
= r
->m_zhdr1
= 0; r
->m_z_adler32
= r
->m_check_adler32
= 1;
281 if (decomp_flags
& TINFL_FLAG_PARSE_ZLIB_HEADER
)
283 TINFL_GET_BYTE(1, r
->m_zhdr0
); TINFL_GET_BYTE(2, r
->m_zhdr1
);
284 counter
= (((r
->m_zhdr0
* 256 + r
->m_zhdr1
) % 31 != 0) || (r
->m_zhdr1
& 32) || ((r
->m_zhdr0
& 15) != 8));
285 if (!(decomp_flags
& TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF
)) counter
|= (((1U << (8U + (r
->m_zhdr0
>> 4))) > 32768U) || ((out_buf_size_mask
+ 1) < (SizeT
)(1U << (8U + (r
->m_zhdr0
>> 4)))));
286 if (counter
) { TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED
); }
291 TINFL_GET_BITS(3, r
->m_final
, 3); r
->m_type
= r
->m_final
>> 1;
294 TINFL_SKIP_BITS(5, num_bits
& 7);
295 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
]); }
296 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
); }
297 while ((counter
) && (num_bits
))
299 TINFL_GET_BITS(51, dist
, 8);
300 while (pOut_buf_cur
>= pOut_buf_end
) { TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT
); }
301 *pOut_buf_cur
++ = (mz_uint8
)dist
;
306 SizeT n
; while (pOut_buf_cur
>= pOut_buf_end
) { TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT
); }
307 while (pIn_buf_cur
>= pIn_buf_end
)
309 if (decomp_flags
& TINFL_FLAG_HAS_MORE_INPUT
)
311 TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT
);
315 TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED
);
318 n
= MZ_MIN(MZ_MIN((SizeT
)(pOut_buf_end
- pOut_buf_cur
), (SizeT
)(pIn_buf_end
- pIn_buf_cur
)), counter
);
319 TINFL_MEMCPY(pOut_buf_cur
, pIn_buf_cur
, n
); pIn_buf_cur
+= n
; pOut_buf_cur
+= n
; counter
-= (mz_uint
)n
;
322 else if (r
->m_type
== 3)
324 TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED
);
330 mz_uint8
*p
= r
->m_tables
[0].m_code_size
; mz_uint i
;
331 r
->m_table_sizes
[0] = 288; r
->m_table_sizes
[1] = 32; TINFL_MEMSET(r
->m_tables
[1].m_code_size
, 5, 32);
332 for ( i
= 0; i
<= 143; ++i
) *p
++ = 8;
333 for ( ; i
<= 255; ++i
) *p
++ = 9;
334 for ( ; i
<= 279; ++i
) *p
++ = 7;
335 for ( ; i
<= 287; ++i
) *p
++ = 8;
339 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
]; }
340 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
; }
341 r
->m_table_sizes
[2] = 19;
343 for ( ; (int)r
->m_type
>= 0; r
->m_type
--)
345 int tree_next
, tree_cur
; tinfl_huff_table
*pTable
;
346 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
);
347 for (i
= 0; i
< r
->m_table_sizes
[r
->m_type
]; ++i
) total_syms
[pTable
->m_code_size
[i
]]++;
348 used_syms
= 0, total
= 0; next_code
[0] = next_code
[1] = 0;
349 for (i
= 1; i
<= 15; ++i
) { used_syms
+= total_syms
[i
]; next_code
[i
+ 1] = (total
= ((total
+ total_syms
[i
]) << 1)); }
350 if ((65536 != total
) && (used_syms
> 1))
352 TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED
);
354 for (tree_next
= -1, sym_index
= 0; sym_index
< r
->m_table_sizes
[r
->m_type
]; ++sym_index
)
356 mz_uint rev_code
= 0, l
, cur_code
, code_size
= pTable
->m_code_size
[sym_index
]; if (!code_size
) continue;
357 cur_code
= next_code
[code_size
]++; for (l
= code_size
; l
> 0; l
--, cur_code
>>= 1) rev_code
= (rev_code
<< 1) | (cur_code
& 1);
358 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; }
359 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; }
360 rev_code
>>= (TINFL_FAST_LOOKUP_BITS
- 1);
361 for (j
= code_size
; j
> (TINFL_FAST_LOOKUP_BITS
+ 1); j
--)
363 tree_cur
-= ((rev_code
>>= 1) & 1);
364 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];
366 tree_cur
-= ((rev_code
>>= 1) & 1); pTable
->m_tree
[-tree_cur
- 1] = (mz_int16
)sym_index
;
370 for (counter
= 0; counter
< (r
->m_table_sizes
[0] + r
->m_table_sizes
[1]); )
372 mz_uint s
; TINFL_HUFF_DECODE(16, dist
, &r
->m_tables
[2]); if (dist
< 16) { r
->m_len_codes
[counter
++] = (mz_uint8
)dist
; continue; }
373 if ((dist
== 16) && (!counter
))
375 TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED
);
377 num_extra
= "\02\03\07"[dist
- 16]; TINFL_GET_BITS(18, s
, num_extra
); s
+= "\03\03\013"[dist
- 16];
378 TINFL_MEMSET(r
->m_len_codes
+ counter
, (dist
== 16) ? r
->m_len_codes
[counter
- 1] : 0, s
); counter
+= s
;
380 if ((r
->m_table_sizes
[0] + r
->m_table_sizes
[1]) != counter
)
382 TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED
);
384 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]);
392 if (((pIn_buf_end
- pIn_buf_cur
) < 4) || ((pOut_buf_end
- pOut_buf_cur
) < 2))
394 TINFL_HUFF_DECODE(23, counter
, &r
->m_tables
[0]);
397 while (pOut_buf_cur
>= pOut_buf_end
) { TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT
); }
398 *pOut_buf_cur
++ = (mz_uint8
)counter
;
402 int sym2
; mz_uint code_len
;
403 #if TINFL_USE_64BIT_BITBUF
404 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; }
406 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; }
408 if ((sym2
= r
->m_tables
[0].m_look_up
[bit_buf
& (TINFL_FAST_LOOKUP_SIZE
- 1)]) >= 0)
409 code_len
= sym2
>> 9;
412 code_len
= TINFL_FAST_LOOKUP_BITS
; do { sym2
= r
->m_tables
[0].m_tree
[~sym2
+ ((bit_buf
>> code_len
++) & 1)]; } while (sym2
< 0);
414 counter
= sym2
; bit_buf
>>= code_len
; num_bits
-= code_len
;
418 #if !TINFL_USE_64BIT_BITBUF
419 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; }
421 if ((sym2
= r
->m_tables
[0].m_look_up
[bit_buf
& (TINFL_FAST_LOOKUP_SIZE
- 1)]) >= 0)
422 code_len
= sym2
>> 9;
425 code_len
= TINFL_FAST_LOOKUP_BITS
; do { sym2
= r
->m_tables
[0].m_tree
[~sym2
+ ((bit_buf
>> code_len
++) & 1)]; } while (sym2
< 0);
427 bit_buf
>>= code_len
; num_bits
-= code_len
;
429 pOut_buf_cur
[0] = (mz_uint8
)counter
;
436 pOut_buf_cur
[1] = (mz_uint8
)sym2
;
440 if ((counter
&= 511) == 256) break;
442 num_extra
= s_length_extra
[counter
- 257]; counter
= s_length_base
[counter
- 257];
443 if (num_extra
) { mz_uint extra_bits
; TINFL_GET_BITS(25, extra_bits
, num_extra
); counter
+= extra_bits
; }
445 TINFL_HUFF_DECODE(26, dist
, &r
->m_tables
[1]);
446 num_extra
= s_dist_extra
[dist
]; dist
= s_dist_base
[dist
];
447 if (num_extra
) { mz_uint extra_bits
; TINFL_GET_BITS(27, extra_bits
, num_extra
); dist
+= extra_bits
; }
449 dist_from_out_buf_start
= pOut_buf_cur
- pOut_buf_start
;
450 if ((dist
> dist_from_out_buf_start
) && (decomp_flags
& TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF
))
452 TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED
);
455 pSrc
= pOut_buf_start
+ ((dist_from_out_buf_start
- dist
) & out_buf_size_mask
);
457 if ((MZ_MAX(pOut_buf_cur
, pSrc
) + counter
) > pOut_buf_end
)
461 while (pOut_buf_cur
>= pOut_buf_end
) { TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT
); }
462 *pOut_buf_cur
++ = pOut_buf_start
[(dist_from_out_buf_start
++ - dist
) & out_buf_size_mask
];
466 #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
467 else if ((counter
>= 9) && (counter
<= dist
))
469 const mz_uint8
*pSrc_end
= pSrc
+ (counter
& ~7);
472 ((mz_uint32
*)pOut_buf_cur
)[0] = ((const mz_uint32
*)pSrc
)[0];
473 ((mz_uint32
*)pOut_buf_cur
)[1] = ((const mz_uint32
*)pSrc
)[1];
475 } while ((pSrc
+= 8) < pSrc_end
);
476 if ((counter
&= 7) < 3)
480 pOut_buf_cur
[0] = pSrc
[0];
482 pOut_buf_cur
[1] = pSrc
[1];
483 pOut_buf_cur
+= counter
;
491 pOut_buf_cur
[0] = pSrc
[0];
492 pOut_buf_cur
[1] = pSrc
[1];
493 pOut_buf_cur
[2] = pSrc
[2];
494 pOut_buf_cur
+= 3; pSrc
+= 3;
495 } while ((int)(counter
-= 3) > 2);
496 if ((int)counter
> 0)
498 pOut_buf_cur
[0] = pSrc
[0];
499 if ((int)counter
> 1)
500 pOut_buf_cur
[1] = pSrc
[1];
501 pOut_buf_cur
+= counter
;
505 } while (!(r
->m_final
& 1));
506 if (decomp_flags
& TINFL_FLAG_PARSE_ZLIB_HEADER
)
508 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
; }
510 TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE
);
514 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
;
515 *pIn_buf_size
= pIn_buf_cur
- pIn_buf_next
; *pOut_buf_size
= pOut_buf_cur
- pOut_buf_next
;
516 if ((decomp_flags
& (TINFL_FLAG_PARSE_ZLIB_HEADER
| TINFL_FLAG_COMPUTE_ADLER32
)) && (status
>= 0))
518 const mz_uint8
*ptr
= pOut_buf_next
; SizeT buf_len
= *pOut_buf_size
;
519 mz_uint32 i
, s1
= r
->m_check_adler32
& 0xffff, s2
= r
->m_check_adler32
>> 16; SizeT block_len
= buf_len
% 5552;
522 for (i
= 0; i
+ 7 < block_len
; i
+= 8, ptr
+= 8)
524 s1
+= ptr
[0], s2
+= s1
; s1
+= ptr
[1], s2
+= s1
; s1
+= ptr
[2], s2
+= s1
; s1
+= ptr
[3], s2
+= s1
;
525 s1
+= ptr
[4], s2
+= s1
; s1
+= ptr
[5], s2
+= s1
; s1
+= ptr
[6], s2
+= s1
; s1
+= ptr
[7], s2
+= s1
;
527 for ( ; i
< block_len
; ++i
) s1
+= *ptr
++, s2
+= s1
;
528 s1
%= 65521U, s2
%= 65521U; buf_len
-= block_len
; block_len
= 5552;
530 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
;
535 // Higher level helper functions.
536 void *tinfl_decompress_mem_to_heap(const void *pSrc_buf
, SizeT src_buf_len
, SizeT
*pOut_len
, int flags
)
538 tinfl_decompressor decomp
; void *pBuf
= NULL
, *pNew_buf
; SizeT src_buf_ofs
= 0, out_buf_capacity
= 0;
543 SizeT src_buf_size
= src_buf_len
- src_buf_ofs
, dst_buf_size
= out_buf_capacity
- *pOut_len
, new_out_buf_capacity
;
544 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
,
545 (flags
& ~TINFL_FLAG_HAS_MORE_INPUT
) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF
);
546 if ((status
< 0) || (status
== TINFL_STATUS_NEEDS_MORE_INPUT
))
548 VG_(free
)(pBuf
); *pOut_len
= 0; return NULL
;
550 src_buf_ofs
+= src_buf_size
;
551 *pOut_len
+= dst_buf_size
;
552 if (status
== TINFL_STATUS_DONE
) break;
553 new_out_buf_capacity
= out_buf_capacity
* 2; if (new_out_buf_capacity
< 128) new_out_buf_capacity
= 128;
554 pNew_buf
= VG_(realloc
)("tinfl.tinfl_decompress_mem_to_heap.1", pBuf
, new_out_buf_capacity
);
557 VG_(free
)(pBuf
); *pOut_len
= 0; return NULL
;
559 pBuf
= pNew_buf
; out_buf_capacity
= new_out_buf_capacity
;
564 SizeT
tinfl_decompress_mem_to_mem(void *pOut_buf
, SizeT out_buf_len
, const void *pSrc_buf
, SizeT src_buf_len
, int flags
)
566 tinfl_decompressor decomp
; tinfl_status status
; tinfl_init(&decomp
);
567 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
);
568 return (status
!= TINFL_STATUS_DONE
) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED
: out_buf_len
;
571 int tinfl_decompress_mem_to_callback(const void *pIn_buf
, SizeT
*pIn_buf_size
, tinfl_put_buf_func_ptr pPut_buf_func
, void *pPut_buf_user
, int flags
)
574 tinfl_decompressor decomp
;
575 mz_uint8
*pDict
= (mz_uint8
*)VG_(malloc
)("tinfl.tinfl_decompress_mem_to_callback.1", TINFL_LZ_DICT_SIZE
); SizeT in_buf_ofs
= 0, dict_ofs
= 0;
577 return TINFL_STATUS_FAILED
;
581 SizeT in_buf_size
= *pIn_buf_size
- in_buf_ofs
, dst_buf_size
= TINFL_LZ_DICT_SIZE
- dict_ofs
;
582 tinfl_status status
= tinfl_decompress(&decomp
, (const mz_uint8
*)pIn_buf
+ in_buf_ofs
, &in_buf_size
, pDict
, pDict
+ dict_ofs
, &dst_buf_size
,
583 (flags
& ~(TINFL_FLAG_HAS_MORE_INPUT
| TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF
)));
584 in_buf_ofs
+= in_buf_size
;
585 if ((dst_buf_size
) && (!(*pPut_buf_func
)(pDict
+ dict_ofs
, (int)dst_buf_size
, pPut_buf_user
)))
587 if (status
!= TINFL_STATUS_HAS_MORE_OUTPUT
)
589 result
= (status
== TINFL_STATUS_DONE
);
592 dict_ofs
= (dict_ofs
+ dst_buf_size
) & (TINFL_LZ_DICT_SIZE
- 1);
595 *pIn_buf_size
= in_buf_ofs
;
599 #endif // #ifndef TINFL_HEADER_FILE_ONLY