Path: blob/master/src/java.base/share/native/libzip/zlib/inffast.c
41153 views
/*1* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.2*3* This code is free software; you can redistribute it and/or modify it4* under the terms of the GNU General Public License version 2 only, as5* published by the Free Software Foundation. Oracle designates this6* particular file as subject to the "Classpath" exception as provided7* by Oracle in the LICENSE file that accompanied this code.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*/2324/* inffast.c -- fast decoding25* Copyright (C) 1995-2017 Mark Adler26* For conditions of distribution and use, see copyright notice in zlib.h27*/2829#include "zutil.h"30#include "inftrees.h"31#include "inflate.h"32#include "inffast.h"3334#ifdef ASMINF35# pragma message("Assembler code may have bugs -- use at your own risk")36#else3738/*39Decode literal, length, and distance codes and write out the resulting40literal and match bytes until either not enough input or output is41available, an end-of-block is encountered, or a data error is encountered.42When large enough input and output buffers are supplied to inflate(), for43example, a 16K input buffer and a 64K output buffer, more than 95% of the44inflate execution time is spent in this routine.4546Entry assumptions:4748state->mode == LEN49strm->avail_in >= 650strm->avail_out >= 25851start >= strm->avail_out52state->bits < 85354On return, state->mode is one of:5556LEN -- ran out of enough output space or enough available input57TYPE -- reached end of block code, inflate() to interpret next block58BAD -- error in block data5960Notes:6162- The maximum input bits used by a length/distance pair is 15 bits for the63length code, 5 bits for the length extra, 15 bits for the distance code,64and 13 bits for the distance extra. This totals 48 bits, or six bytes.65Therefore if strm->avail_in >= 6, then there is enough input to avoid66checking for available input while decoding.6768- The maximum bytes that a single length/distance pair can output is 25869bytes, which is the maximum length that can be coded. inflate_fast()70requires strm->avail_out >= 258 for each loop to avoid checking for71output space.72*/73void ZLIB_INTERNAL inflate_fast(strm, start)74z_streamp strm;75unsigned start; /* inflate()'s starting value for strm->avail_out */76{77struct inflate_state FAR *state;78z_const unsigned char FAR *in; /* local strm->next_in */79z_const unsigned char FAR *last; /* have enough input while in < last */80unsigned char FAR *out; /* local strm->next_out */81unsigned char FAR *beg; /* inflate()'s initial strm->next_out */82unsigned char FAR *end; /* while out < end, enough space available */83#ifdef INFLATE_STRICT84unsigned dmax; /* maximum distance from zlib header */85#endif86unsigned wsize; /* window size or zero if not using window */87unsigned whave; /* valid bytes in the window */88unsigned wnext; /* window write index */89unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */90unsigned long hold; /* local strm->hold */91unsigned bits; /* local strm->bits */92code const FAR *lcode; /* local strm->lencode */93code const FAR *dcode; /* local strm->distcode */94unsigned lmask; /* mask for first level of length codes */95unsigned dmask; /* mask for first level of distance codes */96code here; /* retrieved table entry */97unsigned op; /* code bits, operation, extra bits, or */98/* window position, window bytes to copy */99unsigned len; /* match length, unused bytes */100unsigned dist; /* match distance */101unsigned char FAR *from; /* where to copy match from */102103/* copy state to local variables */104state = (struct inflate_state FAR *)strm->state;105in = strm->next_in;106last = in + (strm->avail_in - 5);107out = strm->next_out;108beg = out - (start - strm->avail_out);109end = out + (strm->avail_out - 257);110#ifdef INFLATE_STRICT111dmax = state->dmax;112#endif113wsize = state->wsize;114whave = state->whave;115wnext = state->wnext;116window = state->window;117hold = state->hold;118bits = state->bits;119lcode = state->lencode;120dcode = state->distcode;121lmask = (1U << state->lenbits) - 1;122dmask = (1U << state->distbits) - 1;123124/* decode literals and length/distances until end-of-block or not enough125input data or output space */126do {127if (bits < 15) {128hold += (unsigned long)(*in++) << bits;129bits += 8;130hold += (unsigned long)(*in++) << bits;131bits += 8;132}133here = lcode[hold & lmask];134dolen:135op = (unsigned)(here.bits);136hold >>= op;137bits -= op;138op = (unsigned)(here.op);139if (op == 0) { /* literal */140Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?141"inflate: literal '%c'\n" :142"inflate: literal 0x%02x\n", here.val));143*out++ = (unsigned char)(here.val);144}145else if (op & 16) { /* length base */146len = (unsigned)(here.val);147op &= 15; /* number of extra bits */148if (op) {149if (bits < op) {150hold += (unsigned long)(*in++) << bits;151bits += 8;152}153len += (unsigned)hold & ((1U << op) - 1);154hold >>= op;155bits -= op;156}157Tracevv((stderr, "inflate: length %u\n", len));158if (bits < 15) {159hold += (unsigned long)(*in++) << bits;160bits += 8;161hold += (unsigned long)(*in++) << bits;162bits += 8;163}164here = dcode[hold & dmask];165dodist:166op = (unsigned)(here.bits);167hold >>= op;168bits -= op;169op = (unsigned)(here.op);170if (op & 16) { /* distance base */171dist = (unsigned)(here.val);172op &= 15; /* number of extra bits */173if (bits < op) {174hold += (unsigned long)(*in++) << bits;175bits += 8;176if (bits < op) {177hold += (unsigned long)(*in++) << bits;178bits += 8;179}180}181dist += (unsigned)hold & ((1U << op) - 1);182#ifdef INFLATE_STRICT183if (dist > dmax) {184strm->msg = (char *)"invalid distance too far back";185state->mode = BAD;186break;187}188#endif189hold >>= op;190bits -= op;191Tracevv((stderr, "inflate: distance %u\n", dist));192op = (unsigned)(out - beg); /* max distance in output */193if (dist > op) { /* see if copy from window */194op = dist - op; /* distance back in window */195if (op > whave) {196if (state->sane) {197strm->msg =198(char *)"invalid distance too far back";199state->mode = BAD;200break;201}202#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR203if (len <= op - whave) {204do {205*out++ = 0;206} while (--len);207continue;208}209len -= op - whave;210do {211*out++ = 0;212} while (--op > whave);213if (op == 0) {214from = out - dist;215do {216*out++ = *from++;217} while (--len);218continue;219}220#endif221}222from = window;223if (wnext == 0) { /* very common case */224from += wsize - op;225if (op < len) { /* some from window */226len -= op;227do {228*out++ = *from++;229} while (--op);230from = out - dist; /* rest from output */231}232}233else if (wnext < op) { /* wrap around window */234from += wsize + wnext - op;235op -= wnext;236if (op < len) { /* some from end of window */237len -= op;238do {239*out++ = *from++;240} while (--op);241from = window;242if (wnext < len) { /* some from start of window */243op = wnext;244len -= op;245do {246*out++ = *from++;247} while (--op);248from = out - dist; /* rest from output */249}250}251}252else { /* contiguous in window */253from += wnext - op;254if (op < len) { /* some from window */255len -= op;256do {257*out++ = *from++;258} while (--op);259from = out - dist; /* rest from output */260}261}262while (len > 2) {263*out++ = *from++;264*out++ = *from++;265*out++ = *from++;266len -= 3;267}268if (len) {269*out++ = *from++;270if (len > 1)271*out++ = *from++;272}273}274else {275from = out - dist; /* copy direct from output */276do { /* minimum length is three */277*out++ = *from++;278*out++ = *from++;279*out++ = *from++;280len -= 3;281} while (len > 2);282if (len) {283*out++ = *from++;284if (len > 1)285*out++ = *from++;286}287}288}289else if ((op & 64) == 0) { /* 2nd level distance code */290here = dcode[here.val + (hold & ((1U << op) - 1))];291goto dodist;292}293else {294strm->msg = (char *)"invalid distance code";295state->mode = BAD;296break;297}298}299else if ((op & 64) == 0) { /* 2nd level length code */300here = lcode[here.val + (hold & ((1U << op) - 1))];301goto dolen;302}303else if (op & 32) { /* end-of-block */304Tracevv((stderr, "inflate: end of block\n"));305state->mode = TYPE;306break;307}308else {309strm->msg = (char *)"invalid literal/length code";310state->mode = BAD;311break;312}313} while (in < last && out < end);314315/* return unused bytes (on entry, bits < 8, so in won't go too far back) */316len = bits >> 3;317in -= len;318bits -= len << 3;319hold &= (1U << bits) - 1;320321/* update state and return */322strm->next_in = in;323strm->next_out = out;324strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));325strm->avail_out = (unsigned)(out < end ?326257 + (end - out) : 257 - (out - end));327state->hold = hold;328state->bits = bits;329return;330}331332/*333inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):334- Using bit fields for code structure335- Different op definition to avoid & for extra bits (do & for table bits)336- Three separate decoding do-loops for direct, window, and wnext == 0337- Special case for distance > 1 copies to do overlapped load and store copy338- Explicit branch predictions (based on measured branch probabilities)339- Deferring match copy and interspersed it with decoding subsequent codes340- Swapping literal/length else341- Swapping window/direct else342- Larger unrolled copy loops (three is about right)343- Moving len -= 3 statement into middle of loop344*/345346#endif /* !ASMINF */347348349