summaryrefslogtreecommitdiff
path: root/zlib/infback.c
diff options
context:
space:
mode:
authorunknown <konstantin@mysql.com>2004-07-21 17:36:26 -0700
committerunknown <konstantin@mysql.com>2004-07-21 17:36:26 -0700
commit9fe0a2fa8dbd83359722e077f761a01e37901bb8 (patch)
treee1c502ab20782af7b4564054ae3c46a321ccbb4e /zlib/infback.c
parent2f26571fdcfc4eb701273079ede7fce7afa89e46 (diff)
downloadmariadb-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/infback.c')
-rw-r--r--zlib/infback.c619
1 files changed, 619 insertions, 0 deletions
diff --git a/zlib/infback.c b/zlib/infback.c
new file mode 100644
index 00000000000..110b03b857f
--- /dev/null
+++ b/zlib/infback.c
@@ -0,0 +1,619 @@
+/* infback.c -- inflate using a call-back interface
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ This code is largely copied from inflate.c. Normally either infback.o or
+ inflate.o would be linked into an application--not both. The interface
+ with inffast.c is retained so that optimized assembler-coded versions of
+ inflate_fast() can be used with either inflate.c or infback.c.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+
+/*
+ strm provides memory allocation functions in zalloc and zfree, or
+ Z_NULL to use the library memory allocation functions.
+
+ windowBits is in the range 8..15, and window is a user-supplied
+ window and output buffer that is 2**windowBits bytes.
+ */
+int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
+z_stream FAR *strm;
+int windowBits;
+unsigned char FAR *window;
+const char *version;
+int stream_size;
+{
+ struct inflate_state FAR *state;
+
+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+ stream_size != (int)(sizeof(z_stream)))
+ return Z_VERSION_ERROR;
+ if (strm == Z_NULL || window == Z_NULL ||
+ windowBits < 8 || windowBits > 15)
+ return Z_STREAM_ERROR;
+ strm->msg = Z_NULL; /* in case we return an error */
+ if (strm->zalloc == (alloc_func)0) {
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+ }
+ if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+ state = (struct inflate_state FAR *)ZALLOC(strm, 1,
+ sizeof(struct inflate_state));
+ if (state == Z_NULL) return Z_MEM_ERROR;
+ Tracev((stderr, "inflate: allocated\n"));
+ strm->state = (voidpf)state;
+ state->wbits = windowBits;
+ state->wsize = 1U << windowBits;
+ state->window = window;
+ state->write = 0;
+ state->whave = 0;
+ return Z_OK;
+}
+
+/*
+ Return state with length and distance decoding tables and index sizes set to
+ fixed code decoding. Normally this returns fixed tables from inffixed.h.
+ If BUILDFIXED is defined, then instead this routine builds the tables the
+ first time it's called, and returns those tables the first time and
+ thereafter. This reduces the size of the code by about 2K bytes, in
+ exchange for a little execution time. However, BUILDFIXED should not be
+ used for threaded applications, since the rewriting of the tables and virgin
+ may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+ static int virgin = 1;
+ static code *lenfix, *distfix;
+ static code fixed[544];
+
+ /* build fixed huffman tables if first call (may not be thread safe) */
+ if (virgin) {
+ unsigned sym, bits;
+ static code *next;
+
+ /* literal/length table */
+ sym = 0;
+ while (sym < 144) state->lens[sym++] = 8;
+ while (sym < 256) state->lens[sym++] = 9;
+ while (sym < 280) state->lens[sym++] = 7;
+ while (sym < 288) state->lens[sym++] = 8;
+ next = fixed;
+ lenfix = next;
+ bits = 9;
+ inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+ /* distance table */
+ sym = 0;
+ while (sym < 32) state->lens[sym++] = 5;
+ distfix = next;
+ bits = 5;
+ inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+ /* do this just once */
+ virgin = 0;
+ }
+#else /* !BUILDFIXED */
+# include "inffixed.h"
+#endif /* BUILDFIXED */
+ state->lencode = lenfix;
+ state->lenbits = 9;
+ state->distcode = distfix;
+ state->distbits = 5;
+}
+
+/* Macros for inflateBack(): */
+
+/* Load returned state from inflate_fast() */
+#define LOAD() \
+ do { \
+ put = strm->next_out; \
+ left = strm->avail_out; \
+ next = strm->next_in; \
+ have = strm->avail_in; \
+ hold = state->hold; \
+ bits = state->bits; \
+ } while (0)
+
+/* Set state from registers for inflate_fast() */
+#define RESTORE() \
+ do { \
+ strm->next_out = put; \
+ strm->avail_out = left; \
+ strm->next_in = next; \
+ strm->avail_in = have; \
+ state->hold = hold; \
+ state->bits = bits; \
+ } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+ do { \
+ hold = 0; \
+ bits = 0; \
+ } while (0)
+
+/* Assure that some input is available. If input is requested, but denied,
+ then return a Z_BUF_ERROR from inflateBack(). */
+#define PULL() \
+ do { \
+ if (have == 0) { \
+ have = in(in_desc, &next); \
+ if (have == 0) { \
+ next = Z_NULL; \
+ ret = Z_BUF_ERROR; \
+ goto inf_leave; \
+ } \
+ } \
+ } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflateBack()
+ with an error if there is no input available. */
+#define PULLBYTE() \
+ do { \
+ PULL(); \
+ have--; \
+ hold += (unsigned long)(*next++) << bits; \
+ bits += 8; \
+ } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator. If there is
+ not enough available input to do that, then return from inflateBack() with
+ an error. */
+#define NEEDBITS(n) \
+ do { \
+ while (bits < (unsigned)(n)) \
+ PULLBYTE(); \
+ } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+ ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+ do { \
+ hold >>= (n); \
+ bits -= (unsigned)(n); \
+ } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+ do { \
+ hold >>= bits & 7; \
+ bits -= bits & 7; \
+ } while (0)
+
+/* Assure that some output space is available, by writing out the window
+ if it's full. If the write fails, return from inflateBack() with a
+ Z_BUF_ERROR. */
+#define ROOM() \
+ do { \
+ if (left == 0) { \
+ put = state->window; \
+ left = state->wsize; \
+ state->whave = left; \
+ if (out(out_desc, put, left)) { \
+ ret = Z_BUF_ERROR; \
+ goto inf_leave; \
+ } \
+ } \
+ } while (0)
+
+/*
+ strm provides the memory allocation functions and window buffer on input,
+ and provides information on the unused input on return. For Z_DATA_ERROR
+ returns, strm will also provide an error message.
+
+ in() and out() are the call-back input and output functions. When
+ inflateBack() needs more input, it calls in(). When inflateBack() has
+ filled the window with output, or when it completes with data in the
+ window, it calls out() to write out the data. The application must not
+ change the provided input until in() is called again or inflateBack()
+ returns. The application must not change the window/output buffer until
+ inflateBack() returns.
+
+ in() and out() are called with a descriptor parameter provided in the
+ inflateBack() call. This parameter can be a structure that provides the
+ information required to do the read or write, as well as accumulated
+ information on the input and output such as totals and check values.
+
+ in() should return zero on failure. out() should return non-zero on
+ failure. If either in() or out() fails, than inflateBack() returns a
+ Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
+ was in() or out() that caused in the error. Otherwise, inflateBack()
+ returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
+ error, or Z_MEM_ERROR if it could not allocate memory for the state.
+ inflateBack() can also return Z_STREAM_ERROR if the input parameters
+ are not correct, i.e. strm is Z_NULL or the state was not initialized.
+ */
+int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
+z_stream FAR *strm;
+in_func in;
+void FAR *in_desc;
+out_func out;
+void FAR *out_desc;
+{
+ struct inflate_state FAR *state;
+ unsigned char FAR *next; /* next input */
+ unsigned char FAR *put; /* next output */
+ unsigned have, left; /* available input and output */
+ unsigned long hold; /* bit buffer */
+ unsigned bits; /* bits in bit buffer */
+ unsigned copy; /* number of stored or match bytes to copy */
+ unsigned char FAR *from; /* where to copy match bytes from */
+ code this; /* current decoding table entry */
+ code last; /* parent table entry */
+ unsigned len; /* length to copy for repeats, bits to drop */
+ int ret; /* return code */
+ static const unsigned short order[19] = /* permutation of code lengths */
+ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+ /* Check that the strm exists and that the state was initialized */
+ if (strm == Z_NULL || strm->state == Z_NULL)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* Reset the state */
+ strm->msg = Z_NULL;
+ state->mode = TYPE;
+ state->last = 0;
+ state->whave = 0;
+ next = strm->next_in;
+ have = next != Z_NULL ? strm->avail_in : 0;
+ hold = 0;
+ bits = 0;
+ put = state->window;
+ left = state->wsize;
+
+ /* Inflate until end of block marked as last */
+ for (;;)
+ switch (state->mode) {
+ case TYPE:
+ /* determine and dispatch block type */
+ if (state->last) {
+ BYTEBITS();
+ state->mode = DONE;
+ break;
+ }
+ NEEDBITS(3);
+ state->last = BITS(1);
+ DROPBITS(1);
+ switch (BITS(2)) {
+ case 0: /* stored block */
+ Tracev((stderr, "inflate: stored block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = STORED;
+ break;
+ case 1: /* fixed block */
+ fixedtables(state);
+ Tracev((stderr, "inflate: fixed codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = LEN; /* decode codes */
+ break;
+ case 2: /* dynamic block */
+ Tracev((stderr, "inflate: dynamic codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = TABLE;
+ break;
+ case 3:
+ strm->msg = (char *)"invalid block type";
+ state->mode = BAD;
+ }
+ DROPBITS(2);
+ break;
+
+ case STORED:
+ /* get and verify stored block length */
+ BYTEBITS(); /* go to byte boundary */
+ NEEDBITS(32);
+ if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+ strm->msg = (char *)"invalid stored block lengths";
+ state->mode = BAD;
+ break;
+ }
+ state->length = (unsigned)hold & 0xffff;
+ Tracev((stderr, "inflate: stored length %u\n",
+ state->length));
+ INITBITS();
+
+ /* copy stored block from input to output */
+ while (state->length != 0) {
+ copy = state->length;
+ PULL();
+ ROOM();
+ if (copy > have) copy = have;
+ if (copy > left) copy = left;
+ zmemcpy(put, next, copy);
+ have -= copy;
+ next += copy;
+ left -= copy;
+ put += copy;
+ state->length -= copy;
+ }
+ Tracev((stderr, "inflate: stored end\n"));
+ state->mode = TYPE;
+ break;
+
+ case TABLE:
+ /* get dynamic table entries descriptor */
+ NEEDBITS(14);
+ state->nlen = BITS(5) + 257;
+ DROPBITS(5);
+ state->ndist = BITS(5) + 1;
+ DROPBITS(5);
+ state->ncode = BITS(4) + 4;
+ DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+ if (state->nlen > 286 || state->ndist > 30) {
+ strm->msg = (char *)"too many length or distance symbols";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ Tracev((stderr, "inflate: table sizes ok\n"));
+
+ /* get code length code lengths (not a typo) */
+ state->have = 0;
+ while (state->have < state->ncode) {
+ NEEDBITS(3);
+ state->lens[order[state->have++]] = (unsigned short)BITS(3);
+ DROPBITS(3);
+ }
+ while (state->have < 19)
+ state->lens[order[state->have++]] = 0;
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 7;
+ ret = inflate_table(CODES, state->lens, 19, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid code lengths set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: code lengths ok\n"));
+
+ /* get length and distance code code lengths */
+ state->have = 0;
+ while (state->have < state->nlen + state->ndist) {
+ for (;;) {
+ this = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (this.val < 16) {
+ NEEDBITS(this.bits);
+ DROPBITS(this.bits);
+ state->lens[state->have++] = this.val;
+ }
+ else {
+ if (this.val == 16) {
+ NEEDBITS(this.bits + 2);
+ DROPBITS(this.bits);
+ if (state->have == 0) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ len = (unsigned)(state->lens[state->have - 1]);
+ copy = 3 + BITS(2);
+ DROPBITS(2);
+ }
+ else if (this.val == 17) {
+ NEEDBITS(this.bits + 3);
+ DROPBITS(this.bits);
+ len = 0;
+ copy = 3 + BITS(3);
+ DROPBITS(3);
+ }
+ else {
+ NEEDBITS(this.bits + 7);
+ DROPBITS(this.bits);
+ len = 0;
+ copy = 11 + BITS(7);
+ DROPBITS(7);
+ }
+ if (state->have + copy > state->nlen + state->ndist) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ while (copy--)
+ state->lens[state->have++] = (unsigned short)len;
+ }
+ }
+
+ /* build code tables */
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 9;
+ ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid literal/lengths set";
+ state->mode = BAD;
+ break;
+ }
+ state->distcode = (code const FAR *)(state->next);
+ state->distbits = 6;
+ ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+ &(state->next), &(state->distbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid distances set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: codes ok\n"));
+ state->mode = LEN;
+
+ case LEN:
+ /* use inflate_fast() if we have enough input and output */
+ if (have >= 6 && left >= 258) {
+ RESTORE();
+ if (state->whave < state->wsize)
+ state->whave = state->wsize - left;
+ inflate_fast(strm, state->wsize);
+ LOAD();
+ break;
+ }
+
+ /* get a literal, length, or end-of-block code */
+ for (;;) {
+ this = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (this.op && (this.op & 0xf0) == 0) {
+ last = this;
+ for (;;) {
+ this = state->lencode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(this.bits);
+ state->length = (unsigned)this.val;
+
+ /* process literal */
+ if (this.op == 0) {
+ Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", this.val));
+ ROOM();
+ *put++ = (unsigned char)(state->length);
+ left--;
+ state->mode = LEN;
+ break;
+ }
+
+ /* process end of block */
+ if (this.op & 32) {
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->mode = TYPE;
+ break;
+ }
+
+ /* invalid code */
+ if (this.op & 64) {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+
+ /* length code -- get extra bits, if any */
+ state->extra = (unsigned)(this.op) & 15;
+ if (state->extra != 0) {
+ NEEDBITS(state->extra);
+ state->length += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+ Tracevv((stderr, "inflate: length %u\n", state->length));
+
+ /* get distance code */
+ for (;;) {
+ this = state->distcode[BITS(state->distbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if ((this.op & 0xf0) == 0) {
+ last = this;
+ for (;;) {
+ this = state->distcode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(this.bits);
+ if (this.op & 64) {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ state->offset = (unsigned)this.val;
+
+ /* get distance extra bits, if any */
+ state->extra = (unsigned)(this.op) & 15;
+ if (state->extra != 0) {
+ NEEDBITS(state->extra);
+ state->offset += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+ if (state->offset > state->wsize - (state->whave < state->wsize ?
+ left : 0)) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+ Tracevv((stderr, "inflate: distance %u\n", state->offset));
+
+ /* copy match from window to output */
+ do {
+ ROOM();
+ copy = state->wsize - state->offset;
+ if (copy < left) {
+ from = put + copy;
+ copy = left - copy;
+ }
+ else {
+ from = put - state->offset;
+ copy = left;
+ }
+ if (copy > state->length) copy = state->length;
+ state->length -= copy;
+ left -= copy;
+ do {
+ *put++ = *from++;
+ } while (--copy);
+ } while (state->length != 0);
+ break;
+
+ case DONE:
+ /* inflate stream terminated properly -- write leftover output */
+ ret = Z_STREAM_END;
+ if (left < state->wsize) {
+ if (out(out_desc, state->window, state->wsize - left))
+ ret = Z_BUF_ERROR;
+ }
+ goto inf_leave;
+
+ case BAD:
+ ret = Z_DATA_ERROR;
+ goto inf_leave;
+
+ default: /* can't happen, but makes compilers happy */
+ ret = Z_STREAM_ERROR;
+ goto inf_leave;
+ }
+
+ /* Return unused input */
+ inf_leave:
+ strm->next_in = next;
+ strm->avail_in = have;
+ return ret;
+}
+
+int ZEXPORT inflateBackEnd(strm)
+z_stream FAR *strm;
+{
+ if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+ return Z_STREAM_ERROR;
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+ Tracev((stderr, "inflate: end\n"));
+ return Z_OK;
+}