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

📄 lzx.c

📁 又一开源的解压缩chm格式文件的代码
💻 C
📖 第 1 页 / 共 3 页
字号:
            /* it's possible to have a file where the next run is less than             * 16 bits in size. In this case, the READ_HUFFSYM() macro used             * in building the tables will exhaust the buffer, so we should             * allow for this, but not allow those accidentally read bits to             * be used (so we check that there are at least 16 bits             * remaining - in this boundary case they aren't really part of             * the compressed data)             */            if (inpos > (endinp+2) || bitsleft < 16) return DECR_ILLEGALDATA;        }        while ((this_run = pState->block_remaining) > 0 && togo > 0) {            if (this_run > togo) this_run = togo;            togo -= this_run;            pState->block_remaining -= this_run;            /* apply 2^x-1 mask */            window_posn &= window_size - 1;            /* runs can't straddle the window wraparound */            if ((window_posn + this_run) > window_size)                return DECR_DATAFORMAT;            switch (pState->block_type) {                case LZX_BLOCKTYPE_VERBATIM:                    while (this_run > 0) {                        READ_HUFFSYM(MAINTREE, main_element);                        if (main_element < LZX_NUM_CHARS) {                            /* literal: 0 to LZX_NUM_CHARS-1 */                            window[window_posn++] = main_element;                            this_run--;                        }                        else {                            /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */                            main_element -= LZX_NUM_CHARS;                            match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;                            if (match_length == LZX_NUM_PRIMARY_LENGTHS) {                                READ_HUFFSYM(LENGTH, length_footer);                                match_length += length_footer;                            }                            match_length += LZX_MIN_MATCH;                            match_offset = main_element >> 3;                            if (match_offset > 2) {                                /* not repeated offset */                                if (match_offset != 3) {                                    extra = extra_bits[match_offset];                                    READ_BITS(verbatim_bits, extra);                                    match_offset = position_base[match_offset] - 2 + verbatim_bits;                                }                                else {                                    match_offset = 1;                                }                                /* update repeated offset LRU queue */                                R2 = R1; R1 = R0; R0 = match_offset;                            }                            else if (match_offset == 0) {                                match_offset = R0;                            }                            else if (match_offset == 1) {                                match_offset = R1;                                R1 = R0; R0 = match_offset;                            }                            else /* match_offset == 2 */ {                                match_offset = R2;                                R2 = R0; R0 = match_offset;                            }                            rundest = window + window_posn;                            runsrc  = rundest - match_offset;                            window_posn += match_length;                            this_run -= match_length;                            /* copy any wrapped around source data */                            while ((runsrc < window) && (match_length-- > 0)) {                                *rundest++ = *(runsrc + window_size); runsrc++;                            }                            /* copy match data - no worries about destination wraps */                            while (match_length-- > 0) *rundest++ = *runsrc++;                        }                    }                    break;                case LZX_BLOCKTYPE_ALIGNED:                    while (this_run > 0) {                        READ_HUFFSYM(MAINTREE, main_element);                        if (main_element < LZX_NUM_CHARS) {                            /* literal: 0 to LZX_NUM_CHARS-1 */                            window[window_posn++] = main_element;                            this_run--;                        }                        else {                            /* match: LZX_NUM_CHARS + ((slot<<3) | length_header (3 bits)) */                            main_element -= LZX_NUM_CHARS;                            match_length = main_element & LZX_NUM_PRIMARY_LENGTHS;                            if (match_length == LZX_NUM_PRIMARY_LENGTHS) {                                READ_HUFFSYM(LENGTH, length_footer);                                match_length += length_footer;                            }                            match_length += LZX_MIN_MATCH;                            match_offset = main_element >> 3;                            if (match_offset > 2) {                                /* not repeated offset */                                extra = extra_bits[match_offset];                                match_offset = position_base[match_offset] - 2;                                if (extra > 3) {                                    /* verbatim and aligned bits */                                    extra -= 3;                                    READ_BITS(verbatim_bits, extra);                                    match_offset += (verbatim_bits << 3);                                    READ_HUFFSYM(ALIGNED, aligned_bits);                                    match_offset += aligned_bits;                                }                                else if (extra == 3) {                                    /* aligned bits only */                                    READ_HUFFSYM(ALIGNED, aligned_bits);                                    match_offset += aligned_bits;                                }                                else if (extra > 0) { /* extra==1, extra==2 */                                    /* verbatim bits only */                                    READ_BITS(verbatim_bits, extra);                                    match_offset += verbatim_bits;                                }                                else /* extra == 0 */ {                                    /* ??? */                                    match_offset = 1;                                }                                /* update repeated offset LRU queue */                                R2 = R1; R1 = R0; R0 = match_offset;                            }                            else if (match_offset == 0) {                                match_offset = R0;                            }                            else if (match_offset == 1) {                                match_offset = R1;                                R1 = R0; R0 = match_offset;                            }                            else /* match_offset == 2 */ {                                match_offset = R2;                                R2 = R0; R0 = match_offset;                            }                            rundest = window + window_posn;                            runsrc  = rundest - match_offset;                            window_posn += match_length;                            this_run -= match_length;                            /* copy any wrapped around source data */                            while ((runsrc < window) && (match_length-- > 0)) {                                *rundest++ = *(runsrc + window_size); runsrc++;                            }                            /* copy match data - no worries about destination wraps */                            while (match_length-- > 0) *rundest++ = *runsrc++;                        }                    }                    break;                case LZX_BLOCKTYPE_UNCOMPRESSED:                    if ((inpos + this_run) > endinp) return DECR_ILLEGALDATA;                    memcpy(window + window_posn, inpos, (size_t) this_run);                    inpos += this_run; window_posn += this_run;                    break;                default:                    return DECR_ILLEGALDATA; /* might as well */            }        }    }    if (togo != 0) return DECR_ILLEGALDATA;    memcpy(outpos, window + ((!window_posn) ? window_size : window_posn) - outlen, (size_t) outlen);    pState->window_posn = window_posn;    pState->R0 = R0;    pState->R1 = R1;    pState->R2 = R2;    /* intel E8 decoding */    if ((pState->frames_read++ < 32768) && pState->intel_filesize != 0) {        if (outlen <= 6 || !pState->intel_started) {            pState->intel_curpos += outlen;        }        else {            UBYTE *data    = outpos;            UBYTE *dataend = data + outlen - 10;            LONG curpos    = pState->intel_curpos;            LONG filesize  = pState->intel_filesize;            LONG abs_off, rel_off;            pState->intel_curpos = curpos + outlen;            while (data < dataend) {                if (*data++ != 0xE8) { curpos++; continue; }                abs_off = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);                if ((abs_off >= -curpos) && (abs_off < filesize)) {                    rel_off = (abs_off >= 0) ? abs_off - curpos : abs_off + filesize;                    data[0] = (UBYTE) rel_off;                    data[1] = (UBYTE) (rel_off >> 8);                    data[2] = (UBYTE) (rel_off >> 16);                    data[3] = (UBYTE) (rel_off >> 24);                }                data += 4;                curpos += 5;            }        }    }    return DECR_OK;}#ifdef LZX_CHM_TESTDRIVERint main(int c, char **v){    FILE *fin, *fout;    struct LZXstate state;    UBYTE ibuf[16384];    UBYTE obuf[32768];    int ilen, olen;    int status;    int i;    int count=0;    int w = atoi(v[1]);    LZXinit(&state, w);    fout = fopen(v[2], "wb");    for (i=3; i<c; i++)    {        fin = fopen(v[i], "rb");        ilen = fread(ibuf, 1, 16384, fin);        status = LZXdecompress(&state, ibuf, obuf, ilen, 32768);        switch (status)        {            case DECR_OK:                printf("ok\n");                fwrite(obuf, 1, 32768, fout);                break;            case DECR_DATAFORMAT:                printf("bad format\n");                break;            case DECR_ILLEGALDATA:                printf("illegal data\n");                break;            case DECR_NOMEMORY:                printf("no memory\n");                break;            default:                break;        }        fclose(fin);        if (++count == 2)        {            count = 0;            LZXreset(&state);        }    }    fclose(fout);}#endif

⌨️ 快捷键说明

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