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