📄 inflate.c
字号:
unsigned ll[288+32];/* literal/length and distance code lengths */#else unsigned ll[286+30];/* literal/length and distance code lengths */#endif static unsigned border[] = { /* Order of the bit length code lengths */ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; BITS_SAVE; reuse_mblock(&decoder->pool); /* read in table lengths */ NEEDBITS(5); nl = 257 + GETBITS(5); /* number of literal/length codes */ DUMPBITS(5); NEEDBITS(5); nd = 1 + GETBITS(5); /* number of distance codes */ DUMPBITS(5); NEEDBITS(4); nb = 4 + GETBITS(4); /* number of bit length codes */ DUMPBITS(4);#ifdef PKZIP_BUG_WORKAROUND if(nl > 288 || nd > 32)#else if(nl > 286 || nd > 30)#endif { BITS_RESTORE; return -1; /* bad lengths */ } /* read in bit-length-code lengths */ for(j = 0; j < nb; j++) { NEEDBITS(3); ll[border[j]] = GETBITS(3); DUMPBITS(3); } for(; j < 19; j++) ll[border[j]] = 0; /* build decoding table for trees--single level, 7 bit lookup */ bl = 7; if((i = huft_build(ll, 19, 19, NULL, NULL, &tl, &bl, &decoder->pool)) != 0) { reuse_mblock(&decoder->pool); BITS_RESTORE; return -1; /* incomplete code set */ } /* read in literal and distance code lengths */ n = nl + nd; i = l = 0; while((unsigned)i < n) { NEEDBITS((unsigned)bl); j = (td = tl + (GETBITS(bl)))->b; DUMPBITS(j); j = td->v.n; if(j < 16) /* length of code in bits (0..15) */ ll[i++] = l = j; /* save last length in l */ else if(j == 16) /* repeat last length 3 to 6 times */ { NEEDBITS(2); j = 3 + GETBITS(2); DUMPBITS(2); if((unsigned)i + j > n) { BITS_RESTORE; return -1; } while(j--) ll[i++] = l; } else if(j == 17) /* 3 to 10 zero length codes */ { NEEDBITS(3); j = 3 + GETBITS(3); DUMPBITS(3); if((unsigned)i + j > n) { BITS_RESTORE; return -1; } while(j--) ll[i++] = 0; l = 0; } else /* j == 18: 11 to 138 zero length codes */ { NEEDBITS(7); j = 11 + GETBITS(7); DUMPBITS(7); if((unsigned)i + j > n) { BITS_RESTORE; return -1; } while(j--) ll[i++] = 0; l = 0; } } BITS_RESTORE; /* free decoding table for trees */ reuse_mblock(&decoder->pool); /* build the decoding tables for literal/length and distance codes */ bl = lbits; i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl, &decoder->pool); if(bl == 0) /* no literals or lengths */ i = 1; if(i) { if(i == 1) fprintf(stderr, " incomplete literal tree\n"); reuse_mblock(&decoder->pool); return -1; /* incomplete code set */ } bd = dbits; i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd, &decoder->pool); if(bd == 0 && nl > 257) /* lengths but no distances */ { fprintf(stderr, " incomplete distance tree\n"); reuse_mblock(&decoder->pool); return -1; } if(i == 1) {#ifdef PKZIP_BUG_WORKAROUND i = 0;#else fprintf(stderr, " incomplete distance tree\n");#endif } if(i) { reuse_mblock(&decoder->pool); return -1; } /* decompress until an end-of-block code */ decoder->tl = tl; decoder->td = td; decoder->bl = bl; decoder->bd = bd; i = inflate_codes(decoder, buff, size); if(i == -1) /* error */ { reuse_mblock(&decoder->pool); return -1; } /* free the decoding tables, return */ return i;}local void inflate_start(InflateHandler decoder)/* initialize window, bit buffer */{ decoder->wp = 0; decoder->bit_buf = 0; decoder->bit_len = 0; decoder->insize = decoder->inptr = 0; decoder->fixed_td = decoder->fixed_tl = NULL; decoder->method = -1; decoder->eof = 0; decoder->copy_leng = decoder->copy_dist = 0; decoder->tl = NULL; init_mblock(&decoder->pool);}/*ARGSUSED*/static long default_read_func(char *buf, long size, void *v){ return (long)fread(buf, 1, size, stdin);}InflateHandler open_inflate_handler( long (* read_func)(char *buf, long size, void *user_val), void *user_val){ InflateHandler decoder; decoder = (InflateHandler) malloc(sizeof(struct _InflateHandler)); inflate_start(decoder); decoder->user_val = user_val; if(read_func == NULL) decoder->read_func = default_read_func; else decoder->read_func = read_func; return decoder;}void close_inflate_handler(InflateHandler decoder){ if(decoder->fixed_tl != NULL) { huft_free(decoder->fixed_td); huft_free(decoder->fixed_tl); decoder->fixed_td = decoder->fixed_tl = NULL; } reuse_mblock(&decoder->pool); free(decoder);}/* decompress an inflated entry */long zip_inflate( InflateHandler decoder, char *buff, long size){ long n, i; n = 0; while(n < size) { if(decoder->eof && decoder->method == -1) return n; if(decoder->copy_leng > 0) { unsigned l, w, d; l = decoder->copy_leng; w = decoder->wp; if(decoder->method != STORED_BLOCK) { /* STATIC_TREES or DYN_TREES */ d = decoder->copy_dist; while(l > 0 && n < size) { l--; d &= WSIZE - 1; w &= WSIZE - 1; buff[n++] = decoder->slide[w++] = decoder->slide[d++]; } decoder->copy_dist = d; } else /* STATIC_TREES or DYN_TREES */ { BITS_SAVE; while(l > 0 && n < size) { l--; w &= WSIZE - 1; NEEDBITS(8); buff[n++] = decoder->slide[w++] = (uch)GETBITS(8); DUMPBITS(8); } BITS_RESTORE; if(l == 0) decoder->method = -1; /* done */ } decoder->copy_leng = l; decoder->wp = w; if(n == size) return n; } if(decoder->method == -1) { BITS_SAVE; if(decoder->eof) { BITS_RESTORE; break; } /* read in last block bit */ NEEDBITS(1); if(GETBITS(1)) decoder->eof = 1; DUMPBITS(1); /* read in block type */ NEEDBITS(2); decoder->method = (int)GETBITS(2); DUMPBITS(2); decoder->tl = NULL; decoder->copy_leng = 0; BITS_RESTORE; } switch(decoder->method) { case STORED_BLOCK: i = inflate_stored(decoder, buff + n, size - n); break; case STATIC_TREES: if(decoder->tl != NULL) i = inflate_codes(decoder, buff + n, size - n); else i = inflate_fixed(decoder, buff + n, size - n); break; case DYN_TREES: if(decoder->tl != NULL) i = inflate_codes(decoder, buff + n, size - n); else i = inflate_dynamic(decoder, buff + n, size - n); break; default: /* error */ i = -1; break; } if(i == -1) { if(decoder->eof) return 0; return -1; /* error */ } n += i; } return n;}/* =========================================================================== * Fill the input buffer. This is called only when the buffer is empty. */local int fill_inbuf(InflateHandler decoder){ int len; /* Read as much as possible */ decoder->insize = 0; errno = 0; do { len = decoder->read_func((char*)decoder->inbuf + decoder->insize, (long)(INBUFSIZ - decoder->insize), decoder->user_val); if(len == 0 || len == EOF) break; decoder->insize += len; } while(decoder->insize < INBUFSIZ); if(decoder->insize == 0) return EOF; decoder->inptr = 1; return decoder->inbuf[0];}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -