aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-01-05 23:58:45 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-01-05 23:58:45 +0000
commitd1a19affeb83a4c33ac0fc9dde3a27232fa23767 (patch)
tree635b243fe742f0eaa782a338ae9ffce166cd3383
parentcd42cb8df066ffd4449af6de168190669dad4453 (diff)
downloadbusybox-w32-d1a19affeb83a4c33ac0fc9dde3a27232fa23767.tar.gz
busybox-w32-d1a19affeb83a4c33ac0fc9dde3a27232fa23767.tar.bz2
busybox-w32-d1a19affeb83a4c33ac0fc9dde3a27232fa23767.zip
split inflate_xx_setup() subroutines from inflate_xx()
-rw-r--r--archival/libunarchive/decompress_unzip.c265
1 files changed, 146 insertions, 119 deletions
diff --git a/archival/libunarchive/decompress_unzip.c b/archival/libunarchive/decompress_unzip.c
index af74e6598..9e8fd7e03 100644
--- a/archival/libunarchive/decompress_unzip.c
+++ b/archival/libunarchive/decompress_unzip.c
@@ -45,22 +45,25 @@ typedef struct huft_s {
45 } v; 45 } v;
46} huft_t; 46} huft_t;
47 47
48enum {
49 /* gunzip_window size--must be a power of two, and
50 * at least 32K for zip's deflate method */
51 GUNZIP_WSIZE = 0x8000,
52 /* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
53 BMAX = 16, /* maximum bit length of any code (16 for explode) */
54 N_MAX = 288, /* maximum number of codes in any set */
55};
56
48static off_t gunzip_bytes_out; /* number of output bytes */ 57static off_t gunzip_bytes_out; /* number of output bytes */
49static uint32_t gunzip_crc; 58static uint32_t gunzip_crc;
50 59
51static int gunzip_src_fd; 60static int gunzip_src_fd;
52static unsigned gunzip_outbuf_count; /* bytes in output buffer */ 61static unsigned gunzip_outbuf_count; /* bytes in output buffer */
53 62
54/* gunzip_window size--must be a power of two, and
55 * at least 32K for zip's deflate method */
56enum { gunzip_wsize = 0x8000 };
57static unsigned char *gunzip_window; 63static unsigned char *gunzip_window;
58 64
59static uint32_t *gunzip_crc_table; 65static uint32_t *gunzip_crc_table;
60 66
61/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
62#define BMAX 16 /* maximum bit length of any code (16 for explode) */
63#define N_MAX 288 /* maximum number of codes in any set */
64 67
65/* bitbuffer */ 68/* bitbuffer */
66static unsigned gunzip_bb; /* bit buffer */ 69static unsigned gunzip_bb; /* bit buffer */
@@ -135,19 +138,16 @@ static unsigned fill_bitbuffer(unsigned bitbuffer, unsigned *current, const unsi
135 * each table. 138 * each table.
136 * t: table to free 139 * t: table to free
137 */ 140 */
138static int huft_free(huft_t * t) 141static void huft_free(huft_t * p)
139{ 142{
140 huft_t *p;
141 huft_t *q; 143 huft_t *q;
142 144
143 /* Go through linked list, freeing from the malloced (t[-1]) address. */ 145 /* Go through linked list, freeing from the malloced (t[-1]) address. */
144 p = t; 146 while (p) {
145 while (p != (huft_t *) NULL) {
146 q = (--p)->v.t; 147 q = (--p)->v.t;
147 free((char *) p); 148 free(p);
148 p = q; 149 p = q;
149 } 150 }
150 return 0;
151} 151}
152 152
153/* Given a list of code lengths and a maximum table size, make a set of 153/* Given a list of code lengths and a maximum table size, make a set of
@@ -339,6 +339,7 @@ static int huft_build(unsigned *b, const unsigned n,
339 return y != 0 && g != 1; 339 return y != 0 && g != 1;
340} 340}
341 341
342
342/* 343/*
343 * inflate (decompress) the codes in a deflated (compressed) block. 344 * inflate (decompress) the codes in a deflated (compressed) block.
344 * Return an error code or zero if it all goes ok. 345 * Return an error code or zero if it all goes ok.
@@ -346,106 +347,116 @@ static int huft_build(unsigned *b, const unsigned n,
346 * tl, td: literal/length and distance decoder tables 347 * tl, td: literal/length and distance decoder tables
347 * bl, bd: number of bits decoded by tl[] and td[] 348 * bl, bd: number of bits decoded by tl[] and td[]
348 */ 349 */
349/* called with setup==1 once from inflate_block */ 350/* called once from inflate_block */
350/* called once with setup==0 from inflate_get_next_window */ 351#define ml inflate_codes_ml
351static int inflate_codes(huft_t * my_tl, huft_t * my_td, const unsigned my_bl, const unsigned my_bd, int setup) 352#define md inflate_codes_md
353#define bb inflate_codes_bb
354#define k inflate_codes_k
355#define w inflate_codes_w
356#define tl inflate_codes_tl
357#define td inflate_codes_td
358#define bl inflate_codes_bl
359#define bd inflate_codes_bd
360static unsigned ml, md; /* masks for bl and bd bits */
361static unsigned bb; /* bit buffer */
362static unsigned k; /* number of bits in bit buffer */
363static unsigned w; /* current gunzip_window position */
364static huft_t *tl, *td;
365static unsigned bl, bd;
366static int resumeCopy; /* = 0; */
367static void inflate_codes_setup(huft_t * my_tl, huft_t * my_td, const unsigned my_bl, const unsigned my_bd)
352{ 368{
353 static unsigned e; /* table entry flag/number of extra bits */ 369 tl = my_tl;
354 static unsigned n, d; /* length and index for copy */ 370 td = my_td;
355 static unsigned w; /* current gunzip_window position */ 371 bl = my_bl;
356 static huft_t *t; /* pointer to table entry */ 372 bd = my_bd;
357 static unsigned ml, md; /* masks for bl and bd bits */ 373 /* make local copies of globals */
358 static unsigned b; /* bit buffer */ 374 bb = gunzip_bb; /* initialize bit buffer */
359 static unsigned k; /* number of bits in bit buffer */ 375 k = gunzip_bk;
360 static huft_t *tl, *td; 376 w = gunzip_outbuf_count; /* initialize gunzip_window position */
361 static unsigned bl, bd; 377 /* inflate the coded data */
362 static int resumeCopy = 0; 378 ml = mask_bits[bl]; /* precompute masks for speed */
363 379 md = mask_bits[bd];
364 if (setup) { // 1st time we are called, copy in variables 380}
365 tl = my_tl; 381/* called once from inflate_get_next_window */
366 td = my_td; 382static int inflate_codes(void)
367 bl = my_bl; 383{
368 bd = my_bd; 384 unsigned e; /* table entry flag/number of extra bits */
369 /* make local copies of globals */ 385 huft_t *t; /* pointer to table entry */
370 b = gunzip_bb; /* initialize bit buffer */
371 k = gunzip_bk;
372 w = gunzip_outbuf_count; /* initialize gunzip_window position */
373
374 /* inflate the coded data */
375 ml = mask_bits[bl]; /* precompute masks for speed */
376 md = mask_bits[bd];
377 return 0; // Don't actually do anything the first time
378 }
379 386
380 if (resumeCopy) goto do_copy; 387 if (resumeCopy) goto do_copy;
381 388
382 while (1) { /* do until end of block */ 389 while (1) { /* do until end of block */
383 b = fill_bitbuffer(b, &k, bl); 390 bb = fill_bitbuffer(bb, &k, bl);
384 t = tl + ((unsigned) b & ml); 391 t = tl + ((unsigned) bb & ml);
385 e = t->e; 392 e = t->e;
386 if (e > 16) 393 if (e > 16)
387 do { 394 do {
388 if (e == 99) { 395 if (e == 99) {
389 bb_error_msg_and_die("inflate_codes error 1"); 396 bb_error_msg_and_die("inflate_codes error 1");
390 } 397 }
391 b >>= t->b; 398 bb >>= t->b;
392 k -= t->b; 399 k -= t->b;
393 e -= 16; 400 e -= 16;
394 b = fill_bitbuffer(b, &k, e); 401 bb = fill_bitbuffer(bb, &k, e);
395 t = t->v.t + ((unsigned) b & mask_bits[e]); 402 t = t->v.t + ((unsigned) bb & mask_bits[e]);
396 e = t->e; 403 e = t->e;
397 } while (e > 16); 404 } while (e > 16);
398 b >>= t->b; 405 bb >>= t->b;
399 k -= t->b; 406 k -= t->b;
400 if (e == 16) { /* then it's a literal */ 407 if (e == 16) { /* then it's a literal */
401 gunzip_window[w++] = (unsigned char) t->v.n; 408 gunzip_window[w++] = (unsigned char) t->v.n;
402 if (w == gunzip_wsize) { 409 if (w == GUNZIP_WSIZE) {
403 gunzip_outbuf_count = (w); 410 gunzip_outbuf_count = w;
404 //flush_gunzip_window(); 411 //flush_gunzip_window();
405 w = 0; 412 w = 0;
406 return 1; // We have a block to read 413 return 1; // We have a block to read
407 } 414 }
408 } else { /* it's an EOB or a length */ 415 } else { /* it's an EOB or a length */
416 /* length and index for copy */
417 unsigned n = n; /* for gcc */
418 unsigned d = d; /* for gcc */
419
409 /* exit if end of block */ 420 /* exit if end of block */
410 if (e == 15) { 421 if (e == 15) {
411 break; 422 break;
412 } 423 }
413 424
414 /* get length of block to copy */ 425 /* get length of block to copy */
415 b = fill_bitbuffer(b, &k, e); 426 bb = fill_bitbuffer(bb, &k, e);
416 n = t->v.n + ((unsigned) b & mask_bits[e]); 427 n = t->v.n + ((unsigned) bb & mask_bits[e]);
417 b >>= e; 428 bb >>= e;
418 k -= e; 429 k -= e;
419 430
420 /* decode distance of block to copy */ 431 /* decode distance of block to copy */
421 b = fill_bitbuffer(b, &k, bd); 432 bb = fill_bitbuffer(bb, &k, bd);
422 t = td + ((unsigned) b & md); 433 t = td + ((unsigned) bb & md);
423 e = t->e; 434 e = t->e;
424 if (e > 16) 435 if (e > 16)
425 do { 436 do {
426 if (e == 99) 437 if (e == 99)
427 bb_error_msg_and_die("inflate_codes error 2"); 438 bb_error_msg_and_die("inflate_codes error 2");
428 b >>= t->b; 439 bb >>= t->b;
429 k -= t->b; 440 k -= t->b;
430 e -= 16; 441 e -= 16;
431 b = fill_bitbuffer(b, &k, e); 442 bb = fill_bitbuffer(bb, &k, e);
432 t = t->v.t + ((unsigned) b & mask_bits[e]); 443 t = t->v.t + ((unsigned) bb & mask_bits[e]);
433 e = t->e; 444 e = t->e;
434 } while (e > 16); 445 } while (e > 16);
435 b >>= t->b; 446 bb >>= t->b;
436 k -= t->b; 447 k -= t->b;
437 b = fill_bitbuffer(b, &k, e); 448 bb = fill_bitbuffer(bb, &k, e);
438 d = w - t->v.n - ((unsigned) b & mask_bits[e]); 449 d = w - t->v.n - ((unsigned) bb & mask_bits[e]);
439 b >>= e; 450 bb >>= e;
440 k -= e; 451 k -= e;
441 452
442 /* do the copy */ 453 /* do the copy */
443 do_copy: 454 do_copy:
444 do { 455 do {
445 /* Was: n -= (e = (e = gunzip_wsize - ((d &= gunzip_wsize - 1) > w ? d : w)) > n ? n : e); */ 456 /* Was: n -= (e = (e = GUNZIP_WSIZE - ((d &= GUNZIP_WSIZE - 1) > w ? d : w)) > n ? n : e); */
446 /* Who wrote THAT?? rewritten as: */ 457 /* Who wrote THAT?? rewritten as: */
447 d &= gunzip_wsize - 1; 458 d &= GUNZIP_WSIZE - 1;
448 e = gunzip_wsize - (d > w ? d : w); 459 e = GUNZIP_WSIZE - (d > w ? d : w);
449 if (e > n) e = n; 460 if (e > n) e = n;
450 n -= e; 461 n -= e;
451 462
@@ -461,8 +472,8 @@ static int inflate_codes(huft_t * my_tl, huft_t * my_td, const unsigned my_bl, c
461 gunzip_window[w++] = gunzip_window[d++]; 472 gunzip_window[w++] = gunzip_window[d++];
462 } while (--e); 473 } while (--e);
463 } 474 }
464 if (w == gunzip_wsize) { 475 if (w == GUNZIP_WSIZE) {
465 gunzip_outbuf_count = (w); 476 gunzip_outbuf_count = w;
466 resumeCopy = (n != 0); 477 resumeCopy = (n != 0);
467 //flush_gunzip_window(); 478 //flush_gunzip_window();
468 w = 0; 479 w = 0;
@@ -474,8 +485,8 @@ static int inflate_codes(huft_t * my_tl, huft_t * my_td, const unsigned my_bl, c
474 } 485 }
475 486
476 /* restore the globals from the locals */ 487 /* restore the globals from the locals */
477 gunzip_outbuf_count = w; /* restore global gunzip_window pointer */ 488 gunzip_outbuf_count = w; /* restore global gunzip_window pointer */
478 gunzip_bb = b; /* restore global bit buffer */ 489 gunzip_bb = bb; /* restore global bit buffer */
479 gunzip_bk = k; 490 gunzip_bk = k;
480 491
481 /* normally just after call to inflate_codes, but save code by putting it here */ 492 /* normally just after call to inflate_codes, but save code by putting it here */
@@ -486,44 +497,54 @@ static int inflate_codes(huft_t * my_tl, huft_t * my_td, const unsigned my_bl, c
486 /* done */ 497 /* done */
487 return 0; 498 return 0;
488} 499}
489 500#undef ml
490/* called once (setup==1) from inflate_block */ 501#undef md
491/* and once (setup==0) from inflate_get_next_window */ 502#undef bb
492static int inflate_stored(int my_n, int my_b_stored, int my_k_stored, int setup) 503#undef k
504#undef w
505#undef tl
506#undef td
507#undef bl
508#undef bd
509
510
511static unsigned inflate_stored_n, inflate_stored_b, inflate_stored_k, inflate_stored_w;
512/* called once from inflate_block */
513static void inflate_stored_setup(int my_n, int my_b, int my_k)
514{
515 inflate_stored_n = my_n;
516 inflate_stored_b = my_b;
517 inflate_stored_k = my_k;
518 /* initialize gunzip_window position */
519 inflate_stored_w = gunzip_outbuf_count;
520}
521/* called once from inflate_get_next_window */
522static int inflate_stored(void)
493{ 523{
494 static unsigned n, b_stored, k_stored, w;
495
496 if (setup) {
497 n = my_n;
498 b_stored = my_b_stored;
499 k_stored = my_k_stored;
500 w = gunzip_outbuf_count; /* initialize gunzip_window position */
501 return 0; // Don't do anything first time
502 }
503
504 /* read and output the compressed data */ 524 /* read and output the compressed data */
505 while (n--) { 525 while (inflate_stored_n--) {
506 b_stored = fill_bitbuffer(b_stored, &k_stored, 8); 526 inflate_stored_b = fill_bitbuffer(inflate_stored_b, &inflate_stored_k, 8);
507 gunzip_window[w++] = (unsigned char) b_stored; 527 gunzip_window[inflate_stored_w++] = (unsigned char) inflate_stored_b;
508 if (w == gunzip_wsize) { 528 if (inflate_stored_w == GUNZIP_WSIZE) {
509 gunzip_outbuf_count = (w); 529 gunzip_outbuf_count = inflate_stored_w;
510 //flush_gunzip_window(); 530 //flush_gunzip_window();
511 w = 0; 531 inflate_stored_w = 0;
512 b_stored >>= 8; 532 inflate_stored_b >>= 8;
513 k_stored -= 8; 533 inflate_stored_k -= 8;
514 return 1; // We have a block 534 return 1; // We have a block
515 } 535 }
516 b_stored >>= 8; 536 inflate_stored_b >>= 8;
517 k_stored -= 8; 537 inflate_stored_k -= 8;
518 } 538 }
519 539
520 /* restore the globals from the locals */ 540 /* restore the globals from the locals */
521 gunzip_outbuf_count = w; /* restore global gunzip_window pointer */ 541 gunzip_outbuf_count = inflate_stored_w; /* restore global gunzip_window pointer */
522 gunzip_bb = b_stored; /* restore global bit buffer */ 542 gunzip_bb = inflate_stored_b; /* restore global bit buffer */
523 gunzip_bk = k_stored; 543 gunzip_bk = inflate_stored_k;
524 return 0; // Finished 544 return 0; // Finished
525} 545}
526 546
547
527/* 548/*
528 * decompress an inflated block 549 * decompress an inflated block
529 * e: last block flag 550 * e: last block flag
@@ -589,7 +610,8 @@ static int inflate_block(int *e)
589 b_stored >>= 16; 610 b_stored >>= 16;
590 k_stored -= 16; 611 k_stored -= 16;
591 612
592 inflate_stored(n, b_stored, k_stored, 1); // Setup inflate_stored 613 inflate_stored_setup(n, b_stored, k_stored); // Setup inflate_stored
614
593 return -1; 615 return -1;
594 } 616 }
595 case 1: 617 case 1:
@@ -636,7 +658,7 @@ static int inflate_block(int *e)
636 } 658 }
637 659
638 /* decompress until an end-of-block code */ 660 /* decompress until an end-of-block code */
639 inflate_codes(tl, td, bl, bd, 1); // Setup inflate_codes 661 inflate_codes_setup(tl, td, bl, bd); // Setup inflate_codes
640 662
641 /* huft_free code moved into inflate_codes */ 663 /* huft_free code moved into inflate_codes */
642 664
@@ -790,7 +812,7 @@ static int inflate_block(int *e)
790 } 812 }
791 813
792 /* decompress until an end-of-block code */ 814 /* decompress until an end-of-block code */
793 inflate_codes(tl, td, bl, bd, 1); // Setup inflate_codes 815 inflate_codes_setup(tl, td, bl, bd); // Setup inflate_codes
794 816
795 /* huft_free code moved into inflate_codes */ 817 /* huft_free code moved into inflate_codes */
796 818
@@ -812,7 +834,7 @@ static void calculate_gunzip_crc(void)
812 gunzip_bytes_out += gunzip_outbuf_count; 834 gunzip_bytes_out += gunzip_outbuf_count;
813} 835}
814 836
815/* One callsite in inflate_unzip */ 837/* One callsite in inflate_unzip_internal */
816static int inflate_get_next_window(void) 838static int inflate_get_next_window(void)
817{ 839{
818 static int method = -1; // Method == -1 for stored, -2 for codes 840 static int method = -1; // Method == -1 for stored, -2 for codes
@@ -825,7 +847,7 @@ static int inflate_get_next_window(void)
825 int ret; 847 int ret;
826 848
827 if (needAnotherBlock) { 849 if (needAnotherBlock) {
828 if(e) { 850 if (e) {
829 calculate_gunzip_crc(); 851 calculate_gunzip_crc();
830 e = 0; 852 e = 0;
831 needAnotherBlock = 1; 853 needAnotherBlock = 1;
@@ -836,32 +858,36 @@ static int inflate_get_next_window(void)
836 } 858 }
837 859
838 switch (method) { 860 switch (method) {
839 case -1: ret = inflate_stored(0,0,0,0); 861 case -1:
840 break; 862 ret = inflate_stored();
841 case -2: ret = inflate_codes(0,0,0,0,0); 863 break;
842 break; 864 case -2:
843 default: bb_error_msg_and_die("inflate error %d", method); 865 ret = inflate_codes();
866 break;
867 default:
868 bb_error_msg_and_die("inflate error %d", method);
844 } 869 }
845 870
846 if (ret == 1) { 871 if (ret == 1) {
847 calculate_gunzip_crc(); 872 calculate_gunzip_crc();
848 return 1; // More data left 873 return 1; // More data left
849 } else needAnotherBlock = 1; // End of that block 874 } else
875 needAnotherBlock = 1; // End of that block
850 } 876 }
851 /* Doesnt get here */ 877 /* Doesnt get here */
852} 878}
853 879
854 880
855/* Called from inflate_gunzip() and archival/unzip.c */ 881/* Called from inflate_gunzip() and inflate_unzip() */
882/* NB: bytebuffer is allocated here but freeing it is left to the caller! */
856static USE_DESKTOP(long long) int 883static USE_DESKTOP(long long) int
857inflate_unzip_internal(int in, int out) 884inflate_unzip_internal(int in, int out)
858{ 885{
859 USE_DESKTOP(long long total = 0;) 886 USE_DESKTOP(long long) int n = 0;
860 ssize_t nwrote; 887 ssize_t nwrote;
861 typedef void (*sig_type) (int);
862 888
863 /* Allocate all global buffers (for DYN_ALLOC option) */ 889 /* Allocate all global buffers (for DYN_ALLOC option) */
864 gunzip_window = xmalloc(gunzip_wsize); 890 gunzip_window = xmalloc(GUNZIP_WSIZE);
865 gunzip_outbuf_count = 0; 891 gunzip_outbuf_count = 0;
866 gunzip_bytes_out = 0; 892 gunzip_bytes_out = 0;
867 gunzip_src_fd = in; 893 gunzip_src_fd = in;
@@ -878,20 +904,17 @@ inflate_unzip_internal(int in, int out)
878 bytebuffer = xmalloc(bytebuffer_max); 904 bytebuffer = xmalloc(bytebuffer_max);
879 905
880 while (1) { 906 while (1) {
881 int ret = inflate_get_next_window(); 907 int r = inflate_get_next_window();
882 nwrote = full_write(out, gunzip_window, gunzip_outbuf_count); 908 nwrote = full_write(out, gunzip_window, gunzip_outbuf_count);
883 if (nwrote != gunzip_outbuf_count) { 909 if (nwrote != gunzip_outbuf_count) {
884 bb_perror_msg("write"); 910 bb_perror_msg("write");
885 return -1; 911 n = -1;
912 goto ret;
886 } 913 }
887 USE_DESKTOP(total += nwrote;) 914 USE_DESKTOP(n += nwrote;)
888 if (ret == 0) break; 915 if (r == 0) break;
889 } 916 }
890 917
891 /* Cleanup */
892 free(gunzip_window);
893 free(gunzip_crc_table);
894
895 /* Store unused bytes in a global buffer so calling applets can access it */ 918 /* Store unused bytes in a global buffer so calling applets can access it */
896 if (gunzip_bk >= 8) { 919 if (gunzip_bk >= 8) {
897 /* Undo too much lookahead. The next read will be byte aligned 920 /* Undo too much lookahead. The next read will be byte aligned
@@ -901,7 +924,11 @@ inflate_unzip_internal(int in, int out)
901 gunzip_bb >>= 8; 924 gunzip_bb >>= 8;
902 gunzip_bk -= 8; 925 gunzip_bk -= 8;
903 } 926 }
904 return USE_DESKTOP(total) + 0; 927 ret:
928 /* Cleanup */
929 free(gunzip_window);
930 free(gunzip_crc_table);
931 return n;
905} 932}
906 933
907 934