⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lzx.c

📁 又一开源的解压缩chm格式文件的代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    bitsleft += 16; inpos+=2;						\  }#define PEEK_BITS(n)   (bitbuf >> (ULONG_BITS - (n)))#define REMOVE_BITS(n) ((bitbuf <<= (n)), (bitsleft -= (n)))#define READ_BITS(v,n) do {						\  ENSURE_BITS(n);							\  (v) = PEEK_BITS(n);							\  REMOVE_BITS(n);							\} while (0)/* Huffman macros */#define TABLEBITS(tbl)   (LZX_##tbl##_TABLEBITS)#define MAXSYMBOLS(tbl)  (LZX_##tbl##_MAXSYMBOLS)#define SYMTABLE(tbl)    (pState->tbl##_table)#define LENTABLE(tbl)    (pState->tbl##_len)/* BUILD_TABLE(tablename) builds a huffman lookup table from code lengths. * In reality, it just calls make_decode_table() with the appropriate * values - they're all fixed by some #defines anyway, so there's no point * writing each call out in full by hand. */#define BUILD_TABLE(tbl)						\  if (make_decode_table(						\    MAXSYMBOLS(tbl), TABLEBITS(tbl), LENTABLE(tbl), SYMTABLE(tbl)	\  )) { return DECR_ILLEGALDATA; }/* READ_HUFFSYM(tablename, var) decodes one huffman symbol from the * bitstream using the stated table and puts it in var. */#define READ_HUFFSYM(tbl,var) do {					\  ENSURE_BITS(16);							\  hufftbl = SYMTABLE(tbl);						\  if ((i = hufftbl[PEEK_BITS(TABLEBITS(tbl))]) >= MAXSYMBOLS(tbl)) {	\    j = 1 << (ULONG_BITS - TABLEBITS(tbl));				\    do {								\      j >>= 1; i <<= 1; i |= (bitbuf & j) ? 1 : 0;			\      if (!j) { return DECR_ILLEGALDATA; }	                        \    } while ((i = hufftbl[i]) >= MAXSYMBOLS(tbl));			\  }									\  j = LENTABLE(tbl)[(var) = i];						\  REMOVE_BITS(j);							\} while (0)/* READ_LENGTHS(tablename, first, last) reads in code lengths for symbols * first to last in the given table. The code lengths are stored in their * own special LZX way. */#define READ_LENGTHS(tbl,first,last) do { \  lb.bb = bitbuf; lb.bl = bitsleft; lb.ip = inpos; \  if (lzx_read_lens(pState, LENTABLE(tbl),(first),(last),&lb)) { \    return DECR_ILLEGALDATA; \  } \  bitbuf = lb.bb; bitsleft = lb.bl; inpos = lb.ip; \} while (0)/* make_decode_table(nsyms, nbits, length[], table[]) * * This function was coded by David Tritscher. It builds a fast huffman * decoding table out of just a canonical huffman code lengths table. * * nsyms  = total number of symbols in this huffman tree. * nbits  = any symbols with a code length of nbits or less can be decoded *          in one lookup of the table. * length = A table to get code lengths from [0 to syms-1] * table  = The table to fill up with decoded symbols and pointers. * * Returns 0 for OK or 1 for error */static int make_decode_table(ULONG nsyms, ULONG nbits, UBYTE *length, UWORD *table) {    register UWORD sym;    register ULONG leaf;    register UBYTE bit_num = 1;    ULONG fill;    ULONG pos         = 0; /* the current position in the decode table */    ULONG table_mask  = 1 << nbits;    ULONG bit_mask    = table_mask >> 1; /* don't do 0 length codes */    ULONG next_symbol = bit_mask; /* base of allocation for long codes */    /* fill entries for codes short enough for a direct mapping */    while (bit_num <= nbits) {        for (sym = 0; sym < nsyms; sym++) {            if (length[sym] == bit_num) {                leaf = pos;                if((pos += bit_mask) > table_mask) return 1; /* table overrun */                /* fill all possible lookups of this symbol with the symbol itself */                fill = bit_mask;                while (fill-- > 0) table[leaf++] = sym;            }        }        bit_mask >>= 1;        bit_num++;    }    /* if there are any codes longer than nbits */    if (pos != table_mask) {        /* clear the remainder of the table */        for (sym = pos; sym < table_mask; sym++) table[sym] = 0;        /* give ourselves room for codes to grow by up to 16 more bits */        pos <<= 16;        table_mask <<= 16;        bit_mask = 1 << 15;        while (bit_num <= 16) {            for (sym = 0; sym < nsyms; sym++) {                if (length[sym] == bit_num) {                    leaf = pos >> 16;                    for (fill = 0; fill < bit_num - nbits; fill++) {                        /* if this path hasn't been taken yet, 'allocate' two entries */                        if (table[leaf] == 0) {                            table[(next_symbol << 1)] = 0;                            table[(next_symbol << 1) + 1] = 0;                            table[leaf] = next_symbol++;                        }                        /* follow the path and select either left or right for next bit */                        leaf = table[leaf] << 1;                        if ((pos >> (15-fill)) & 1) leaf++;                    }                    table[leaf] = sym;                    if ((pos += bit_mask) > table_mask) return 1; /* table overflow */                }            }            bit_mask >>= 1;            bit_num++;        }    }    /* full table? */    if (pos == table_mask) return 0;    /* either erroneous table, or all elements are 0 - let's find out. */    for (sym = 0; sym < nsyms; sym++) if (length[sym]) return 1;    return 0;}struct lzx_bits {  ULONG bb;  int bl;  UBYTE *ip;};static int lzx_read_lens(struct LZXstate *pState, UBYTE *lens, ULONG first, ULONG last, struct lzx_bits *lb) {    ULONG i,j, x,y;    int z;    register ULONG bitbuf = lb->bb;    register int bitsleft = lb->bl;    UBYTE *inpos = lb->ip;    UWORD *hufftbl;    for (x = 0; x < 20; x++) {        READ_BITS(y, 4);        LENTABLE(PRETREE)[x] = y;    }    BUILD_TABLE(PRETREE);    for (x = first; x < last; ) {        READ_HUFFSYM(PRETREE, z);        if (z == 17) {            READ_BITS(y, 4); y += 4;            while (y--) lens[x++] = 0;        }        else if (z == 18) {            READ_BITS(y, 5); y += 20;            while (y--) lens[x++] = 0;        }        else if (z == 19) {            READ_BITS(y, 1); y += 4;            READ_HUFFSYM(PRETREE, z);            z = lens[x] - z; if (z < 0) z += 17;            while (y--) lens[x++] = z;        }        else {            z = lens[x] - z; if (z < 0) z += 17;            lens[x++] = z;        }    }    lb->bb = bitbuf;    lb->bl = bitsleft;    lb->ip = inpos;    return 0;}int LZXdecompress(struct LZXstate *pState, unsigned char *inpos, unsigned char *outpos, int inlen, int outlen) {    UBYTE *endinp = inpos + inlen;    UBYTE *window = pState->window;    UBYTE *runsrc, *rundest;    UWORD *hufftbl; /* used in READ_HUFFSYM macro as chosen decoding table */    ULONG window_posn = pState->window_posn;    ULONG window_size = pState->window_size;    ULONG R0 = pState->R0;    ULONG R1 = pState->R1;    ULONG R2 = pState->R2;    register ULONG bitbuf;    register int bitsleft;    ULONG match_offset, i,j,k; /* ijk used in READ_HUFFSYM macro */    struct lzx_bits lb; /* used in READ_LENGTHS macro */    int togo = outlen, this_run, main_element, aligned_bits;    int match_length, length_footer, extra, verbatim_bits;    INIT_BITSTREAM;    /* read header if necessary */    if (!pState->header_read) {        i = j = 0;        READ_BITS(k, 1); if (k) { READ_BITS(i,16); READ_BITS(j,16); }        pState->intel_filesize = (i << 16) | j; /* or 0 if not encoded */        pState->header_read = 1;    }    /* main decoding loop */    while (togo > 0) {        /* last block finished, new block expected */        if (pState->block_remaining == 0) {            if (pState->block_type == LZX_BLOCKTYPE_UNCOMPRESSED) {                if (pState->block_length & 1) inpos++; /* realign bitstream to word */                INIT_BITSTREAM;            }            READ_BITS(pState->block_type, 3);            READ_BITS(i, 16);            READ_BITS(j, 8);            pState->block_remaining = pState->block_length = (i << 8) | j;            switch (pState->block_type) {                case LZX_BLOCKTYPE_ALIGNED:                    for (i = 0; i < 8; i++) { READ_BITS(j, 3); LENTABLE(ALIGNED)[i] = j; }                    BUILD_TABLE(ALIGNED);                    /* rest of aligned header is same as verbatim */                case LZX_BLOCKTYPE_VERBATIM:                    READ_LENGTHS(MAINTREE, 0, 256);                    READ_LENGTHS(MAINTREE, 256, pState->main_elements);                    BUILD_TABLE(MAINTREE);                    if (LENTABLE(MAINTREE)[0xE8] != 0) pState->intel_started = 1;                    READ_LENGTHS(LENGTH, 0, LZX_NUM_SECONDARY_LENGTHS);                    BUILD_TABLE(LENGTH);                    break;                case LZX_BLOCKTYPE_UNCOMPRESSED:                    pState->intel_started = 1; /* because we can't assume otherwise */                    ENSURE_BITS(16); /* get up to 16 pad bits into the buffer */                    if (bitsleft > 16) inpos -= 2; /* and align the bitstream! */                    R0 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;                    R1 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;                    R2 = inpos[0]|(inpos[1]<<8)|(inpos[2]<<16)|(inpos[3]<<24);inpos+=4;                    break;                default:                    return DECR_ILLEGALDATA;            }        }        /* buffer exhaustion check */        if (inpos > endinp) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -