/* inffast.c -- fast decoding1* Copyright (C) 1995-2017 Mark Adler2* For conditions of distribution and use, see copyright notice in zlib.h3*/45#include "zutil.h"6#include "inftrees.h"7#include "inflate.h"8#include "inffast.h"910#ifdef ASMINF11# pragma message("Assembler code may have bugs -- use at your own risk")12#else1314/*15Decode literal, length, and distance codes and write out the resulting16literal and match bytes until either not enough input or output is17available, an end-of-block is encountered, or a data error is encountered.18When large enough input and output buffers are supplied to inflate(), for19example, a 16K input buffer and a 64K output buffer, more than 95% of the20inflate execution time is spent in this routine.2122Entry assumptions:2324state->mode == LEN25strm->avail_in >= 626strm->avail_out >= 25827start >= strm->avail_out28state->bits < 82930On return, state->mode is one of:3132LEN -- ran out of enough output space or enough available input33TYPE -- reached end of block code, inflate() to interpret next block34BAD -- error in block data3536Notes:3738- The maximum input bits used by a length/distance pair is 15 bits for the39length code, 5 bits for the length extra, 15 bits for the distance code,40and 13 bits for the distance extra. This totals 48 bits, or six bytes.41Therefore if strm->avail_in >= 6, then there is enough input to avoid42checking for available input while decoding.4344- The maximum bytes that a single length/distance pair can output is 25845bytes, which is the maximum length that can be coded. inflate_fast()46requires strm->avail_out >= 258 for each loop to avoid checking for47output space.48*/49void ZLIB_INTERNAL inflate_fast(strm, start)50z_streamp strm;51unsigned start; /* inflate()'s starting value for strm->avail_out */52{53struct inflate_state FAR *state;54z_const unsigned char FAR *in; /* local strm->next_in */55z_const unsigned char FAR *last; /* have enough input while in < last */56unsigned char FAR *out; /* local strm->next_out */57unsigned char FAR *beg; /* inflate()'s initial strm->next_out */58unsigned char FAR *end; /* while out < end, enough space available */59#ifdef INFLATE_STRICT60unsigned dmax; /* maximum distance from zlib header */61#endif62unsigned wsize; /* window size or zero if not using window */63unsigned whave; /* valid bytes in the window */64unsigned wnext; /* window write index */65unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */66unsigned long hold; /* local strm->hold */67unsigned bits; /* local strm->bits */68code const FAR *lcode; /* local strm->lencode */69code const FAR *dcode; /* local strm->distcode */70unsigned lmask; /* mask for first level of length codes */71unsigned dmask; /* mask for first level of distance codes */72code here; /* retrieved table entry */73unsigned op; /* code bits, operation, extra bits, or */74/* window position, window bytes to copy */75unsigned len; /* match length, unused bytes */76unsigned dist; /* match distance */77unsigned char FAR *from; /* where to copy match from */7879/* copy state to local variables */80state = (struct inflate_state FAR *)strm->state;81in = strm->next_in;82last = in + (strm->avail_in - 5);83out = strm->next_out;84beg = out - (start - strm->avail_out);85end = out + (strm->avail_out - 257);86#ifdef INFLATE_STRICT87dmax = state->dmax;88#endif89wsize = state->wsize;90whave = state->whave;91wnext = state->wnext;92window = state->window;93hold = state->hold;94bits = state->bits;95lcode = state->lencode;96dcode = state->distcode;97lmask = (1U << state->lenbits) - 1;98dmask = (1U << state->distbits) - 1;99100/* decode literals and length/distances until end-of-block or not enough101input data or output space */102do {103if (bits < 15) {104hold += (unsigned long)(*in++) << bits;105bits += 8;106hold += (unsigned long)(*in++) << bits;107bits += 8;108}109here = lcode[hold & lmask];110dolen:111op = (unsigned)(here.bits);112hold >>= op;113bits -= op;114op = (unsigned)(here.op);115if (op == 0) { /* literal */116Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?117"inflate: literal '%c'\n" :118"inflate: literal 0x%02x\n", here.val));119*out++ = (unsigned char)(here.val);120}121else if (op & 16) { /* length base */122len = (unsigned)(here.val);123op &= 15; /* number of extra bits */124if (op) {125if (bits < op) {126hold += (unsigned long)(*in++) << bits;127bits += 8;128}129len += (unsigned)hold & ((1U << op) - 1);130hold >>= op;131bits -= op;132}133Tracevv((stderr, "inflate: length %u\n", len));134if (bits < 15) {135hold += (unsigned long)(*in++) << bits;136bits += 8;137hold += (unsigned long)(*in++) << bits;138bits += 8;139}140here = dcode[hold & dmask];141dodist:142op = (unsigned)(here.bits);143hold >>= op;144bits -= op;145op = (unsigned)(here.op);146if (op & 16) { /* distance base */147dist = (unsigned)(here.val);148op &= 15; /* number of extra bits */149if (bits < op) {150hold += (unsigned long)(*in++) << bits;151bits += 8;152if (bits < op) {153hold += (unsigned long)(*in++) << bits;154bits += 8;155}156}157dist += (unsigned)hold & ((1U << op) - 1);158#ifdef INFLATE_STRICT159if (dist > dmax) {160strm->msg = (char *)"invalid distance too far back";161state->mode = BAD;162break;163}164#endif165hold >>= op;166bits -= op;167Tracevv((stderr, "inflate: distance %u\n", dist));168op = (unsigned)(out - beg); /* max distance in output */169if (dist > op) { /* see if copy from window */170op = dist - op; /* distance back in window */171if (op > whave) {172if (state->sane) {173strm->msg =174(char *)"invalid distance too far back";175state->mode = BAD;176break;177}178#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR179if (len <= op - whave) {180do {181*out++ = 0;182} while (--len);183continue;184}185len -= op - whave;186do {187*out++ = 0;188} while (--op > whave);189if (op == 0) {190from = out - dist;191do {192*out++ = *from++;193} while (--len);194continue;195}196#endif197}198from = window;199if (wnext == 0) { /* very common case */200from += wsize - op;201if (op < len) { /* some from window */202len -= op;203do {204*out++ = *from++;205} while (--op);206from = out - dist; /* rest from output */207}208}209else if (wnext < op) { /* wrap around window */210from += wsize + wnext - op;211op -= wnext;212if (op < len) { /* some from end of window */213len -= op;214do {215*out++ = *from++;216} while (--op);217from = window;218if (wnext < len) { /* some from start of window */219op = wnext;220len -= op;221do {222*out++ = *from++;223} while (--op);224from = out - dist; /* rest from output */225}226}227}228else { /* contiguous in window */229from += wnext - op;230if (op < len) { /* some from window */231len -= op;232do {233*out++ = *from++;234} while (--op);235from = out - dist; /* rest from output */236}237}238while (len > 2) {239*out++ = *from++;240*out++ = *from++;241*out++ = *from++;242len -= 3;243}244if (len) {245*out++ = *from++;246if (len > 1)247*out++ = *from++;248}249}250else {251from = out - dist; /* copy direct from output */252do { /* minimum length is three */253*out++ = *from++;254*out++ = *from++;255*out++ = *from++;256len -= 3;257} while (len > 2);258if (len) {259*out++ = *from++;260if (len > 1)261*out++ = *from++;262}263}264}265else if ((op & 64) == 0) { /* 2nd level distance code */266here = dcode[here.val + (hold & ((1U << op) - 1))];267goto dodist;268}269else {270strm->msg = (char *)"invalid distance code";271state->mode = BAD;272break;273}274}275else if ((op & 64) == 0) { /* 2nd level length code */276here = lcode[here.val + (hold & ((1U << op) - 1))];277goto dolen;278}279else if (op & 32) { /* end-of-block */280Tracevv((stderr, "inflate: end of block\n"));281state->mode = TYPE;282break;283}284else {285strm->msg = (char *)"invalid literal/length code";286state->mode = BAD;287break;288}289} while (in < last && out < end);290291/* return unused bytes (on entry, bits < 8, so in won't go too far back) */292len = bits >> 3;293in -= len;294bits -= len << 3;295hold &= (1U << bits) - 1;296297/* update state and return */298strm->next_in = in;299strm->next_out = out;300strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));301strm->avail_out = (unsigned)(out < end ?302257 + (end - out) : 257 - (out - end));303state->hold = hold;304state->bits = bits;305return;306}307308/*309inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):310- Using bit fields for code structure311- Different op definition to avoid & for extra bits (do & for table bits)312- Three separate decoding do-loops for direct, window, and wnext == 0313- Special case for distance > 1 copies to do overlapped load and store copy314- Explicit branch predictions (based on measured branch probabilities)315- Deferring match copy and interspersed it with decoding subsequent codes316- Swapping literal/length else317- Swapping window/direct else318- Larger unrolled copy loops (three is about right)319- Moving len -= 3 statement into middle of loop320*/321322#endif /* !ASMINF */323324325