diff options
author | unknown <konstantin@mysql.com> | 2004-07-21 17:36:26 -0700 |
---|---|---|
committer | unknown <konstantin@mysql.com> | 2004-07-21 17:36:26 -0700 |
commit | 9fe0a2fa8dbd83359722e077f761a01e37901bb8 (patch) | |
tree | e1c502ab20782af7b4564054ae3c46a321ccbb4e /zlib/inffast.c | |
parent | 2f26571fdcfc4eb701273079ede7fce7afa89e46 (diff) | |
download | mariadb-git-9fe0a2fa8dbd83359722e077f761a01e37901bb8.tar.gz |
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
Diffstat (limited to 'zlib/inffast.c')
-rw-r--r-- | zlib/inffast.c | 454 |
1 files changed, 288 insertions, 166 deletions
diff --git a/zlib/inffast.c b/zlib/inffast.c index aa7f1d4d2ad..c716440a92a 100644 --- a/zlib/inffast.c +++ b/zlib/inffast.c @@ -1,183 +1,305 @@ -/* inffast.c -- process literals and length/distance pairs fast - * Copyright (C) 1995-2002 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h +/* 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 "infblock.h" -#include "infcodes.h" -#include "infutil.h" +#include "inflate.h" #include "inffast.h" -struct inflate_codes_state {int dummy;}; /* for buggy compilers */ +#ifndef ASMINF -/* simplify the use of the inflate_huft type with some defines */ -#define exop word.what.Exop -#define bits word.what.Bits +/* 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 -/* macros for bit input with no checking and for returning unused bytes */ -#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}} -#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;} + Notes: -/* Called with number of bytes left to write in window at least 258 - (the maximum string length) and number of input bytes available - at least ten. The ten bytes are six bytes for the longest length/ - distance pair plus four bytes for overloading the bit buffer. */ + - 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. -int inflate_fast(bl, bd, tl, td, s, z) -uInt bl, bd; -inflate_huft *tl; -inflate_huft *td; /* need separate declaration for Borland C++ */ -inflate_blocks_statef *s; -z_streamp z; + - 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 */ { - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - uInt ml; /* mask for literal/length tree */ - uInt md; /* mask for distance tree */ - uInt c; /* bytes to copy */ - uInt d; /* distance back to copy from */ - Bytef *r; /* copy source pointer */ - - /* load input, output, bit values */ - LOAD - - /* initialize masks */ - ml = inflate_mask[bl]; - md = inflate_mask[bd]; - - /* do until not enough input or output space for fast loop */ - do { /* assume called with m >= 258 && n >= 10 */ - /* get literal/length code */ - GRABBITS(20) /* max bits for literal/length code */ - if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) - { - DUMPBITS(t->bits) - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base)); - *q++ = (Byte)t->base; - m--; - continue; - } + 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 { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits for length */ - e &= 15; - c = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv((stderr, "inflate: * length %u\n", c)); - - /* decode distance base of block to copy */ - GRABBITS(15); /* max bits for distance code */ - e = (t = td + ((uInt)b & md))->exop; - do { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits to add to distance base */ - e &= 15; - GRABBITS(e) /* get extra bits (up to 13) */ - d = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv((stderr, "inflate: * distance %u\n", d)); - - /* do the copy */ - m -= c; - r = q - d; - if (r < s->window) /* wrap if needed */ - { - do { - r += s->end - s->window; /* force pointer in window */ - } while (r < s->window); /* covers invalid distances */ - e = s->end - r; - if (c > e) - { - c -= e; /* wrapped copy */ - do { - *q++ = *r++; - } while (--e); - r = s->window; - do { - *q++ = *r++; - } while (--c); - } - else /* normal copy */ - { - *q++ = *r++; c--; - *q++ = *r++; c--; - do { - *q++ = *r++; - } while (--c); - } + 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; } - else /* normal copy */ - { - *q++ = *r++; c--; - *q++ = *r++; c--; - do { - *q++ = *r++; - } while (--c); + 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; - } - else if ((e & 64) == 0) - { - t += t->base; - e = (t += ((uInt)b & inflate_mask[e]))->exop; - } - else - { - z->msg = (char*)"invalid distance code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - break; - } - if ((e & 64) == 0) - { - t += t->base; - if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0) - { - DUMPBITS(t->bits) - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base)); - *q++ = (Byte)t->base; - m--; - break; } - } - else if (e & 32) - { - Tracevv((stderr, "inflate: * end of block\n")); - UNGRAB - UPDATE - return Z_STREAM_END; - } - else - { - z->msg = (char*)"invalid literal/length code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - } while (m >= 258 && n >= 10); - - /* not enough input or output--restore pointers and return */ - UNGRAB - UPDATE - return Z_OK; + } 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 */ |