1793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* infback.c -- inflate using a call-back interface 2793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Copyright (C) 1995-2011 Mark Adler 3793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * For conditions of distribution and use, see copyright notice in zlib.h 4793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 5793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 6793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 7793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler This code is largely copied from inflate.c. Normally either infback.o or 8793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler inflate.o would be linked into an application--not both. The interface 9793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler with inffast.c is retained so that optimized assembler-coded versions of 10793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler inflate_fast() can be used with either inflate.c or infback.c. 11793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 12793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 13793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "zutil.h" 14793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "inftrees.h" 15793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "inflate.h" 16793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "inffast.h" 17793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 18793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* function prototypes */ 19793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerlocal void fixedtables OF((struct inflate_state FAR *state)); 20793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 21793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 22793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm provides memory allocation functions in zalloc and zfree, or 23793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Z_NULL to use the library memory allocation functions. 24793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 25793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler windowBits is in the range 8..15, and window is a user-supplied 26793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler window and output buffer that is 2**windowBits bytes. 27793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 28793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) 29793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerz_streamp strm; 30793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint windowBits; 31793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerunsigned char FAR *window; 32793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerconst char *version; 33793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint stream_size; 34793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 35793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct inflate_state FAR *state; 36793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 37793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || 38793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler stream_size != (int)(sizeof(z_stream))) 39793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_VERSION_ERROR; 40793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (strm == Z_NULL || window == Z_NULL || 41793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler windowBits < 8 || windowBits > 15) 42793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_STREAM_ERROR; 43793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = Z_NULL; /* in case we return an error */ 44793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (strm->zalloc == (alloc_func)0) { 45793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef Z_SOLO 46793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_STREAM_ERROR; 47793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#else 48793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->zalloc = zcalloc; 49793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->opaque = (voidpf)0; 50793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 51793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 52793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (strm->zfree == (free_func)0) 53793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef Z_SOLO 54793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_STREAM_ERROR; 55793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#else 56793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->zfree = zcfree; 57793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 58793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state = (struct inflate_state FAR *)ZALLOC(strm, 1, 59793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sizeof(struct inflate_state)); 60793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state == Z_NULL) return Z_MEM_ERROR; 61793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: allocated\n")); 62793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->state = (struct internal_state FAR *)state; 63793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->dmax = 32768U; 64793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->wbits = windowBits; 65793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->wsize = 1U << windowBits; 66793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->window = window; 67793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->wnext = 0; 68793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->whave = 0; 69793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_OK; 70793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 71793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 72793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 73793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Return state with length and distance decoding tables and index sizes set to 74793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fixed code decoding. Normally this returns fixed tables from inffixed.h. 75793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler If BUILDFIXED is defined, then instead this routine builds the tables the 76793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler first time it's called, and returns those tables the first time and 77793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler thereafter. This reduces the size of the code by about 2K bytes, in 78793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler exchange for a little execution time. However, BUILDFIXED should not be 79793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler used for threaded applications, since the rewriting of the tables and virgin 80793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler may not be thread-safe. 81793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 82793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerlocal void fixedtables(state) 83793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstruct inflate_state FAR *state; 84793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 85793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef BUILDFIXED 86793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler static int virgin = 1; 87793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler static code *lenfix, *distfix; 88793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler static code fixed[544]; 89793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 90793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* build fixed huffman tables if first call (may not be thread safe) */ 91793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (virgin) { 92793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned sym, bits; 93793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler static code *next; 94793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 95793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* literal/length table */ 96793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sym = 0; 97793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (sym < 144) state->lens[sym++] = 8; 98793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (sym < 256) state->lens[sym++] = 9; 99793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (sym < 280) state->lens[sym++] = 7; 100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (sym < 288) state->lens[sym++] = 8; 101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler next = fixed; 102793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler lenfix = next; 103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bits = 9; 104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); 105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* distance table */ 107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sym = 0; 108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (sym < 32) state->lens[sym++] = 5; 109793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler distfix = next; 110793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bits = 5; 111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); 112793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* do this just once */ 114793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler virgin = 0; 115793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 116793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#else /* !BUILDFIXED */ 117793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler# include "inffixed.h" 118793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif /* BUILDFIXED */ 119793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->lencode = lenfix; 120793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->lenbits = 9; 121793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->distcode = distfix; 122793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->distbits = 5; 123793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 124793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 125793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* Macros for inflateBack(): */ 126793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 127793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* Load returned state from inflate_fast() */ 128793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define LOAD() \ 129793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { \ 130793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler put = strm->next_out; \ 131793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler left = strm->avail_out; \ 132793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler next = strm->next_in; \ 133793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler have = strm->avail_in; \ 134793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler hold = state->hold; \ 135793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bits = state->bits; \ 136793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (0) 137793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 138793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* Set state from registers for inflate_fast() */ 139793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define RESTORE() \ 140793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { \ 141793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->next_out = put; \ 142793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->avail_out = left; \ 143793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->next_in = next; \ 144793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->avail_in = have; \ 145793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->hold = hold; \ 146793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->bits = bits; \ 147793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (0) 148793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 149793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* Clear the input bit accumulator */ 150793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define INITBITS() \ 151793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { \ 152793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler hold = 0; \ 153793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bits = 0; \ 154793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (0) 155793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 156793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* Assure that some input is available. If input is requested, but denied, 157793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler then return a Z_BUF_ERROR from inflateBack(). */ 158793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define PULL() \ 159793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { \ 160793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (have == 0) { \ 161793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler have = in(in_desc, &next); \ 162793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (have == 0) { \ 163793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler next = Z_NULL; \ 164793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = Z_BUF_ERROR; \ 165793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler goto inf_leave; \ 166793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } \ 167793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } \ 168793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (0) 169793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 170793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* Get a byte of input into the bit accumulator, or return from inflateBack() 171793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler with an error if there is no input available. */ 172793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define PULLBYTE() \ 173793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { \ 174793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler PULL(); \ 175793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler have--; \ 176793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler hold += (unsigned long)(*next++) << bits; \ 177793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bits += 8; \ 178793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (0) 179793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 180793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* Assure that there are at least n bits in the bit accumulator. If there is 181793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler not enough available input to do that, then return from inflateBack() with 182793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler an error. */ 183793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define NEEDBITS(n) \ 184793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { \ 185793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (bits < (unsigned)(n)) \ 186793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler PULLBYTE(); \ 187793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (0) 188793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 189793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* Return the low n bits of the bit accumulator (n < 16) */ 190793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define BITS(n) \ 191793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ((unsigned)hold & ((1U << (n)) - 1)) 192793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 193793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* Remove n bits from the bit accumulator */ 194793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define DROPBITS(n) \ 195793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { \ 196793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler hold >>= (n); \ 197793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bits -= (unsigned)(n); \ 198793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (0) 199793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 200793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* Remove zero to seven bits as needed to go to a byte boundary */ 201793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define BYTEBITS() \ 202793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { \ 203793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler hold >>= bits & 7; \ 204793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bits -= bits & 7; \ 205793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (0) 206793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 207793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* Assure that some output space is available, by writing out the window 208793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if it's full. If the write fails, return from inflateBack() with a 209793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Z_BUF_ERROR. */ 210793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define ROOM() \ 211793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { \ 212793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (left == 0) { \ 213793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler put = state->window; \ 214793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler left = state->wsize; \ 215793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->whave = left; \ 216793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (out(out_desc, put, left)) { \ 217793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = Z_BUF_ERROR; \ 218793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler goto inf_leave; \ 219793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } \ 220793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } \ 221793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (0) 222793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 223793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 224793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm provides the memory allocation functions and window buffer on input, 225793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler and provides information on the unused input on return. For Z_DATA_ERROR 226793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler returns, strm will also provide an error message. 227793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 228793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler in() and out() are the call-back input and output functions. When 229793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler inflateBack() needs more input, it calls in(). When inflateBack() has 230793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler filled the window with output, or when it completes with data in the 231793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler window, it calls out() to write out the data. The application must not 232793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler change the provided input until in() is called again or inflateBack() 233793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler returns. The application must not change the window/output buffer until 234793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler inflateBack() returns. 235793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 236793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler in() and out() are called with a descriptor parameter provided in the 237793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler inflateBack() call. This parameter can be a structure that provides the 238793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler information required to do the read or write, as well as accumulated 239793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler information on the input and output such as totals and check values. 240793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 241793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler in() should return zero on failure. out() should return non-zero on 242793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler failure. If either in() or out() fails, than inflateBack() returns a 243793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it 244793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler was in() or out() that caused in the error. Otherwise, inflateBack() 245793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format 246793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler error, or Z_MEM_ERROR if it could not allocate memory for the state. 247793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler inflateBack() can also return Z_STREAM_ERROR if the input parameters 248793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler are not correct, i.e. strm is Z_NULL or the state was not initialized. 249793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 250793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) 251793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerz_streamp strm; 252793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerin_func in; 253793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid FAR *in_desc; 254793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerout_func out; 255793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid FAR *out_desc; 256793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 257793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct inflate_state FAR *state; 258793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler z_const unsigned char FAR *next; /* next input */ 259793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned char FAR *put; /* next output */ 260793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned have, left; /* available input and output */ 261793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned long hold; /* bit buffer */ 262793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned bits; /* bits in bit buffer */ 263793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned copy; /* number of stored or match bytes to copy */ 264793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned char FAR *from; /* where to copy match bytes from */ 265793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler code here; /* current decoding table entry */ 266793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler code last; /* parent table entry */ 267793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned len; /* length to copy for repeats, bits to drop */ 268793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int ret; /* return code */ 269793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler static const unsigned short order[19] = /* permutation of code lengths */ 270793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; 271793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 272793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Check that the strm exists and that the state was initialized */ 273793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (strm == Z_NULL || strm->state == Z_NULL) 274793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_STREAM_ERROR; 275793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state = (struct inflate_state FAR *)strm->state; 276793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 277793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Reset the state */ 278793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = Z_NULL; 279793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = TYPE; 280793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->last = 0; 281793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->whave = 0; 282793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler next = strm->next_in; 283793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler have = next != Z_NULL ? strm->avail_in : 0; 284793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler hold = 0; 285793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bits = 0; 286793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler put = state->window; 287793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler left = state->wsize; 288793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 289793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Inflate until end of block marked as last */ 290793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (;;) 291793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (state->mode) { 292793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case TYPE: 293793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* determine and dispatch block type */ 294793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->last) { 295793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler BYTEBITS(); 296793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = DONE; 297793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 298793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 299793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(3); 300793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->last = BITS(1); 301793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(1); 302793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (BITS(2)) { 303793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 0: /* stored block */ 304793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: stored block%s\n", 305793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->last ? " (last)" : "")); 306793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = STORED; 307793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 308793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 1: /* fixed block */ 309793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fixedtables(state); 310793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: fixed codes block%s\n", 311793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->last ? " (last)" : "")); 312793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = LEN; /* decode codes */ 313793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 314793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 2: /* dynamic block */ 315793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: dynamic codes block%s\n", 316793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->last ? " (last)" : "")); 317793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = TABLE; 318793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 319793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 3: 320793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid block type"; 321793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 322793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 323793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(2); 324793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 325793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 326793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case STORED: 327793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* get and verify stored block length */ 328793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler BYTEBITS(); /* go to byte boundary */ 329793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(32); 330793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { 331793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid stored block lengths"; 332793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 333793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 334793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 335793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->length = (unsigned)hold & 0xffff; 336793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: stored length %u\n", 337793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->length)); 338793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler INITBITS(); 339793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 340793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* copy stored block from input to output */ 341793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (state->length != 0) { 342793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy = state->length; 343793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler PULL(); 344793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ROOM(); 345793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (copy > have) copy = have; 346793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (copy > left) copy = left; 347793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler zmemcpy(put, next, copy); 348793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler have -= copy; 349793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler next += copy; 350793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler left -= copy; 351793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler put += copy; 352793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->length -= copy; 353793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 354793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: stored end\n")); 355793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = TYPE; 356793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 357793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 358793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case TABLE: 359793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* get dynamic table entries descriptor */ 360793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(14); 361793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->nlen = BITS(5) + 257; 362793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(5); 363793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->ndist = BITS(5) + 1; 364793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(5); 365793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->ncode = BITS(4) + 4; 366793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(4); 367793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifndef PKZIP_BUG_WORKAROUND 368793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->nlen > 286 || state->ndist > 30) { 369793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"too many length or distance symbols"; 370793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 371793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 372793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 373793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 374793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: table sizes ok\n")); 375793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 376793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* get code length code lengths (not a typo) */ 377793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->have = 0; 378793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (state->have < state->ncode) { 379793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(3); 380793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->lens[order[state->have++]] = (unsigned short)BITS(3); 381793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(3); 382793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 383793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (state->have < 19) 384793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->lens[order[state->have++]] = 0; 385793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->next = state->codes; 386793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->lencode = (code const FAR *)(state->next); 387793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->lenbits = 7; 388793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = inflate_table(CODES, state->lens, 19, &(state->next), 389793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler &(state->lenbits), state->work); 390793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (ret) { 391793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid code lengths set"; 392793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 393793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 394793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 395793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: code lengths ok\n")); 396793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 397793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* get length and distance code code lengths */ 398793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->have = 0; 399793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (state->have < state->nlen + state->ndist) { 400793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (;;) { 401793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler here = state->lencode[BITS(state->lenbits)]; 402793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((unsigned)(here.bits) <= bits) break; 403793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler PULLBYTE(); 404793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 405793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (here.val < 16) { 406793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(here.bits); 407793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->lens[state->have++] = here.val; 408793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 409793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else { 410793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (here.val == 16) { 411793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(here.bits + 2); 412793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(here.bits); 413793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->have == 0) { 414793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid bit length repeat"; 415793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 416793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 417793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 418793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler len = (unsigned)(state->lens[state->have - 1]); 419793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy = 3 + BITS(2); 420793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(2); 421793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 422793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if (here.val == 17) { 423793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(here.bits + 3); 424793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(here.bits); 425793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler len = 0; 426793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy = 3 + BITS(3); 427793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(3); 428793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 429793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else { 430793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(here.bits + 7); 431793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(here.bits); 432793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler len = 0; 433793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy = 11 + BITS(7); 434793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(7); 435793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 436793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->have + copy > state->nlen + state->ndist) { 437793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid bit length repeat"; 438793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 439793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 440793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 441793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (copy--) 442793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->lens[state->have++] = (unsigned short)len; 443793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 444793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 445793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 446793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* handle error breaks in while */ 447793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->mode == BAD) break; 448793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 449793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* check for end-of-block code (better have one) */ 450793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->lens[256] == 0) { 451793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid code -- missing end-of-block"; 452793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 453793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 454793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 455793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 456793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* build code tables -- note: do not change the lenbits or distbits 457793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler values here (9 and 6) without reading the comments in inftrees.h 458793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler concerning the ENOUGH constants, which depend on those values */ 459793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->next = state->codes; 460793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->lencode = (code const FAR *)(state->next); 461793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->lenbits = 9; 462793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), 463793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler &(state->lenbits), state->work); 464793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (ret) { 465793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid literal/lengths set"; 466793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 467793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 468793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 469793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->distcode = (code const FAR *)(state->next); 470793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->distbits = 6; 471793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, 472793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler &(state->next), &(state->distbits), state->work); 473793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (ret) { 474793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid distances set"; 475793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 476793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 477793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 478793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: codes ok\n")); 479793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = LEN; 480793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 481793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case LEN: 482793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* use inflate_fast() if we have enough input and output */ 483793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (have >= 6 && left >= 258) { 484793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler RESTORE(); 485793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->whave < state->wsize) 486793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->whave = state->wsize - left; 487793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler inflate_fast(strm, state->wsize); 488793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler LOAD(); 489793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 490793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 491793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 492793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* get a literal, length, or end-of-block code */ 493793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (;;) { 494793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler here = state->lencode[BITS(state->lenbits)]; 495793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((unsigned)(here.bits) <= bits) break; 496793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler PULLBYTE(); 497793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 498793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (here.op && (here.op & 0xf0) == 0) { 499793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler last = here; 500793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (;;) { 501793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler here = state->lencode[last.val + 502793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (BITS(last.bits + last.op) >> last.bits)]; 503793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((unsigned)(last.bits + here.bits) <= bits) break; 504793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler PULLBYTE(); 505793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 506793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(last.bits); 507793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 508793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(here.bits); 509793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->length = (unsigned)here.val; 510793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 511793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* process literal */ 512793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (here.op == 0) { 513793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? 514793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "inflate: literal '%c'\n" : 515793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "inflate: literal 0x%02x\n", here.val)); 516793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ROOM(); 517793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *put++ = (unsigned char)(state->length); 518793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler left--; 519793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = LEN; 520793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 521793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 522793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 523793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* process end of block */ 524793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (here.op & 32) { 525793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracevv((stderr, "inflate: end of block\n")); 526793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = TYPE; 527793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 528793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 529793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 530793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* invalid code */ 531793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (here.op & 64) { 532793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid literal/length code"; 533793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 534793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 535793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 536793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 537793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* length code -- get extra bits, if any */ 538793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->extra = (unsigned)(here.op) & 15; 539793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->extra != 0) { 540793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(state->extra); 541793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->length += BITS(state->extra); 542793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(state->extra); 543793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 544793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracevv((stderr, "inflate: length %u\n", state->length)); 545793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 546793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* get distance code */ 547793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (;;) { 548793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler here = state->distcode[BITS(state->distbits)]; 549793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((unsigned)(here.bits) <= bits) break; 550793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler PULLBYTE(); 551793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 552793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((here.op & 0xf0) == 0) { 553793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler last = here; 554793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (;;) { 555793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler here = state->distcode[last.val + 556793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (BITS(last.bits + last.op) >> last.bits)]; 557793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((unsigned)(last.bits + here.bits) <= bits) break; 558793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler PULLBYTE(); 559793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 560793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(last.bits); 561793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 562793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(here.bits); 563793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (here.op & 64) { 564793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid distance code"; 565793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 566793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 567793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 568793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->offset = (unsigned)here.val; 569793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 570793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* get distance extra bits, if any */ 571793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->extra = (unsigned)(here.op) & 15; 572793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->extra != 0) { 573793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(state->extra); 574793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->offset += BITS(state->extra); 575793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(state->extra); 576793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 577793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->offset > state->wsize - (state->whave < state->wsize ? 578793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler left : 0)) { 579793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid distance too far back"; 580793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 581793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 582793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 583793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracevv((stderr, "inflate: distance %u\n", state->offset)); 584793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 585793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* copy match from window to output */ 586793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { 587793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ROOM(); 588793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy = state->wsize - state->offset; 589793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (copy < left) { 590793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler from = put + copy; 591793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy = left - copy; 592793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 593793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else { 594793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler from = put - state->offset; 595793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy = left; 596793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 597793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (copy > state->length) copy = state->length; 598793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->length -= copy; 599793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler left -= copy; 600793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { 601793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *put++ = *from++; 602793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (--copy); 603793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (state->length != 0); 604793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 605793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 606793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case DONE: 607793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* inflate stream terminated properly -- write leftover output */ 608793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = Z_STREAM_END; 609793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (left < state->wsize) { 610793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (out(out_desc, state->window, state->wsize - left)) 611793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = Z_BUF_ERROR; 612793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 613793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler goto inf_leave; 614793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 615793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case BAD: 616793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = Z_DATA_ERROR; 617793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler goto inf_leave; 618793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 619793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: /* can't happen, but makes compilers happy */ 620793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = Z_STREAM_ERROR; 621793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler goto inf_leave; 622793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 623793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 624793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* Return unused input */ 625793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler inf_leave: 626793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->next_in = next; 627793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->avail_in = have; 628793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return ret; 629793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 630793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 631793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint ZEXPORT inflateBackEnd(strm) 632793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerz_streamp strm; 633793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 634793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) 635793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_STREAM_ERROR; 636793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ZFREE(strm, strm->state); 637793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->state = Z_NULL; 638793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: end\n")); 639793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_OK; 640793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 641