diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-06 00:03:11 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-01-06 00:03:11 +0000 |
commit | c7a4aa5c9921c8725a3fdd6b12ef87835a755139 (patch) | |
tree | aead5a5579bdb32b92527b5e91f3d94358bc8b13 | |
parent | d1a19affeb83a4c33ac0fc9dde3a27232fa23767 (diff) | |
download | busybox-w32-c7a4aa5c9921c8725a3fdd6b12ef87835a755139.tar.gz busybox-w32-c7a4aa5c9921c8725a3fdd6b12ef87835a755139.tar.bz2 busybox-w32-c7a4aa5c9921c8725a3fdd6b12ef87835a755139.zip |
move [g]zip decompressor state into malloc'ed buffer. size:
text data bss dec hex
5256 0 108 5364 14f4 - old
4915 0 0 4915 1333 - new
-rw-r--r-- | archival/libunarchive/decompress_unzip.c | 280 |
1 files changed, 192 insertions, 88 deletions
diff --git a/archival/libunarchive/decompress_unzip.c b/archival/libunarchive/decompress_unzip.c index 9e8fd7e03..424fe5190 100644 --- a/archival/libunarchive/decompress_unzip.c +++ b/archival/libunarchive/decompress_unzip.c | |||
@@ -54,26 +54,129 @@ enum { | |||
54 | N_MAX = 288, /* maximum number of codes in any set */ | 54 | N_MAX = 288, /* maximum number of codes in any set */ |
55 | }; | 55 | }; |
56 | 56 | ||
57 | static off_t gunzip_bytes_out; /* number of output bytes */ | ||
58 | static uint32_t gunzip_crc; | ||
59 | 57 | ||
60 | static int gunzip_src_fd; | 58 | /* This is somewhat complex-looking arrangement, but it allows |
61 | static unsigned gunzip_outbuf_count; /* bytes in output buffer */ | 59 | * to place decompressor state either in bss or in |
62 | 60 | * malloc'ed space simply by changing #defines below. | |
63 | static unsigned char *gunzip_window; | 61 | * Sizes on i386: |
64 | 62 | * text data bss dec hex | |
65 | static uint32_t *gunzip_crc_table; | 63 | * 5256 0 108 5364 14f4 - bss |
66 | 64 | * 4915 0 0 4915 1333 - malloc | |
67 | 65 | */ | |
68 | /* bitbuffer */ | 66 | #define STATE_IN_BSS 0 |
69 | static unsigned gunzip_bb; /* bit buffer */ | 67 | #define STATE_IN_MALLOC 1 |
70 | static unsigned char gunzip_bk; /* bits in bit buffer */ | 68 | |
69 | |||
70 | typedef struct state_t { | ||
71 | off_t gunzip_bytes_out; /* number of output bytes */ | ||
72 | uint32_t gunzip_crc; | ||
73 | |||
74 | int gunzip_src_fd; | ||
75 | unsigned gunzip_outbuf_count; /* bytes in output buffer */ | ||
76 | |||
77 | unsigned char *gunzip_window; | ||
78 | |||
79 | uint32_t *gunzip_crc_table; | ||
80 | |||
81 | /* bitbuffer */ | ||
82 | unsigned gunzip_bb; /* bit buffer */ | ||
83 | unsigned char gunzip_bk; /* bits in bit buffer */ | ||
84 | |||
85 | /* These control the size of the STATE()bytebuffer */ | ||
86 | unsigned bytebuffer_max; | ||
87 | unsigned char *bytebuffer; | ||
88 | unsigned bytebuffer_offset; | ||
89 | unsigned bytebuffer_size; | ||
90 | |||
91 | /* private data of inflate_codes() */ | ||
92 | unsigned inflate_codes_ml; /* masks for bl and bd bits */ | ||
93 | unsigned inflate_codes_md; /* masks for bl and bd bits */ | ||
94 | unsigned inflate_codes_bb; /* bit buffer */ | ||
95 | unsigned inflate_codes_k; /* number of bits in bit buffer */ | ||
96 | unsigned inflate_codes_w; /* current gunzip_window position */ | ||
97 | huft_t *inflate_codes_tl; | ||
98 | huft_t *inflate_codes_td; | ||
99 | unsigned inflate_codes_bl; | ||
100 | unsigned inflate_codes_bd; | ||
101 | smallint resume_copy; | ||
102 | |||
103 | /* private data of inflate_get_next_window() */ | ||
104 | smallint method; /* Method == -1 for stored, -2 for codes */ | ||
105 | smallint need_another_block; | ||
106 | smallint end_reached; | ||
107 | |||
108 | /* private data of inflate_stored() */ | ||
109 | unsigned inflate_stored_n; | ||
110 | unsigned inflate_stored_b; | ||
111 | unsigned inflate_stored_k; | ||
112 | unsigned inflate_stored_w; | ||
113 | } state_t; | ||
114 | #define gunzip_bytes_out (S()gunzip_bytes_out ) | ||
115 | #define gunzip_crc (S()gunzip_crc ) | ||
116 | #define gunzip_src_fd (S()gunzip_src_fd ) | ||
117 | #define gunzip_outbuf_count (S()gunzip_outbuf_count) | ||
118 | #define gunzip_window (S()gunzip_window ) | ||
119 | #define gunzip_crc_table (S()gunzip_crc_table ) | ||
120 | #define gunzip_bb (S()gunzip_bb ) | ||
121 | #define gunzip_bk (S()gunzip_bk ) | ||
122 | #define bytebuffer_max (S()bytebuffer_max ) | ||
123 | #define bytebuffer (S()bytebuffer ) | ||
124 | #define bytebuffer_offset (S()bytebuffer_offset ) | ||
125 | #define bytebuffer_size (S()bytebuffer_size ) | ||
126 | #define inflate_codes_ml (S()inflate_codes_ml ) | ||
127 | #define inflate_codes_md (S()inflate_codes_md ) | ||
128 | #define inflate_codes_bb (S()inflate_codes_bb ) | ||
129 | #define inflate_codes_k (S()inflate_codes_k ) | ||
130 | #define inflate_codes_w (S()inflate_codes_w ) | ||
131 | #define inflate_codes_tl (S()inflate_codes_tl ) | ||
132 | #define inflate_codes_td (S()inflate_codes_td ) | ||
133 | #define inflate_codes_bl (S()inflate_codes_bl ) | ||
134 | #define inflate_codes_bd (S()inflate_codes_bd ) | ||
135 | #define resume_copy (S()resume_copy ) | ||
136 | #define method (S()method ) | ||
137 | #define need_another_block (S()need_another_block ) | ||
138 | #define end_reached (S()end_reached ) | ||
139 | #define inflate_stored_n (S()inflate_stored_n ) | ||
140 | #define inflate_stored_b (S()inflate_stored_b ) | ||
141 | #define inflate_stored_k (S()inflate_stored_k ) | ||
142 | #define inflate_stored_w (S()inflate_stored_w ) | ||
143 | #define INIT_STATE ({ bytebuffer_size = 0; method = -1; need_another_block = 1; }) | ||
144 | |||
145 | |||
146 | /* This is generic part */ | ||
147 | #if STATE_IN_BSS /* Use global data segment */ | ||
148 | #define DECLARE_STATE /*nothing*/ | ||
149 | #define ALLOC_STATE (init_state()) | ||
150 | #define DEALLOC_STATE ((void)0) | ||
151 | #define S() state. | ||
152 | #define PASS_STATE /*nothing*/ | ||
153 | #define PASS_STATE_ONLY /*nothing*/ | ||
154 | #define STATE_PARAM /*nothing*/ | ||
155 | #define STATE_PARAM_ONLY void | ||
156 | static state_t state; | ||
157 | static void init_state(void) | ||
158 | { | ||
159 | INIT_STATE; | ||
160 | } | ||
161 | #endif | ||
162 | |||
163 | #if STATE_IN_MALLOC /* Use malloc space */ | ||
164 | #define DECLARE_STATE state_t *state | ||
165 | #define ALLOC_STATE (state = alloc_state()) | ||
166 | #define DEALLOC_STATE free(state) | ||
167 | #define S() state-> | ||
168 | #define PASS_STATE state, | ||
169 | #define PASS_STATE_ONLY state | ||
170 | #define STATE_PARAM state_t *state, | ||
171 | #define STATE_PARAM_ONLY state_t *state | ||
172 | static state_t* alloc_state(void) | ||
173 | { | ||
174 | state_t* state = xzalloc(sizeof(*state)); | ||
175 | INIT_STATE; | ||
176 | return state; | ||
177 | } | ||
178 | #endif | ||
71 | 179 | ||
72 | /* These control the size of the bytebuffer */ | ||
73 | static unsigned bytebuffer_max = 0x8000; | ||
74 | static unsigned char *bytebuffer = NULL; | ||
75 | static unsigned bytebuffer_offset = 0; | ||
76 | static unsigned bytebuffer_size = 0; | ||
77 | 180 | ||
78 | static const unsigned short mask_bits[] = { | 181 | static const unsigned short mask_bits[] = { |
79 | 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, | 182 | 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, |
@@ -91,7 +194,7 @@ static const unsigned short cplens[] = { | |||
91 | static const unsigned char cplext[] = { | 194 | static const unsigned char cplext[] = { |
92 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, | 195 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, |
93 | 5, 5, 5, 0, 99, 99 | 196 | 5, 5, 5, 0, 99, 99 |
94 | }; /* 99==invalid */ | 197 | }; /* 99 == invalid */ |
95 | 198 | ||
96 | /* Copy offsets for distance codes 0..29 */ | 199 | /* Copy offsets for distance codes 0..29 */ |
97 | static const unsigned short cpdist[] = { | 200 | static const unsigned short cpdist[] = { |
@@ -111,7 +214,7 @@ static const unsigned char border[] = { | |||
111 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 | 214 | 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 |
112 | }; | 215 | }; |
113 | 216 | ||
114 | static unsigned fill_bitbuffer(unsigned bitbuffer, unsigned *current, const unsigned required) | 217 | static unsigned fill_bitbuffer(STATE_PARAM unsigned bitbuffer, unsigned *current, const unsigned required) |
115 | { | 218 | { |
116 | while (*current < required) { | 219 | while (*current < required) { |
117 | if (bytebuffer_offset >= bytebuffer_size) { | 220 | if (bytebuffer_offset >= bytebuffer_size) { |
@@ -201,7 +304,7 @@ static int huft_build(unsigned *b, const unsigned n, | |||
201 | p++; /* Can't combine with above line (Solaris bug) */ | 304 | p++; /* Can't combine with above line (Solaris bug) */ |
202 | } while (--i); | 305 | } while (--i); |
203 | if (c[0] == n) { /* null input--all zero length codes */ | 306 | if (c[0] == n) { /* null input--all zero length codes */ |
204 | *t = (huft_t *) NULL; | 307 | *t = NULL; |
205 | *m = 0; | 308 | *m = 0; |
206 | return 2; | 309 | return 2; |
207 | } | 310 | } |
@@ -250,8 +353,8 @@ static int huft_build(unsigned *b, const unsigned n, | |||
250 | p = v; /* grab values in bit order */ | 353 | p = v; /* grab values in bit order */ |
251 | htl = -1; /* no tables yet--level -1 */ | 354 | htl = -1; /* no tables yet--level -1 */ |
252 | w = ws[0] = 0; /* bits decoded */ | 355 | w = ws[0] = 0; /* bits decoded */ |
253 | u[0] = (huft_t *) NULL; /* just to keep compilers happy */ | 356 | u[0] = NULL; /* just to keep compilers happy */ |
254 | q = (huft_t *) NULL; /* ditto */ | 357 | q = NULL; /* ditto */ |
255 | z = 0; /* ditto */ | 358 | z = 0; /* ditto */ |
256 | 359 | ||
257 | /* go through the bit lengths (k already is bits in shortest code) */ | 360 | /* go through the bit lengths (k already is bits in shortest code) */ |
@@ -357,14 +460,7 @@ static int huft_build(unsigned *b, const unsigned n, | |||
357 | #define td inflate_codes_td | 460 | #define td inflate_codes_td |
358 | #define bl inflate_codes_bl | 461 | #define bl inflate_codes_bl |
359 | #define bd inflate_codes_bd | 462 | #define bd inflate_codes_bd |
360 | static unsigned ml, md; /* masks for bl and bd bits */ | 463 | static void inflate_codes_setup(STATE_PARAM huft_t * my_tl, huft_t * my_td, const unsigned my_bl, const unsigned my_bd) |
361 | static unsigned bb; /* bit buffer */ | ||
362 | static unsigned k; /* number of bits in bit buffer */ | ||
363 | static unsigned w; /* current gunzip_window position */ | ||
364 | static huft_t *tl, *td; | ||
365 | static unsigned bl, bd; | ||
366 | static int resumeCopy; /* = 0; */ | ||
367 | static void inflate_codes_setup(huft_t * my_tl, huft_t * my_td, const unsigned my_bl, const unsigned my_bd) | ||
368 | { | 464 | { |
369 | tl = my_tl; | 465 | tl = my_tl; |
370 | td = my_td; | 466 | td = my_td; |
@@ -379,26 +475,27 @@ static void inflate_codes_setup(huft_t * my_tl, huft_t * my_td, const unsigned m | |||
379 | md = mask_bits[bd]; | 475 | md = mask_bits[bd]; |
380 | } | 476 | } |
381 | /* called once from inflate_get_next_window */ | 477 | /* called once from inflate_get_next_window */ |
382 | static int inflate_codes(void) | 478 | static int inflate_codes(STATE_PARAM_ONLY) |
383 | { | 479 | { |
384 | unsigned e; /* table entry flag/number of extra bits */ | 480 | unsigned e; /* table entry flag/number of extra bits */ |
385 | huft_t *t; /* pointer to table entry */ | 481 | huft_t *t; /* pointer to table entry */ |
386 | 482 | ||
387 | if (resumeCopy) goto do_copy; | 483 | if (resume_copy) goto do_copy; |
388 | 484 | ||
389 | while (1) { /* do until end of block */ | 485 | while (1) { /* do until end of block */ |
390 | bb = fill_bitbuffer(bb, &k, bl); | 486 | bb = fill_bitbuffer(PASS_STATE bb, &k, bl); |
391 | t = tl + ((unsigned) bb & ml); | 487 | t = tl + ((unsigned) bb & ml); |
392 | e = t->e; | 488 | e = t->e; |
393 | if (e > 16) | 489 | if (e > 16) |
394 | do { | 490 | do { |
395 | if (e == 99) { | 491 | if (e == 99) { |
492 | //shouldn't we propagate error? | ||
396 | bb_error_msg_and_die("inflate_codes error 1"); | 493 | bb_error_msg_and_die("inflate_codes error 1"); |
397 | } | 494 | } |
398 | bb >>= t->b; | 495 | bb >>= t->b; |
399 | k -= t->b; | 496 | k -= t->b; |
400 | e -= 16; | 497 | e -= 16; |
401 | bb = fill_bitbuffer(bb, &k, e); | 498 | bb = fill_bitbuffer(PASS_STATE bb, &k, e); |
402 | t = t->v.t + ((unsigned) bb & mask_bits[e]); | 499 | t = t->v.t + ((unsigned) bb & mask_bits[e]); |
403 | e = t->e; | 500 | e = t->e; |
404 | } while (e > 16); | 501 | } while (e > 16); |
@@ -423,29 +520,30 @@ static int inflate_codes(void) | |||
423 | } | 520 | } |
424 | 521 | ||
425 | /* get length of block to copy */ | 522 | /* get length of block to copy */ |
426 | bb = fill_bitbuffer(bb, &k, e); | 523 | bb = fill_bitbuffer(PASS_STATE bb, &k, e); |
427 | n = t->v.n + ((unsigned) bb & mask_bits[e]); | 524 | n = t->v.n + ((unsigned) bb & mask_bits[e]); |
428 | bb >>= e; | 525 | bb >>= e; |
429 | k -= e; | 526 | k -= e; |
430 | 527 | ||
431 | /* decode distance of block to copy */ | 528 | /* decode distance of block to copy */ |
432 | bb = fill_bitbuffer(bb, &k, bd); | 529 | bb = fill_bitbuffer(PASS_STATE bb, &k, bd); |
433 | t = td + ((unsigned) bb & md); | 530 | t = td + ((unsigned) bb & md); |
434 | e = t->e; | 531 | e = t->e; |
435 | if (e > 16) | 532 | if (e > 16) |
436 | do { | 533 | do { |
437 | if (e == 99) | 534 | if (e == 99) |
535 | //shouldn't we propagate error? | ||
438 | bb_error_msg_and_die("inflate_codes error 2"); | 536 | bb_error_msg_and_die("inflate_codes error 2"); |
439 | bb >>= t->b; | 537 | bb >>= t->b; |
440 | k -= t->b; | 538 | k -= t->b; |
441 | e -= 16; | 539 | e -= 16; |
442 | bb = fill_bitbuffer(bb, &k, e); | 540 | bb = fill_bitbuffer(PASS_STATE bb, &k, e); |
443 | t = t->v.t + ((unsigned) bb & mask_bits[e]); | 541 | t = t->v.t + ((unsigned) bb & mask_bits[e]); |
444 | e = t->e; | 542 | e = t->e; |
445 | } while (e > 16); | 543 | } while (e > 16); |
446 | bb >>= t->b; | 544 | bb >>= t->b; |
447 | k -= t->b; | 545 | k -= t->b; |
448 | bb = fill_bitbuffer(bb, &k, e); | 546 | bb = fill_bitbuffer(PASS_STATE bb, &k, e); |
449 | d = w - t->v.n - ((unsigned) bb & mask_bits[e]); | 547 | d = w - t->v.n - ((unsigned) bb & mask_bits[e]); |
450 | bb >>= e; | 548 | bb >>= e; |
451 | k -= e; | 549 | k -= e; |
@@ -474,13 +572,13 @@ static int inflate_codes(void) | |||
474 | } | 572 | } |
475 | if (w == GUNZIP_WSIZE) { | 573 | if (w == GUNZIP_WSIZE) { |
476 | gunzip_outbuf_count = w; | 574 | gunzip_outbuf_count = w; |
477 | resumeCopy = (n != 0); | 575 | resume_copy = (n != 0); |
478 | //flush_gunzip_window(); | 576 | //flush_gunzip_window(); |
479 | w = 0; | 577 | w = 0; |
480 | return 1; | 578 | return 1; |
481 | } | 579 | } |
482 | } while (n); | 580 | } while (n); |
483 | resumeCopy = 0; | 581 | resume_copy = 0; |
484 | } | 582 | } |
485 | } | 583 | } |
486 | 584 | ||
@@ -508,9 +606,8 @@ static int inflate_codes(void) | |||
508 | #undef bd | 606 | #undef bd |
509 | 607 | ||
510 | 608 | ||
511 | static unsigned inflate_stored_n, inflate_stored_b, inflate_stored_k, inflate_stored_w; | ||
512 | /* called once from inflate_block */ | 609 | /* called once from inflate_block */ |
513 | static void inflate_stored_setup(int my_n, int my_b, int my_k) | 610 | static void inflate_stored_setup(STATE_PARAM int my_n, int my_b, int my_k) |
514 | { | 611 | { |
515 | inflate_stored_n = my_n; | 612 | inflate_stored_n = my_n; |
516 | inflate_stored_b = my_b; | 613 | inflate_stored_b = my_b; |
@@ -519,11 +616,11 @@ static void inflate_stored_setup(int my_n, int my_b, int my_k) | |||
519 | inflate_stored_w = gunzip_outbuf_count; | 616 | inflate_stored_w = gunzip_outbuf_count; |
520 | } | 617 | } |
521 | /* called once from inflate_get_next_window */ | 618 | /* called once from inflate_get_next_window */ |
522 | static int inflate_stored(void) | 619 | static int inflate_stored(STATE_PARAM_ONLY) |
523 | { | 620 | { |
524 | /* read and output the compressed data */ | 621 | /* read and output the compressed data */ |
525 | while (inflate_stored_n--) { | 622 | while (inflate_stored_n--) { |
526 | inflate_stored_b = fill_bitbuffer(inflate_stored_b, &inflate_stored_k, 8); | 623 | inflate_stored_b = fill_bitbuffer(PASS_STATE inflate_stored_b, &inflate_stored_k, 8); |
527 | gunzip_window[inflate_stored_w++] = (unsigned char) inflate_stored_b; | 624 | gunzip_window[inflate_stored_w++] = (unsigned char) inflate_stored_b; |
528 | if (inflate_stored_w == GUNZIP_WSIZE) { | 625 | if (inflate_stored_w == GUNZIP_WSIZE) { |
529 | gunzip_outbuf_count = inflate_stored_w; | 626 | gunzip_outbuf_count = inflate_stored_w; |
@@ -553,7 +650,7 @@ static int inflate_stored(void) | |||
553 | */ | 650 | */ |
554 | /* Return values: -1 = inflate_stored, -2 = inflate_codes */ | 651 | /* Return values: -1 = inflate_stored, -2 = inflate_codes */ |
555 | /* One callsite in inflate_get_next_window */ | 652 | /* One callsite in inflate_get_next_window */ |
556 | static int inflate_block(int *e) | 653 | static int inflate_block(STATE_PARAM smallint *e) |
557 | { | 654 | { |
558 | unsigned t; /* block type */ | 655 | unsigned t; /* block type */ |
559 | unsigned b; /* bit buffer */ | 656 | unsigned b; /* bit buffer */ |
@@ -565,13 +662,13 @@ static int inflate_block(int *e) | |||
565 | k = gunzip_bk; | 662 | k = gunzip_bk; |
566 | 663 | ||
567 | /* read in last block bit */ | 664 | /* read in last block bit */ |
568 | b = fill_bitbuffer(b, &k, 1); | 665 | b = fill_bitbuffer(PASS_STATE b, &k, 1); |
569 | *e = (int) b & 1; | 666 | *e = b & 1; |
570 | b >>= 1; | 667 | b >>= 1; |
571 | k -= 1; | 668 | k -= 1; |
572 | 669 | ||
573 | /* read in block type */ | 670 | /* read in block type */ |
574 | b = fill_bitbuffer(b, &k, 2); | 671 | b = fill_bitbuffer(PASS_STATE b, &k, 2); |
575 | t = (unsigned) b & 3; | 672 | t = (unsigned) b & 3; |
576 | b >>= 2; | 673 | b >>= 2; |
577 | k -= 2; | 674 | k -= 2; |
@@ -598,19 +695,19 @@ static int inflate_block(int *e) | |||
598 | k_stored -= n; | 695 | k_stored -= n; |
599 | 696 | ||
600 | /* get the length and its complement */ | 697 | /* get the length and its complement */ |
601 | b_stored = fill_bitbuffer(b_stored, &k_stored, 16); | 698 | b_stored = fill_bitbuffer(PASS_STATE b_stored, &k_stored, 16); |
602 | n = ((unsigned) b_stored & 0xffff); | 699 | n = ((unsigned) b_stored & 0xffff); |
603 | b_stored >>= 16; | 700 | b_stored >>= 16; |
604 | k_stored -= 16; | 701 | k_stored -= 16; |
605 | 702 | ||
606 | b_stored = fill_bitbuffer(b_stored, &k_stored, 16); | 703 | b_stored = fill_bitbuffer(PASS_STATE b_stored, &k_stored, 16); |
607 | if (n != (unsigned) ((~b_stored) & 0xffff)) { | 704 | if (n != (unsigned) ((~b_stored) & 0xffff)) { |
608 | return 1; /* error in compressed data */ | 705 | return 1; /* error in compressed data */ |
609 | } | 706 | } |
610 | b_stored >>= 16; | 707 | b_stored >>= 16; |
611 | k_stored -= 16; | 708 | k_stored -= 16; |
612 | 709 | ||
613 | inflate_stored_setup(n, b_stored, k_stored); // Setup inflate_stored | 710 | inflate_stored_setup(PASS_STATE n, b_stored, k_stored); // Setup inflate_stored |
614 | 711 | ||
615 | return -1; | 712 | return -1; |
616 | } | 713 | } |
@@ -658,7 +755,7 @@ static int inflate_block(int *e) | |||
658 | } | 755 | } |
659 | 756 | ||
660 | /* decompress until an end-of-block code */ | 757 | /* decompress until an end-of-block code */ |
661 | inflate_codes_setup(tl, td, bl, bd); // Setup inflate_codes | 758 | inflate_codes_setup(PASS_STATE tl, td, bl, bd); // Setup inflate_codes |
662 | 759 | ||
663 | /* huft_free code moved into inflate_codes */ | 760 | /* huft_free code moved into inflate_codes */ |
664 | 761 | ||
@@ -691,17 +788,17 @@ static int inflate_block(int *e) | |||
691 | k_dynamic = gunzip_bk; | 788 | k_dynamic = gunzip_bk; |
692 | 789 | ||
693 | /* read in table lengths */ | 790 | /* read in table lengths */ |
694 | b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 5); | 791 | b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 5); |
695 | nl = 257 + ((unsigned) b_dynamic & 0x1f); /* number of literal/length codes */ | 792 | nl = 257 + ((unsigned) b_dynamic & 0x1f); /* number of literal/length codes */ |
696 | 793 | ||
697 | b_dynamic >>= 5; | 794 | b_dynamic >>= 5; |
698 | k_dynamic -= 5; | 795 | k_dynamic -= 5; |
699 | b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 5); | 796 | b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 5); |
700 | nd = 1 + ((unsigned) b_dynamic & 0x1f); /* number of distance codes */ | 797 | nd = 1 + ((unsigned) b_dynamic & 0x1f); /* number of distance codes */ |
701 | 798 | ||
702 | b_dynamic >>= 5; | 799 | b_dynamic >>= 5; |
703 | k_dynamic -= 5; | 800 | k_dynamic -= 5; |
704 | b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 4); | 801 | b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 4); |
705 | nb = 4 + ((unsigned) b_dynamic & 0xf); /* number of bit length codes */ | 802 | nb = 4 + ((unsigned) b_dynamic & 0xf); /* number of bit length codes */ |
706 | 803 | ||
707 | b_dynamic >>= 4; | 804 | b_dynamic >>= 4; |
@@ -712,7 +809,7 @@ static int inflate_block(int *e) | |||
712 | 809 | ||
713 | /* read in bit-length-code lengths */ | 810 | /* read in bit-length-code lengths */ |
714 | for (j = 0; j < nb; j++) { | 811 | for (j = 0; j < nb; j++) { |
715 | b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 3); | 812 | b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 3); |
716 | ll[border[j]] = (unsigned) b_dynamic & 7; | 813 | ll[border[j]] = (unsigned) b_dynamic & 7; |
717 | b_dynamic >>= 3; | 814 | b_dynamic >>= 3; |
718 | k_dynamic -= 3; | 815 | k_dynamic -= 3; |
@@ -736,7 +833,7 @@ static int inflate_block(int *e) | |||
736 | m = mask_bits[bl]; | 833 | m = mask_bits[bl]; |
737 | i = l = 0; | 834 | i = l = 0; |
738 | while ((unsigned) i < n) { | 835 | while ((unsigned) i < n) { |
739 | b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, (unsigned)bl); | 836 | b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, (unsigned)bl); |
740 | j = (td = tl + ((unsigned) b_dynamic & m))->b; | 837 | j = (td = tl + ((unsigned) b_dynamic & m))->b; |
741 | b_dynamic >>= j; | 838 | b_dynamic >>= j; |
742 | k_dynamic -= j; | 839 | k_dynamic -= j; |
@@ -744,7 +841,7 @@ static int inflate_block(int *e) | |||
744 | if (j < 16) { /* length of code in bits (0..15) */ | 841 | if (j < 16) { /* length of code in bits (0..15) */ |
745 | ll[i++] = l = j; /* save last length in l */ | 842 | ll[i++] = l = j; /* save last length in l */ |
746 | } else if (j == 16) { /* repeat last length 3 to 6 times */ | 843 | } else if (j == 16) { /* repeat last length 3 to 6 times */ |
747 | b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 2); | 844 | b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 2); |
748 | j = 3 + ((unsigned) b_dynamic & 3); | 845 | j = 3 + ((unsigned) b_dynamic & 3); |
749 | b_dynamic >>= 2; | 846 | b_dynamic >>= 2; |
750 | k_dynamic -= 2; | 847 | k_dynamic -= 2; |
@@ -755,7 +852,7 @@ static int inflate_block(int *e) | |||
755 | ll[i++] = l; | 852 | ll[i++] = l; |
756 | } | 853 | } |
757 | } else if (j == 17) { /* 3 to 10 zero length codes */ | 854 | } else if (j == 17) { /* 3 to 10 zero length codes */ |
758 | b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 3); | 855 | b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 3); |
759 | j = 3 + ((unsigned) b_dynamic & 7); | 856 | j = 3 + ((unsigned) b_dynamic & 7); |
760 | b_dynamic >>= 3; | 857 | b_dynamic >>= 3; |
761 | k_dynamic -= 3; | 858 | k_dynamic -= 3; |
@@ -767,7 +864,7 @@ static int inflate_block(int *e) | |||
767 | } | 864 | } |
768 | l = 0; | 865 | l = 0; |
769 | } else { /* j == 18: 11 to 138 zero length codes */ | 866 | } else { /* j == 18: 11 to 138 zero length codes */ |
770 | b_dynamic = fill_bitbuffer(b_dynamic, &k_dynamic, 7); | 867 | b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 7); |
771 | j = 11 + ((unsigned) b_dynamic & 0x7f); | 868 | j = 11 + ((unsigned) b_dynamic & 0x7f); |
772 | b_dynamic >>= 7; | 869 | b_dynamic >>= 7; |
773 | k_dynamic -= 7; | 870 | k_dynamic -= 7; |
@@ -794,6 +891,7 @@ static int inflate_block(int *e) | |||
794 | i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl); | 891 | i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl); |
795 | if (i != 0) { | 892 | if (i != 0) { |
796 | if (i == 1) { | 893 | if (i == 1) { |
894 | //shouldn't we propagate error? | ||
797 | bb_error_msg_and_die("incomplete literal tree"); | 895 | bb_error_msg_and_die("incomplete literal tree"); |
798 | /* huft_free(tl); */ | 896 | /* huft_free(tl); */ |
799 | } | 897 | } |
@@ -804,6 +902,7 @@ static int inflate_block(int *e) | |||
804 | i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd); | 902 | i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd); |
805 | if (i != 0) { | 903 | if (i != 0) { |
806 | if (i == 1) { | 904 | if (i == 1) { |
905 | //shouldn't we propagate error? | ||
807 | bb_error_msg_and_die("incomplete distance tree"); | 906 | bb_error_msg_and_die("incomplete distance tree"); |
808 | /* huft_free(td); */ | 907 | /* huft_free(td); */ |
809 | } | 908 | } |
@@ -812,7 +911,7 @@ static int inflate_block(int *e) | |||
812 | } | 911 | } |
813 | 912 | ||
814 | /* decompress until an end-of-block code */ | 913 | /* decompress until an end-of-block code */ |
815 | inflate_codes_setup(tl, td, bl, bd); // Setup inflate_codes | 914 | inflate_codes_setup(PASS_STATE tl, td, bl, bd); // Setup inflate_codes |
816 | 915 | ||
817 | /* huft_free code moved into inflate_codes */ | 916 | /* huft_free code moved into inflate_codes */ |
818 | 917 | ||
@@ -820,12 +919,13 @@ static int inflate_block(int *e) | |||
820 | } | 919 | } |
821 | default: | 920 | default: |
822 | /* bad block type */ | 921 | /* bad block type */ |
922 | //shouldn't we propagate error? | ||
823 | bb_error_msg_and_die("bad block type %d", t); | 923 | bb_error_msg_and_die("bad block type %d", t); |
824 | } | 924 | } |
825 | } | 925 | } |
826 | 926 | ||
827 | /* Two callsites, both in inflate_get_next_window */ | 927 | /* Two callsites, both in inflate_get_next_window */ |
828 | static void calculate_gunzip_crc(void) | 928 | static void calculate_gunzip_crc(STATE_PARAM_ONLY) |
829 | { | 929 | { |
830 | int n; | 930 | int n; |
831 | for (n = 0; n < gunzip_outbuf_count; n++) { | 931 | for (n = 0; n < gunzip_outbuf_count; n++) { |
@@ -835,44 +935,41 @@ static void calculate_gunzip_crc(void) | |||
835 | } | 935 | } |
836 | 936 | ||
837 | /* One callsite in inflate_unzip_internal */ | 937 | /* One callsite in inflate_unzip_internal */ |
838 | static int inflate_get_next_window(void) | 938 | static int inflate_get_next_window(STATE_PARAM_ONLY) |
839 | { | 939 | { |
840 | static int method = -1; // Method == -1 for stored, -2 for codes | ||
841 | static int e = 0; | ||
842 | static int needAnotherBlock = 1; | ||
843 | |||
844 | gunzip_outbuf_count = 0; | 940 | gunzip_outbuf_count = 0; |
845 | 941 | ||
846 | while (1) { | 942 | while (1) { |
847 | int ret; | 943 | int ret; |
848 | 944 | ||
849 | if (needAnotherBlock) { | 945 | if (need_another_block) { |
850 | if (e) { | 946 | if (end_reached) { |
851 | calculate_gunzip_crc(); | 947 | calculate_gunzip_crc(PASS_STATE_ONLY); |
852 | e = 0; | 948 | end_reached = 0; |
853 | needAnotherBlock = 1; | 949 | need_another_block = 1; |
854 | return 0; | 950 | return 0; /* Last block */ |
855 | } // Last block | 951 | } |
856 | method = inflate_block(&e); | 952 | method = inflate_block(PASS_STATE &end_reached); |
857 | needAnotherBlock = 0; | 953 | need_another_block = 0; |
858 | } | 954 | } |
859 | 955 | ||
860 | switch (method) { | 956 | switch (method) { |
861 | case -1: | 957 | case -1: |
862 | ret = inflate_stored(); | 958 | ret = inflate_stored(PASS_STATE_ONLY); |
863 | break; | 959 | break; |
864 | case -2: | 960 | case -2: |
865 | ret = inflate_codes(); | 961 | ret = inflate_codes(PASS_STATE_ONLY); |
866 | break; | 962 | break; |
867 | default: | 963 | default: |
964 | //shouldn't we propagate error? | ||
868 | bb_error_msg_and_die("inflate error %d", method); | 965 | bb_error_msg_and_die("inflate error %d", method); |
869 | } | 966 | } |
870 | 967 | ||
871 | if (ret == 1) { | 968 | if (ret == 1) { |
872 | calculate_gunzip_crc(); | 969 | calculate_gunzip_crc(PASS_STATE_ONLY); |
873 | return 1; // More data left | 970 | return 1; // More data left |
874 | } else | 971 | } |
875 | needAnotherBlock = 1; // End of that block | 972 | need_another_block = 1; // End of that block |
876 | } | 973 | } |
877 | /* Doesnt get here */ | 974 | /* Doesnt get here */ |
878 | } | 975 | } |
@@ -881,7 +978,7 @@ static int inflate_get_next_window(void) | |||
881 | /* Called from inflate_gunzip() and inflate_unzip() */ | 978 | /* Called from inflate_gunzip() and inflate_unzip() */ |
882 | /* NB: bytebuffer is allocated here but freeing it is left to the caller! */ | 979 | /* NB: bytebuffer is allocated here but freeing it is left to the caller! */ |
883 | static USE_DESKTOP(long long) int | 980 | static USE_DESKTOP(long long) int |
884 | inflate_unzip_internal(int in, int out) | 981 | inflate_unzip_internal(STATE_PARAM int in, int out) |
885 | { | 982 | { |
886 | USE_DESKTOP(long long) int n = 0; | 983 | USE_DESKTOP(long long) int n = 0; |
887 | ssize_t nwrote; | 984 | ssize_t nwrote; |
@@ -904,7 +1001,7 @@ inflate_unzip_internal(int in, int out) | |||
904 | bytebuffer = xmalloc(bytebuffer_max); | 1001 | bytebuffer = xmalloc(bytebuffer_max); |
905 | 1002 | ||
906 | while (1) { | 1003 | while (1) { |
907 | int r = inflate_get_next_window(); | 1004 | int r = inflate_get_next_window(PASS_STATE_ONLY); |
908 | nwrote = full_write(out, gunzip_window, gunzip_outbuf_count); | 1005 | nwrote = full_write(out, gunzip_window, gunzip_outbuf_count); |
909 | if (nwrote != gunzip_outbuf_count) { | 1006 | if (nwrote != gunzip_outbuf_count) { |
910 | bb_perror_msg("write"); | 1007 | bb_perror_msg("write"); |
@@ -936,16 +1033,18 @@ USE_DESKTOP(long long) int | |||
936 | inflate_unzip(inflate_unzip_result *res, unsigned bufsize, int in, int out) | 1033 | inflate_unzip(inflate_unzip_result *res, unsigned bufsize, int in, int out) |
937 | { | 1034 | { |
938 | USE_DESKTOP(long long) int n; | 1035 | USE_DESKTOP(long long) int n; |
1036 | DECLARE_STATE; | ||
1037 | |||
1038 | ALLOC_STATE; | ||
939 | 1039 | ||
940 | bytebuffer_max = bufsize + 8; | 1040 | bytebuffer_max = bufsize + 8; |
941 | bytebuffer_offset = 4; | 1041 | bytebuffer_offset = 4; |
942 | bytebuffer_size = 0; | 1042 | n = inflate_unzip_internal(PASS_STATE in, out); |
943 | |||
944 | n = inflate_unzip_internal(in, out); | ||
945 | 1043 | ||
946 | res->crc = gunzip_crc; | 1044 | res->crc = gunzip_crc; |
947 | res->bytes_out = gunzip_bytes_out; | 1045 | res->bytes_out = gunzip_bytes_out; |
948 | free(bytebuffer); | 1046 | free(bytebuffer); |
1047 | DEALLOC_STATE; | ||
949 | return n; | 1048 | return n; |
950 | } | 1049 | } |
951 | 1050 | ||
@@ -956,8 +1055,12 @@ inflate_gunzip(int in, int out) | |||
956 | uint32_t stored_crc = 0; | 1055 | uint32_t stored_crc = 0; |
957 | unsigned count; | 1056 | unsigned count; |
958 | USE_DESKTOP(long long) int n; | 1057 | USE_DESKTOP(long long) int n; |
1058 | DECLARE_STATE; | ||
1059 | |||
1060 | ALLOC_STATE; | ||
959 | 1061 | ||
960 | n = inflate_unzip_internal(in, out); | 1062 | bytebuffer_max = 0x8000; |
1063 | n = inflate_unzip_internal(PASS_STATE in, out); | ||
961 | 1064 | ||
962 | if (n < 0) goto ret; | 1065 | if (n < 0) goto ret; |
963 | 1066 | ||
@@ -990,5 +1093,6 @@ inflate_gunzip(int in, int out) | |||
990 | } | 1093 | } |
991 | ret: | 1094 | ret: |
992 | free(bytebuffer); | 1095 | free(bytebuffer); |
1096 | DEALLOC_STATE; | ||
993 | return n; | 1097 | return n; |
994 | } | 1098 | } |