summaryrefslogtreecommitdiff
path: root/firmware/common/inflate.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/common/inflate.c')
-rw-r--r--firmware/common/inflate.c759
1 files changed, 759 insertions, 0 deletions
diff --git a/firmware/common/inflate.c b/firmware/common/inflate.c
new file mode 100644
index 0000000000..26fd191690
--- /dev/null
+++ b/firmware/common/inflate.c
@@ -0,0 +1,759 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2021 by James Buren (libflate adaptations for RockBox)
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22/* Copyright 2021 Plan 9 Foundation
23 *
24 * Permission is hereby granted, free of charge, to any person obtaining
25 * a copy of this software and associated documentation files (the
26 * "Software"), to deal in the Software without restriction, including
27 * without limitation the rights to use, copy, modify, merge, publish,
28 * distribute, sublicense, and/or sell copies of the Software, and to
29 * permit persons to whom the Software is furnished to do so, subject to
30 * the following conditions:
31 *
32 * The above copyright notice and this permission notice shall be
33 * included in all copies or substantial portions of the Software.
34 *
35 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
36 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
37 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
38 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
39 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
40 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
41 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42 */
43
44#include "inflate.h"
45#include <stdbool.h>
46#include "adler32.h"
47#include "crc32.h"
48#include "system.h"
49
50enum {
51 INFLATE_BUFFER_SIZE = 32768,
52 INFLATE_SYMBOL_MAX = 288,
53 INFLATE_OFFSET_MAX = 32,
54 INFLATE_CODELEN_MAX = 19,
55 INFLATE_HUFF_BITS = 17,
56 INFLATE_FLAT_BITS = 7,
57 INFLATE_SYMBOL_BITS = 7,
58 INFLATE_OFFSET_BITS = 6,
59 INFLATE_CODELEN_BITS = 6,
60};
61
62struct inflate_huff {
63 uint32_t max_bits;
64 uint32_t min_bits;
65 uint32_t flat_mask;
66 uint32_t flat[1 << INFLATE_FLAT_BITS];
67 uint32_t max_code[INFLATE_HUFF_BITS];
68 uint32_t last[INFLATE_HUFF_BITS];
69 uint32_t decode[INFLATE_SYMBOL_MAX];
70};
71
72struct inflate {
73 uint8_t in[INFLATE_BUFFER_SIZE];
74 uint8_t out[INFLATE_BUFFER_SIZE];
75 union {
76 struct {
77 uint8_t len[INFLATE_SYMBOL_MAX];
78 uint8_t off[INFLATE_OFFSET_MAX];
79 };
80 uint8_t combo[INFLATE_SYMBOL_MAX + INFLATE_OFFSET_MAX];
81 };
82 uint8_t clen[INFLATE_CODELEN_MAX];
83 struct inflate_huff lentab;
84 struct inflate_huff offtab;
85 struct inflate_huff clentab;
86 uint32_t bits[INFLATE_HUFF_BITS];
87 uint32_t codes[INFLATE_HUFF_BITS];
88};
89
90#define INFLATE_FILL(E) do { \
91 const uint32_t _size = read(is, sizeof(it->in), rctx); \
92 if (_size == 0) { \
93 rv = (E); \
94 goto bail; \
95 } \
96 ip = is; \
97 ie = is + _size; \
98} while (0)
99
100#define INFLATE_FLUSH(E) do { \
101 const uint32_t _size = (op - os); \
102 if (write(os, _size, wctx) != _size) { \
103 rv = (E); \
104 goto bail; \
105 } \
106 flushed = true; \
107 if (st == INFLATE_ZLIB) \
108 chksum = adler_32(os, _size, chksum); \
109 else if (st == INFLATE_GZIP) \
110 chksum = crc_32r(os, _size, chksum); \
111 op = os; \
112} while (0)
113
114#define INFLATE_GET_BYTE(E,C) do { \
115 if (ip == ie) \
116 INFLATE_FILL(E); \
117 (C) = ip[0]; \
118 ++ip; \
119} while (0)
120
121#define INFLATE_PUT_BYTE(E,B) do { \
122 if (op == oe) \
123 INFLATE_FLUSH(E); \
124 op[0] = (B); \
125 ++op; \
126} while (0)
127
128#define INFLATE_FILL_BITS(E,N) do { \
129 while ((N) > nbits) { \
130 uint8_t _byte; \
131 INFLATE_GET_BYTE(E, _byte); \
132 sreg |= (_byte << nbits); \
133 nbits += 8; \
134 } \
135} while (0)
136
137#define INFLATE_CONSUME_BITS(N) do { \
138 sreg >>= (N); \
139 nbits -= (N); \
140} while (0)
141
142#define INFLATE_EXTRACT_BITS(N,B) do { \
143 (B) = (sreg & ((1 << (N)) - 1)); \
144 INFLATE_CONSUME_BITS(N); \
145} while (0)
146
147#define INFLATE_CHECK_LENGTH(E,N) do { \
148 if ((N) > (ie - ip)) { \
149 rv = (E); \
150 goto bail; \
151 } \
152} while (0)
153
154#define INFLATE_REVERSE(C,B) ({ \
155 uint32_t _c = (C); \
156 _c <<= (16 - (B)); \
157 ((revtab[_c >> 8]) | (revtab[_c & 0xff] << 8)); \
158})
159
160#define INFLATE_DECODE(E,H) ({ \
161 __label__ _found; \
162 uint32_t _c = (H)->flat[sreg & (H)->flat_mask]; \
163 uint32_t _b = (_c & 0xff); \
164 uint32_t _code; \
165 if (_b == 0xff) { \
166 for (_b = (_c >> 8); _b <= (H)->max_bits; _b++) { \
167 _c = (revtab[sreg & 0xff] << 8); \
168 _c |= (revtab[(sreg >> 8) & 0xff]); \
169 _c >>= (16 - _b); \
170 if (_c <= (H)->max_code[_b]) { \
171 _code = (H)->decode[(H)->last[_b] - _c]; \
172 goto _found; \
173 } \
174 } \
175 rv = (E); \
176 goto bail; \
177 } \
178 _code = (_c >> 8); \
179_found: \
180 INFLATE_CONSUME_BITS(_b); \
181 _code; \
182})
183
184static int inflate_blocks(struct inflate* it, int st, inflate_reader read, void* rctx, inflate_writer write, void* wctx) {
185 int rv = 0;
186 uint8_t* is = it->in;
187 uint8_t* ip;
188 uint8_t* ie;
189 uint8_t* os = it->out;
190 uint8_t* op = os;
191 uint8_t* oe = os + sizeof(it->out);
192 bool flushed = false;
193 uint32_t chksum;
194 uint32_t nbits = 0;
195 uint32_t sreg = 0;
196 uint32_t i;
197 uint32_t j;
198 bool final;
199 uint8_t type;
200
201 INFLATE_FILL(-1);
202
203 if (st == INFLATE_ZLIB) {
204 uint16_t header;
205
206 INFLATE_CHECK_LENGTH(-2, 2);
207
208 header = (ip[0] << 8 | ip[1]);
209 ip += 2;
210
211 if ((header % 31) != 0) {
212 rv = -3;
213 goto bail;
214 }
215
216 if (((header & 0xf000) >> 12) > 7) {
217 rv = -4;
218 goto bail;
219 }
220
221 if (((header & 0x0f00) >> 8) != 8) {
222 rv = -5;
223 goto bail;
224 }
225
226 if (((header & 0x0020) >> 5) != 0) {
227 rv = -6;
228 goto bail;
229 }
230
231 chksum = 1;
232 } else if (st == INFLATE_GZIP) {
233 uint8_t flg;
234
235 INFLATE_CHECK_LENGTH(-7, 10);
236
237 if (ip[0] != 0x1f || ip[1] != 0x8b) {
238 rv = -8;
239 goto bail;
240 }
241
242 if (ip[2] != 8) {
243 rv = -9;
244 goto bail;
245 }
246
247 flg = ip[3];
248
249 if ((flg & 0xe0) != 0) {
250 rv = -10;
251 goto bail;
252 }
253
254 ip += 10;
255 chksum = 0xffffffff;
256
257 if ((flg & 0x04) != 0) {
258 uint16_t xlen;
259
260 INFLATE_CHECK_LENGTH(-11, 2);
261
262 xlen = (ip[0] | ip[1] << 8);
263 ip += 2;
264
265 while (xlen >= (ie - ip)) {
266 xlen -= (ie - ip);
267
268 if ((flg & 0x02) != 0)
269 chksum = crc_32r(is, ie - is, chksum);
270
271 INFLATE_FILL(-12);
272 }
273
274 ip += xlen;
275 }
276
277 if ((flg & 0x08) != 0) {
278 while (ip++[0] != '\0') {
279 if (ip == ie) {
280 if ((flg & 0x02) != 0)
281 chksum = crc_32r(is, ie - is, chksum);
282
283 INFLATE_FILL(-13);
284 }
285 }
286 }
287
288 if ((flg & 0x10) != 0) {
289 while (ip++[0] != '\0') {
290 if (ip == ie) {
291 if ((flg & 0x02) != 0)
292 chksum = crc_32r(is, ie - is, chksum);
293
294 INFLATE_FILL(-14);
295 }
296 }
297 }
298
299 if ((flg & 0x02) != 0) {
300 uint16_t crc16;
301
302 INFLATE_CHECK_LENGTH(-15, 2);
303
304 crc16 = (ip[0] | ip[1] << 8);
305 chksum = crc_32r(is, ip - is, chksum);
306 chksum &= 0xffff;
307 chksum ^= 0xffff;
308
309 if (crc16 != chksum) {
310 rv = -16;
311 goto bail;
312 }
313
314 ip += 2;
315 }
316
317 chksum = 0xffffffff;
318 } else {
319 chksum = 0;
320 }
321
322 do {
323 INFLATE_FILL_BITS(-17, 3);
324 final = (sreg & 0x01);
325 type = ((sreg & 0x06) >> 1);
326 INFLATE_CONSUME_BITS(3);
327
328 if (type == 0) {
329 uint8_t header[4];
330 uint32_t len;
331 uint32_t clen;
332
333 INFLATE_CONSUME_BITS(nbits & 0x07);
334
335 for (i = 0; i < 4; i++) {
336 if (nbits != 0)
337 INFLATE_EXTRACT_BITS(8, header[i]);
338 else
339 INFLATE_GET_BYTE(-18, header[i]);
340 }
341
342 len = (header[0] | (header[1] << 8));
343 clen = (header[2] | (header[3] << 8)) ^ 0xffff;
344
345 if (len != clen) {
346 rv = -19;
347 goto bail;
348 }
349
350 while (len != 0) {
351 if (ip == ie)
352 INFLATE_FILL(-20);
353
354 if (op == oe)
355 INFLATE_FLUSH(-21);
356
357 j = MIN(len, MIN((uint32_t) (ie - ip), (uint32_t) (oe - op)));
358 for (i = 0; i < j; i++)
359 op[i] = ip[i];
360
361 len -= j;
362 ip += j;
363 op += j;
364 }
365 } else if (type == 3) {
366 rv = -22;
367 goto bail;
368 } else {
369 static const uint8_t revtab[256] =
370 {
371 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
372 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
373 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
374 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
375 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
376 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
377 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
378 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
379 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
380 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
381 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
382 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
383 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
384 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
385 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
386 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
387 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
388 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
389 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
390 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
391 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
392 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
393 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
394 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
395 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
396 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
397 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
398 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
399 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
400 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
401 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
402 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
403 };
404 uint8_t* tab[3];
405 uint32_t tab_lens[3];
406 uint32_t tab_bits[3];
407 struct inflate_huff* tab_huffs[3] = { &it->lentab, &it->offtab, &it->clentab, };
408 uint32_t c;
409 uint32_t k;
410
411 if (type == 2) {
412 static const uint32_t min_tab_sizes[3] = { 257, 1, 4, };
413 static const uint32_t min_tab_bits[3] = { 5, 5, 4, };
414 static const uint32_t clen_order[INFLATE_CODELEN_MAX] = {
415 16, 17, 18, 0, 8,
416 7, 9, 6, 10, 5,
417 11, 4, 12, 3, 13,
418 2, 14, 1, 15,
419 };
420
421 INFLATE_FILL_BITS(-23, 14);
422 for (i = 0; i < 3; i++) {
423 INFLATE_EXTRACT_BITS(min_tab_bits[i], tab_lens[i]);
424 tab_lens[i] += min_tab_sizes[i];
425 }
426
427 tab[2] = it->clen;
428 for (i = 0; i < INFLATE_CODELEN_MAX; i++)
429 tab[2][i] = 0;
430 for (i = 0; i < tab_lens[2]; i++) {
431 INFLATE_FILL_BITS(-24, 3);
432 INFLATE_EXTRACT_BITS(3, tab[2][clen_order[i]]);
433 }
434
435 tab[0] = it->combo;
436 tab_bits[0] = INFLATE_SYMBOL_BITS;
437
438 tab[1] = tab[0] + tab_lens[0];
439 tab_bits[1] = INFLATE_OFFSET_BITS;
440
441 tab_lens[2] = INFLATE_CODELEN_MAX;
442 tab_bits[2] = INFLATE_CODELEN_BITS;
443 } else {
444 tab[0] = it->len;
445 for (i = 0; i < 144; i++)
446 tab[0][i] = 8;
447 for (; i < 256; i++)
448 tab[0][i] = 9;
449 for (; i < 280; i++)
450 tab[0][i] = 7;
451 for (; i < INFLATE_SYMBOL_MAX; i++)
452 tab[0][i] = 8;
453 tab_lens[0] = INFLATE_SYMBOL_MAX;
454 tab_bits[0] = INFLATE_FLAT_BITS;
455
456 tab[1] = it->off;
457 for (i = 0; i < INFLATE_OFFSET_MAX; i++)
458 tab[1][i] = 5;
459 tab_lens[1] = INFLATE_OFFSET_MAX;
460 tab_bits[1] = INFLATE_FLAT_BITS;
461 }
462
463 for(; type != 0xff; --type) {
464 const uint8_t* hb = tab[type];
465 uint32_t hb_len = tab_lens[type];
466 uint32_t flat_bits = tab_bits[type];
467 struct inflate_huff* h = tab_huffs[type];
468 uint32_t* bits = it->bits;
469 uint32_t* codes = it->codes;
470 uint32_t max_bits = 0;
471 uint32_t min_bits = INFLATE_HUFF_BITS + 1;
472 uint32_t min_code;
473 uint32_t b;
474 uint32_t code;
475 uint32_t fc;
476 uint32_t ec;
477
478 for (i = 0; i < INFLATE_HUFF_BITS; i++)
479 bits[i] = 0;
480
481 for (i = 0; i < hb_len; i++) {
482 b = hb[i];
483
484 if (b != 0) {
485 bits[b]++;
486
487 if (b < min_bits)
488 min_bits = b;
489
490 if (b > max_bits)
491 max_bits = b;
492 }
493 }
494
495 if (max_bits == 0) {
496 h->flat_mask = h->min_bits = h->max_bits = 0;
497 goto table_done;
498 }
499
500 h->max_bits = max_bits;
501
502 for (b = c = code = 0; b <= max_bits; b++) {
503 h->last[b] = c;
504 c += bits[b];
505
506 min_code = (code << 1);
507 codes[b] = min_code;
508 code = (min_code + bits[b]);
509
510 if (code > (1U << b)) {
511 rv = -25;
512 goto bail;
513 }
514
515 h->max_code[b] = (code - 1);
516 h->last[b] += (code - 1);
517 }
518
519 if (flat_bits > max_bits)
520 flat_bits = max_bits;
521
522 h->flat_mask = ((1 << flat_bits) - 1);
523
524 if (min_bits > flat_bits)
525 min_bits = flat_bits;
526
527 h->min_bits = min_bits;
528
529 for (i = 0, b = (1 << flat_bits); i < b; i++)
530 h->flat[i] = 0xffffffff;
531
532 for (b = max_bits; b > flat_bits; b--) {
533 code = h->max_code[b];
534
535 if (code == 0xffffffff)
536 break;
537
538 min_code = ((code + 1) - bits[b]);
539 min_code >>= (b - flat_bits);
540 code >>= (b - flat_bits);
541
542 for (; min_code <= code; min_code++)
543 h->flat[INFLATE_REVERSE(min_code, flat_bits)] = ((b << 8) | 0xff);
544 }
545
546 for (i = 0; i < hb_len; i++) {
547 b = hb[i];
548
549 if (b == 0)
550 continue;
551
552 c = codes[b]++;
553
554 if (b <= flat_bits) {
555 code = ((i << 8) | b);
556 ec = ((c + 1) << (flat_bits - b));
557
558 if (ec > (1U << flat_bits)) {
559 rv = -26;
560 goto bail;
561 }
562
563 for (fc = (c << (flat_bits - b)); fc < ec; fc++)
564 h->flat[INFLATE_REVERSE(fc, flat_bits)] = code;
565 }
566
567 if (b > min_bits) {
568 c = h->last[b] - c;
569
570 if (c >= hb_len) {
571 rv = -27;
572 goto bail;
573 }
574
575 h->decode[c] = i;
576 }
577 }
578
579 table_done:
580
581 if (type == 2) {
582 static const uint32_t bits[3] = { 2, 3, 7, };
583 static const uint32_t bases[3] = { 3, 3, 11, };
584
585 for (i = 0, j = tab_lens[0] + tab_lens[1]; i < j; ) {
586 uint32_t len;
587 uint8_t byte;
588
589 INFLATE_FILL_BITS(-28, h->max_bits);
590
591 c = INFLATE_DECODE(-29, h);
592
593 if (c < 16) {
594 tab[0][i++] = c;
595 continue;
596 }
597
598 c -= 16;
599
600 if (c == 0 && i == 0) {
601 rv = -30;
602 goto bail;
603 }
604
605 INFLATE_FILL_BITS(-31, bits[c]);
606 INFLATE_EXTRACT_BITS(bits[c], len);
607 len += bases[c];
608
609 if ((i + len) > j) {
610 rv = -32;
611 goto bail;
612 }
613
614 byte = ((c == 0) ? tab[0][i - 1] : 0);
615 for (k = 0; k < len; k++)
616 tab[0][i + k] = byte;
617
618 i += len;
619 }
620 }
621 }
622
623 while (1) {
624 static const uint32_t lenbase[INFLATE_SYMBOL_MAX - 257] = {
625 3, 4, 5, 6, 7, 8, 9, 10,
626 11, 13, 15, 17, 19, 23, 27, 31,
627 35, 43, 51, 59, 67, 83, 99, 115,
628 131, 163, 195, 227, 258, 0, 0,
629 };
630 static const uint32_t lenextra[INFLATE_SYMBOL_MAX - 257] = {
631 0, 0, 0, 0, 0, 0, 0, 0,
632 1, 1, 1, 1, 2, 2, 2, 2,
633 3, 3, 3, 3, 4, 4, 4, 4,
634 5, 5, 5, 5, 0, 0, 0,
635 };
636 static const uint32_t offbase[INFLATE_OFFSET_MAX] = {
637 1, 2, 3, 4, 5, 7, 9, 13,
638 17, 25, 33, 49, 65, 97, 129, 193,
639 257, 385, 513, 769, 1025, 1537, 2049, 3073,
640 4097, 6145, 8193, 12289, 16385, 24577, 0, 0,
641 };
642 static const uint32_t offextra[INFLATE_OFFSET_MAX] = {
643 0, 0, 0, 0, 1, 1, 2, 2,
644 3, 3, 4, 4, 5, 5, 6, 6,
645 7, 7, 8, 8, 9, 9, 10, 10,
646 11, 11, 12, 12, 13, 13, 0, 0,
647 };
648 uint32_t len;
649 uint32_t off;
650 uint8_t* cp;
651
652 INFLATE_FILL_BITS(-33, tab_huffs[0]->max_bits);
653 c = INFLATE_DECODE(-34, tab_huffs[0]);
654
655 if (c < 256) {
656 INFLATE_PUT_BYTE(-35, c);
657 continue;
658 }
659
660 if (c == 256)
661 break;
662
663 if (c > 285) {
664 rv = -36;
665 goto bail;
666 }
667
668 c -= 257;
669 INFLATE_FILL_BITS(-37, lenextra[c]);
670 INFLATE_EXTRACT_BITS(lenextra[c], len);
671 len += lenbase[c];
672
673 INFLATE_FILL_BITS(-38, tab_huffs[1]->max_bits);
674 c = INFLATE_DECODE(-39, tab_huffs[1]);
675
676 if (c > 29) {
677 rv = -40;
678 goto bail;
679 }
680
681 INFLATE_FILL_BITS(-41, offextra[c]);
682 INFLATE_EXTRACT_BITS(offextra[c], off);
683 off += offbase[c];
684
685 cp = op - off;
686 if (cp < os) {
687 if (!flushed) {
688 rv = -42;
689 goto bail;
690 }
691
692 cp += sizeof(it->out);
693 }
694
695 while (len != 0) {
696 if (op == oe)
697 INFLATE_FLUSH(-43);
698
699 if (cp == oe)
700 cp = os;
701
702 j = MIN(len, MIN((uint32_t) (oe - op), (uint32_t) (oe - cp)));
703
704 for (i = 0; i < j; i++)
705 op[i] = cp[i];
706
707 op += j;
708 cp += j;
709 len -= j;
710 }
711 }
712 }
713 } while (!final);
714
715 INFLATE_FLUSH(-44);
716
717 if (st != INFLATE_RAW) {
718 uint8_t header[4];
719 uint32_t chksum2;
720
721 INFLATE_CONSUME_BITS(nbits & 0x07);
722
723 for (i = 0; i < 4; i++) {
724 if (nbits != 0)
725 INFLATE_EXTRACT_BITS(8, header[i]);
726 else
727 INFLATE_GET_BYTE(-45, header[i]);
728 }
729
730 if (st == INFLATE_ZLIB) {
731 chksum2 = ((header[0] << 24) | (header[1] << 16) | (header[2] << 8) | (header[3] << 0));
732
733 if (chksum != chksum2) {
734 rv = -46;
735 goto bail;
736 }
737 } else if (st == INFLATE_GZIP) {
738 chksum2 = ((header[3] << 24) | (header[2] << 16) | (header[1] << 8) | (header[0] << 0));
739
740 if (~chksum != chksum2) {
741 rv = -47;
742 goto bail;
743 }
744 }
745 }
746
747bail:
748 return rv;
749}
750
751const uint32_t inflate_size = sizeof(struct inflate);
752const uint32_t inflate_align = _Alignof(struct inflate);
753
754int inflate(struct inflate* it, int st, inflate_reader read, void* rctx, inflate_writer write, void* wctx) {
755 if (it == NULL || read == NULL || write == NULL || st < 0 || st > 2 || (((uintptr_t) it) & (_Alignof(struct inflate) - 1)) != 0)
756 return -48;
757
758 return inflate_blocks(it, st, read, rctx, write, wctx);
759}