static int inflate_stored(int my_n, int my_b_stored, int my_k_stored, int setup) { static unsigned int n, b_stored, k_stored, w; if (setup) { n = my_n; b_stored = my_b_stored; k_stored = my_k_stored; w = gunzip_outbuf_count; /* initialize gunzip_window position */ return 0; /* Don't do anything first time */ } /* read and output the compressed data */ while (n--) { b_stored = fill_bitbuffer(b_stored, &k_stored, 8); gunzip_window[w++] = (unsigned char) b_stored; if (w == gunzip_wsize) { gunzip_outbuf_count = (w); w = 0; b_stored >>= 8; k_stored -= 8; return 1; /* We have a block */ } b_stored >>= 8; k_stored -= 8; }
/* 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; }
/* 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) { //shouldn't we propagate error? bb_error_msg_and_die("inflate_codes error 1"); } 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) //shouldn't we propagate error? bb_error_msg_and_die("inflate_codes error 2"); 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, return */ huft_free(tl); huft_free(td); /* done */ return 0; }
static int inflate_codes(huft_t * my_tl, huft_t * my_td, const unsigned int my_bl, const unsigned int my_bd, int setup) { static unsigned int e; /* table entry flag/number of extra bits */ static unsigned int n, d; /* length and index for copy */ static unsigned int w; /* current gunzip_window position */ static huft_t *t; /* pointer to table entry */ static unsigned int ml, md; /* masks for bl and bd bits */ static unsigned int b; /* bit buffer */ static unsigned int k; /* number of bits in bit buffer */ static huft_t *tl, *td; static unsigned int bl, bd; if (setup) /* 1st time we are called, copy in variables */ { tl = my_tl; td = my_td; bl = my_bl; bd = my_bd; /* make local copies of globals */ b = 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]; return 0; /* Don't actually do anything the first time */ } if (inflate_codes_resumeCopy) goto do_copy; while (1) /* do until end of block */ { b = fill_bitbuffer(b, &k, bl); if ((e = (t = tl + ((unsigned) b & ml))->e) > 16) do { if (e == 99) error_die("inflate_codes error 1"); b >>= t->b; k -= t->b; e -= 16; b = fill_bitbuffer(b, &k, e); } while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16); b >>= 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); 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 */ b = fill_bitbuffer(b, &k, e); n = t->v.n + ((unsigned) b & mask_bits[e]); b >>= e; k -= e; /* decode distance of block to copy */ b = fill_bitbuffer(b, &k, bd); if ((e = (t = td + ((unsigned) b & md))->e) > 16) do { if (e == 99) error_die("inflate_codes error 2"); b >>= t->b; k -= t->b; e -= 16; b = fill_bitbuffer(b, &k, e); } while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16); b >>= t->b; k -= t->b; b = fill_bitbuffer(b, &k, e); d = w - t->v.n - ((unsigned) b & mask_bits[e]); b >>= e; k -= e; /* do the copy */ do_copy: do { n -= (e = (e = gunzip_wsize - ((d &= gunzip_wsize - 1) > w ? d : w)) > n ? n : e); /* copy to new buffer to prevent possible overwrite */ if (w - d >= e) /* (this test assumes unsigned comparison) */ { memcpy(gunzip_window + w, gunzip_window + d, e); w += e; d += e; } else { /* do it slow to avoid memcpy() overlap */ /* !NOMEMCPY */ do { gunzip_window[w++] = gunzip_window[d++]; } while (--e); } if (w == gunzip_wsize) { gunzip_outbuf_count = (w); if (n) inflate_codes_resumeCopy = 1; else inflate_codes_resumeCopy = 0; w = 0; return 1; } } while (n); inflate_codes_resumeCopy = 0; } } /* restore the globals from the locals */ gunzip_outbuf_count = w; /* restore global gunzip_window pointer */ gunzip_bb = b; /* 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, return */ huft_free(tl,HUFT_MMP1); huft_free(td,HUFT_MMP2); /* done */ return 0; }