📄 decompress.c
字号:
else if (j == 16) /* repeat last length 3 to 6 times */ { NEEDBITS(2) j = 3 + ((unsigned)b & 3); DUMPBITS(2) if ((unsigned)i + j > n) return 1; while (j--) ll[i++] = l; } else if (j == 17) /* 3 to 10 zero length codes */ { NEEDBITS(3) j = 3 + ((unsigned)b & 7); DUMPBITS(3) if ((unsigned)i + j > n) return 1; while (j--) ll[i++] = 0; l = 0; } else /* j == 18: 11 to 138 zero length codes */ { NEEDBITS(7) j = 11 + ((unsigned)b & 0x7f); DUMPBITS(7) if ((unsigned)i + j > n) return 1; while (j--) ll[i++] = 0; l = 0; } }DEBG("dyn4 "); /* free decoding table for trees */ huft_free(tl);DEBG("dyn5 "); /* restore the global bit buffer */ bb = b; bk = k;DEBG("dyn5a "); /* build the decoding tables for literal/length and distance codes */ bl = lbits; if ((i = huft_build(ll, nl, 257, cplens, cplext, &tl, &bl)) != 0) {DEBG("dyn5b "); if (i == 1) { error(" incomplete literal tree\n"); huft_free(tl); } return i; /* incomplete code set */ }DEBG("dyn5c "); bd = dbits; if ((i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0) {DEBG("dyn5d "); if (i == 1) { error(" incomplete distance tree\n");#ifdef PKZIP_BUG_WORKAROUND i = 0; }#else huft_free(td); } huft_free(tl); return i; /* incomplete code set */#endif }DEBG("dyn6 "); /* decompress until an end-of-block code */ if (inflate_codes(tl, td, bl, bd)) return 1;DEBG("dyn7 "); /* free the decoding tables, return */ huft_free(tl); huft_free(td); DEBG(">"); return 0;}static int inflate_block(e)int *e; /* last block flag *//* decompress an inflated block */{ unsigned t; /* block type */ register ulg b; /* bit buffer */ register unsigned k; /* number of bits in bit buffer */ DEBG("<blk"); /* make local bit buffer */ b = bb; k = bk; /* read in last block bit */ NEEDBITS(1) *e = (int)b & 1; DUMPBITS(1) /* read in block type */ NEEDBITS(2) t = (unsigned)b & 3; DUMPBITS(2) /* restore the global bit buffer */ bb = b; bk = k; /* inflate that block type */ if (t == 2) return inflate_dynamic(); if (t == 0) return inflate_stored(); if (t == 1) return inflate_fixed(); DEBG(">"); /* bad block type */ return 2;}static int inflate()/* decompress an inflated entry */{ int e; /* last block flag */ int r; /* result code */ unsigned h; /* maximum struct huft's malloc'ed */ void *ptr; /* initialize window, bit buffer */ wp = 0; bk = 0; bb = 0; /* decompress until the last block */ h = 0; do { hufts = 0; gzip_mark(&ptr); if ((r = inflate_block(&e)) != 0) { gzip_release(&ptr); return r; } gzip_release(&ptr); if (hufts > h) h = hufts; } while (!e); /* Undo too much lookahead. The next read will be byte aligned so we * can discard unused bits in the last meaningful byte. */ while (bk >= 8) { bk -= 8; inptr--; } /* flush out slide */ flush_output(wp); /* return success */#ifdef DEBUG printk("<%u> ", h);#endif /* DEBUG */ return 0;}/********************************************************************** * * The following are support routines for inflate.c * **********************************************************************/static ulg crc_32_tab[256];static ulg crc; /* initialized in makecrc() so it'll reside in bss */#define CRC_VALUE (crc ^ 0xffffffffL)/* * Code to compute the CRC-32 table. Borrowed from * gzip-1.0.3/makecrc.c. */static voidmakecrc(void){/* Not copyrighted 1990 Mark Adler */ unsigned long c; /* crc shift register */ unsigned long e; /* polynomial exclusive-or pattern */ int i; /* counter for all possible eight bit values */ int k; /* byte being shifted into crc apparatus */ /* terms of polynomial defining this crc (except x^32): */ static const int p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; /* Make exclusive-or pattern from polynomial */ e = 0; for (i = 0; i < sizeof(p)/sizeof(int); i++) e |= 1L << (31 - p[i]); crc_32_tab[0] = 0; for (i = 1; i < 256; i++) { c = 0; for (k = i | 256; k != 1; k >>= 1) { c = c & 1 ? (c >> 1) ^ e : c >> 1; if (k & 1) c ^= e; } crc_32_tab[i] = c; } /* this is initialized here so this code could reside in ROM */ crc = (ulg)0xffffffffL; /* shift register contents */}/* gzip flag byte */#define ASCII_FLAG 0x01 /* bit 0 set: file probably ASCII text */#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */#define ORIG_NAME 0x08 /* bit 3 set: original file name present */#define COMMENT 0x10 /* bit 4 set: file comment present */#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */#define RESERVED 0xC0 /* bit 6,7: reserved *//* * Do the uncompression! */static int gunzip(void){ uch flags; unsigned char magic[2]; /* magic header */ char method; ulg orig_crc = 0; /* original crc */ ulg orig_len = 0; /* original uncompressed length */ int res; magic[0] = (unsigned char)get_byte(); magic[1] = (unsigned char)get_byte(); method = (unsigned char)get_byte(); if (magic[0] != 037 || ((magic[1] != 0213) && (magic[1] != 0236))) { error("bad gzip magic numbers"); return -1; } /* We only support method #8, DEFLATED */ if (method != 8) { error("internal error, invalid method"); return -1; } flags = (uch)get_byte(); if ((flags & ENCRYPTED) != 0) { error("Input is encrypted\n"); return -1; } if ((flags & CONTINUATION) != 0) { error("Multi part input\n"); return -1; } if ((flags & RESERVED) != 0) { error("Input has invalid flags\n"); return -1; } (ulg)get_byte(); /* Get timestamp */ ((ulg)get_byte()) << 8; ((ulg)get_byte()) << 16; ((ulg)get_byte()) << 24; (void)get_byte(); /* Ignore extra flags for the moment */ (void)get_byte(); /* Ignore OS type for the moment */ if ((flags & EXTRA_FIELD) != 0) { unsigned len = (unsigned)get_byte(); len |= ((unsigned)get_byte())<<8; while (len--) (void)get_byte(); } /* Get original file name if it was truncated */ if ((flags & ORIG_NAME) != 0) { /* Discard the old name */ while (get_byte() != 0) /* null */ ; } /* Discard file comment if any */ if ((flags & COMMENT) != 0) { while (get_byte() != 0) /* null */ ; } /* Decompress */ if ((res = inflate())) { switch (res) { case 0: break; case 1: error("invalid compressed format (err=1)"); break; case 2: error("invalid compressed format (err=2)"); break; case 3: error("out of memory"); break; default: error("invalid compressed format (other)"); } return -1; } /* Get the crc and original length */ /* crc32 (see algorithm.doc) * uncompressed input size modulo 2^32 */ orig_crc = (ulg) get_byte(); orig_crc |= (ulg) get_byte() << 8; orig_crc |= (ulg) get_byte() << 16; orig_crc |= (ulg) get_byte() << 24; orig_len = (ulg) get_byte(); orig_len |= (ulg) get_byte() << 8; orig_len |= (ulg) get_byte() << 16; orig_len |= (ulg) get_byte() << 24; return 0; /* Validate decompression */ if (orig_crc != CRC_VALUE) { error("crc error"); return -1; } if (orig_len != bytes_out) { error("length error"); return -1; } return 0;}#ifndef STANDALONE_DEBUGstatic void *malloc(int size){ void *p; if (size <0) error("Malloc error\n"); if (free_mem_ptr <= 0) error("Memory error\n"); free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ p = (void *)free_mem_ptr; free_mem_ptr += size; if (free_mem_ptr >= free_mem_ptr_end) error("Out of memory"); // util_printf("malloc: %d, %X\n", size, p); return p;}static void free(void *where){ /* gzip_mark & gzip_release do the free */}static void gzip_mark(void **ptr){ *ptr = (void *) free_mem_ptr;}static void gzip_release(void **ptr){ free_mem_ptr = (long) *ptr;}#elsestatic void gzip_mark(void **ptr){}static void gzip_release(void **ptr){}#endif/* =========================================================================== * Fill the input buffer. This is called only when the buffer is empty * and at least one byte is really needed. */int fill_inbuf(void){ if (insize != 0) error("ran out of input data\n"); inbuf = input_data; insize = &input_data_end[0] - &input_data[0]; inptr = 1; return inbuf[0];}/* =========================================================================== * Write the output window window[0..outcnt-1] and update crc and bytes_out. * (Used for the decompressed data only.) */void flush_window(void){ ulg c = crc; unsigned n; uch *in, *out, ch; in = window; out = &output_data[output_ptr]; for (n = 0; n < outcnt; n++) { ch = *out++ = *in++; c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8); } crc = c; bytes_out += (ulg)outcnt; output_ptr += (ulg)outcnt; outcnt = 0; puts(".");}static void error(char *x){ puts("\n\n"); puts(x); puts("\n\n -- System halted"); while(1); /* Halt */}char *decompress_comp(const char *output_start, const char *free_mem_ptr_p, const unsigned int free_mem_size, const char *input_start, const unsigned int input_size){ output_data = (uch *)output_start; /* Points to comp start */ free_mem_ptr = (ulg)free_mem_ptr_p; free_mem_ptr_end = (ulg)free_mem_ptr + free_mem_size - 1; inbuf = (uch *)input_start; insize = input_size; inptr = 0; output_ptr = 0; makecrc(); puts("Uncompressing..."); gunzip(); util_printf("done\n"); return (char *)output_ptr;}int image_is_compressed(char *image_start_addr) { return( (image_start_addr[0] == 037) && ( (image_start_addr[1] == 0213) || (image_start_addr[1] == 0236) ) );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -