mariadb/zlib/inffast.c
unknown 9fe0a2fa8d First step of implementation of WL#1518 "make bundled zlib
usable for unix builds": zlib 1.2.1 imported


BitKeeper/deleted/.del-Make_vms.com~95dd9cc7505c3153:
  Delete: zlib/Make_vms.com
BitKeeper/deleted/.del-Makefile.riscos~f85c6493d3e51733:
  Delete: zlib/Makefile.riscos
BitKeeper/deleted/.del-Makefile.pup~b0e9ed99224cc5f4:
  Delete: zlib/amiga/Makefile.pup
BitKeeper/deleted/.del-Makefile.sas~be103e936c85b66a:
  Delete: zlib/amiga/Makefile.sas
BitKeeper/deleted/.del-README.contrib~2924ba28ef1f9fab:
  Delete: zlib/contrib/README.contrib
BitKeeper/deleted/.del-gvmat32.asm~edf721a2de30e964:
  Delete: zlib/contrib/asm386/gvmat32.asm
BitKeeper/deleted/.del-visual-basic.txt~859fcbcb668ffbb3:
  Delete: zlib/contrib/visual-basic.txt
BitKeeper/deleted/.del-gvmat32c.c~2e97d7d65dd59113:
  Delete: zlib/contrib/asm386/gvmat32c.c
BitKeeper/deleted/.del-mkgvmt32.bat~5a92cf0febe3dc81:
  Delete: zlib/contrib/asm386/mkgvmt32.bat
BitKeeper/deleted/.del-zlibvc.def~67961fa7815b9267:
  Delete: zlib/contrib/asm386/zlibvc.def
BitKeeper/deleted/.del-zlibvc.dsp~a3323c77bcd12995:
  Delete: zlib/contrib/asm386/zlibvc.dsp
BitKeeper/deleted/.del-match.s~51b8fef5136642ed:
  Delete: zlib/contrib/asm586/match.s
BitKeeper/deleted/.del-readme.586~cb1bb7136b0803bb:
  Delete: zlib/contrib/asm586/readme.586
BitKeeper/deleted/.del-zlibvc.dsw~e3dca9d8f342e64e:
  Delete: zlib/contrib/asm386/zlibvc.dsw
BitKeeper/deleted/.del-match.s~e4bbe1fa486d1c6c:
  Delete: zlib/contrib/asm686/match.s
BitKeeper/deleted/.del-readme.686~98a220c13809fce5:
  Delete: zlib/contrib/asm686/readme.686
BitKeeper/deleted/.del-zlib.mak~70f7c5f6947fd807:
  Delete: zlib/contrib/delphi/zlib.mak
BitKeeper/deleted/.del-d_zlib.bpr~cefb1beee520d6e8:
  Delete: zlib/contrib/delphi2/d_zlib.bpr
BitKeeper/deleted/.del-d_zlib.cpp~62dff1931881afa6:
  Delete: zlib/contrib/delphi2/d_zlib.cpp
BitKeeper/deleted/.del-zlibdef.pas~780244c8d12b6c53:
  Delete: zlib/contrib/delphi/zlibdef.pas
BitKeeper/deleted/.del-readme.txt~8222e54ca00f2729:
  Delete: zlib/contrib/delphi2/readme.txt
BitKeeper/deleted/.del-zlib.bpg~fbd9308275ad8e3:
  Delete: zlib/contrib/delphi2/zlib.bpg
BitKeeper/deleted/.del-zlib.bpr~fe8bf5d1c4a2ce5a:
  Delete: zlib/contrib/delphi2/zlib.bpr
BitKeeper/deleted/.del-zlib.cpp~bb0c3df062410f5c:
  Delete: zlib/contrib/delphi2/zlib.cpp
BitKeeper/deleted/.del-zlib.pas~1d5285e2449b50a3:
  Delete: zlib/contrib/delphi2/zlib.pas
BitKeeper/deleted/.del-zlib32.bpr~c2a9f0aa47a1d9ad:
  Delete: zlib/contrib/delphi2/zlib32.bpr
BitKeeper/deleted/.del-test.cpp~4480297b204dc360:
  Delete: zlib/contrib/iostream/test.cpp
BitKeeper/deleted/.del-zfstream.cpp~943ecbd558e86dde:
  Delete: zlib/contrib/iostream/zfstream.cpp
BitKeeper/deleted/.del-zlib32.cpp~bbb4a200d2fe6497:
  Delete: zlib/contrib/delphi2/zlib32.cpp
BitKeeper/deleted/.del-ChangeLogUnzip~a3ae0ba899cadd:
  Delete: zlib/contrib/minizip/ChangeLogUnzip
BitKeeper/deleted/.del-zfstream.h~71ee057bdc6366ac:
  Delete: zlib/contrib/iostream/zfstream.h
BitKeeper/deleted/.del-zstream.h~a6f6be5634962c81:
  Delete: zlib/contrib/iostream2/zstream.h
BitKeeper/deleted/.del-zstream_test.cpp~e471b51e7fb553ec:
  Delete: zlib/contrib/iostream2/zstream_test.cpp
BitKeeper/deleted/.del-miniunz.c~9da181975b3a48:
  Delete: zlib/contrib/minizip/miniunz.c
BitKeeper/deleted/.del-minizip.c~4a49a0addb97272b:
  Delete: zlib/contrib/minizip/minizip.c
BitKeeper/deleted/.del-readme.txt~174eb00680149f6b:
  Delete: zlib/contrib/minizip/readme.txt
BitKeeper/deleted/.del-unzip.c~662c5ba4edbb3a19:
  Delete: zlib/contrib/minizip/unzip.c
BitKeeper/deleted/.del-unzip.def~8a0ad6f745ee5cd4:
  Delete: zlib/contrib/minizip/unzip.def
BitKeeper/deleted/.del-unzip.h~d5e800088a368c32:
  Delete: zlib/contrib/minizip/unzip.h
BitKeeper/deleted/.del-zip.c~9750c19a123f3057:
  Delete: zlib/contrib/minizip/zip.c
BitKeeper/deleted/.del-zip.def~4ffe888e9fd7b5aa:
  Delete: zlib/contrib/minizip/zip.def
BitKeeper/deleted/.del-zip.h~4c72b8fcc492f055:
  Delete: zlib/contrib/minizip/zip.h
BitKeeper/deleted/.del-zlibvc.def~dd272b3ed71647ba:
  Delete: zlib/contrib/minizip/zlibvc.def
BitKeeper/deleted/.del-zlibvc.dsp~ad83fb048811e2d2:
  Delete: zlib/contrib/minizip/zlibvc.dsp
BitKeeper/deleted/.del-zlibvc.dsw~c66b33a2d52f37c5:
  Delete: zlib/contrib/minizip/zlibvc.dsw
BitKeeper/deleted/.del-makefile.w32~6507530fa1b017c:
  Delete: zlib/contrib/untgz/makefile.w32
BitKeeper/deleted/.del-untgz.c~4e8f1a3a2c145373:
  Delete: zlib/contrib/untgz/untgz.c
BitKeeper/deleted/.del-Makefile.os2~8ab058477b24d1ff:
  Delete: zlib/os2/Makefile.os2
BitKeeper/deleted/.del-zlib.def~385b56ed82784ff3:
  Delete: zlib/os2/zlib.def
BitKeeper/deleted/.del-Makefile.b32~10ffaac6cc41847a:
  Delete: zlib/msdos/Makefile.b32
BitKeeper/deleted/.del-Makefile.bor~121b2bc837b6367:
  Delete: zlib/msdos/Makefile.bor
BitKeeper/deleted/.del-Makefile.dj2~a069623cad6ce7f4:
  Delete: zlib/msdos/Makefile.dj2
BitKeeper/deleted/.del-Makefile.emx~11a9e6c8a719ba60:
  Delete: zlib/msdos/Makefile.emx
BitKeeper/deleted/.del-Makefile.msc~ba5ad7709ff22aab:
  Delete: zlib/msdos/Makefile.msc
BitKeeper/deleted/.del-Makefile.tc~d1398368648e8836:
  Delete: zlib/msdos/Makefile.tc
BitKeeper/deleted/.del-Makefile.w32~921a473e873d94d1:
  Delete: zlib/msdos/Makefile.w32
BitKeeper/deleted/.del-Makefile.wat~b2b51cbc2c2bc2f4:
  Delete: zlib/msdos/Makefile.wat
BitKeeper/deleted/.del-zlib.def~189fba701e5e4b9c:
  Delete: zlib/msdos/zlib.def
BitKeeper/deleted/.del-zlib.rc~e5ce22c7c915ec00:
  Delete: zlib/msdos/zlib.rc
BitKeeper/deleted/.del-Makefile.emx~b5fa0633cbe6fe01:
  Delete: zlib/nt/Makefile.emx
BitKeeper/deleted/.del-Makefile.gcc~7fcd3dd326341fa0:
  Delete: zlib/nt/Makefile.gcc
BitKeeper/deleted/.del-Makefile.nt~9910c98f5da056de:
  Delete: zlib/nt/Makefile.nt
BitKeeper/deleted/.del-zlib.dnt~8160c636eb3eeed7:
  Delete: zlib/nt/zlib.dnt
