decompress_unzip.c
来自「最新的busybox源码」· C语言 代码 · 共 1,254 行 · 第 1/3 页
C
1,254 行
t = &(q->v.t); u[htl] = ++q; /* table starts after link */ /* connect to last table, if there is one */ if (htl) { x[htl] = i; /* save pattern for backing up */ r.b = (unsigned char) (w - ws[htl - 1]); /* bits to dump before this table */ r.e = (unsigned char) (16 + j); /* bits in this table */ r.v.t = q; /* pointer to this table */ j = (i & ((1 << w) - 1)) >> ws[htl - 1]; u[htl - 1][j] = r; /* connect to last table */ } } /* set up table entry in r */ r.b = (unsigned char) (k - w); if (p >= v + n) { r.e = 99; /* out of values--invalid code */ } else if (*p < s) { r.e = (unsigned char) (*p < 256 ? 16 : 15); /* 256 is EOB code */ r.v.n = (unsigned short) (*p++); /* simple code is just the value */ } else { r.e = (unsigned char) e[*p - s]; /* non-simple--look up in lists */ r.v.n = d[*p++ - s]; } /* fill code-like entries with r */ f = 1 << (k - w); for (j = i >> w; j < z; j += f) { q[j] = r; } /* backwards increment the k-bit code i */ for (j = 1 << (k - 1); i & j; j >>= 1) { i ^= j; } i ^= j; /* backup over finished tables */ while ((i & ((1 << w) - 1)) != x[htl]) { w = ws[--htl]; } } } /* return actual size of base table */ *m = ws[1]; /* Return 1 if we were given an incomplete table */ return y != 0 && g != 1;}/* * inflate (decompress) the codes in a deflated (compressed) block. * Return an error code or zero if it all goes ok. * * tl, td: literal/length and distance decoder tables * bl, bd: number of bits decoded by tl[] and td[] *//* called once from inflate_block *//* map formerly local static variables to globals */#define ml inflate_codes_ml#define md inflate_codes_md#define bb inflate_codes_bb#define k inflate_codes_k#define w inflate_codes_w#define tl inflate_codes_tl#define td inflate_codes_td#define bl inflate_codes_bl#define bd inflate_codes_bd#define nn inflate_codes_nn#define dd inflate_codes_ddstatic void inflate_codes_setup(STATE_PARAM unsigned my_bl, unsigned my_bd){ bl = my_bl; bd = my_bd; /* make local copies of globals */ bb = gunzip_bb; /* initialize bit buffer */ k = gunzip_bk; w = gunzip_outbuf_count; /* initialize gunzip_window position */ /* inflate the coded data */ ml = mask_bits[bl]; /* precompute masks for speed */ md = mask_bits[bd];}/* called once from inflate_get_next_window */static int inflate_codes(STATE_PARAM_ONLY){ unsigned e; /* table entry flag/number of extra bits */ huft_t *t; /* pointer to table entry */ if (resume_copy) goto do_copy; while (1) { /* do until end of block */ bb = fill_bitbuffer(PASS_STATE bb, &k, bl); t = tl + ((unsigned) bb & ml); e = t->e; if (e > 16) do { if (e == 99) abort_unzip(PASS_STATE_ONLY);; bb >>= t->b; k -= t->b; e -= 16; bb = fill_bitbuffer(PASS_STATE bb, &k, e); t = t->v.t + ((unsigned) bb & mask_bits[e]); e = t->e; } while (e > 16); bb >>= t->b; k -= t->b; if (e == 16) { /* then it's a literal */ gunzip_window[w++] = (unsigned char) t->v.n; if (w == GUNZIP_WSIZE) { gunzip_outbuf_count = w; //flush_gunzip_window(); w = 0; return 1; // We have a block to read } } else { /* it's an EOB or a length */ /* exit if end of block */ if (e == 15) { break; } /* get length of block to copy */ bb = fill_bitbuffer(PASS_STATE bb, &k, e); nn = t->v.n + ((unsigned) bb & mask_bits[e]); bb >>= e; k -= e; /* decode distance of block to copy */ bb = fill_bitbuffer(PASS_STATE bb, &k, bd); t = td + ((unsigned) bb & md); e = t->e; if (e > 16) do { if (e == 99) abort_unzip(PASS_STATE_ONLY); bb >>= t->b; k -= t->b; e -= 16; bb = fill_bitbuffer(PASS_STATE bb, &k, e); t = t->v.t + ((unsigned) bb & mask_bits[e]); e = t->e; } while (e > 16); bb >>= t->b; k -= t->b; bb = fill_bitbuffer(PASS_STATE bb, &k, e); dd = w - t->v.n - ((unsigned) bb & mask_bits[e]); bb >>= e; k -= e; /* do the copy */ do_copy: do { /* Was: nn -= (e = (e = GUNZIP_WSIZE - ((dd &= GUNZIP_WSIZE - 1) > w ? dd : w)) > nn ? nn : e); */ /* Who wrote THAT?? rewritten as: */ dd &= GUNZIP_WSIZE - 1; e = GUNZIP_WSIZE - (dd > w ? dd : w); if (e > nn) e = nn; nn -= e; /* copy to new buffer to prevent possible overwrite */ if (w - dd >= e) { /* (this test assumes unsigned comparison) */ memcpy(gunzip_window + w, gunzip_window + dd, e); w += e; dd += e; } else { /* do it slow to avoid memcpy() overlap */ /* !NOMEMCPY */ do { gunzip_window[w++] = gunzip_window[dd++]; } while (--e); } if (w == GUNZIP_WSIZE) { gunzip_outbuf_count = w; resume_copy = (nn != 0); //flush_gunzip_window(); w = 0; return 1; } } while (nn); resume_copy = 0; } } /* restore the globals from the locals */ gunzip_outbuf_count = w; /* restore global gunzip_window pointer */ gunzip_bb = bb; /* restore global bit buffer */ gunzip_bk = k; /* normally just after call to inflate_codes, but save code by putting it here */ /* free the decoding tables (tl and td), return */ huft_free_all(PASS_STATE_ONLY); /* done */ return 0;}#undef ml#undef md#undef bb#undef k#undef w#undef tl#undef td#undef bl#undef bd#undef nn#undef dd/* called once from inflate_block */static void inflate_stored_setup(STATE_PARAM int my_n, int my_b, int my_k){ inflate_stored_n = my_n; inflate_stored_b = my_b; inflate_stored_k = my_k; /* initialize gunzip_window position */ inflate_stored_w = gunzip_outbuf_count;}/* called once from inflate_get_next_window */static int inflate_stored(STATE_PARAM_ONLY){ /* read and output the compressed data */ while (inflate_stored_n--) { inflate_stored_b = fill_bitbuffer(PASS_STATE inflate_stored_b, &inflate_stored_k, 8); gunzip_window[inflate_stored_w++] = (unsigned char) inflate_stored_b; if (inflate_stored_w == GUNZIP_WSIZE) { gunzip_outbuf_count = inflate_stored_w; //flush_gunzip_window(); inflate_stored_w = 0; inflate_stored_b >>= 8; inflate_stored_k -= 8; return 1; /* We have a block */ } inflate_stored_b >>= 8; inflate_stored_k -= 8; } /* restore the globals from the locals */ gunzip_outbuf_count = inflate_stored_w; /* restore global gunzip_window pointer */ gunzip_bb = inflate_stored_b; /* restore global bit buffer */ gunzip_bk = inflate_stored_k; return 0; /* Finished */}/* * decompress an inflated block * e: last block flag * * GLOBAL VARIABLES: bb, kk, *//* Return values: -1 = inflate_stored, -2 = inflate_codes *//* One callsite in inflate_get_next_window */static int inflate_block(STATE_PARAM smallint *e){ unsigned ll[286 + 30]; /* literal/length and distance code lengths */ unsigned t; /* block type */ unsigned b; /* bit buffer */ unsigned k; /* number of bits in bit buffer */ /* make local bit buffer */ b = gunzip_bb; k = gunzip_bk; /* read in last block bit */ b = fill_bitbuffer(PASS_STATE b, &k, 1); *e = b & 1; b >>= 1; k -= 1; /* read in block type */ b = fill_bitbuffer(PASS_STATE b, &k, 2); t = (unsigned) b & 3; b >>= 2; k -= 2; /* restore the global bit buffer */ gunzip_bb = b; gunzip_bk = k; /* Do we see block type 1 often? Yes! * TODO: fix performance problem (see below) */ //bb_error_msg("blktype %d", t); /* inflate that block type */ switch (t) { case 0: /* Inflate stored */ { unsigned n; /* number of bytes in block */ unsigned b_stored; /* bit buffer */ unsigned k_stored; /* number of bits in bit buffer */ /* make local copies of globals */ b_stored = gunzip_bb; /* initialize bit buffer */ k_stored = gunzip_bk; /* go to byte boundary */ n = k_stored & 7; b_stored >>= n; k_stored -= n; /* get the length and its complement */ b_stored = fill_bitbuffer(PASS_STATE b_stored, &k_stored, 16); n = ((unsigned) b_stored & 0xffff); b_stored >>= 16; k_stored -= 16; b_stored = fill_bitbuffer(PASS_STATE b_stored, &k_stored, 16); if (n != (unsigned) ((~b_stored) & 0xffff)) { abort_unzip(PASS_STATE_ONLY); /* error in compressed data */ } b_stored >>= 16; k_stored -= 16; inflate_stored_setup(PASS_STATE n, b_stored, k_stored); return -1; } case 1: /* Inflate fixed * decompress an inflated type 1 (fixed Huffman codes) block. We should * either replace this with a custom decoder, or at least precompute the * Huffman tables. TODO */ { int i; /* temporary variable */ unsigned bl; /* lookup bits for tl */ unsigned bd; /* lookup bits for td */ /* gcc 4.2.1 is too dumb to reuse stackspace. Moved up... */ //unsigned ll[288]; /* length list for huft_build */ /* set up literal table */ for (i = 0; i < 144; i++) ll[i] = 8; for (; i < 256; i++) ll[i] = 9; for (; i < 280; i++) ll[i] = 7; for (; i < 288; i++) /* make a complete, but wrong code set */ ll[i] = 8; bl = 7; huft_build(ll, 288, 257, cplens, cplext, &inflate_codes_tl, &bl); /* huft_build() never return nonzero - we use known data */ /* set up distance table */ for (i = 0; i < 30; i++) /* make an incomplete code set */ ll[i] = 5; bd = 5; huft_build(ll, 30, 0, cpdist, cpdext, &inflate_codes_td, &bd); /* set up data for inflate_codes() */ inflate_codes_setup(PASS_STATE bl, bd); /* huft_free code moved into inflate_codes */ return -2; } case 2: /* Inflate dynamic */ { enum { dbits = 6 }; /* bits in base distance lookup table */ enum { lbits = 9 }; /* bits in base literal/length lookup table */ huft_t *td; /* distance code table */ unsigned i; /* temporary variables */ unsigned j; unsigned l; /* last length */ unsigned m; /* mask for bit lengths table */ unsigned n; /* number of lengths to get */ unsigned bl; /* lookup bits for tl */ unsigned bd; /* lookup bits for td */ unsigned nb; /* number of bit length codes */ unsigned nl; /* number of literal/length codes */ unsigned nd; /* number of distance codes */ //unsigned ll[286 + 30];/* literal/length and distance code lengths */ unsigned b_dynamic; /* bit buffer */ unsigned k_dynamic; /* number of bits in bit buffer */ /* make local bit buffer */ b_dynamic = gunzip_bb; k_dynamic = gunzip_bk; /* read in table lengths */ b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 5); nl = 257 + ((unsigned) b_dynamic & 0x1f); /* number of literal/length codes */ b_dynamic >>= 5; k_dynamic -= 5; b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 5); nd = 1 + ((unsigned) b_dynamic & 0x1f); /* number of distance codes */ b_dynamic >>= 5; k_dynamic -= 5; b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 4); nb = 4 + ((unsigned) b_dynamic & 0xf); /* number of bit length codes */ b_dynamic >>= 4; k_dynamic -= 4; if (nl > 286 || nd > 30) abort_unzip(PASS_STATE_ONLY); /* bad lengths */ /* read in bit-length-code lengths */ for (j = 0; j < nb; j++) { b_dynamic = fill_bitbuffer(PASS_STATE b_dynamic, &k_dynamic, 3); ll[border[j]] = (unsigned) b_dynamic & 7; b_dynamic >>= 3; k_dynamic -= 3; } for (; j < 19; j++) ll[border[j]] = 0; /* build decoding table for trees - single level, 7 bit lookup */ bl = 7; i = huft_build(ll, 19, 19, NULL, NULL, &inflate_codes_tl, &bl);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?