-@start:inflate()'sstartingvalueforstrm->avail_out
*/ void inflate_fast(z_streamp strm, unsigned start)
{ struct inflate_state *state; constunsignedchar *in; /* local strm->next_in */ constunsignedchar *last; /* while in < last, enough input available */ unsignedchar *out; /* local strm->next_out */ unsignedchar *beg; /* inflate()'s initial strm->next_out */ unsignedchar *end; /* while out < end, enough space available */ #ifdef INFLATE_STRICT unsigned dmax; /* maximum distance from zlib header */ #endif unsigned wsize; /* window size or zero if not using window */ unsigned whave; /* valid bytes in the window */ unsigned write; /* window write index */ unsignedchar *window; /* allocated sliding window, if wsize != 0 */ unsignedlong hold; /* local strm->hold */ unsigned bits; /* local strm->bits */
code const *lcode; /* local strm->lencode */
code const *dcode; /* local strm->distcode */ unsigned lmask; /* mask for first level of length codes */ unsigned dmask; /* mask for first level of distance codes */
code this; /* retrieved table entry */ unsigned op; /* code bits, operation, extra bits, or */ /* window position, window bytes to copy */ unsigned len; /* match length, unused bytes */ unsigned dist; /* match distance */ unsignedchar *from; /* where to copy match from */
/* copy state to local variables */
state = (struct inflate_state *)strm->state;
in = strm->next_in;
last = in + (strm->avail_in - 5);
out = strm->next_out;
beg = out - (start - strm->avail_out);
end = out + (strm->avail_out - 257); #ifdef INFLATE_STRICT
dmax = state->dmax; #endif
wsize = state->wsize;
whave = state->whave;
write = state->write;
window = state->window;
hold = state->hold;
bits = state->bits;
lcode = state->lencode;
dcode = state->distcode;
lmask = (1U << state->lenbits) - 1;
dmask = (1U << state->distbits) - 1;
/* decode literals and length/distances until end-of-block or not enough
input data or output space */ do { if (bits < 15) {
hold += (unsignedlong)(*in++) << bits;
bits += 8;
hold += (unsignedlong)(*in++) << bits;
bits += 8;
} this = lcode[hold & lmask];
dolen:
op = (unsigned)(this.bits);
hold >>= op;
bits -= op;
op = (unsigned)(this.op); if (op == 0) { /* literal */
*out++ = (unsignedchar)(this.val);
} elseif (op & 16) { /* length base */
len = (unsigned)(this.val);
op &= 15; /* number of extra bits */ if (op) { if (bits < op) {
hold += (unsignedlong)(*in++) << bits;
bits += 8;
}
len += (unsigned)hold & ((1U << op) - 1);
hold >>= op;
bits -= op;
} if (bits < 15) {
hold += (unsignedlong)(*in++) << bits;
bits += 8;
hold += (unsignedlong)(*in++) << bits;
bits += 8;
} this = dcode[hold & dmask];
dodist:
op = (unsigned)(this.bits);
hold >>= op;
bits -= op;
op = (unsigned)(this.op); if (op & 16) { /* distance base */
dist = (unsigned)(this.val);
op &= 15; /* number of extra bits */ if (bits < op) {
hold += (unsignedlong)(*in++) << bits;
bits += 8; if (bits < op) {
hold += (unsignedlong)(*in++) << bits;
bits += 8;
}
}
dist += (unsigned)hold & ((1U << op) - 1); #ifdef INFLATE_STRICT if (dist > dmax) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD; break;
} #endif
hold >>= op;
bits -= op;
op = (unsigned)(out - beg); /* max distance in output */ if (dist > op) { /* see if copy from window */
op = dist - op; /* distance back in window */ if (op > whave) {
strm->msg = (char *)"invalid distance too far back";
state->mode = BAD; break;
}
from = window; if (write == 0) { /* very common case */
from += wsize - op; if (op < len) { /* some from window */
len -= op; do {
*out++ = *from++;
} while (--op);
from = out - dist; /* rest from output */
}
} elseif (write < op) { /* wrap around window */
from += wsize + write - op;
op -= write; if (op < len) { /* some from end of window */
len -= op; do {
*out++ = *from++;
} while (--op);
from = window; if (write < len) { /* some from start of window */
op = write;
len -= op; do {
*out++ = *from++;
} while (--op);
from = out - dist; /* rest from output */
}
}
} else { /* contiguous in window */
from += write - op; if (op < len) { /* some from window */
len -= op; do {
*out++ = *from++;
} while (--op);
from = out - dist; /* rest from output */
}
} while (len > 2) {
*out++ = *from++;
*out++ = *from++;
*out++ = *from++;
len -= 3;
} if (len) {
*out++ = *from++; if (len > 1)
*out++ = *from++;
}
} else { unsignedshort *sout; unsignedlong loops;
from = out - dist; /* copy direct from output */ /* minimum length is three */ /* Align out addr */ if (!((long)(out - 1) & 1)) {
*out++ = *from++;
len--;
}
sout = (unsignedshort *)(out); if (dist > 2) { unsignedshort *sfrom;
sfrom = (unsignedshort *)(from);
loops = len >> 1; do { if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS))
*sout++ = *sfrom++; else
*sout++ = get_unaligned16(sfrom++);
} while (--loops);
out = (unsignedchar *)sout;
from = (unsignedchar *)sfrom;
} else { /* dist == 1 or dist == 2 */ unsignedshort pat16;
pat16 = *(sout-1); if (dist == 1) { union uu mm; /* copy one char pattern to both bytes */
mm.us = pat16;
mm.b[0] = mm.b[1];
pat16 = mm.us;
}
loops = len >> 1; do
*sout++ = pat16; while (--loops);
out = (unsignedchar *)sout;
} if (len & 1)
*out++ = *from++;
}
} elseif ((op & 64) == 0) { /* 2nd level distance code */ this = dcode[this.val + (hold & ((1U << op) - 1))]; goto dodist;
} else {
strm->msg = (char *)"invalid distance code";
state->mode = BAD; break;
}
} elseif ((op & 64) == 0) { /* 2nd level length code */ this = lcode[this.val + (hold & ((1U << op) - 1))]; goto dolen;
} elseif (op & 32) { /* end-of-block */
state->mode = TYPE; break;
} else {
strm->msg = (char *)"invalid literal/length code";
state->mode = BAD; break;
}
} while (in < last && out < end);
/* return unused bytes (on entry, bits < 8, so in won't go too far back) */
len = bits >> 3;
in -= len;
bits -= len << 3;
hold &= (1U << bits) - 1;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.