BitKeeper/deleted/.del-zlib.dsp~a8abac2fb721276e:
  Delete: zlib/zlib.dsp
BitKeeper/deleted/.del-zlib.html~2e74efd497dcd4d0:
  Delete: zlib/zlib.html
BitKeeper/deleted/.del-minigzip.c~1f21a5863f457cb0:
  Delete: zlib/minigzip.c
BitKeeper/deleted/.del-example.c~5ea43c929ccd2a4f:
  Delete: zlib/example.c
BitKeeper/deleted/.del-descrip.mms~51cd5d1792d76b9c:
  Delete: zlib/descrip.mms
BitKeeper/deleted/.del-infblock.h~7d4f40c3a1d4cdf8:
  Delete: zlib/infblock.h
BitKeeper/deleted/.del-infblock.c~3c866934e0f44c43:
  Delete: zlib/infblock.c
BitKeeper/deleted/.del-infutil.c~43d2340436244b52:
  Delete: zlib/infutil.c
BitKeeper/deleted/.del-infutil.h~a6bd0dcbbdc187ac:
  Delete: zlib/infutil.h
BitKeeper/deleted/.del-infcodes.h~c9f64a612c2cc56a:
  Delete: zlib/infcodes.h
BitKeeper/deleted/.del-infcodes.c~7ed73df8a54d6d55:
  Delete: zlib/infcodes.c
BitKeeper/deleted/.del-maketree.c~846b8b96ac6872d8:
  Delete: zlib/maketree.c
VC++Files/zlib/zlib.dsp:
  Modified to suit zlib upgrade.
mysys/my_crc32.c:
  Modified to suit zlib upgrade.
zlib/ChangeLog:
  zlib 1.2.1 imported
zlib/FAQ:
  zlib 1.2.1 imported
zlib/INDEX:
  zlib 1.2.1 imported
zlib/README:
  zlib 1.2.1 imported
zlib/adler32.c:
  zlib 1.2.1 imported
zlib/algorithm.txt:
  zlib 1.2.1 imported
zlib/compress.c:
  zlib 1.2.1 imported
zlib/crc32.c:
  zlib 1.2.1 imported
zlib/deflate.c:
  zlib 1.2.1 imported
zlib/deflate.h:
  zlib 1.2.1 imported
zlib/gzio.c:
  zlib 1.2.1 imported
zlib/inffast.c:
  zlib 1.2.1 imported
zlib/inffast.h:
  zlib 1.2.1 imported
zlib/inffixed.h:
  zlib 1.2.1 imported
zlib/inflate.c:
  zlib 1.2.1 imported
zlib/inftrees.c:
  zlib 1.2.1 imported
zlib/inftrees.h:
  zlib 1.2.1 imported
zlib/trees.c:
  zlib 1.2.1 imported
zlib/uncompr.c:
  zlib 1.2.1 imported
zlib/zconf.h:
  zlib 1.2.1 imported
zlib/zlib.3:
  zlib 1.2.1 imported
zlib/zlib.h:
  zlib 1.2.1 imported
zlib/zutil.c:
  zlib 1.2.1 imported
zlib/zutil.h:
  zlib 1.2.1 imported
2004-07-21 17:36:26 -07:00

305 lines
12 KiB
C

