📄 inflatelib.c
字号:
# define Tracecv(c,x)# define DBG_PUT(a,b)#endif/* internal data types */typedef unsigned char Byte; /* 8 bits */typedef unsigned int uInt; /* 16 bits or more */typedef unsigned long uLong; /* 32 bits or more */typedef void * voidp;typedef unsigned char uch;typedef unsigned short ush;typedef unsigned long ulg;#ifdef __cplusplusextern "C" {#endiftypedef voidp (*alloc_func) OF((voidp opaque, uInt items, uInt size));typedef void (*free_func) OF((voidp opaque, voidp address));struct internal_state;typedef struct z_stream_s { Byte *next_in; /* next input byte */ uInt avail_in; /* number of bytes available at next_in */ uLong total_in; /* total nb of input bytes read so far */ Byte *next_out; /* next output byte should be put there */ uInt avail_out; /* remaining free space at next_out */ uLong total_out; /* total nb of bytes output so far */ char *msg; /* last error message, NULL if no error */ struct internal_state *state; /* not visible by applications */ alloc_func zalloc; /* used to allocate the internal state */ free_func zfree; /* used to free the internal state */ voidp opaque; /* private data object passed to zalloc and zfree */ int data_type; /* best guess about the data type: ascii or binary */ uLong adler; /* adler32 value of the uncompressed data */ uLong reserved; /* reserved for future use */} z_stream;typedef z_stream *z_streamp;#ifdef __cplusplus}#endiftypedef uLong (*check_func) OF((uLong check, const Byte *buf, uInt len));/* Data structure describing a single value and its code string. */typedef struct ct_data_s { union { ush freq; /* frequency count */ ush code; /* bit string */ } fc; union { ush dad; /* father node in Huffman tree */ ush len; /* length of bit string */ } dl;} ct_data;typedef struct static_tree_desc_s static_tree_desc;typedef struct tree_desc_s { ct_data *dyn_tree; /* the dynamic tree */ int max_code; /* largest code with non zero frequency */ static_tree_desc *stat_desc; /* the corresponding static tree */} tree_desc;typedef ush Pos;typedef Pos Posf;typedef unsigned IPos;/* Huffman code lookup table entry--this entry is four bytes for machines that have 16-bit pointers (e.g. PC's in the small or medium model). */typedef struct inflate_huft_s inflate_huft;struct inflate_huft_s { union { struct { Byte Exop; /* number of extra bits or operation */ Byte Bits; /* number of bits in this code or subcode */ } what; Byte *pad; /* pad structure to a power of 2 (4 bytes for */ } word; /* 16-bit, 8 bytes for 32-bit machines) */ union { uInt Base; /* literal, length base, or distance base */ inflate_huft *Next; /* pointer to next level of table */ } more;};struct inflate_blocks_state;typedef struct inflate_blocks_state inflate_blocks_statef;struct inflate_codes_state;typedef struct inflate_codes_state inflate_codes_statef;typedef enum { TYPE, /* get type bits (3, including end bit) */ LENS, /* get lengths for stored */ STORED, /* processing stored block */ TABLE, /* get table lengths */ BTREE, /* get bit lengths tree for a dynamic block */ DTREE, /* get length, distance trees for a dynamic block */ CODES, /* processing fixed or dynamic block */ DRY, /* output remaining window bytes */ DONE, /* finished last block, done */ BAD} /* got a data error--stuck here */inflate_block_mode;/* inflate blocks semi-private state */struct inflate_blocks_state { /* mode */ inflate_block_mode mode; /* current inflate_block mode */ /* mode dependent information */ union { uInt left; /* if STORED, bytes left to copy */ struct { uInt table; /* table lengths (14 bits) */ uInt index; /* index into blens (or border) */ uInt *blens; /* bit lengths of codes */ uInt bb; /* bit length tree depth */ inflate_huft *tb; /* bit length decoding tree */ } trees; /* if DTREE, decoding info for trees */ struct { inflate_huft *tl; inflate_huft *td; /* trees to free */ inflate_codes_statef *codes; } decode; /* if CODES, current state */ } sub; /* submode */ uInt last; /* true if this block is the last block */ /* mode independent information */ uInt bitk; /* bits in bit buffer */ uLong bitb; /* bit buffer */ Byte *window; /* sliding window */ Byte *end; /* one byte after sliding window */ Byte *read; /* window read pointer */ Byte *write; /* window write pointer */ check_func checkfn; /* check function */ uLong check; /* check on output */};/* inflate codes private state */struct inflate_codes_state { /* mode */ enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ START, /* x: set up for LEN */ LEN, /* i: get length/literal/eob next */ LENEXT, /* i: getting length extra (have base) */ DIST, /* i: get distance next */ DISTEXT, /* i: getting distance extra */ COPY, /* o: copying bytes in window, waiting for space */ LIT, /* o: got literal, waiting for output space */ WASH, /* o: got eob, possibly still output waiting */ END, /* x: got eob and all data flushed */ BADCODE} /* x: got error */ mode; /* current inflate_codes mode */ /* mode dependent information */ uInt len; union { struct { inflate_huft *tree; /* pointer into tree */ uInt need; /* bits needed */ } code; /* if LEN or DIST, where in tree */ uInt lit; /* if LIT, literal */ struct { uInt get; /* bits to get for extra */ uInt dist; /* distance back to copy from */ } copy; /* if EXT or COPY, where and how much */ } sub; /* submode */ /* mode independent information */ Byte lbits; /* ltree bits decoded per branch */ Byte dbits; /* dtree bits decoder per branch */ inflate_huft *ltree; /* literal/length/eob tree */ inflate_huft *dtree; /* distance tree */};/* inflate private state */struct internal_state { /* mode */ enum { METHOD, /* waiting for method byte */ FLAG, /* waiting for flag byte */ DICT4, /* four dictionary check bytes to go */ DICT3, /* three dictionary check bytes to go */ DICT2, /* two dictionary check bytes to go */ DICT1, /* one dictionary check byte to go */ DICT0, /* waiting for inflateSetDictionary */ BLOCKS, /* decompressing blocks */ CHECK4, /* four check bytes to go */ CHECK3, /* three check bytes to go */ CHECK2, /* two check bytes to go */ CHECK1, /* one check byte to go */ INF_DONE, /* finished check, done */ INF_BAD} /* got an error--stay here */ mode; /* current inflate mode */ /* mode dependent information */ union { uInt method; /* if FLAGS, method byte */ struct { uLong was; /* computed check value */ uLong need; /* stream check value */ } check; /* if CHECK, check values to compare */ } sub; /* submode */ /* mode independent information */ int nowrap; /* flag for no wrapper */ uInt wbits; /* log2(window size) (8..15, defaults to 15) */ inflate_blocks_statef *blocks; /* current inflate_blocks state */};/* static variables *//* Tables for deflate from PKZIP's appnote.txt. */static uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; /* actually lengths - 2; also see note #13 above about 258 */static uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */static uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577};static uInt cpdext[30] = { /* Extra bits for distance codes */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};static uInt inflate_mask[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff};/* Table for deflate from PKZIP's appnote.txt. */static uInt 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};/* build fixed tables only once--keep them here */static int fixed_built = 0;static inflate_huft fixed_mem[FIXEDH];static uInt fixed_bl = 0;static uInt fixed_bd = 0;static inflate_huft *fixed_tl = 0;static inflate_huft *fixed_td = 0;/* allocate two extra words for prev/next pointers for first block */static int intBuf [(BLK_HDR_SIZE + BUF_SIZE)/sizeof(int)];static char * buf = BLK_HDR_SIZE + (char *)intBuf;static char * nextBlock = BLK_HDR_SIZE + (char *)intBuf;/* forward static function declarations */static int huft_build OF(( uInt *, /* code lengths in bits */ uInt, /* number of codes */ uInt, /* number of "simple" codes */ uInt *, /* list of base values for non-simple codes */ uInt *, /* list of extra bits for non-simple codes */ inflate_huft * *, /* result: starting table */ uInt *, /* maximum lookup bits (returns actual) */ z_streamp )); /* for zalloc function */static voidp falloc OF(( voidp, /* opaque pointer (not used) */ uInt, /* number of items */ uInt)); /* size of item */static int inflate_trees_free OF(( inflate_huft * t, /* table to free */ z_streamp z /* for zfree function */ ));static int inflate_flush OF(( inflate_blocks_statef *, z_streamp , int));static int inflate_fast OF(( uInt, uInt, inflate_huft *, inflate_huft *, inflate_blocks_statef *, z_streamp ));/******************************************************************************** memcpy - copy memory*/ static void memcpy ( Byte * dest, Byte * src, uInt nBytes ) { if ((((uInt)dest & 0x3) == 0) && (((uInt)src & 0x3) == 0)) { while (nBytes >= 4) { *((uInt *)dest) = *((uInt *)src); dest += 4; src += 4; nBytes -= 4; } } while (nBytes > 0) { *dest++ = *src++; nBytes--; } }/******************************************************************************** bzero - zeroes a buffer*/ static void bzero ( char *buffer, /* buffer to be zeroed */ int nbytes /* number of bytes in buffer */ ) { if (((int)buffer & 0x3) == 0) { while (nbytes >= 4) { *(int *)buffer = 0; buffer += 4; nbytes -= 4; } } while (nbytes >= 1) { *buffer = 0; buffer += 1; nbytes -= 1; } }/******************************************************************************** adler32 - 32 bit checksum*/ static uLong adler32 ( uLong adler, /* previous total */ const Byte *buf, /* buffer to checksum */ uInt len /* size of buffer */ ) { unsigned long s1 = adler & 0xffff; unsigned long s2 = (adler >> 16) & 0xffff; int k; if (buf == Z_NULL) return 1L; while (len > 0) { k = len < NMAX ? len : NMAX; len -= k; while (k >= 16) { DO16(buf); buf += 16; k -= 16; } if (k != 0) do { s1 += *buf++; s2 += s1; } while (--k); s1 %= BASE; s2 %= BASE; } return (s2 << 16) | s1; }/******************************************************************************** cksum - compute checksum**/ static ush cksum ( ush prevSum, /* previous total */ const uch * buf, /* buffer to checksum */ ulg len /* size of buffer */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -