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

📄 inflate.c

📁 Lib files of linux kernel
💻 C
📖 第 1 页 / 共 3 页
字号:
   A state may also return if there is not enough output space available to   complete that state.  Those states are copying stored data, writing a   literal byte, and copying a matching string.   When returning, a "goto inf_leave" is used to update the total counters,   update the check value, and determine whether any progress has been made   during that inflate() call in order to return the proper return code.   Progress is defined as a change in either strm->avail_in or strm->avail_out.   When there is a window, goto inf_leave will update the window with the last   output written.  If a goto inf_leave occurs in the middle of decompression   and there is no window currently, goto inf_leave will create one and copy   output to the window for the next call of inflate().   In this implementation, the flush parameter of inflate() only affects the   return code (per zlib.h).  inflate() always writes as much as possible to   strm->next_out, given the space available and the provided input--the effect   documented in zlib.h of Z_SYNC_FLUSH.  Furthermore, inflate() always defers   the allocation of and copying into a sliding window until necessary, which   provides the effect documented in zlib.h for Z_FINISH when the entire input   stream available.  So the only thing the flush parameter actually does is:   when flush is set to Z_FINISH, inflate() cannot return Z_OK.  Instead it   will return Z_BUF_ERROR if it has not reached the end of the stream. */int zlib_inflate(z_streamp strm, int flush){    struct inflate_state *state;    const unsigned char *next;  /* next input */    unsigned char *put;         /* next output */    unsigned have, left;        /* available input and output */    unsigned long hold;         /* bit buffer */    unsigned bits;              /* bits in bit buffer */    unsigned in, out;           /* save starting available input and output */    unsigned copy;              /* number of stored or match bytes to copy */    unsigned char *from;        /* where to copy match bytes from */    code this;                  /* current decoding table entry */    code last;                  /* parent table entry */    unsigned len;               /* length to copy for repeats, bits to drop */    int ret;                    /* return code */    static const unsigned short order[19] = /* permutation of code lengths */        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};    /* Do not check for strm->next_out == NULL here as ppc zImage       inflates to strm->next_out = 0 */    if (strm == NULL || strm->state == NULL ||        (strm->next_in == NULL && strm->avail_in != 0))        return Z_STREAM_ERROR;    state = (struct inflate_state *)strm->state;    if (state->mode == TYPE) state->mode = TYPEDO;      /* skip check */    LOAD();    in = have;    out = left;    ret = Z_OK;    for (;;)        switch (state->mode) {        case HEAD:            if (state->wrap == 0) {                state->mode = TYPEDO;                break;            }            NEEDBITS(16);            if (                ((BITS(8) << 8) + (hold >> 8)) % 31) {                strm->msg = (char *)"incorrect header check";                state->mode = BAD;                break;            }            if (BITS(4) != Z_DEFLATED) {                strm->msg = (char *)"unknown compression method";                state->mode = BAD;                break;            }            DROPBITS(4);            len = BITS(4) + 8;            if (len > state->wbits) {                strm->msg = (char *)"invalid window size";                state->mode = BAD;                break;            }            state->dmax = 1U << len;            strm->adler = state->check = zlib_adler32(0L, NULL, 0);            state->mode = hold & 0x200 ? DICTID : TYPE;            INITBITS();            break;        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 = zlib_adler32(0L, 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 */                state->mode = STORED;                break;            case 1:                             /* fixed block */                zlib_fixedtables(state);                state->mode = LEN;              /* decode codes */                break;            case 2:                             /* dynamic block */                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;            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;                memcpy(put, next, copy);                have -= copy;                next += copy;                left -= copy;                put += copy;                state->length -= copy;                break;            }            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            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 *)(state->next);            state->lenbits = 7;            ret = zlib_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;            }            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 *)(state->next);            state->lenbits = 9;            ret = zlib_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 *)(state->next);            state->distbits = 6;            ret = zlib_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;            }            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) {                state->mode = LIT;                break;            }            if (this.op & 32) {                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);

⌨️ 快捷键说明

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