/* inffast.c -- fast decoding
* Copyright (C) 1995-2003 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "inftrees.h"
#include "inflate.h"
#include "inffast.h"
#ifndef ASMINF
/* Allow machine dependent optimization for post-increment or pre-increment.
Based on testing to date,
Pre-increment preferred for:
- PowerPC G3 (Adler)
- MIPS R5000 (Randers-Pehrson)
Post-increment preferred for:
- none
No measurable difference:
- Pentium III (Anderson)
- 68060 (Nikl)
*/
#ifdef POSTINC
# define OFF 0
# define PUP(a) *(a)++
#else
# define OFF 1
# define PUP(a) *++(a)
#endif
/*
Decode literal, length, and distance codes and write out the resulting
literal and match bytes until either not enough input or output is
available, an end-of-block is encountered, or a data error is encountered.
When large enough input and output buffers are supplied to inflate(), for
example, a 16K input buffer and a 64K output buffer, more than 95% of the
inflate execution time is spent in this routine.
Entry assumptions:
state->mode == LEN
strm->avail_in >= 6
strm->avail_out >= 258
start >= strm->avail_out
state->bits < 8
On return, state->mode is one of:
LEN -- ran out of enough output space or enough available input
TYPE -- reached end of block code, inflate() to interpret next block
BAD -- error in block data
Notes:
- The maximum input bits used by a length/distance pair is 15 bits for the
length code, 5 bits for the length extra, 15 bits for the distance code,
and 13 bits for the distance extra. This totals 48 bits, or six bytes.
Therefore if strm->avail_in >= 6, then there is enough input to avoid
checking for available input while decoding.
- The maximum bytes that a single length/distance pair can output is 258
bytes, which is the maximum length that can be coded. inflate_fast()
requires strm->avail_out >= 258 for each loop to avoid checking for
output space.
*/
void inflate_fast(strm, start)
z_streamp strm;
unsigned start; /* inflate()'s starting value for strm->avail_out */
{
struct inflate_state FAR *state;
unsigned char FAR *in; /* local strm->next_in */
unsigned char FAR *last; /* while in < last, enough input available */
unsigned char FAR *out; /* local strm->next_out */
unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
unsigned char FAR *end; /* while out < end, enough space available */
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
unsigned write; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
unsigned long hold; /* local strm->hold */
unsigned bits; /* local strm->bits */
code const FAR *lcode; /* local strm->lencode */
code const FAR *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 */
unsigned char FAR *from; /* where to copy match from */
/* copy state to local variables */
state = (struct inflate_state FAR *)strm->state;
in = strm->next_in - OFF;
last = in + (strm->avail_in - 5);
out = strm->next_out - OFF;
beg = out - (start - strm->avail_out);
end = out + (strm->avail_out - 257);
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 += (unsigned long)(PUP(in)) << bits;
bits += 8;
hold += (unsigned long)(PUP(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 */
Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
"inflate: literal '%c'\n" :
"inflate: literal 0x%02x\n", this.val));
PUP(out) = (unsigned char)(this.val);
}
else if (op & 16) { /* length base */
len = (unsigned)(this.val);
op &= 15; /* number of extra bits */
if (op) {
if (bits < op) {
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
}
len += (unsigned)hold & ((1U << op) - 1);
hold >>= op;
bits -= op;
}
Tracevv((stderr, "inflate: length %u\n", len));
if (bits < 15) {
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
hold += (unsigned long)(PUP(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 += (unsigned long)(PUP(in)) << bits;
bits += 8;
if (bits < op) {
hold += (unsigned long)(PUP(in)) << bits;
bits += 8;
}
}
dist += (unsigned)hold & ((1U << op) - 1);
hold >>= op;
bits -= op;
Tracevv((stderr, "inflate: distance %u\n", dist));
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 - OFF;
if (write == 0) { /* very common case */
from += wsize - op;
if (op < len) { /* some from window */
len -= op;
do {
PUP(out) = PUP(from);
} while (--op);
from = out - dist; /* rest from output */
}
}
else if (write < op) { /* wrap around window */
from += wsize + write - op;
op -= write;
if (op < len) { /* some from end of window */
len -= op;
do {
PUP(out) = PUP(from);
} while (--op);
from = window - OFF;
if (write < len) { /* some from start of window */
op = write;
len -= op;
do {
PUP(out) = PUP(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 {
PUP(out) = PUP(from);
} while (--op);
from = out - dist; /* rest from output */
}
}
while (len > 2) {
PUP(out) = PUP(from);
PUP(out) = PUP(from);
PUP(out) = PUP(from);
len -= 3;
}
if (len) {
PUP(out) = PUP(from);
if (len > 1)
PUP(out) = PUP(from);
}
}
else {
from = out - dist; /* copy direct from output */
do { /* minimum length is three */
PUP(out) = PUP(from);
PUP(out) = PUP(from);
PUP(out) = PUP(from);
len -= 3;
} while (len > 2);
if (len) {
PUP(out) = PUP(from);
if (len > 1)
PUP(out) = PUP(from);
}
}
}
else if ((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;
}
}
else if ((op & 64) == 0) { /* 2nd level length code */
this = lcode[this.val + (hold & ((1U << op) - 1))];
goto dolen;
}
else if (op & 32) { /* end-of-block */
Tracevv((stderr, "inflate: end of block\n"));
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;
/* update state and return */
strm->next_in = in + OFF;
strm->next_out = out + OFF;
strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
strm->avail_out = (unsigned)(out < end ?
257 + (end - out) : 257 - (out - end));
state->hold = hold;
state->bits = bits;
return;
}
/*
inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
- Using bit fields for code structure
- Different op definition to avoid & for extra bits (do & for table bits)
- Three separate decoding do-loops for direct, window, and write == 0
- Special case for distance > 1 copies to do overlapped load and store copy
- Explicit branch predictions (based on measured branch probabilities)
- Deferring match copy and interspersed it with decoding subsequent codes
- Swapping literal/length else
- Swapping window/direct else
- Larger unrolled copy loops (three is about right)
- Moving len -= 3 statement into middle of loop
*/
#endif /* !ASMINF */