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

📄 inflate.c

📁 在linux下实现压缩
💻 C
📖 第 1 页 / 共 4 页
字号:
                        len = state->head->extra_len - state->length;                        zmemcpy(state->head->extra + len, next,                                len + copy > state->head->extra_max ?                                state->head->extra_max - len : copy);                    }                    if (state->flags & 0x0200)                        state->check = crc32(state->check, next, copy);                    have -= copy;                    next += copy;                    state->length -= copy;                }                if (state->length) goto inf_leave;            }            state->length = 0;            state->mode = NAME;        case NAME:            if (state->flags & 0x0800) {                if (have == 0) goto inf_leave;                copy = 0;                do {                    len = (unsigned)(next[copy++]);                    if (state->head != Z_NULL &&                            state->head->name != Z_NULL &&                            state->length < state->head->name_max)                        state->head->name[state->length++] = len;                } while (len && copy < have);                if (state->flags & 0x0200)                    state->check = crc32(state->check, next, copy);                have -= copy;                next += copy;                if (len) goto inf_leave;            }            else if (state->head != Z_NULL)                state->head->name = Z_NULL;            state->length = 0;            state->mode = COMMENT;        case COMMENT:            if (state->flags & 0x1000) {                if (have == 0) goto inf_leave;                copy = 0;                do {                    len = (unsigned)(next[copy++]);                    if (state->head != Z_NULL &&                            state->head->comment != Z_NULL &&                            state->length < state->head->comm_max)                        state->head->comment[state->length++] = len;                } while (len && copy < have);                if (state->flags & 0x0200)                    state->check = crc32(state->check, next, copy);                have -= copy;                next += copy;                if (len) goto inf_leave;            }            else if (state->head != Z_NULL)                state->head->comment = Z_NULL;            state->mode = HCRC;        case HCRC:            if (state->flags & 0x0200) {                NEEDBITS(16);                if (hold != (state->check & 0xffff)) {                    strm->msg = (char *)"header crc mismatch";                    state->mode = BAD;                    break;                }                INITBITS();            }            if (state->head != Z_NULL) {                state->head->hcrc = (int)((state->flags >> 9) & 1);                state->head->done = 1;            }            strm->adler = state->check = crc32(0L, Z_NULL, 0);            state->mode = TYPE;            break;#endif        case DICTID:            NEEDBITS(32);            strm->adler = state->check = REVERSE(hold);            INITBITS();            state->mode = DICT;        case DICT:            if (state->havedict == 0) {                RESTORE();                return Z_NEED_DICT;            }            strm->adler = state->check = adler32(0L, Z_NULL, 0);            state->mode = TYPE;        case TYPE:            if (flush == Z_BLOCK) goto inf_leave;        case TYPEDO:            if (state->last) {                BYTEBITS();                state->mode = CHECK;                break;            }            NEEDBITS(3);            state->last = BITS(1);            DROPBITS(1);            switch (BITS(2)) {            case 0:                             /* stored block */                Tracev((stderr, "inflate:     stored block%s\n",                        state->last ? " (last)" : ""));                state->mode = STORED;                break;            case 1:                             /* fixed block */                fixedtables(state);                Tracev((stderr, "inflate:     fixed codes block%s\n",                        state->last ? " (last)" : ""));                state->mode = LEN;              /* decode codes */                break;            case 2:                             /* dynamic block */                Tracev((stderr, "inflate:     dynamic codes block%s\n",                        state->last ? " (last)" : ""));                state->mode = TABLE;                break;            case 3:                strm->msg = (char *)"invalid block type";                state->mode = BAD;            }            DROPBITS(2);            break;        case STORED:            BYTEBITS();                         /* go to byte boundary */            NEEDBITS(32);            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {                strm->msg = (char *)"invalid stored block lengths";                state->mode = BAD;                break;            }            state->length = (unsigned)hold & 0xffff;            Tracev((stderr, "inflate:       stored length %u\n",                    state->length));            INITBITS();            state->mode = COPY;        case COPY:            copy = state->length;            if (copy) {                if (copy > have) copy = have;                if (copy > left) copy = left;                if (copy == 0) goto inf_leave;                zmemcpy(put, next, copy);                have -= copy;                next += copy;                left -= copy;                put += copy;                state->length -= copy;                break;            }            Tracev((stderr, "inflate:       stored end\n"));            state->mode = TYPE;            break;        case TABLE:            NEEDBITS(14);            state->nlen = BITS(5) + 257;            DROPBITS(5);            state->ndist = BITS(5) + 1;            DROPBITS(5);            state->ncode = BITS(4) + 4;            DROPBITS(4);#ifndef PKZIP_BUG_WORKAROUND            if (state->nlen > 286 || state->ndist > 30) {                strm->msg = (char *)"too many length or distance symbols";                state->mode = BAD;                break;            }#endif            Tracev((stderr, "inflate:       table sizes ok\n"));            state->have = 0;            state->mode = LENLENS;        case LENLENS:            while (state->have < state->ncode) {                NEEDBITS(3);                state->lens[order[state->have++]] = (unsigned short)BITS(3);                DROPBITS(3);            }            while (state->have < 19)                state->lens[order[state->have++]] = 0;            state->next = state->codes;            state->lencode = (code const FAR *)(state->next);            state->lenbits = 7;            ret = inflate_table(CODES, state->lens, 19, &(state->next),                                &(state->lenbits), state->work);            if (ret) {                strm->msg = (char *)"invalid code lengths set";                state->mode = BAD;                break;            }            Tracev((stderr, "inflate:       code lengths ok\n"));            state->have = 0;            state->mode = CODELENS;        case CODELENS:            while (state->have < state->nlen + state->ndist) {                for (;;) {                    this = state->lencode[BITS(state->lenbits)];                    if ((unsigned)(this.bits) <= bits) break;                    PULLBYTE();                }                if (this.val < 16) {                    NEEDBITS(this.bits);                    DROPBITS(this.bits);                    state->lens[state->have++] = this.val;                }                else {                    if (this.val == 16) {                        NEEDBITS(this.bits + 2);                        DROPBITS(this.bits);                        if (state->have == 0) {                            strm->msg = (char *)"invalid bit length repeat";                            state->mode = BAD;                            break;                        }                        len = state->lens[state->have - 1];                        copy = 3 + BITS(2);                        DROPBITS(2);                    }                    else if (this.val == 17) {                        NEEDBITS(this.bits + 3);                        DROPBITS(this.bits);                        len = 0;                        copy = 3 + BITS(3);                        DROPBITS(3);                    }                    else {                        NEEDBITS(this.bits + 7);                        DROPBITS(this.bits);                        len = 0;                        copy = 11 + BITS(7);                        DROPBITS(7);                    }                    if (state->have + copy > state->nlen + state->ndist) {                        strm->msg = (char *)"invalid bit length repeat";                        state->mode = BAD;                        break;                    }                    while (copy--)                        state->lens[state->have++] = (unsigned short)len;                }            }            /* handle error breaks in while */            if (state->mode == BAD) break;            /* build code tables */            state->next = state->codes;            state->lencode = (code const FAR *)(state->next);            state->lenbits = 9;            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),                                &(state->lenbits), state->work);            if (ret) {                strm->msg = (char *)"invalid literal/lengths set";                state->mode = BAD;                break;            }            state->distcode = (code const FAR *)(state->next);            state->distbits = 6;            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,                            &(state->next), &(state->distbits), state->work);            if (ret) {                strm->msg = (char *)"invalid distances set";                state->mode = BAD;                break;            }            Tracev((stderr, "inflate:       codes ok\n"));            state->mode = LEN;        case LEN:            if (have >= 6 && left >= 258) {                RESTORE();                inflate_fast(strm, out);                LOAD();                break;            }            for (;;) {                this = state->lencode[BITS(state->lenbits)];                if ((unsigned)(this.bits) <= bits) break;                PULLBYTE();            }            if (this.op && (this.op & 0xf0) == 0) {                last = this;                for (;;) {                    this = state->lencode[last.val +                            (BITS(last.bits + last.op) >> last.bits)];                    if ((unsigned)(last.bits + this.bits) <= bits) break;                    PULLBYTE();                }                DROPBITS(last.bits);            }            DROPBITS(this.bits);            state->length = (unsigned)this.val;            if ((int)(this.op) == 0) {                Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?                        "inflate:         literal '%c'\n" :                        "inflate:         literal 0x%02x\n", this.val));                state->mode = LIT;                break;            }            if (this.op & 32) {                Tracevv((stderr, "inflate:         end of block\n"));                state->mode = TYPE;                break;            }            if (this.op & 64) {                strm->msg = (char *)"invalid literal/length code";                state->mode = BAD;                break;            }            state->extra = (unsigned)(this.op) & 15;            state->mode = LENEXT;        case LENEXT:            if (state->extra) {                NEEDBITS(state->extra);                state->length += BITS(state->extra);                DROPBITS(state->extra);            }            Tracevv((stderr, "inflate:         length %u\n", state->length));            state->mode = DIST;        case DIST:            for (;;) {                this = state->distcode[BITS(state->distbits)];                if ((unsigned)(this.bits) <= bits) break;                PULLBYTE();            }            if ((this.op & 0xf0) == 0) {                last = this;                for (;;) {                    this = state->distcode[last.val +                            (BITS(last.bits + last.op) >> last.bits)];                    if ((unsigned)(last.bits + this.bits) <= bits) break;                    PULLBYTE();                }                DROPBITS(last.bits);            }            DROPBITS(this.bits);            if (this.op & 64) {                strm->msg = (char *)"invalid distance code";                state->mode = BAD;                break;            }            state->offset = (unsigned)this.val;            state->extra = (unsigned)(this.op) & 15;            state->mode = DISTEXT;        case DISTEXT:            if (state->extra) {                NEEDBITS(state->extra);                state->offset += BITS(state->extra);

⌨️ 快捷键说明

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