]> git.proxmox.com Git - ceph.git/blame - ceph/src/isa-l/igzip/igzip_inflate.c
Import ceph 15.2.8
[ceph.git] / ceph / src / isa-l / igzip / igzip_inflate.c
CommitLineData
224ce89b
WB
1/**********************************************************************
2 Copyright(c) 2011-2016 Intel Corporation All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in
11 the documentation and/or other materials provided with the
12 distribution.
13 * Neither the name of Intel Corporation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28**********************************************************************/
29
30#include <stdint.h>
31#include "igzip_lib.h"
f91f0fd5 32#include "crc.h"
224ce89b 33#include "huff_codes.h"
f91f0fd5
TL
34#include "igzip_checksums.h"
35#include "igzip_wrapper.h"
36#include "unaligned.h"
37
38#ifndef NO_STATIC_INFLATE_H
39#include "static_inflate.h"
40#endif
41
42#ifdef __FreeBSD__
43#include <sys/types.h>
44#include <sys/endian.h>
45# define bswap_32(x) bswap32(x)
46#elif defined (__APPLE__)
47#include <libkern/OSByteOrder.h>
48# define bswap_32(x) OSSwapInt32(x)
49#elif defined (__GNUC__) && !defined (__MINGW32__)
50# include <byteswap.h>
51#elif defined _WIN64
52# define bswap_32(x) _byteswap_ulong(x)
53#endif
54
55extern int decode_huffman_code_block_stateless(struct inflate_state *, uint8_t * start_out);
56
57#define LARGE_SHORT_SYM_LEN 25
58#define LARGE_SHORT_SYM_MASK ((1 << LARGE_SHORT_SYM_LEN) - 1)
59#define LARGE_LONG_SYM_LEN 10
60#define LARGE_LONG_SYM_MASK ((1 << LARGE_LONG_SYM_LEN) - 1)
61#define LARGE_SHORT_CODE_LEN_OFFSET 28
62#define LARGE_LONG_CODE_LEN_OFFSET 10
63#define LARGE_FLAG_BIT_OFFSET 25
64#define LARGE_FLAG_BIT (1 << LARGE_FLAG_BIT_OFFSET)
65#define LARGE_SYM_COUNT_OFFSET 26
66#define LARGE_SYM_COUNT_LEN 2
67#define LARGE_SYM_COUNT_MASK ((1 << LARGE_SYM_COUNT_LEN) - 1)
68#define LARGE_SHORT_MAX_LEN_OFFSET 26
69
70#define SMALL_SHORT_SYM_LEN 9
71#define SMALL_SHORT_SYM_MASK ((1 << SMALL_SHORT_SYM_LEN) - 1)
72#define SMALL_LONG_SYM_LEN 9
73#define SMALL_LONG_SYM_MASK ((1 << SMALL_LONG_SYM_LEN) - 1)
74#define SMALL_SHORT_CODE_LEN_OFFSET 11
75#define SMALL_LONG_CODE_LEN_OFFSET 10
76#define SMALL_FLAG_BIT_OFFSET 10
77#define SMALL_FLAG_BIT (1 << SMALL_FLAG_BIT_OFFSET)
78
79#define DIST_SYM_OFFSET 0
80#define DIST_SYM_LEN 5
81#define DIST_SYM_MASK ((1 << DIST_SYM_LEN) - 1)
82#define DIST_SYM_EXTRA_OFFSET 5
83#define DIST_SYM_EXTRA_LEN 4
84#define DIST_SYM_EXTRA_MASK ((1 << DIST_SYM_EXTRA_LEN) - 1)
85
86#define MAX_LIT_LEN_CODE_LEN 21
87#define MAX_LIT_LEN_COUNT (MAX_LIT_LEN_CODE_LEN + 2)
88#define MAX_LIT_LEN_SYM 512
89#define LIT_LEN_ELEMS 514
90
91#define INVALID_SYMBOL 0x1FFF
92#define INVALID_CODE 0xFFFFFF
93
94#define MIN_DEF_MATCH 3
95
96#define TRIPLE_SYM_FLAG 0
97#define DOUBLE_SYM_FLAG TRIPLE_SYM_FLAG + 1
98#define SINGLE_SYM_FLAG DOUBLE_SYM_FLAG + 1
99#define DEFAULT_SYM_FLAG TRIPLE_SYM_FLAG
100
101#define SINGLE_SYM_THRESH (2 * 1024)
102#define DOUBLE_SYM_THRESH (4 * 1024)
224ce89b
WB
103
104/* structure contain lookup data based on RFC 1951 */
105struct rfc1951_tables {
106 uint8_t dist_extra_bit_count[32];
107 uint32_t dist_start[32];
108 uint8_t len_extra_bit_count[32];
109 uint16_t len_start[32];
110
111};
112
113/* The following tables are based on the tables in the deflate standard,
114 * RFC 1951 page 11. */
115static struct rfc1951_tables rfc_lookup_table = {
116 .dist_extra_bit_count = {
117 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02,
118 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06,
119 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a,
120 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x00, 0x00},
121
122 .dist_start = {
123 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0007, 0x0009, 0x000d,
124 0x0011, 0x0019, 0x0021, 0x0031, 0x0041, 0x0061, 0x0081, 0x00c1,
125 0x0101, 0x0181, 0x0201, 0x0301, 0x0401, 0x0601, 0x0801, 0x0c01,
126 0x1001, 0x1801, 0x2001, 0x3001, 0x4001, 0x6001, 0x0000, 0x0000},
127
128 .len_extra_bit_count = {
129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
131 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04,
132 0x05, 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00},
133
134 .len_start = {
135 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a,
136 0x000b, 0x000d, 0x000f, 0x0011, 0x0013, 0x0017, 0x001b, 0x001f,
137 0x0023, 0x002b, 0x0033, 0x003b, 0x0043, 0x0053, 0x0063, 0x0073,
f91f0fd5 138 0x0083, 0x00a3, 0x00c3, 0x00e3, 0x0102, 0x0103, 0x0000, 0x0000}
224ce89b
WB
139};
140
141struct slver {
142 uint16_t snum;
143 uint8_t ver;
144 uint8_t core;
145};
146
147/* Version info */
148struct slver isal_inflate_init_slver_00010088;
149struct slver isal_inflate_init_slver = { 0x0088, 0x01, 0x00 };
150
f91f0fd5
TL
151struct slver isal_inflate_reset_slver_0001008f;
152struct slver isal_inflate_reset_slver = { 0x008f, 0x01, 0x00 };
153
224ce89b
WB
154struct slver isal_inflate_stateless_slver_00010089;
155struct slver isal_inflate_stateless_slver = { 0x0089, 0x01, 0x00 };
156
157struct slver isal_inflate_slver_0001008a;
158struct slver isal_inflate_slver = { 0x008a, 0x01, 0x00 };
159
f91f0fd5
TL
160struct slver isal_inflate_set_dict_slver_0001008d;
161struct slver isal_inflate_set_dict_slver = { 0x008d, 0x01, 0x00 };
162
224ce89b
WB
163/*Performs a copy of length repeat_length data starting at dest -
164 * lookback_distance into dest. This copy copies data previously copied when the
165 * src buffer and the dest buffer overlap. */
166static void inline byte_copy(uint8_t * dest, uint64_t lookback_distance, int repeat_length)
167{
168 uint8_t *src = dest - lookback_distance;
169
170 for (; repeat_length > 0; repeat_length--)
171 *dest++ = *src++;
172}
173
f91f0fd5
TL
174static void update_checksum(struct inflate_state *state, uint8_t * start_in, uint64_t length)
175{
176 switch (state->crc_flag) {
177 case ISAL_GZIP:
178 case ISAL_GZIP_NO_HDR:
179 case ISAL_GZIP_NO_HDR_VER:
180 state->crc = crc32_gzip_refl(state->crc, start_in, length);
181 break;
182 case ISAL_ZLIB:
183 case ISAL_ZLIB_NO_HDR:
184 case ISAL_ZLIB_NO_HDR_VER:
185 state->crc = isal_adler32_bam1(state->crc, start_in, length);
186 break;
187 }
188}
189
190static void finalize_adler32(struct inflate_state *state)
191{
192
193 state->crc = (state->crc & 0xffff0000) | (((state->crc & 0xffff) + 1) % ADLER_MOD);
194}
195
196static const uint8_t bitrev_table[] = {
197 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
198 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
199 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
200 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
201 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
202 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
203 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
204 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
205 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
206 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
207 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
208 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
209 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
210 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
211 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
212 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
213 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
214 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
215 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
216 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
217 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
218 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
219 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
220 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
221 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
222 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
223 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
224 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
225 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
226 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
227 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
228 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
229
230};
231
224ce89b
WB
232/*
233 * Returns integer with first length bits reversed and all higher bits zeroed
234 */
f91f0fd5 235static uint32_t inline bit_reverse2(uint16_t bits, uint8_t length)
224ce89b 236{
f91f0fd5
TL
237 uint32_t bitrev;
238 bitrev = bitrev_table[bits >> 8];
239 bitrev |= bitrev_table[bits & 0xFF] << 8;
240
241 return bitrev >> (16 - length);
224ce89b
WB
242}
243
244/* Load data from the in_stream into a buffer to allow for handling unaligned data*/
245static void inline inflate_in_load(struct inflate_state *state, int min_required)
246{
247 uint64_t temp = 0;
248 uint8_t new_bytes;
249
250 if (state->read_in_length >= 64)
251 return;
252
253 if (state->avail_in >= 8) {
254 /* If there is enough space to load a 64 bits, load the data and use
255 * that to fill read_in */
256 new_bytes = 8 - (state->read_in_length + 7) / 8;
f91f0fd5 257 temp = load_u64(state->next_in);
224ce89b
WB
258
259 state->read_in |= temp << state->read_in_length;
260 state->next_in += new_bytes;
261 state->avail_in -= new_bytes;
262 state->read_in_length += new_bytes * 8;
263
264 } else {
265 /* Else fill the read_in buffer 1 byte at a time */
266 while (state->read_in_length < 57 && state->avail_in > 0) {
267 temp = *state->next_in;
268 state->read_in |= temp << state->read_in_length;
269 state->next_in++;
270 state->avail_in--;
271 state->read_in_length += 8;
272
273 }
274 }
275}
276
f91f0fd5
TL
277static uint64_t inline inflate_in_read_bits_unsafe(struct inflate_state *state,
278 uint8_t bit_count)
224ce89b
WB
279{
280 uint64_t ret;
224ce89b
WB
281
282 ret = (state->read_in) & ((1 << bit_count) - 1);
283 state->read_in >>= bit_count;
284 state->read_in_length -= bit_count;
285
286 return ret;
287}
288
f91f0fd5
TL
289/* Returns the next bit_count bits from the in stream and shifts the stream over
290 * by bit-count bits */
291static uint64_t inline inflate_in_read_bits(struct inflate_state *state, uint8_t bit_count)
292{
293 /* Load inflate_in if not enough data is in the read_in buffer */
294 inflate_in_load(state, bit_count);
295 return inflate_in_read_bits_unsafe(state, bit_count);
296}
297
298static void inline write_huff_code(struct huff_code *huff_code, uint32_t code, uint32_t length)
299{
300 huff_code->code_and_length = code | length << 24;
301}
302
303static int inline set_codes(struct huff_code *huff_code_table, int table_length,
304 uint16_t * count)
305{
306 uint32_t max, code, length;
307 uint32_t next_code[MAX_HUFF_TREE_DEPTH + 1];
308 int i;
309 struct huff_code *table_end = huff_code_table + table_length;
310
311 /* Setup for calculating huffman codes */
312 next_code[0] = 0;
313 next_code[1] = 0;
314 for (i = 2; i < MAX_HUFF_TREE_DEPTH + 1; i++)
315 next_code[i] = (next_code[i - 1] + count[i - 1]) << 1;
316
317 max = (next_code[MAX_HUFF_TREE_DEPTH] + count[MAX_HUFF_TREE_DEPTH]);
318
319 if (max > (1 << MAX_HUFF_TREE_DEPTH))
320 return ISAL_INVALID_BLOCK;
321
322 /* Calculate code corresponding to a given symbol */
323 for (; huff_code_table < table_end; huff_code_table++) {
324 length = huff_code_table->length;
325 if (length == 0)
326 continue;
327
328 code = bit_reverse2(next_code[length], length);
329
330 write_huff_code(huff_code_table, code, length);
331 next_code[length] += 1;
332 }
333 return 0;
334}
335
336static int inline set_and_expand_lit_len_huffcode(struct huff_code *lit_len_huff,
337 uint32_t table_length,
338 uint16_t * count,
339 uint16_t * expand_count,
340 uint32_t * code_list)
341{
342 int len_sym, len_size, extra_count, extra;
343 uint32_t count_total, count_tmp;
344 uint32_t code, code_len, expand_len;
345 struct huff_code *expand_next = &lit_len_huff[ISAL_DEF_LIT_SYMBOLS];
346 struct huff_code tmp_table[LIT_LEN - ISAL_DEF_LIT_SYMBOLS];
347 uint32_t max;
348 uint32_t next_code[MAX_HUFF_TREE_DEPTH + 1];
349 int i;
350 struct huff_code *table_end;
351 struct huff_code *huff_code_table = lit_len_huff;
352 uint32_t insert_index;
353
354 /* Setup for calculating huffman codes */
355 count_total = 0;
356 count_tmp = expand_count[1];
357 next_code[0] = 0;
358 next_code[1] = 0;
359 expand_count[0] = 0;
360 expand_count[1] = 0;
361
362 for (i = 1; i < MAX_HUFF_TREE_DEPTH; i++) {
363 count_total = count[i] + count_tmp + count_total;
364 count_tmp = expand_count[i + 1];
365 expand_count[i + 1] = count_total;
366 next_code[i + 1] = (next_code[i] + count[i]) << 1;
367 }
368
369 count_tmp = count[i] + count_tmp;
370
371 for (; i < MAX_LIT_LEN_COUNT - 1; i++) {
372 count_total = count_tmp + count_total;
373 count_tmp = expand_count[i + 1];
374 expand_count[i + 1] = count_total;
375 }
376
377 /* Correct for extra symbols used by static header */
378 if (table_length > LIT_LEN)
379 count[8] -= 2;
380
381 max = (next_code[MAX_HUFF_TREE_DEPTH] + count[MAX_HUFF_TREE_DEPTH]);
382
383 if (max > (1 << MAX_HUFF_TREE_DEPTH))
384 return ISAL_INVALID_BLOCK;
385
386 memcpy(count, expand_count, sizeof(*count) * MAX_LIT_LEN_COUNT);
387
388 memcpy(tmp_table, &lit_len_huff[ISAL_DEF_LIT_SYMBOLS],
389 sizeof(*lit_len_huff) * (LIT_LEN - ISAL_DEF_LIT_SYMBOLS));
390 memset(&lit_len_huff[ISAL_DEF_LIT_SYMBOLS], 0,
391 sizeof(*lit_len_huff) * (LIT_LEN_ELEMS - ISAL_DEF_LIT_SYMBOLS));
392
393 /* Calculate code corresponding to a given literal symbol */
394 table_end = huff_code_table + ISAL_DEF_LIT_SYMBOLS;
395 for (; huff_code_table < table_end; huff_code_table++) {
396 code_len = huff_code_table->length;
397 if (code_len == 0)
398 continue;
399
400 code = bit_reverse2(next_code[code_len], code_len);
401
402 insert_index = expand_count[code_len];
403 code_list[insert_index] = huff_code_table - lit_len_huff;
404 expand_count[code_len]++;
405
406 write_huff_code(huff_code_table, code, code_len);
407 next_code[code_len] += 1;
408 }
409
410 /* Calculate code corresponding to a given len symbol */
411 for (len_sym = 0; len_sym < LIT_LEN - ISAL_DEF_LIT_SYMBOLS; len_sym++) {
412 extra_count = rfc_lookup_table.len_extra_bit_count[len_sym];
413 len_size = (1 << extra_count);
414
415 code_len = tmp_table[len_sym].length;
416 if (code_len == 0) {
417 expand_next += len_size;
418 continue;
419 }
420
421 code = bit_reverse2(next_code[code_len], code_len);
422 expand_len = code_len + extra_count;
423 next_code[code_len] += 1;
424 insert_index = expand_count[expand_len];
425 expand_count[expand_len] += len_size;
426
427 for (extra = 0; extra < len_size; extra++) {
428 code_list[insert_index] = expand_next - lit_len_huff;
429 write_huff_code(expand_next, code | (extra << code_len), expand_len);
430 insert_index++;
431 expand_next++;
432 }
433 }
434
435 return 0;
436}
437
438static int inline index_to_sym(int index)
439{
440 return (index != 513) ? index : 512;
441}
442
224ce89b
WB
443/* Sets result to the inflate_huff_code corresponding to the huffcode defined by
444 * the lengths in huff_code_table,where count is a histogram of the appearance
445 * of each code length */
f91f0fd5
TL
446static void make_inflate_huff_code_lit_len(struct inflate_huff_code_large *result,
447 struct huff_code *huff_code_table,
448 uint32_t table_length, uint16_t * count_total,
449 uint32_t * code_list, uint32_t multisym)
224ce89b 450{
f91f0fd5 451 int i, j;
224ce89b 452 uint16_t code = 0;
f91f0fd5 453 uint32_t *long_code_list;
224ce89b 454 uint32_t long_code_length = 0;
f91f0fd5 455 uint16_t temp_code_list[1 << (MAX_LIT_LEN_CODE_LEN - ISAL_DECODE_LONG_BITS)];
224ce89b
WB
456 uint32_t temp_code_length;
457 uint32_t long_code_lookup_length = 0;
458 uint32_t max_length;
459 uint16_t first_bits;
460 uint32_t code_length;
461 uint16_t long_bits;
462 uint16_t min_increment;
224ce89b 463 uint32_t code_list_len;
f91f0fd5 464 uint32_t last_length, min_length;
224ce89b 465 uint32_t copy_size;
f91f0fd5
TL
466 uint32_t *short_code_lookup = result->short_code_lookup;
467 int index1, index2, index3;
468 int sym1, sym2, sym3, sym1_index, sym2_index, sym3_index;
469 uint32_t sym1_code, sym2_code, sym3_code, sym1_len, sym2_len, sym3_len;
224ce89b 470
f91f0fd5
TL
471 uint32_t max_symbol = MAX_LIT_LEN_SYM;
472
473 code_list_len = count_total[MAX_LIT_LEN_COUNT - 1];
224ce89b 474
224ce89b
WB
475 if (code_list_len == 0) {
476 memset(result->short_code_lookup, 0, sizeof(result->short_code_lookup));
477 return;
478 }
479
f91f0fd5 480 /* Determine the length of the first code */
224ce89b
WB
481 last_length = huff_code_table[code_list[0]].length;
482 if (last_length > ISAL_DECODE_LONG_BITS)
f91f0fd5
TL
483 last_length = ISAL_DECODE_LONG_BITS + 1;
484 copy_size = (1 << (last_length - 1));
224ce89b
WB
485
486 /* Initialize short_code_lookup, so invalid lookups process data */
487 memset(short_code_lookup, 0x00, copy_size * sizeof(*short_code_lookup));
488
f91f0fd5
TL
489 min_length = last_length;
490 for (; last_length <= ISAL_DECODE_LONG_BITS; last_length++) {
491 /* Copy forward previosly set codes */
492 memcpy(short_code_lookup + copy_size, short_code_lookup,
493 sizeof(*short_code_lookup) * copy_size);
494 copy_size *= 2;
495
496 /* Encode code singletons */
497 for (index1 = count_total[last_length];
498 index1 < count_total[last_length + 1]; index1++) {
499 sym1_index = code_list[index1];
500 sym1 = index_to_sym(sym1_index);
501 sym1_len = huff_code_table[sym1_index].length;
502 sym1_code = huff_code_table[sym1_index].code;
503
504 if (sym1 > max_symbol)
505 continue;
506
507 /* Set new codes */
508 short_code_lookup[sym1_code] =
509 sym1 | sym1_len << LARGE_SHORT_CODE_LEN_OFFSET |
510 (1 << LARGE_SYM_COUNT_OFFSET);
511 }
512
513 /* Continue if no pairs are possible */
514 if (multisym >= SINGLE_SYM_FLAG || last_length < 2 * min_length)
515 continue;
516
517 /* Encode code pairs */
518 for (index1 = count_total[min_length];
519 index1 < count_total[last_length - min_length + 1]; index1++) {
520 sym1_index = code_list[index1];
521 sym1 = index_to_sym(sym1_index);
522 sym1_len = huff_code_table[sym1_index].length;
523 sym1_code = huff_code_table[sym1_index].code;
524
525 /*Check that sym1 is a literal */
526 if (sym1 >= 256) {
527 index1 = count_total[sym1_len + 1] - 1;
528 continue;
529 }
530
531 sym2_len = last_length - sym1_len;
532 for (index2 = count_total[sym2_len];
533 index2 < count_total[sym2_len + 1]; index2++) {
534 sym2_index = code_list[index2];
535 sym2 = index_to_sym(sym2_index);
536
537 /* Check that sym2 is an existing symbol */
538 if (sym2 > max_symbol)
539 break;
224ce89b 540
f91f0fd5
TL
541 sym2_code = huff_code_table[sym2_index].code;
542 code = sym1_code | (sym2_code << sym1_len);
543 code_length = sym1_len + sym2_len;
544 short_code_lookup[code] =
545 sym1 | (sym2 << 8) |
546 (code_length << LARGE_SHORT_CODE_LEN_OFFSET)
547 | (2 << LARGE_SYM_COUNT_OFFSET);
548 }
224ce89b
WB
549 }
550
f91f0fd5
TL
551 /* Continue if no triples are possible */
552 if (multisym >= DOUBLE_SYM_FLAG || last_length < 3 * min_length)
553 continue;
224ce89b 554
f91f0fd5
TL
555 /* Encode code triples */
556 for (index1 = count_total[min_length];
557 index1 < count_total[last_length - 2 * min_length + 1]; index1++) {
558 sym1_index = code_list[index1];
559 sym1 = index_to_sym(sym1_index);
560 sym1_len = huff_code_table[sym1_index].length;
561 sym1_code = huff_code_table[sym1_index].code;
562 /*Check that sym1 is a literal */
563 if (sym1 >= 256) {
564 index1 = count_total[sym1_len + 1] - 1;
565 continue;
566 }
224ce89b 567
f91f0fd5
TL
568 if (last_length - sym1_len < 2 * min_length)
569 break;
224ce89b 570
f91f0fd5
TL
571 for (index2 = count_total[min_length];
572 index2 < count_total[last_length - sym1_len - min_length + 1];
573 index2++) {
574 sym2_index = code_list[index2];
575 sym2 = index_to_sym(sym2_index);
576 sym2_len = huff_code_table[sym2_index].length;
577 sym2_code = huff_code_table[sym2_index].code;
578
579 /* Check that sym2 is a literal */
580 if (sym2 >= 256) {
581 index2 = count_total[sym2_len + 1] - 1;
582 continue;
583 }
224ce89b 584
f91f0fd5
TL
585 sym3_len = last_length - sym1_len - sym2_len;
586 for (index3 = count_total[sym3_len];
587 index3 < count_total[sym3_len + 1]; index3++) {
588 sym3_index = code_list[index3];
589 sym3 = index_to_sym(sym3_index);
590 sym3_code = huff_code_table[sym3_index].code;
224ce89b 591
f91f0fd5
TL
592 /* Check that sym3 is writable existing symbol */
593 if (sym3 > max_symbol - 1)
594 break;
224ce89b 595
f91f0fd5
TL
596 code = sym1_code | (sym2_code << sym1_len) |
597 (sym3_code << (sym2_len + sym1_len));
598 code_length = sym1_len + sym2_len + sym3_len;
599 short_code_lookup[code] =
600 sym1 | (sym2 << 8) | sym3 << 16 |
601 (code_length << LARGE_SHORT_CODE_LEN_OFFSET)
602 | (3 << LARGE_SYM_COUNT_OFFSET);
224ce89b 603
f91f0fd5 604 }
224ce89b 605
f91f0fd5
TL
606 }
607 }
224ce89b 608
224ce89b
WB
609 }
610
f91f0fd5
TL
611 index1 = count_total[ISAL_DECODE_LONG_BITS + 1];
612 long_code_length = code_list_len - index1;
613 long_code_list = &code_list[index1];
224ce89b
WB
614 for (i = 0; i < long_code_length; i++) {
615 /*Set the look up table to point to a hint where the symbol can be found
616 * in the list of long codes and add the current symbol to the list of
617 * long codes. */
f91f0fd5 618 if (huff_code_table[long_code_list[i]].code_and_extra == INVALID_CODE)
224ce89b
WB
619 continue;
620
621 max_length = huff_code_table[long_code_list[i]].length;
622 first_bits =
f91f0fd5 623 huff_code_table[long_code_list[i]].code_and_extra
224ce89b
WB
624 & ((1 << ISAL_DECODE_LONG_BITS) - 1);
625
626 temp_code_list[0] = long_code_list[i];
627 temp_code_length = 1;
628
629 for (j = i + 1; j < long_code_length; j++) {
630 if ((huff_code_table[long_code_list[j]].code &
631 ((1 << ISAL_DECODE_LONG_BITS) - 1)) == first_bits) {
f91f0fd5 632 max_length = huff_code_table[long_code_list[j]].length;
224ce89b
WB
633 temp_code_list[temp_code_length] = long_code_list[j];
634 temp_code_length++;
635 }
636 }
637
638 memset(&result->long_code_lookup[long_code_lookup_length], 0x00,
f91f0fd5
TL
639 sizeof(*result->long_code_lookup) *
640 (1 << (max_length - ISAL_DECODE_LONG_BITS)));
224ce89b
WB
641
642 for (j = 0; j < temp_code_length; j++) {
f91f0fd5
TL
643 sym1_index = temp_code_list[j];
644 sym1 = index_to_sym(sym1_index);
645 sym1_len = huff_code_table[sym1_index].length;
646 sym1_code = huff_code_table[sym1_index].code_and_extra;
647
648 long_bits = sym1_code >> ISAL_DECODE_LONG_BITS;
649 min_increment = 1 << (sym1_len - ISAL_DECODE_LONG_BITS);
650
224ce89b
WB
651 for (; long_bits < (1 << (max_length - ISAL_DECODE_LONG_BITS));
652 long_bits += min_increment) {
653 result->long_code_lookup[long_code_lookup_length + long_bits] =
f91f0fd5 654 sym1 | (sym1_len << LARGE_LONG_CODE_LEN_OFFSET);
224ce89b 655 }
f91f0fd5
TL
656 huff_code_table[sym1_index].code_and_extra = INVALID_CODE;
657
224ce89b 658 }
f91f0fd5
TL
659 result->short_code_lookup[first_bits] = long_code_lookup_length |
660 (max_length << LARGE_SHORT_MAX_LEN_OFFSET) | LARGE_FLAG_BIT;
224ce89b 661 long_code_lookup_length += 1 << (max_length - ISAL_DECODE_LONG_BITS);
224ce89b
WB
662 }
663}
664
f91f0fd5
TL
665static void inline make_inflate_huff_code_dist(struct inflate_huff_code_small *result,
666 struct huff_code *huff_code_table,
667 uint32_t table_length, uint16_t * count,
668 uint32_t max_symbol)
224ce89b
WB
669{
670 int i, j, k;
f91f0fd5 671 uint32_t *long_code_list;
224ce89b
WB
672 uint32_t long_code_length = 0;
673 uint16_t temp_code_list[1 << (15 - ISAL_DECODE_SHORT_BITS)];
674 uint32_t temp_code_length;
675 uint32_t long_code_lookup_length = 0;
676 uint32_t max_length;
677 uint16_t first_bits;
678 uint32_t code_length;
679 uint16_t long_bits;
680 uint16_t min_increment;
681 uint32_t code_list[DIST_LEN + 2]; /* The +2 is for the extra codes in the static header */
682 uint32_t code_list_len;
f91f0fd5 683 uint32_t count_total[17], count_total_tmp[17];
224ce89b
WB
684 uint32_t insert_index;
685 uint32_t last_length;
686 uint32_t copy_size;
687 uint16_t *short_code_lookup = result->short_code_lookup;
f91f0fd5 688 uint32_t sym;
224ce89b
WB
689
690 count_total[0] = 0;
691 count_total[1] = 0;
692 for (i = 2; i < 17; i++)
693 count_total[i] = count_total[i - 1] + count[i - 1];
f91f0fd5 694 memcpy(count_total_tmp, count_total, sizeof(count_total_tmp));
224ce89b
WB
695
696 code_list_len = count_total[16];
697 if (code_list_len == 0) {
698 memset(result->short_code_lookup, 0, sizeof(result->short_code_lookup));
699 return;
700 }
701
702 for (i = 0; i < table_length; i++) {
703 code_length = huff_code_table[i].length;
f91f0fd5
TL
704 if (code_length == 0)
705 continue;
224ce89b 706
f91f0fd5
TL
707 insert_index = count_total_tmp[code_length];
708 code_list[insert_index] = i;
709 count_total_tmp[code_length]++;
710 }
224ce89b
WB
711
712 last_length = huff_code_table[code_list[0]].length;
713 if (last_length > ISAL_DECODE_SHORT_BITS)
f91f0fd5
TL
714 last_length = ISAL_DECODE_SHORT_BITS + 1;
715 copy_size = (1 << (last_length - 1));
224ce89b
WB
716
717 /* Initialize short_code_lookup, so invalid lookups process data */
718 memset(short_code_lookup, 0x00, copy_size * sizeof(*short_code_lookup));
719
f91f0fd5
TL
720 for (; last_length <= ISAL_DECODE_SHORT_BITS; last_length++) {
721 memcpy(short_code_lookup + copy_size, short_code_lookup,
722 sizeof(*short_code_lookup) * copy_size);
723 copy_size *= 2;
724
725 for (k = count_total[last_length]; k < count_total[last_length + 1]; k++) {
726 i = code_list[k];
727
728 if (i >= max_symbol) {
729 /* If the symbol is invalid, set code to be the
730 * length of the symbol and the code_length to 0
731 * to determine if there was enough input */
732 short_code_lookup[huff_code_table[i].code] =
733 huff_code_table[i].length;
734 continue;
735 }
224ce89b 736
f91f0fd5
TL
737 /* Set lookup table to return the current symbol concatenated
738 * with the code length when the first DECODE_LENGTH bits of the
739 * address are the same as the code for the current symbol. The
740 * first 9 bits are the code, bits 14:10 are the code length,
741 * bit 15 is a flag representing this is a symbol*/
742 short_code_lookup[huff_code_table[i].code] = i |
743 rfc_lookup_table.dist_extra_bit_count[i] << DIST_SYM_EXTRA_OFFSET |
744 (huff_code_table[i].length) << SMALL_SHORT_CODE_LEN_OFFSET;
224ce89b 745 }
f91f0fd5
TL
746 }
747
748 k = count_total[ISAL_DECODE_SHORT_BITS + 1];
749 long_code_list = &code_list[k];
750 long_code_length = code_list_len - k;
751 for (i = 0; i < long_code_length; i++) {
752 /*Set the look up table to point to a hint where the symbol can be found
753 * in the list of long codes and add the current symbol to the list of
754 * long codes. */
755 if (huff_code_table[long_code_list[i]].code == 0xFFFF)
756 continue;
224ce89b 757
f91f0fd5
TL
758 max_length = huff_code_table[long_code_list[i]].length;
759 first_bits =
760 huff_code_table[long_code_list[i]].code
761 & ((1 << ISAL_DECODE_SHORT_BITS) - 1);
224ce89b 762
f91f0fd5
TL
763 temp_code_list[0] = long_code_list[i];
764 temp_code_length = 1;
224ce89b 765
f91f0fd5
TL
766 for (j = i + 1; j < long_code_length; j++) {
767 if ((huff_code_table[long_code_list[j]].code &
768 ((1 << ISAL_DECODE_SHORT_BITS) - 1)) == first_bits) {
769 max_length = huff_code_table[long_code_list[j]].length;
770 temp_code_list[temp_code_length] = long_code_list[j];
771 temp_code_length++;
772 }
773 }
774
775 memset(&result->long_code_lookup[long_code_lookup_length], 0x00,
776 2 * (1 << (max_length - ISAL_DECODE_SHORT_BITS)));
777
778 for (j = 0; j < temp_code_length; j++) {
779 sym = temp_code_list[j];
780 code_length = huff_code_table[sym].length;
781 long_bits = huff_code_table[sym].code >> ISAL_DECODE_SHORT_BITS;
782 min_increment = 1 << (code_length - ISAL_DECODE_SHORT_BITS);
783 for (; long_bits < (1 << (max_length - ISAL_DECODE_SHORT_BITS));
784 long_bits += min_increment) {
785 if (sym >= max_symbol) {
786 /* If the symbol is invalid, set code to be the
787 * length of the symbol and the code_length to 0
788 * to determine if there was enough input */
789 result->long_code_lookup[long_code_lookup_length +
790 long_bits] = code_length;
791 continue;
792 }
793 result->long_code_lookup[long_code_lookup_length + long_bits] =
794 sym |
795 rfc_lookup_table.dist_extra_bit_count[sym] <<
796 DIST_SYM_EXTRA_OFFSET |
797 (code_length << SMALL_LONG_CODE_LEN_OFFSET);
798 }
799 huff_code_table[sym].code = 0xFFFF;
800 }
801 result->short_code_lookup[first_bits] = long_code_lookup_length |
802 (max_length << SMALL_SHORT_CODE_LEN_OFFSET) | SMALL_FLAG_BIT;
803 long_code_lookup_length += 1 << (max_length - ISAL_DECODE_SHORT_BITS);
804
805 }
806}
807
808static void inline make_inflate_huff_code_header(struct inflate_huff_code_small *result,
809 struct huff_code *huff_code_table,
810 uint32_t table_length, uint16_t * count,
811 uint32_t max_symbol)
812{
813 int i, j, k;
814 uint32_t *long_code_list;
815 uint32_t long_code_length = 0;
816 uint16_t temp_code_list[1 << (15 - ISAL_DECODE_SHORT_BITS)];
817 uint32_t temp_code_length;
818 uint32_t long_code_lookup_length = 0;
819 uint32_t max_length;
820 uint16_t first_bits;
821 uint32_t code_length;
822 uint16_t long_bits;
823 uint16_t min_increment;
824 uint32_t code_list[DIST_LEN + 2]; /* The +2 is for the extra codes in the static header */
825 uint32_t code_list_len;
826 uint32_t count_total[17], count_total_tmp[17];
827 uint32_t insert_index;
828 uint32_t last_length;
829 uint32_t copy_size;
830 uint16_t *short_code_lookup = result->short_code_lookup;
831
832 count_total[0] = 0;
833 count_total[1] = 0;
834 for (i = 2; i < 17; i++)
835 count_total[i] = count_total[i - 1] + count[i - 1];
836
837 memcpy(count_total_tmp, count_total, sizeof(count_total_tmp));
838
839 code_list_len = count_total[16];
840 if (code_list_len == 0) {
841 memset(result->short_code_lookup, 0, sizeof(result->short_code_lookup));
842 return;
843 }
844
845 for (i = 0; i < table_length; i++) {
846 code_length = huff_code_table[i].length;
847 if (code_length == 0)
848 continue;
849
850 insert_index = count_total_tmp[code_length];
851 code_list[insert_index] = i;
852 count_total_tmp[code_length]++;
224ce89b
WB
853 }
854
f91f0fd5
TL
855 last_length = huff_code_table[code_list[0]].length;
856 if (last_length > ISAL_DECODE_SHORT_BITS)
857 last_length = ISAL_DECODE_SHORT_BITS + 1;
858 copy_size = (1 << (last_length - 1));
859
860 /* Initialize short_code_lookup, so invalid lookups process data */
861 memset(short_code_lookup, 0x00, copy_size * sizeof(*short_code_lookup));
862
863 for (; last_length <= ISAL_DECODE_SHORT_BITS; last_length++) {
224ce89b
WB
864 memcpy(short_code_lookup + copy_size, short_code_lookup,
865 sizeof(*short_code_lookup) * copy_size);
f91f0fd5 866 copy_size *= 2;
224ce89b 867
f91f0fd5
TL
868 for (k = count_total[last_length]; k < count_total[last_length + 1]; k++) {
869 i = code_list[k];
224ce89b 870
f91f0fd5
TL
871 if (i >= max_symbol)
872 continue;
224ce89b 873
f91f0fd5
TL
874 /* Set lookup table to return the current symbol concatenated
875 * with the code length when the first DECODE_LENGTH bits of the
876 * address are the same as the code for the current symbol. The
877 * first 9 bits are the code, bits 14:10 are the code length,
878 * bit 15 is a flag representing this is a symbol*/
879 short_code_lookup[huff_code_table[i].code] =
880 i | (huff_code_table[i].length) << SMALL_SHORT_CODE_LEN_OFFSET;
881 }
224ce89b
WB
882 }
883
f91f0fd5
TL
884 k = count_total[ISAL_DECODE_SHORT_BITS + 1];
885 long_code_list = &code_list[k];
886 long_code_length = code_list_len - k;
224ce89b
WB
887 for (i = 0; i < long_code_length; i++) {
888 /*Set the look up table to point to a hint where the symbol can be found
889 * in the list of long codes and add the current symbol to the list of
890 * long codes. */
891 if (huff_code_table[long_code_list[i]].code == 0xFFFF)
892 continue;
893
894 max_length = huff_code_table[long_code_list[i]].length;
895 first_bits =
896 huff_code_table[long_code_list[i]].code
897 & ((1 << ISAL_DECODE_SHORT_BITS) - 1);
898
899 temp_code_list[0] = long_code_list[i];
900 temp_code_length = 1;
901
902 for (j = i + 1; j < long_code_length; j++) {
903 if ((huff_code_table[long_code_list[j]].code &
904 ((1 << ISAL_DECODE_SHORT_BITS) - 1)) == first_bits) {
905 if (max_length < huff_code_table[long_code_list[j]].length)
906 max_length = huff_code_table[long_code_list[j]].length;
907 temp_code_list[temp_code_length] = long_code_list[j];
908 temp_code_length++;
909 }
910 }
911
912 memset(&result->long_code_lookup[long_code_lookup_length], 0x00,
913 2 * (1 << (max_length - ISAL_DECODE_SHORT_BITS)));
914
915 for (j = 0; j < temp_code_length; j++) {
916 code_length = huff_code_table[temp_code_list[j]].length;
917 long_bits =
918 huff_code_table[temp_code_list[j]].code >> ISAL_DECODE_SHORT_BITS;
919 min_increment = 1 << (code_length - ISAL_DECODE_SHORT_BITS);
920 for (; long_bits < (1 << (max_length - ISAL_DECODE_SHORT_BITS));
921 long_bits += min_increment) {
922 result->long_code_lookup[long_code_lookup_length + long_bits] =
f91f0fd5
TL
923 temp_code_list[j] |
924 (code_length << SMALL_LONG_CODE_LEN_OFFSET);
224ce89b
WB
925 }
926 huff_code_table[temp_code_list[j]].code = 0xFFFF;
927 }
f91f0fd5
TL
928 result->short_code_lookup[first_bits] = long_code_lookup_length |
929 (max_length << SMALL_SHORT_CODE_LEN_OFFSET) | SMALL_FLAG_BIT;
224ce89b
WB
930 long_code_lookup_length += 1 << (max_length - ISAL_DECODE_SHORT_BITS);
931
932 }
933}
934
935/* Sets the inflate_huff_codes in state to be the huffcodes corresponding to the
936 * deflate static header */
937static int inline setup_static_header(struct inflate_state *state)
938{
f91f0fd5
TL
939#ifdef ISAL_STATIC_INFLATE_TABLE
940 memcpy(&state->lit_huff_code, &static_lit_huff_code, sizeof(static_lit_huff_code));
941 memcpy(&state->dist_huff_code, &static_dist_huff_code, sizeof(static_dist_huff_code));
942#else
943
944#ifndef NO_STATIC_INFLATE_H
945# warning "Defaulting to static inflate table fallback."
946# warning "For best performance, run generate_static_inflate, replace static_inflate.h, and recompile"
947#endif
224ce89b 948 int i;
f91f0fd5 949 struct huff_code lit_code[LIT_LEN_ELEMS];
224ce89b 950 struct huff_code dist_code[DIST_LEN + 2];
f91f0fd5 951 uint32_t multisym = SINGLE_SYM_FLAG, max_dist = DIST_LEN;
224ce89b
WB
952 /* These tables are based on the static huffman tree described in RFC
953 * 1951 */
f91f0fd5
TL
954 uint16_t lit_count[MAX_LIT_LEN_COUNT] = {
955 0, 0, 0, 0, 0, 0, 0, 24, 152, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
956 };
957
958 uint16_t lit_expand_count[MAX_LIT_LEN_COUNT] = {
959 0, 0, 0, 0, 0, 0, 0, -15, 1, 16, 32, 48, 16, 128, 0, 0, 0, 0, 0, 0, 0, 0
224ce89b
WB
960 };
961 uint16_t dist_count[16] = {
962 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
963 };
f91f0fd5 964 uint32_t code_list[LIT_LEN_ELEMS + 2]; /* The +2 is for the extra codes in the static header */
224ce89b
WB
965 /* These for loops set the code lengths for the static literal/length
966 * and distance codes defined in the deflate standard RFC 1951 */
967 for (i = 0; i < 144; i++)
968 lit_code[i].length = 8;
969
970 for (i = 144; i < 256; i++)
971 lit_code[i].length = 9;
972
973 for (i = 256; i < 280; i++)
974 lit_code[i].length = 7;
975
976 for (i = 280; i < LIT_LEN + 2; i++)
977 lit_code[i].length = 8;
978
979 for (i = 0; i < DIST_LEN + 2; i++)
980 dist_code[i].length = 5;
981
f91f0fd5
TL
982 set_and_expand_lit_len_huffcode(lit_code, LIT_LEN + 2, lit_count, lit_expand_count,
983 code_list);
224ce89b 984
f91f0fd5
TL
985 set_codes(dist_code, DIST_LEN + 2, dist_count);
986
987 make_inflate_huff_code_lit_len(&state->lit_huff_code, lit_code, LIT_LEN_ELEMS,
988 lit_count, code_list, multisym);
989
990 if (state->hist_bits && state->hist_bits < 15)
991 max_dist = 2 * state->hist_bits;
992
993 make_inflate_huff_code_dist(&state->dist_huff_code, dist_code, DIST_LEN + 2,
994 dist_count, max_dist);
995#endif
224ce89b
WB
996 state->block_state = ISAL_BLOCK_CODED;
997
998 return 0;
999}
1000
1001/* Decodes the next symbol symbol in in_buffer using the huff code defined by
f91f0fd5
TL
1002 * huff_code and returns the value in next_lits and sym_count */
1003static void inline decode_next_lit_len(uint32_t * next_lits, uint32_t * sym_count,
1004 struct inflate_state *state,
1005 struct inflate_huff_code_large *huff_code)
224ce89b 1006{
f91f0fd5
TL
1007 uint32_t next_bits;
1008 uint32_t next_sym;
224ce89b
WB
1009 uint32_t bit_count;
1010 uint32_t bit_mask;
1011
1012 if (state->read_in_length <= ISAL_DEF_MAX_CODE_LEN)
1013 inflate_in_load(state, 0);
1014
1015 next_bits = state->read_in & ((1 << ISAL_DECODE_LONG_BITS) - 1);
1016
1017 /* next_sym is a possible symbol decoded from next_bits. If bit 15 is 0,
1018 * next_code is a symbol. Bits 9:0 represent the symbol, and bits 14:10
1019 * represent the length of that symbols huffman code. If next_sym is not
1020 * a symbol, it provides a hint of where the large symbols containin
1021 * this code are located. Note the hint is at largest the location the
1022 * first actual symbol in the long code list.*/
1023 next_sym = huff_code->short_code_lookup[next_bits];
1024
f91f0fd5 1025 if ((next_sym & LARGE_FLAG_BIT) == 0) {
224ce89b
WB
1026 /* Return symbol found if next_code is a complete huffman code
1027 * and shift in buffer over by the length of the next_code */
f91f0fd5 1028 bit_count = next_sym >> LARGE_SHORT_CODE_LEN_OFFSET;
224ce89b
WB
1029 state->read_in >>= bit_count;
1030 state->read_in_length -= bit_count;
1031
1032 if (bit_count == 0)
f91f0fd5 1033 next_sym = INVALID_SYMBOL;
224ce89b 1034
f91f0fd5
TL
1035 *sym_count = (next_sym >> LARGE_SYM_COUNT_OFFSET) & LARGE_SYM_COUNT_MASK;
1036 *next_lits = next_sym & LARGE_SHORT_SYM_MASK;
224ce89b
WB
1037
1038 } else {
f91f0fd5 1039 /* If a symbol is not found, do a lookup in the long code
224ce89b 1040 * list starting from the hint in next_sym */
f91f0fd5 1041 bit_mask = next_sym >> LARGE_SHORT_MAX_LEN_OFFSET;
224ce89b
WB
1042 bit_mask = (1 << bit_mask) - 1;
1043 next_bits = state->read_in & bit_mask;
1044 next_sym =
f91f0fd5 1045 huff_code->long_code_lookup[(next_sym & LARGE_SHORT_SYM_MASK) +
224ce89b 1046 (next_bits >> ISAL_DECODE_LONG_BITS)];
f91f0fd5 1047 bit_count = next_sym >> LARGE_LONG_CODE_LEN_OFFSET;
224ce89b
WB
1048 state->read_in >>= bit_count;
1049 state->read_in_length -= bit_count;
1050
1051 if (bit_count == 0)
f91f0fd5 1052 next_sym = INVALID_SYMBOL;
224ce89b 1053
f91f0fd5
TL
1054 *sym_count = 1;
1055 *next_lits = next_sym & LARGE_LONG_SYM_MASK;
224ce89b
WB
1056 }
1057}
1058
f91f0fd5
TL
1059static uint16_t inline decode_next_dist(struct inflate_state *state,
1060 struct inflate_huff_code_small *huff_code)
224ce89b
WB
1061{
1062 uint16_t next_bits;
1063 uint16_t next_sym;
1064 uint32_t bit_count;
1065 uint32_t bit_mask;
1066
1067 if (state->read_in_length <= ISAL_DEF_MAX_CODE_LEN)
1068 inflate_in_load(state, 0);
1069
1070 next_bits = state->read_in & ((1 << ISAL_DECODE_SHORT_BITS) - 1);
1071
1072 /* next_sym is a possible symbol decoded from next_bits. If bit 15 is 0,
1073 * next_code is a symbol. Bits 9:0 represent the symbol, and bits 14:10
1074 * represent the length of that symbols huffman code. If next_sym is not
1075 * a symbol, it provides a hint of where the large symbols containin
1076 * this code are located. Note the hint is at largest the location the
1077 * first actual symbol in the long code list.*/
1078 next_sym = huff_code->short_code_lookup[next_bits];
1079
f91f0fd5 1080 if ((next_sym & SMALL_FLAG_BIT) == 0) {
224ce89b
WB
1081 /* Return symbol found if next_code is a complete huffman code
1082 * and shift in buffer over by the length of the next_code */
f91f0fd5 1083 bit_count = next_sym >> SMALL_SHORT_CODE_LEN_OFFSET;
224ce89b
WB
1084 state->read_in >>= bit_count;
1085 state->read_in_length -= bit_count;
1086
f91f0fd5
TL
1087 if (bit_count == 0) {
1088 state->read_in_length -= next_sym;
1089 next_sym = INVALID_SYMBOL;
1090 }
224ce89b 1091
f91f0fd5 1092 return next_sym & DIST_SYM_MASK;
224ce89b
WB
1093
1094 } else {
1095 /* If a symbol is not found, perform a linear search of the long code
1096 * list starting from the hint in next_sym */
f91f0fd5 1097 bit_mask = (next_sym - SMALL_FLAG_BIT) >> SMALL_SHORT_CODE_LEN_OFFSET;
224ce89b
WB
1098 bit_mask = (1 << bit_mask) - 1;
1099 next_bits = state->read_in & bit_mask;
1100 next_sym =
f91f0fd5 1101 huff_code->long_code_lookup[(next_sym & SMALL_SHORT_SYM_MASK) +
224ce89b 1102 (next_bits >> ISAL_DECODE_SHORT_BITS)];
f91f0fd5 1103 bit_count = next_sym >> SMALL_LONG_CODE_LEN_OFFSET;
224ce89b
WB
1104 state->read_in >>= bit_count;
1105 state->read_in_length -= bit_count;
224ce89b 1106
f91f0fd5
TL
1107 if (bit_count == 0) {
1108 state->read_in_length -= next_sym;
1109 next_sym = INVALID_SYMBOL;
1110 }
1111
1112 return next_sym & DIST_SYM_MASK;
224ce89b
WB
1113 }
1114}
1115
f91f0fd5
TL
1116static uint16_t inline decode_next_header(struct inflate_state *state,
1117 struct inflate_huff_code_small *huff_code)
224ce89b 1118{
f91f0fd5
TL
1119 uint16_t next_bits;
1120 uint16_t next_sym;
1121 uint32_t bit_count;
1122 uint32_t bit_mask;
224ce89b 1123
f91f0fd5
TL
1124 if (state->read_in_length <= ISAL_DEF_MAX_CODE_LEN)
1125 inflate_in_load(state, 0);
1126
1127 next_bits = state->read_in & ((1 << ISAL_DECODE_SHORT_BITS) - 1);
1128
1129 /* next_sym is a possible symbol decoded from next_bits. If bit 15 is 0,
1130 * next_code is a symbol. Bits 9:0 represent the symbol, and bits 14:10
1131 * represent the length of that symbols huffman code. If next_sym is not
1132 * a symbol, it provides a hint of where the large symbols containin
1133 * this code are located. Note the hint is at largest the location the
1134 * first actual symbol in the long code list.*/
1135 next_sym = huff_code->short_code_lookup[next_bits];
1136
1137 if ((next_sym & SMALL_FLAG_BIT) == 0) {
1138 /* Return symbol found if next_code is a complete huffman code
1139 * and shift in buffer over by the length of the next_code */
1140 bit_count = next_sym >> SMALL_SHORT_CODE_LEN_OFFSET;
1141 state->read_in >>= bit_count;
1142 state->read_in_length -= bit_count;
1143
1144 if (bit_count == 0)
1145 next_sym = INVALID_SYMBOL;
1146
1147 return next_sym & SMALL_SHORT_SYM_MASK;
1148
1149 } else {
1150 /* If a symbol is not found, perform a linear search of the long code
1151 * list starting from the hint in next_sym */
1152 bit_mask = (next_sym - SMALL_FLAG_BIT) >> SMALL_SHORT_CODE_LEN_OFFSET;
1153 bit_mask = (1 << bit_mask) - 1;
1154 next_bits = state->read_in & bit_mask;
1155 next_sym =
1156 huff_code->long_code_lookup[(next_sym & SMALL_SHORT_SYM_MASK) +
1157 (next_bits >> ISAL_DECODE_SHORT_BITS)];
1158 bit_count = next_sym >> SMALL_LONG_CODE_LEN_OFFSET;
1159 state->read_in >>= bit_count;
1160 state->read_in_length -= bit_count;
1161 return next_sym & SMALL_LONG_SYM_MASK;
1162
1163 }
1164}
1165
1166/* Reads data from the in_buffer and sets the huff code corresponding to that
1167 * data */
1168static int inline setup_dynamic_header(struct inflate_state *state)
1169{
1170 int i, j;
1171 struct huff_code code_huff[CODE_LEN_CODES];
1172 struct huff_code lit_and_dist_huff[LIT_LEN_ELEMS];
1173 struct huff_code *previous = NULL, *current, *end, rep_code;
1174 struct inflate_huff_code_small inflate_code_huff;
1175 uint64_t hclen, hdist, hlit;
1176 uint16_t code_count[16], lit_count[MAX_LIT_LEN_COUNT],
1177 lit_expand_count[MAX_LIT_LEN_COUNT], dist_count[16];
1178 uint16_t *count;
1179 uint16_t symbol;
1180 uint32_t multisym = DEFAULT_SYM_FLAG, length, max_dist = DIST_LEN;
1181 struct huff_code *code;
1182 uint64_t flag = 0;
1183
1184 int extra_count;
1185 uint32_t code_list[LIT_LEN_ELEMS + 2]; /* The +2 is for the extra codes in the static header */
1186
1187 /* This order is defined in RFC 1951 page 13 */
1188 const uint8_t code_length_order[CODE_LEN_CODES] = {
224ce89b 1189 0x10, 0x11, 0x12, 0x00, 0x08, 0x07, 0x09, 0x06,
f91f0fd5 1190 0x0a, 0x05, 0x0b, 0x04, 0x0c, 0x03, 0x0d, 0x02, 0x0e, 0x01, 0x0f
224ce89b
WB
1191 };
1192
f91f0fd5
TL
1193 if (state->bfinal && state->avail_in <= SINGLE_SYM_THRESH) {
1194 multisym = SINGLE_SYM_FLAG;
1195 } else if (state->bfinal && state->avail_in <= DOUBLE_SYM_THRESH) {
1196 multisym = DOUBLE_SYM_FLAG;
1197 }
1198
224ce89b
WB
1199 memset(code_count, 0, sizeof(code_count));
1200 memset(lit_count, 0, sizeof(lit_count));
f91f0fd5 1201 memset(lit_expand_count, 0, sizeof(lit_expand_count));
224ce89b
WB
1202 memset(dist_count, 0, sizeof(dist_count));
1203 memset(code_huff, 0, sizeof(code_huff));
1204 memset(lit_and_dist_huff, 0, sizeof(lit_and_dist_huff));
1205
1206 /* These variables are defined in the deflate standard, RFC 1951 */
f91f0fd5
TL
1207 inflate_in_load(state, 0);
1208 if (state->read_in_length < 14)
1209 return ISAL_END_INPUT;
1210
1211 hlit = inflate_in_read_bits_unsafe(state, 5);
1212 hdist = inflate_in_read_bits_unsafe(state, 5);
1213 hclen = inflate_in_read_bits_unsafe(state, 4);
224ce89b
WB
1214
1215 if (hlit > 29 || hdist > 29 || hclen > 15)
1216 return ISAL_INVALID_BLOCK;
1217
1218 /* Create the code huffman code for decoding the lit/len and dist huffman codes */
f91f0fd5
TL
1219 for (i = 0; i < 4; i++) {
1220 code = &code_huff[code_length_order[i]];
1221 length = inflate_in_read_bits_unsafe(state, 3);
1222 write_huff_code(code, 0, length);
1223 code_count[length] += 1;
1224 flag |= length;
224ce89b
WB
1225 }
1226
f91f0fd5
TL
1227 inflate_in_load(state, 0);
1228
1229 for (i = 4; i < hclen + 4; i++) {
1230 code = &code_huff[code_length_order[i]];
1231 length = inflate_in_read_bits_unsafe(state, 3);
1232 write_huff_code(code, 0, length);
1233 code_count[length] += 1;
1234 flag |= length;
224ce89b
WB
1235 }
1236
1237 if (state->read_in_length < 0)
1238 return ISAL_END_INPUT;
1239
f91f0fd5 1240 if (!flag || set_codes(code_huff, CODE_LEN_CODES, code_count))
224ce89b
WB
1241 return ISAL_INVALID_BLOCK;
1242
f91f0fd5
TL
1243 make_inflate_huff_code_header(&inflate_code_huff, code_huff, CODE_LEN_CODES,
1244 code_count, CODE_LEN_CODES);
224ce89b
WB
1245
1246 /* Decode the lit/len and dist huffman codes using the code huffman code */
1247 count = lit_count;
1248 current = lit_and_dist_huff;
1249 end = lit_and_dist_huff + LIT_LEN + hdist + 1;
1250
1251 while (current < end) {
f91f0fd5 1252 symbol = decode_next_header(state, &inflate_code_huff);
224ce89b
WB
1253
1254 if (state->read_in_length < 0) {
1255 if (current > &lit_and_dist_huff[256]
1256 && lit_and_dist_huff[256].length <= 0)
1257 return ISAL_INVALID_BLOCK;
1258 return ISAL_END_INPUT;
1259 }
1260
1261 if (symbol < 16) {
1262 /* If a length is found, update the current lit/len/dist
1263 * to have length symbol */
f91f0fd5
TL
1264 if (current == lit_and_dist_huff + LIT_TABLE_SIZE + hlit) {
1265 /* Switch code upon completion of lit_len table */
1266 current = lit_and_dist_huff + LIT_LEN;
1267 count = dist_count;
1268 }
224ce89b 1269 count[symbol]++;
f91f0fd5 1270 write_huff_code(current, 0, symbol);
224ce89b
WB
1271 previous = current;
1272 current++;
1273
f91f0fd5
TL
1274 if (symbol == 0 // No symbol
1275 || (previous >= lit_and_dist_huff + LIT_TABLE_SIZE + hlit) // Dist table
1276 || (previous < lit_and_dist_huff + 264)) // Lit/Len with no extra bits
1277 continue;
1278
1279 extra_count =
1280 rfc_lookup_table.len_extra_bit_count[previous - LIT_TABLE_SIZE -
1281 lit_and_dist_huff];
1282 lit_expand_count[symbol]--;
1283 lit_expand_count[symbol + extra_count] += (1 << extra_count);
1284
224ce89b
WB
1285 } else if (symbol == 16) {
1286 /* If a repeat length is found, update the next repeat
1287 * length lit/len/dist elements to have the value of the
1288 * repeated length */
224ce89b
WB
1289
1290 i = 3 + inflate_in_read_bits(state, 2);
1291
f91f0fd5 1292 if (current + i > end || previous == NULL)
224ce89b
WB
1293 return ISAL_INVALID_BLOCK;
1294
f91f0fd5 1295 rep_code = *previous;
224ce89b 1296 for (j = 0; j < i; j++) {
f91f0fd5
TL
1297 if (current == lit_and_dist_huff + LIT_TABLE_SIZE + hlit) {
1298 /* Switch code upon completion of lit_len table */
224ce89b
WB
1299 current = lit_and_dist_huff + LIT_LEN;
1300 count = dist_count;
f91f0fd5 1301 }
224ce89b 1302
f91f0fd5
TL
1303 *current = rep_code;
1304 count[rep_code.length]++;
1305 previous = current;
1306 current++;
1307
1308 if (rep_code.length == 0 // No symbol
1309 || (previous >= lit_and_dist_huff + LIT_TABLE_SIZE + hlit) // Dist table
1310 || (previous < lit_and_dist_huff + 264)) // Lit/Len with no extra
1311 continue;
1312
1313 extra_count =
1314 rfc_lookup_table.len_extra_bit_count
1315 [previous - lit_and_dist_huff - LIT_TABLE_SIZE];
1316 lit_expand_count[rep_code.length]--;
1317 lit_expand_count[rep_code.length +
1318 extra_count] += (1 << extra_count);
224ce89b 1319
f91f0fd5 1320 }
224ce89b
WB
1321 } else if (symbol == 17) {
1322 /* If a repeat zeroes if found, update then next
1323 * repeated zeroes length lit/len/dist elements to have
1324 * length 0. */
1325 i = 3 + inflate_in_read_bits(state, 3);
1326
f91f0fd5
TL
1327 current = current + i;
1328 previous = current - 1;
224ce89b 1329
f91f0fd5
TL
1330 if (count != dist_count
1331 && current > lit_and_dist_huff + LIT_TABLE_SIZE + hlit) {
1332 /* Switch code upon completion of lit_len table */
1333 current += LIT_LEN - LIT_TABLE_SIZE - hlit;
1334 count = dist_count;
1335 if (current > lit_and_dist_huff + LIT_LEN)
1336 previous = current - 1;
224ce89b
WB
1337 }
1338
1339 } else if (symbol == 18) {
1340 /* If a repeat zeroes if found, update then next
1341 * repeated zeroes length lit/len/dist elements to have
1342 * length 0. */
1343 i = 11 + inflate_in_read_bits(state, 7);
1344
f91f0fd5
TL
1345 current = current + i;
1346 previous = current - 1;
224ce89b 1347
f91f0fd5
TL
1348 if (count != dist_count
1349 && current > lit_and_dist_huff + LIT_TABLE_SIZE + hlit) {
1350 /* Switch code upon completion of lit_len table */
1351 current += LIT_LEN - LIT_TABLE_SIZE - hlit;
1352 count = dist_count;
1353 if (current > lit_and_dist_huff + LIT_LEN)
1354 previous = current - 1;
224ce89b 1355 }
f91f0fd5 1356
224ce89b
WB
1357 } else
1358 return ISAL_INVALID_BLOCK;
1359
1360 }
1361
1362 if (current > end || lit_and_dist_huff[256].length <= 0)
1363 return ISAL_INVALID_BLOCK;
1364
1365 if (state->read_in_length < 0)
1366 return ISAL_END_INPUT;
1367
f91f0fd5
TL
1368 if (set_codes(&lit_and_dist_huff[LIT_LEN], DIST_LEN, dist_count))
1369 return ISAL_INVALID_BLOCK;
1370
1371 if (state->hist_bits && state->hist_bits < 15)
1372 max_dist = 2 * state->hist_bits;
1373
1374 make_inflate_huff_code_dist(&state->dist_huff_code, &lit_and_dist_huff[LIT_LEN],
1375 DIST_LEN, dist_count, max_dist);
1376
1377 if (set_and_expand_lit_len_huffcode
1378 (lit_and_dist_huff, LIT_LEN, lit_count, lit_expand_count, code_list))
1379 return ISAL_INVALID_BLOCK;
1380
1381 make_inflate_huff_code_lit_len(&state->lit_huff_code, lit_and_dist_huff, LIT_LEN_ELEMS,
1382 lit_count, code_list, multisym);
224ce89b
WB
1383
1384 state->block_state = ISAL_BLOCK_CODED;
1385
1386 return 0;
1387}
1388
1389/* Reads in the header pointed to by in_stream and sets up state to reflect that
1390 * header information*/
f91f0fd5 1391static int read_header(struct inflate_state *state)
224ce89b
WB
1392{
1393 uint8_t bytes;
1394 uint32_t btype;
1395 uint16_t len, nlen;
1396 int ret = 0;
1397
1398 /* btype and bfinal are defined in RFC 1951, bfinal represents whether
1399 * the current block is the end of block, and btype represents the
1400 * encoding method on the current block. */
1401
1402 state->bfinal = inflate_in_read_bits(state, 1);
1403 btype = inflate_in_read_bits(state, 2);
1404
1405 if (state->read_in_length < 0)
1406 ret = ISAL_END_INPUT;
1407
1408 else if (btype == 0) {
1409 inflate_in_load(state, 40);
1410 bytes = state->read_in_length / 8;
1411
1412 if (bytes < 4)
1413 return ISAL_END_INPUT;
1414
1415 state->read_in >>= state->read_in_length % 8;
1416 state->read_in_length = bytes * 8;
1417
1418 len = state->read_in & 0xFFFF;
1419 state->read_in >>= 16;
1420 nlen = state->read_in & 0xFFFF;
1421 state->read_in >>= 16;
1422 state->read_in_length -= 32;
1423
224ce89b
WB
1424 /* Check if len and nlen match */
1425 if (len != (~nlen & 0xffff))
1426 return ISAL_INVALID_BLOCK;
1427
1428 state->type0_block_len = len;
1429 state->block_state = ISAL_BLOCK_TYPE0;
1430
1431 ret = 0;
1432
1433 } else if (btype == 1)
1434 ret = setup_static_header(state);
1435
1436 else if (btype == 2)
1437 ret = setup_dynamic_header(state);
1438
1439 else
1440 ret = ISAL_INVALID_BLOCK;
1441
1442 return ret;
1443}
1444
1445/* Reads in the header pointed to by in_stream and sets up state to reflect that
1446 * header information*/
f91f0fd5 1447static int read_header_stateful(struct inflate_state *state)
224ce89b
WB
1448{
1449 uint64_t read_in_start = state->read_in;
1450 int32_t read_in_length_start = state->read_in_length;
1451 uint8_t *next_in_start = state->next_in;
1452 uint32_t avail_in_start = state->avail_in;
1453 int block_state_start = state->block_state;
1454 int ret;
1455 int copy_size;
1456 int bytes_read;
1457
1458 if (block_state_start == ISAL_BLOCK_HDR) {
1459 /* Setup so read_header decodes data in tmp_in_buffer */
1460 copy_size = ISAL_DEF_MAX_HDR_SIZE - state->tmp_in_size;
1461 if (copy_size > state->avail_in)
1462 copy_size = state->avail_in;
1463
1464 memcpy(&state->tmp_in_buffer[state->tmp_in_size], state->next_in, copy_size);
1465 state->next_in = state->tmp_in_buffer;
1466 state->avail_in = state->tmp_in_size + copy_size;
1467 }
1468
1469 ret = read_header(state);
1470
1471 if (block_state_start == ISAL_BLOCK_HDR) {
1472 /* Setup so state is restored to a valid state */
1473 bytes_read = state->next_in - state->tmp_in_buffer - state->tmp_in_size;
1474 if (bytes_read < 0)
1475 bytes_read = 0;
1476 state->next_in = next_in_start + bytes_read;
1477 state->avail_in = avail_in_start - bytes_read;
1478 }
1479
1480 if (ret == ISAL_END_INPUT) {
1481 /* Save off data so header can be decoded again with more data */
1482 state->read_in = read_in_start;
1483 state->read_in_length = read_in_length_start;
1484 memcpy(&state->tmp_in_buffer[state->tmp_in_size], next_in_start,
1485 avail_in_start);
1486 state->tmp_in_size += avail_in_start;
1487 state->avail_in = 0;
1488 state->next_in = next_in_start + avail_in_start;
1489 state->block_state = ISAL_BLOCK_HDR;
1490 } else
1491 state->tmp_in_size = 0;
1492
1493 return ret;
1494
1495}
1496
1497static int inline decode_literal_block(struct inflate_state *state)
1498{
1499 uint32_t len = state->type0_block_len;
f91f0fd5 1500 uint32_t bytes = state->read_in_length / 8;
224ce89b
WB
1501 /* If the block is uncompressed, perform a memcopy while
1502 * updating state data */
f91f0fd5 1503 state->block_state = state->bfinal ? ISAL_BLOCK_INPUT_DONE : ISAL_BLOCK_NEW_HDR;
224ce89b
WB
1504
1505 if (state->avail_out < len) {
1506 len = state->avail_out;
1507 state->block_state = ISAL_BLOCK_TYPE0;
1508 }
1509
f91f0fd5
TL
1510 if (state->avail_in + bytes < len) {
1511 len = state->avail_in + bytes;
224ce89b
WB
1512 state->block_state = ISAL_BLOCK_TYPE0;
1513 }
f91f0fd5
TL
1514 if (state->read_in_length) {
1515 if (len >= bytes) {
1516 memcpy(state->next_out, &state->read_in, bytes);
1517
1518 state->next_out += bytes;
1519 state->avail_out -= bytes;
1520 state->total_out += bytes;
1521 state->type0_block_len -= bytes;
1522
1523 state->read_in = 0;
1524 state->read_in_length = 0;
1525 len -= bytes;
1526 bytes = 0;
1527
1528 } else {
1529 memcpy(state->next_out, &state->read_in, len);
1530
1531 state->next_out += len;
1532 state->avail_out -= len;
1533 state->total_out += len;
1534 state->type0_block_len -= len;
1535
1536 state->read_in >>= 8 * len;
1537 state->read_in_length -= 8 * len;
1538 bytes -= len;
1539 len = 0;
1540 }
1541 }
224ce89b
WB
1542 memcpy(state->next_out, state->next_in, len);
1543
1544 state->next_out += len;
1545 state->avail_out -= len;
1546 state->total_out += len;
1547 state->next_in += len;
1548 state->avail_in -= len;
1549 state->type0_block_len -= len;
1550
f91f0fd5 1551 if (state->avail_in + bytes == 0 && state->block_state != ISAL_BLOCK_INPUT_DONE)
224ce89b
WB
1552 return ISAL_END_INPUT;
1553
1554 if (state->avail_out == 0 && state->type0_block_len > 0)
1555 return ISAL_OUT_OVERFLOW;
1556
1557 return 0;
1558
1559}
1560
1561/* Decodes the next block if it was encoded using a huffman code */
f91f0fd5 1562int decode_huffman_code_block_stateless_base(struct inflate_state *state, uint8_t * start_out)
224ce89b
WB
1563{
1564 uint16_t next_lit;
1565 uint8_t next_dist;
1566 uint32_t repeat_length;
1567 uint32_t look_back_dist;
1568 uint64_t read_in_tmp;
1569 int32_t read_in_length_tmp;
f91f0fd5
TL
1570 uint8_t *next_in_tmp, *next_out_tmp;
1571 uint32_t avail_in_tmp, avail_out_tmp, total_out_tmp;
1572 uint32_t next_lits, sym_count;
1573 struct rfc1951_tables *rfc = &rfc_lookup_table;
224ce89b
WB
1574
1575 state->copy_overflow_length = 0;
1576 state->copy_overflow_distance = 0;
1577
1578 while (state->block_state == ISAL_BLOCK_CODED) {
1579 /* While not at the end of block, decode the next
1580 * symbol */
1581 inflate_in_load(state, 0);
1582
1583 read_in_tmp = state->read_in;
1584 read_in_length_tmp = state->read_in_length;
1585 next_in_tmp = state->next_in;
1586 avail_in_tmp = state->avail_in;
f91f0fd5
TL
1587 next_out_tmp = state->next_out;
1588 avail_out_tmp = state->avail_out;
1589 total_out_tmp = state->total_out;
224ce89b 1590
f91f0fd5
TL
1591 decode_next_lit_len(&next_lits, &sym_count, state, &state->lit_huff_code);
1592
1593 if (sym_count == 0)
1594 return ISAL_INVALID_SYMBOL;
224ce89b
WB
1595
1596 if (state->read_in_length < 0) {
1597 state->read_in = read_in_tmp;
1598 state->read_in_length = read_in_length_tmp;
1599 state->next_in = next_in_tmp;
1600 state->avail_in = avail_in_tmp;
1601 return ISAL_END_INPUT;
1602 }
1603
f91f0fd5
TL
1604 while (sym_count > 0) {
1605 next_lit = next_lits & 0xffff;
1606 if (next_lit < 256 || sym_count > 1) {
1607 /* If the next symbol is a literal,
1608 * write out the symbol and update state
1609 * data accordingly. */
1610 if (state->avail_out < 1) {
1611 state->write_overflow_lits = next_lits;
1612 state->write_overflow_len = sym_count;
1613 next_lits = next_lits >> (8 * (sym_count - 1));
1614 sym_count = 1;
1615
1616 if (next_lits < 256)
1617 return ISAL_OUT_OVERFLOW;
1618 else if (next_lits == 256) {
1619 state->write_overflow_len -= 1;
1620 state->block_state = state->bfinal ?
1621 ISAL_BLOCK_INPUT_DONE : ISAL_BLOCK_NEW_HDR;
1622 return ISAL_OUT_OVERFLOW;
1623 } else {
1624 state->write_overflow_len -= 1;
1625 continue;
1626 }
1627 }
224ce89b 1628
f91f0fd5
TL
1629 *state->next_out = next_lit;
1630 state->next_out++;
1631 state->avail_out--;
1632 state->total_out++;
1633
1634 } else if (next_lit == 256) {
1635 /* If the next symbol is the end of
1636 * block, update the state data
1637 * accordingly */
1638 state->block_state = state->bfinal ?
1639 ISAL_BLOCK_INPUT_DONE : ISAL_BLOCK_NEW_HDR;
1640
1641 } else if (next_lit <= MAX_LIT_LEN_SYM) {
1642 /* Else if the next symbol is a repeat
1643 * length, read in the length extra
1644 * bits, the distance code, the distance
1645 * extra bits. Then write out the
1646 * corresponding data and update the
1647 * state data accordingly*/
1648 repeat_length = next_lit - 254;
1649 next_dist = decode_next_dist(state, &state->dist_huff_code);
1650
1651 if (state->read_in_length >= 0) {
1652 if (next_dist >= DIST_LEN)
1653 return ISAL_INVALID_SYMBOL;
1654
1655 look_back_dist = rfc->dist_start[next_dist] +
1656 inflate_in_read_bits(state,
1657 rfc->dist_extra_bit_count
1658 [next_dist]);
1659 }
224ce89b 1660
f91f0fd5
TL
1661 if (state->read_in_length < 0) {
1662 state->read_in = read_in_tmp;
1663 state->read_in_length = read_in_length_tmp;
1664 state->next_in = next_in_tmp;
1665 state->avail_in = avail_in_tmp;
1666 state->next_out = next_out_tmp;
1667 state->avail_out = avail_out_tmp;
1668 state->total_out = total_out_tmp;
1669 state->write_overflow_lits = 0;
1670 state->write_overflow_len = 0;
1671 return ISAL_END_INPUT;
1672 }
224ce89b 1673
f91f0fd5
TL
1674 if (state->next_out - look_back_dist < start_out)
1675 return ISAL_INVALID_LOOKBACK;
224ce89b 1676
f91f0fd5
TL
1677 if (state->avail_out < repeat_length) {
1678 state->copy_overflow_length =
1679 repeat_length - state->avail_out;
1680 state->copy_overflow_distance = look_back_dist;
1681 repeat_length = state->avail_out;
1682 }
224ce89b 1683
f91f0fd5
TL
1684 if (look_back_dist > repeat_length)
1685 memcpy(state->next_out,
1686 state->next_out - look_back_dist,
1687 repeat_length);
1688 else
1689 byte_copy(state->next_out, look_back_dist,
1690 repeat_length);
1691
1692 state->next_out += repeat_length;
1693 state->avail_out -= repeat_length;
1694 state->total_out += repeat_length;
1695
1696 if (state->copy_overflow_length > 0)
1697 return ISAL_OUT_OVERFLOW;
1698 } else
1699 /* Else the read in bits do not
1700 * correspond to any valid symbol */
1701 return ISAL_INVALID_SYMBOL;
224ce89b 1702
f91f0fd5
TL
1703 next_lits >>= 8;
1704 sym_count--;
1705 }
224ce89b 1706
224ce89b
WB
1707 }
1708 return 0;
1709}
1710
1711void isal_inflate_init(struct inflate_state *state)
1712{
1713
1714 state->read_in = 0;
1715 state->read_in_length = 0;
1716 state->next_in = NULL;
1717 state->avail_in = 0;
1718 state->next_out = NULL;
1719 state->avail_out = 0;
1720 state->total_out = 0;
f91f0fd5 1721 state->dict_length = 0;
224ce89b
WB
1722 state->block_state = ISAL_BLOCK_NEW_HDR;
1723 state->bfinal = 0;
1724 state->crc_flag = 0;
1725 state->crc = 0;
f91f0fd5 1726 state->hist_bits = 0;
224ce89b 1727 state->type0_block_len = 0;
f91f0fd5
TL
1728 state->write_overflow_lits = 0;
1729 state->write_overflow_len = 0;
224ce89b
WB
1730 state->copy_overflow_length = 0;
1731 state->copy_overflow_distance = 0;
f91f0fd5 1732 state->wrapper_flag = 0;
224ce89b
WB
1733 state->tmp_in_size = 0;
1734 state->tmp_out_processed = 0;
1735 state->tmp_out_valid = 0;
1736}
1737
f91f0fd5
TL
1738void isal_inflate_reset(struct inflate_state *state)
1739{
1740 state->read_in = 0;
1741 state->read_in_length = 0;
1742 state->total_out = 0;
1743 state->dict_length = 0;
1744 state->block_state = ISAL_BLOCK_NEW_HDR;
1745 state->bfinal = 0;
1746 state->crc = 0;
1747 state->type0_block_len = 0;
1748 state->write_overflow_lits = 0;
1749 state->write_overflow_len = 0;
1750 state->copy_overflow_length = 0;
1751 state->copy_overflow_distance = 0;
1752 state->tmp_in_size = 0;
1753 state->tmp_out_processed = 0;
1754 state->tmp_out_valid = 0;
1755}
1756
1757static inline uint32_t fixed_size_read(struct inflate_state *state,
1758 uint8_t ** read_buf, int read_size)
1759{
1760 uint32_t tmp_in_size = state->tmp_in_size;
1761
1762 if (state->avail_in + tmp_in_size < read_size) {
1763 memcpy(state->tmp_in_buffer + tmp_in_size, state->next_in, state->avail_in);
1764 tmp_in_size += state->avail_in;
1765 state->tmp_in_size = tmp_in_size;
1766 state->next_in += state->avail_in;
1767 state->avail_in = 0;
1768
1769 return ISAL_END_INPUT;
1770 }
1771
1772 *read_buf = state->next_in;
1773 if (tmp_in_size) {
1774 memcpy(state->tmp_in_buffer + tmp_in_size, state->next_in,
1775 read_size - tmp_in_size);
1776 *read_buf = state->tmp_in_buffer;
1777 state->tmp_in_size = 0;
1778 }
1779
1780 state->next_in += read_size - tmp_in_size;
1781 state->avail_in -= read_size - tmp_in_size;
1782 tmp_in_size = 0;
1783
1784 return 0;
1785
1786}
1787
1788static inline uint32_t buffer_header_copy(struct inflate_state *state, uint32_t in_len,
1789 uint8_t * buf, uint32_t buf_len, uint32_t buf_error)
1790{
1791 uint32_t len = in_len;
1792 if (len > state->avail_in)
1793 len = state->avail_in;
1794
1795 if (buf != NULL && buf_len < len) {
1796 memcpy(buf, state->next_in, buf_len);
1797 state->next_in += buf_len;
1798 state->avail_in -= buf_len;
1799 state->count = in_len - buf_len;
1800 return buf_error;
1801 } else {
1802 if (buf != NULL)
1803 memcpy(buf, state->next_in, len);
1804 state->next_in += len;
1805 state->avail_in -= len;
1806 state->count = in_len - len;
1807
1808 if (len == in_len)
1809 return 0;
1810 else
1811 return ISAL_END_INPUT;
1812 }
1813}
1814
1815static inline uint32_t string_header_copy(struct inflate_state *state,
1816 char *str_buf, uint32_t str_len, uint32_t str_error)
1817{
1818 uint32_t len, max_len = str_len;
1819
1820 if (max_len > state->avail_in || str_buf == NULL)
1821 max_len = state->avail_in;
1822
1823 len = strnlen((char *)state->next_in, max_len);
1824
1825 if (str_buf != NULL)
1826 memcpy(str_buf, state->next_in, len);
1827
1828 state->next_in += len;
1829 state->avail_in -= len;
1830 state->count += len;
1831
1832 if (str_buf != NULL && len == str_len)
1833 return str_error;
1834 else if (state->avail_in <= 0)
1835 return ISAL_END_INPUT;
1836 else {
1837 state->next_in++;
1838 state->avail_in--;
1839 state->count = 0;
1840 if (str_buf != NULL)
1841 str_buf[len] = 0;
1842 }
1843
1844 return 0;
1845}
1846
1847static int check_gzip_checksum(struct inflate_state *state)
1848{
1849 uint64_t trailer, crc, total_out;
1850 uint8_t *next_in;
1851 uint32_t byte_count, offset, tmp_in_size = state->tmp_in_size;
1852 int ret;
1853
1854 if (state->read_in_length >= 8 * GZIP_TRAILER_LEN) {
1855 /* The following is unecessary as state->read_in_length == 64 */
1856 /* bit_count = state->read_in_length % 8; */
1857 /* state->read_in >>= bit_count; */
1858 /* state->read_in_length -= bit_count; */
1859
1860 trailer = state->read_in;
1861 state->read_in_length = 0;
1862 state->read_in = 0;
1863 } else {
1864 if (state->read_in_length >= 8) {
1865 byte_count = state->read_in_length / 8;
1866 offset = state->read_in_length % 8;
1867
1868 store_u64(state->tmp_in_buffer + tmp_in_size,
1869 state->read_in >> offset);
1870 state->read_in = 0;
1871 state->read_in_length = 0;
1872
1873 tmp_in_size += byte_count;
1874 state->tmp_in_size = tmp_in_size;
1875 }
1876
1877 ret = fixed_size_read(state, &next_in, GZIP_TRAILER_LEN);
1878 if (ret) {
1879 state->block_state = ISAL_CHECKSUM_CHECK;
1880 return ret;
1881 }
1882
1883 trailer = load_u64(next_in);
1884 }
1885
1886 state->block_state = ISAL_BLOCK_FINISH;
1887
1888 crc = state->crc;
1889 total_out = state->total_out;
1890
1891 if (trailer != (crc | (total_out << 32)))
1892 return ISAL_INCORRECT_CHECKSUM;
1893 else
1894 return ISAL_DECOMP_OK;
1895}
1896
1897static int check_zlib_checksum(struct inflate_state *state)
1898{
1899
1900 uint32_t trailer;
1901 uint8_t *next_in;
1902 uint32_t byte_count, offset, tmp_in_size = state->tmp_in_size;
1903 int ret, bit_count;
1904
1905 if (state->read_in_length >= 8 * ZLIB_TRAILER_LEN) {
1906 bit_count = state->read_in_length % 8;
1907 state->read_in >>= bit_count;
1908 state->read_in_length -= bit_count;
1909
1910 trailer = state->read_in;
1911
1912 state->read_in_length -= 8 * ZLIB_TRAILER_LEN;
1913 state->read_in >>= 8 * ZLIB_TRAILER_LEN;
1914 } else {
1915 if (state->read_in_length >= 8) {
1916 byte_count = state->read_in_length / 8;
1917 offset = state->read_in_length % 8;
1918
1919 store_u64(state->tmp_in_buffer + tmp_in_size,
1920 state->read_in >> offset);
1921 state->read_in = 0;
1922 state->read_in_length = 0;
1923
1924 tmp_in_size += byte_count;
1925 state->tmp_in_size = tmp_in_size;
1926 }
1927
1928 ret = fixed_size_read(state, &next_in, ZLIB_TRAILER_LEN);
1929 if (ret) {
1930 state->block_state = ISAL_CHECKSUM_CHECK;
1931 return ret;
1932 }
1933
1934 trailer = load_u32(next_in);
1935 }
1936
1937 state->block_state = ISAL_BLOCK_FINISH;
1938
1939 if (bswap_32(trailer) != state->crc)
1940 return ISAL_INCORRECT_CHECKSUM;
1941 else
1942 return ISAL_DECOMP_OK;
1943}
1944
1945int isal_read_gzip_header(struct inflate_state *state, struct isal_gzip_header *gz_hdr)
1946{
1947 int cm, flags = gz_hdr->flags, id1, id2;
1948 uint16_t xlen = gz_hdr->extra_len;
1949 uint32_t block_state = state->block_state;
1950 uint8_t *start_in = state->next_in, *next_in;
1951 uint32_t tmp_in_size = state->tmp_in_size;
1952 uint32_t count = state->count, offset;
1953 uint32_t hcrc = gz_hdr->hcrc;
1954 int ret = 0;
1955
1956 /* This switch is a jump table into the function so that decoding the
1957 * header can continue where it stopped on the last call */
1958 switch (block_state) {
1959 case ISAL_BLOCK_NEW_HDR:
1960 state->count = 0;
1961 flags = UNDEFINED_FLAG;
1962 if (tmp_in_size == 0)
1963 hcrc = 0;
1964
1965 ret = fixed_size_read(state, &next_in, GZIP_HDR_BASE);
1966 if (ret)
1967 break;
1968
1969 id1 = next_in[0];
1970 id2 = next_in[1];
1971 cm = next_in[2];
1972 flags = next_in[3];
1973 gz_hdr->time = load_u32(next_in + 4);
1974 gz_hdr->xflags = *(next_in + 8);
1975 gz_hdr->os = *(next_in + 9);
1976
1977 if (id1 != 0x1f || id2 != 0x8b)
1978 return ISAL_INVALID_WRAPPER;
1979
1980 if (cm != DEFLATE_METHOD)
1981 return ISAL_UNSUPPORTED_METHOD;
1982
1983 gz_hdr->text = 0;
1984 if (flags & TEXT_FLAG)
1985 gz_hdr->text = 1;
1986
1987 gz_hdr->flags = flags;
1988
1989 if (flags & EXTRA_FLAG) {
1990 case ISAL_GZIP_EXTRA_LEN:
1991 ret = fixed_size_read(state, &next_in, GZIP_EXTRA_LEN);
1992 if (ret) {
1993 state->block_state = ISAL_GZIP_EXTRA_LEN;
1994 break;
1995 }
1996
1997 xlen = load_u16(next_in);
1998 count = xlen;
1999
2000 gz_hdr->extra_len = xlen;
2001
2002 case ISAL_GZIP_EXTRA:
2003 offset = gz_hdr->extra_len - count;
2004 ret =
2005 buffer_header_copy(state, count, gz_hdr->extra + offset,
2006 gz_hdr->extra_buf_len - offset,
2007 ISAL_EXTRA_OVERFLOW);
2008
2009 if (ret) {
2010 state->block_state = ISAL_GZIP_EXTRA;
2011 break;
2012 }
2013 } else {
2014 gz_hdr->extra_len = 0;
2015 }
2016
2017 if (flags & NAME_FLAG) {
2018 case ISAL_GZIP_NAME:
2019 offset = state->count;
2020 ret = string_header_copy(state, gz_hdr->name + offset,
2021 gz_hdr->name_buf_len - offset,
2022 ISAL_NAME_OVERFLOW);
2023 if (ret) {
2024 state->block_state = ISAL_GZIP_NAME;
2025 break;
2026 }
2027 }
2028
2029 if (flags & COMMENT_FLAG) {
2030 case ISAL_GZIP_COMMENT:
2031 offset = state->count;
2032 ret = string_header_copy(state, gz_hdr->comment + offset,
2033 gz_hdr->comment_buf_len - offset,
2034 ISAL_COMMENT_OVERFLOW);
2035 if (ret) {
2036 state->block_state = ISAL_GZIP_COMMENT;
2037 break;
2038 }
2039 }
2040
2041 if (flags & HCRC_FLAG) {
2042 hcrc = crc32_gzip_refl(hcrc, start_in, state->next_in - start_in);
2043 gz_hdr->hcrc = hcrc;
2044
2045 case ISAL_GZIP_HCRC:
2046 ret = fixed_size_read(state, &next_in, GZIP_HCRC_LEN);
2047 if (ret) {
2048 state->block_state = ISAL_GZIP_HCRC;
2049 return ret;
2050 }
2051
2052 if ((hcrc & 0xffff) != load_u16(next_in))
2053 return ISAL_INCORRECT_CHECKSUM;
2054 }
2055
2056 state->wrapper_flag = 1;
2057 state->block_state = ISAL_BLOCK_NEW_HDR;
2058 return ISAL_DECOMP_OK;
2059 }
2060
2061 if (flags & HCRC_FLAG)
2062 gz_hdr->hcrc = crc32_gzip_refl(hcrc, start_in, state->next_in - start_in);
2063
2064 return ret;
2065}
2066
2067int isal_read_zlib_header(struct inflate_state *state, struct isal_zlib_header *zlib_hdr)
2068{
2069 int cmf, method, flags;
2070 uint32_t block_state = state->block_state;
2071 uint8_t *next_in;
2072 int ret = 0;
2073
2074 switch (block_state) {
2075 case ISAL_BLOCK_NEW_HDR:
2076 zlib_hdr->dict_flag = 0;
2077 ret = fixed_size_read(state, &next_in, ZLIB_HDR_BASE);
2078 if (ret)
2079 break;
2080
2081 cmf = *next_in;
2082 method = cmf & 0xf;
2083 flags = *(next_in + 1);
2084
2085 zlib_hdr->info = cmf >> ZLIB_INFO_OFFSET;
2086 zlib_hdr->dict_flag = (flags & ZLIB_DICT_FLAG) ? 1 : 0;
2087 zlib_hdr->level = flags >> ZLIB_LEVEL_OFFSET;
2088
2089 if (method != DEFLATE_METHOD)
2090 return ISAL_UNSUPPORTED_METHOD;
2091
2092 if ((256 * cmf + flags) % 31 != 0)
2093 return ISAL_INCORRECT_CHECKSUM;
2094
2095 if (zlib_hdr->dict_flag) {
2096 case ISAL_ZLIB_DICT:
2097 ret = fixed_size_read(state, &next_in, ZLIB_DICT_LEN);
2098 if (ret) {
2099 state->block_state = ISAL_ZLIB_DICT;
2100 break;
2101 }
2102
2103 zlib_hdr->dict_id = load_u32(next_in);
2104 }
2105
2106 state->wrapper_flag = 1;
2107 state->block_state = ISAL_BLOCK_NEW_HDR;
2108 }
2109
2110 return ret;
2111}
2112
2113int isal_inflate_set_dict(struct inflate_state *state, uint8_t * dict, uint32_t dict_len)
2114{
2115
2116 if (state->block_state != ISAL_BLOCK_NEW_HDR
2117 || state->tmp_out_processed != state->tmp_out_valid)
2118 return ISAL_INVALID_STATE;
2119
2120 if (dict_len > IGZIP_HIST_SIZE) {
2121 dict = dict + dict_len - IGZIP_HIST_SIZE;
2122 dict_len = IGZIP_HIST_SIZE;
2123 }
2124
2125 memcpy(state->tmp_out_buffer, dict, dict_len);
2126 state->tmp_out_processed = dict_len;
2127 state->tmp_out_valid = dict_len;
2128 state->dict_length = dict_len;
2129
2130 return COMP_OK;
2131}
2132
224ce89b
WB
2133int isal_inflate_stateless(struct inflate_state *state)
2134{
2135 uint32_t ret = 0;
2136 uint8_t *start_out = state->next_out;
2137
2138 state->read_in = 0;
2139 state->read_in_length = 0;
2140 state->block_state = ISAL_BLOCK_NEW_HDR;
f91f0fd5 2141 state->dict_length = 0;
224ce89b
WB
2142 state->bfinal = 0;
2143 state->crc = 0;
2144 state->total_out = 0;
f91f0fd5
TL
2145 state->hist_bits = 0;
2146 state->tmp_in_size = 0;
2147
2148 if (state->crc_flag == IGZIP_GZIP) {
2149 struct isal_gzip_header gz_hdr;
2150 ret = isal_read_gzip_header(state, &gz_hdr);
2151 if (ret)
2152 return ret;
2153 } else if (state->crc_flag == IGZIP_ZLIB) {
2154 struct isal_zlib_header z_hdr;
2155 ret = isal_read_zlib_header(state, &z_hdr);
2156 if (ret)
2157 return ret;
2158 if (z_hdr.dict_flag)
2159 return ISAL_NEED_DICT;
2160
2161 }
224ce89b
WB
2162
2163 while (state->block_state != ISAL_BLOCK_FINISH) {
2164 if (state->block_state == ISAL_BLOCK_NEW_HDR) {
2165 ret = read_header(state);
2166
2167 if (ret)
2168 break;
2169 }
2170
2171 if (state->block_state == ISAL_BLOCK_TYPE0)
2172 ret = decode_literal_block(state);
2173 else
f91f0fd5 2174 ret = decode_huffman_code_block_stateless(state, start_out);
224ce89b
WB
2175
2176 if (ret)
2177 break;
f91f0fd5 2178 if (state->block_state == ISAL_BLOCK_INPUT_DONE)
224ce89b
WB
2179 state->block_state = ISAL_BLOCK_FINISH;
2180 }
2181
224ce89b
WB
2182 /* Undo count stuff of bytes read into the read buffer */
2183 state->next_in -= state->read_in_length / 8;
2184 state->avail_in += state->read_in_length / 8;
f91f0fd5
TL
2185 state->read_in_length = 0;
2186 state->read_in = 0;
2187
2188 if (!ret && state->crc_flag) {
2189 update_checksum(state, start_out, state->next_out - start_out);
2190 switch (state->crc_flag) {
2191 case ISAL_ZLIB:
2192 case ISAL_ZLIB_NO_HDR_VER:
2193 finalize_adler32(state);
2194 ret = check_zlib_checksum(state);
2195 break;
2196
2197 case ISAL_ZLIB_NO_HDR:
2198 finalize_adler32(state);
2199 break;
2200
2201 case ISAL_GZIP:
2202 case ISAL_GZIP_NO_HDR_VER:
2203 ret = check_gzip_checksum(state);
2204 break;
2205 }
2206 }
224ce89b
WB
2207
2208 return ret;
2209}
2210
2211int isal_inflate(struct inflate_state *state)
2212{
2213
2214 uint8_t *start_out = state->next_out;
2215 uint32_t avail_out = state->avail_out;
2216 uint32_t copy_size = 0;
2217 int32_t shift_size = 0;
2218 int ret = 0;
2219
f91f0fd5
TL
2220 if (!state->wrapper_flag && state->crc_flag == IGZIP_GZIP) {
2221 struct isal_gzip_header gz_hdr;
2222 ret = isal_read_gzip_header(state, &gz_hdr);
2223 if (ret < 0)
2224 return ret;
2225 else if (ret > 0)
2226 return ISAL_DECOMP_OK;
2227 } else if (!state->wrapper_flag && state->crc_flag == IGZIP_ZLIB) {
2228 struct isal_zlib_header z_hdr;
2229 ret = isal_read_zlib_header(state, &z_hdr);
2230 if (ret < 0)
2231 return ret;
2232 else if (ret > 0)
2233 return ISAL_DECOMP_OK;
2234
2235 if (z_hdr.dict_flag) {
2236 state->dict_id = z_hdr.dict_id;
2237 return ISAL_NEED_DICT;
2238 }
2239 } else if (state->block_state == ISAL_CHECKSUM_CHECK) {
2240 switch (state->crc_flag) {
2241 case ISAL_ZLIB:
2242 case ISAL_ZLIB_NO_HDR_VER:
2243 ret = check_zlib_checksum(state);
2244 break;
2245 case ISAL_GZIP:
2246 case ISAL_GZIP_NO_HDR_VER:
2247 ret = check_gzip_checksum(state);
2248 break;
2249 }
2250
2251 return (ret > 0) ? ISAL_DECOMP_OK : ret;
2252 }
2253
224ce89b 2254 if (state->block_state != ISAL_BLOCK_FINISH) {
f91f0fd5 2255 state->total_out += state->tmp_out_valid - state->tmp_out_processed;
224ce89b
WB
2256 /* If space in tmp_out buffer, decompress into the tmp_out_buffer */
2257 if (state->tmp_out_valid < 2 * ISAL_DEF_HIST_SIZE) {
2258 /* Setup to start decoding into temp buffer */
2259 state->next_out = &state->tmp_out_buffer[state->tmp_out_valid];
2260 state->avail_out =
2261 sizeof(state->tmp_out_buffer) - ISAL_LOOK_AHEAD -
2262 state->tmp_out_valid;
2263
2264 if ((int32_t) state->avail_out < 0)
2265 state->avail_out = 0;
2266
2267 /* Decode into internal buffer until exit */
2268 while (state->block_state != ISAL_BLOCK_INPUT_DONE) {
2269 if (state->block_state == ISAL_BLOCK_NEW_HDR
2270 || state->block_state == ISAL_BLOCK_HDR) {
2271 ret = read_header_stateful(state);
2272
2273 if (ret)
2274 break;
2275 }
2276
2277 if (state->block_state == ISAL_BLOCK_TYPE0) {
2278 ret = decode_literal_block(state);
f91f0fd5
TL
2279 } else {
2280 uint8_t *tmp = state->tmp_out_buffer;
2281 ret = decode_huffman_code_block_stateless(state, tmp);
2282 }
224ce89b
WB
2283
2284 if (ret)
2285 break;
224ce89b
WB
2286 }
2287
2288 /* Copy valid data from internal buffer into out_buffer */
f91f0fd5
TL
2289 if (state->write_overflow_len != 0) {
2290 store_u32(state->next_out, state->write_overflow_lits);
2291 state->next_out += state->write_overflow_len;
2292 state->total_out += state->write_overflow_len;
2293 state->write_overflow_lits = 0;
2294 state->write_overflow_len = 0;
2295 }
2296
224ce89b
WB
2297 if (state->copy_overflow_length != 0) {
2298 byte_copy(state->next_out, state->copy_overflow_distance,
2299 state->copy_overflow_length);
2300 state->tmp_out_valid += state->copy_overflow_length;
2301 state->next_out += state->copy_overflow_length;
2302 state->total_out += state->copy_overflow_length;
2303 state->copy_overflow_distance = 0;
2304 state->copy_overflow_length = 0;
2305 }
2306
2307 state->tmp_out_valid = state->next_out - state->tmp_out_buffer;
2308
2309 /* Setup state for decompressing into out_buffer */
2310 state->next_out = start_out;
2311 state->avail_out = avail_out;
2312 }
2313
2314 /* Copy data from tmp_out buffer into out_buffer */
2315 copy_size = state->tmp_out_valid - state->tmp_out_processed;
2316 if (copy_size > avail_out)
2317 copy_size = avail_out;
2318
2319 memcpy(state->next_out,
2320 &state->tmp_out_buffer[state->tmp_out_processed], copy_size);
2321
2322 state->tmp_out_processed += copy_size;
2323 state->avail_out -= copy_size;
2324 state->next_out += copy_size;
2325
2326 if (ret == ISAL_INVALID_LOOKBACK || ret == ISAL_INVALID_BLOCK
2327 || ret == ISAL_INVALID_SYMBOL) {
2328 /* Set total_out to not count data in tmp_out_buffer */
2329 state->total_out -= state->tmp_out_valid - state->tmp_out_processed;
2330 if (state->crc_flag)
f91f0fd5 2331 update_checksum(state, start_out, state->next_out - start_out);
224ce89b
WB
2332 return ret;
2333 }
2334
2335 /* If all data from tmp_out buffer has been processed, start
2336 * decompressing into the out buffer */
2337 if (state->tmp_out_processed == state->tmp_out_valid) {
2338 while (state->block_state != ISAL_BLOCK_INPUT_DONE) {
2339 if (state->block_state == ISAL_BLOCK_NEW_HDR
2340 || state->block_state == ISAL_BLOCK_HDR) {
2341 ret = read_header_stateful(state);
2342 if (ret)
2343 break;
2344 }
2345
2346 if (state->block_state == ISAL_BLOCK_TYPE0)
2347 ret = decode_literal_block(state);
2348 else
f91f0fd5
TL
2349 ret =
2350 decode_huffman_code_block_stateless(state,
2351 start_out);
224ce89b
WB
2352 if (ret)
2353 break;
224ce89b
WB
2354 }
2355 }
2356
2357 if (state->crc_flag)
f91f0fd5 2358 update_checksum(state, start_out, state->next_out - start_out);
224ce89b 2359
f91f0fd5
TL
2360 if (state->block_state != ISAL_BLOCK_INPUT_DONE
2361 || state->copy_overflow_length + state->write_overflow_len +
2362 state->tmp_out_valid > sizeof(state->tmp_out_buffer)) {
224ce89b
WB
2363 /* Save decompression history in tmp_out buffer */
2364 if (state->tmp_out_valid == state->tmp_out_processed
2365 && avail_out - state->avail_out >= ISAL_DEF_HIST_SIZE) {
2366 memcpy(state->tmp_out_buffer,
2367 state->next_out - ISAL_DEF_HIST_SIZE,
2368 ISAL_DEF_HIST_SIZE);
2369 state->tmp_out_valid = ISAL_DEF_HIST_SIZE;
2370 state->tmp_out_processed = ISAL_DEF_HIST_SIZE;
2371
2372 } else if (state->tmp_out_processed >= ISAL_DEF_HIST_SIZE) {
2373 shift_size = state->tmp_out_valid - ISAL_DEF_HIST_SIZE;
2374 if (shift_size > state->tmp_out_processed)
2375 shift_size = state->tmp_out_processed;
2376
2377 memmove(state->tmp_out_buffer,
2378 &state->tmp_out_buffer[shift_size],
2379 state->tmp_out_valid - shift_size);
2380 state->tmp_out_valid -= shift_size;
2381 state->tmp_out_processed -= shift_size;
2382
2383 }
f91f0fd5 2384 }
224ce89b 2385
f91f0fd5
TL
2386 /* Write overflow data into tmp buffer */
2387 if (state->write_overflow_len != 0) {
2388 store_u32(&state->tmp_out_buffer[state->tmp_out_valid],
2389 state->write_overflow_lits);
2390 state->tmp_out_valid += state->write_overflow_len;
2391 state->total_out += state->write_overflow_len;
2392 state->write_overflow_lits = 0;
2393 state->write_overflow_len = 0;
2394 }
224ce89b 2395
f91f0fd5
TL
2396 if (state->copy_overflow_length != 0) {
2397 byte_copy(&state->tmp_out_buffer[state->tmp_out_valid],
2398 state->copy_overflow_distance, state->copy_overflow_length);
2399 state->tmp_out_valid += state->copy_overflow_length;
2400 state->total_out += state->copy_overflow_length;
2401 state->copy_overflow_distance = 0;
2402 state->copy_overflow_length = 0;
2403 }
2404
2405 if (ret == ISAL_INVALID_LOOKBACK || ret == ISAL_INVALID_BLOCK
2406 || ret == ISAL_INVALID_SYMBOL) {
2407 state->total_out -= state->tmp_out_valid - state->tmp_out_processed;
2408 return ret;
2409 }
224ce89b 2410
f91f0fd5
TL
2411 if (state->block_state == ISAL_BLOCK_INPUT_DONE
2412 && state->tmp_out_valid == state->tmp_out_processed) {
224ce89b 2413 state->block_state = ISAL_BLOCK_FINISH;
f91f0fd5
TL
2414
2415 switch (state->crc_flag) {
2416 case ISAL_ZLIB:
2417 case ISAL_ZLIB_NO_HDR_VER:
2418 finalize_adler32(state);
2419 ret = check_zlib_checksum(state);
2420 break;
2421
2422 case ISAL_ZLIB_NO_HDR:
2423 finalize_adler32(state);
2424 break;
2425
2426 case ISAL_GZIP:
2427 case ISAL_GZIP_NO_HDR_VER:
2428 ret = check_gzip_checksum(state);
2429 break;
2430 }
2431 }
2432
2433 state->total_out -= state->tmp_out_valid - state->tmp_out_processed;
224ce89b
WB
2434 }
2435
f91f0fd5 2436 return (ret > 0) ? ISAL_DECOMP_OK : ret;
224ce89b 2437}