1*4a5d661aSToomas Soome /* infback.c -- inflate using a call-back interface 2*4a5d661aSToomas Soome * Copyright (C) 1995-2011 Mark Adler 3*4a5d661aSToomas Soome * For conditions of distribution and use, see copyright notice in zlib.h 4*4a5d661aSToomas Soome */ 5*4a5d661aSToomas Soome 6*4a5d661aSToomas Soome /* 7*4a5d661aSToomas Soome This code is largely copied from inflate.c. Normally either infback.o or 8*4a5d661aSToomas Soome inflate.o would be linked into an application--not both. The interface 9*4a5d661aSToomas Soome with inffast.c is retained so that optimized assembler-coded versions of 10*4a5d661aSToomas Soome inflate_fast() can be used with either inflate.c or infback.c. 11*4a5d661aSToomas Soome */ 12*4a5d661aSToomas Soome 13*4a5d661aSToomas Soome #include "zutil.h" 14*4a5d661aSToomas Soome #include "inftrees.h" 15*4a5d661aSToomas Soome #include "inflate.h" 16*4a5d661aSToomas Soome #include "inffast.h" 17*4a5d661aSToomas Soome 18*4a5d661aSToomas Soome /* function prototypes */ 19*4a5d661aSToomas Soome local void fixedtables OF((struct inflate_state FAR *state)); 20*4a5d661aSToomas Soome 21*4a5d661aSToomas Soome /* 22*4a5d661aSToomas Soome strm provides memory allocation functions in zalloc and zfree, or 23*4a5d661aSToomas Soome Z_NULL to use the library memory allocation functions. 24*4a5d661aSToomas Soome 25*4a5d661aSToomas Soome windowBits is in the range 8..15, and window is a user-supplied 26*4a5d661aSToomas Soome window and output buffer that is 2**windowBits bytes. 27*4a5d661aSToomas Soome */ 28*4a5d661aSToomas Soome int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) 29*4a5d661aSToomas Soome z_streamp strm; 30*4a5d661aSToomas Soome int windowBits; 31*4a5d661aSToomas Soome unsigned char FAR *window; 32*4a5d661aSToomas Soome const char *version; 33*4a5d661aSToomas Soome int stream_size; 34*4a5d661aSToomas Soome { 35*4a5d661aSToomas Soome struct inflate_state FAR *state; 36*4a5d661aSToomas Soome 37*4a5d661aSToomas Soome if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || 38*4a5d661aSToomas Soome stream_size != (int)(sizeof(z_stream))) 39*4a5d661aSToomas Soome return Z_VERSION_ERROR; 40*4a5d661aSToomas Soome if (strm == Z_NULL || window == Z_NULL || 41*4a5d661aSToomas Soome windowBits < 8 || windowBits > 15) 42*4a5d661aSToomas Soome return Z_STREAM_ERROR; 43*4a5d661aSToomas Soome strm->msg = Z_NULL; /* in case we return an error */ 44*4a5d661aSToomas Soome if (strm->zalloc == (alloc_func)0) { 45*4a5d661aSToomas Soome #ifdef Z_SOLO 46*4a5d661aSToomas Soome return Z_STREAM_ERROR; 47*4a5d661aSToomas Soome #else 48*4a5d661aSToomas Soome strm->zalloc = zcalloc; 49*4a5d661aSToomas Soome strm->opaque = (voidpf)0; 50*4a5d661aSToomas Soome #endif 51*4a5d661aSToomas Soome } 52*4a5d661aSToomas Soome if (strm->zfree == (free_func)0) 53*4a5d661aSToomas Soome #ifdef Z_SOLO 54*4a5d661aSToomas Soome return Z_STREAM_ERROR; 55*4a5d661aSToomas Soome #else 56*4a5d661aSToomas Soome strm->zfree = zcfree; 57*4a5d661aSToomas Soome #endif 58*4a5d661aSToomas Soome state = (struct inflate_state FAR *)ZALLOC(strm, 1, 59*4a5d661aSToomas Soome sizeof(struct inflate_state)); 60*4a5d661aSToomas Soome if (state == Z_NULL) return Z_MEM_ERROR; 61*4a5d661aSToomas Soome Tracev((stderr, "inflate: allocated\n")); 62*4a5d661aSToomas Soome strm->state = (struct internal_state FAR *)state; 63*4a5d661aSToomas Soome state->dmax = 32768U; 64*4a5d661aSToomas Soome state->wbits = windowBits; 65*4a5d661aSToomas Soome state->wsize = 1U << windowBits; 66*4a5d661aSToomas Soome state->window = window; 67*4a5d661aSToomas Soome state->wnext = 0; 68*4a5d661aSToomas Soome state->whave = 0; 69*4a5d661aSToomas Soome return Z_OK; 70*4a5d661aSToomas Soome } 71*4a5d661aSToomas Soome 72*4a5d661aSToomas Soome /* 73*4a5d661aSToomas Soome Return state with length and distance decoding tables and index sizes set to 74*4a5d661aSToomas Soome fixed code decoding. Normally this returns fixed tables from inffixed.h. 75*4a5d661aSToomas Soome If BUILDFIXED is defined, then instead this routine builds the tables the 76*4a5d661aSToomas Soome first time it's called, and returns those tables the first time and 77*4a5d661aSToomas Soome thereafter. This reduces the size of the code by about 2K bytes, in 78*4a5d661aSToomas Soome exchange for a little execution time. However, BUILDFIXED should not be 79*4a5d661aSToomas Soome used for threaded applications, since the rewriting of the tables and virgin 80*4a5d661aSToomas Soome may not be thread-safe. 81*4a5d661aSToomas Soome */ 82*4a5d661aSToomas Soome local void fixedtables(state) 83*4a5d661aSToomas Soome struct inflate_state FAR *state; 84*4a5d661aSToomas Soome { 85*4a5d661aSToomas Soome #ifdef BUILDFIXED 86*4a5d661aSToomas Soome static int virgin = 1; 87*4a5d661aSToomas Soome static code *lenfix, *distfix; 88*4a5d661aSToomas Soome static code fixed[544]; 89*4a5d661aSToomas Soome 90*4a5d661aSToomas Soome /* build fixed huffman tables if first call (may not be thread safe) */ 91*4a5d661aSToomas Soome if (virgin) { 92*4a5d661aSToomas Soome unsigned sym, bits; 93*4a5d661aSToomas Soome static code *next; 94*4a5d661aSToomas Soome 95*4a5d661aSToomas Soome /* literal/length table */ 96*4a5d661aSToomas Soome sym = 0; 97*4a5d661aSToomas Soome while (sym < 144) state->lens[sym++] = 8; 98*4a5d661aSToomas Soome while (sym < 256) state->lens[sym++] = 9; 99*4a5d661aSToomas Soome while (sym < 280) state->lens[sym++] = 7; 100*4a5d661aSToomas Soome while (sym < 288) state->lens[sym++] = 8; 101*4a5d661aSToomas Soome next = fixed; 102*4a5d661aSToomas Soome lenfix = next; 103*4a5d661aSToomas Soome bits = 9; 104*4a5d661aSToomas Soome inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); 105*4a5d661aSToomas Soome 106*4a5d661aSToomas Soome /* distance table */ 107*4a5d661aSToomas Soome sym = 0; 108*4a5d661aSToomas Soome while (sym < 32) state->lens[sym++] = 5; 109*4a5d661aSToomas Soome distfix = next; 110*4a5d661aSToomas Soome bits = 5; 111*4a5d661aSToomas Soome inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); 112*4a5d661aSToomas Soome 113*4a5d661aSToomas Soome /* do this just once */ 114*4a5d661aSToomas Soome virgin = 0; 115*4a5d661aSToomas Soome } 116*4a5d661aSToomas Soome #else /* !BUILDFIXED */ 117*4a5d661aSToomas Soome # include "inffixed.h" 118*4a5d661aSToomas Soome #endif /* BUILDFIXED */ 119*4a5d661aSToomas Soome state->lencode = lenfix; 120*4a5d661aSToomas Soome state->lenbits = 9; 121*4a5d661aSToomas Soome state->distcode = distfix; 122*4a5d661aSToomas Soome state->distbits = 5; 123*4a5d661aSToomas Soome } 124*4a5d661aSToomas Soome 125*4a5d661aSToomas Soome /* Macros for inflateBack(): */ 126*4a5d661aSToomas Soome 127*4a5d661aSToomas Soome /* Load returned state from inflate_fast() */ 128*4a5d661aSToomas Soome #define LOAD() \ 129*4a5d661aSToomas Soome do { \ 130*4a5d661aSToomas Soome put = strm->next_out; \ 131*4a5d661aSToomas Soome left = strm->avail_out; \ 132*4a5d661aSToomas Soome next = strm->next_in; \ 133*4a5d661aSToomas Soome have = strm->avail_in; \ 134*4a5d661aSToomas Soome hold = state->hold; \ 135*4a5d661aSToomas Soome bits = state->bits; \ 136*4a5d661aSToomas Soome } while (0) 137*4a5d661aSToomas Soome 138*4a5d661aSToomas Soome /* Set state from registers for inflate_fast() */ 139*4a5d661aSToomas Soome #define RESTORE() \ 140*4a5d661aSToomas Soome do { \ 141*4a5d661aSToomas Soome strm->next_out = put; \ 142*4a5d661aSToomas Soome strm->avail_out = left; \ 143*4a5d661aSToomas Soome strm->next_in = next; \ 144*4a5d661aSToomas Soome strm->avail_in = have; \ 145*4a5d661aSToomas Soome state->hold = hold; \ 146*4a5d661aSToomas Soome state->bits = bits; \ 147*4a5d661aSToomas Soome } while (0) 148*4a5d661aSToomas Soome 149*4a5d661aSToomas Soome /* Clear the input bit accumulator */ 150*4a5d661aSToomas Soome #define INITBITS() \ 151*4a5d661aSToomas Soome do { \ 152*4a5d661aSToomas Soome hold = 0; \ 153*4a5d661aSToomas Soome bits = 0; \ 154*4a5d661aSToomas Soome } while (0) 155*4a5d661aSToomas Soome 156*4a5d661aSToomas Soome /* Assure that some input is available. If input is requested, but denied, 157*4a5d661aSToomas Soome then return a Z_BUF_ERROR from inflateBack(). */ 158*4a5d661aSToomas Soome #define PULL() \ 159*4a5d661aSToomas Soome do { \ 160*4a5d661aSToomas Soome if (have == 0) { \ 161*4a5d661aSToomas Soome have = in(in_desc, &next); \ 162*4a5d661aSToomas Soome if (have == 0) { \ 163*4a5d661aSToomas Soome next = Z_NULL; \ 164*4a5d661aSToomas Soome ret = Z_BUF_ERROR; \ 165*4a5d661aSToomas Soome goto inf_leave; \ 166*4a5d661aSToomas Soome } \ 167*4a5d661aSToomas Soome } \ 168*4a5d661aSToomas Soome } while (0) 169*4a5d661aSToomas Soome 170*4a5d661aSToomas Soome /* Get a byte of input into the bit accumulator, or return from inflateBack() 171*4a5d661aSToomas Soome with an error if there is no input available. */ 172*4a5d661aSToomas Soome #define PULLBYTE() \ 173*4a5d661aSToomas Soome do { \ 174*4a5d661aSToomas Soome PULL(); \ 175*4a5d661aSToomas Soome have--; \ 176*4a5d661aSToomas Soome hold += (unsigned long)(*next++) << bits; \ 177*4a5d661aSToomas Soome bits += 8; \ 178*4a5d661aSToomas Soome } while (0) 179*4a5d661aSToomas Soome 180*4a5d661aSToomas Soome /* Assure that there are at least n bits in the bit accumulator. If there is 181*4a5d661aSToomas Soome not enough available input to do that, then return from inflateBack() with 182*4a5d661aSToomas Soome an error. */ 183*4a5d661aSToomas Soome #define NEEDBITS(n) \ 184*4a5d661aSToomas Soome do { \ 185*4a5d661aSToomas Soome while (bits < (unsigned)(n)) \ 186*4a5d661aSToomas Soome PULLBYTE(); \ 187*4a5d661aSToomas Soome } while (0) 188*4a5d661aSToomas Soome 189*4a5d661aSToomas Soome /* Return the low n bits of the bit accumulator (n < 16) */ 190*4a5d661aSToomas Soome #define BITS(n) \ 191*4a5d661aSToomas Soome ((unsigned)hold & ((1U << (n)) - 1)) 192*4a5d661aSToomas Soome 193*4a5d661aSToomas Soome /* Remove n bits from the bit accumulator */ 194*4a5d661aSToomas Soome #define DROPBITS(n) \ 195*4a5d661aSToomas Soome do { \ 196*4a5d661aSToomas Soome hold >>= (n); \ 197*4a5d661aSToomas Soome bits -= (unsigned)(n); \ 198*4a5d661aSToomas Soome } while (0) 199*4a5d661aSToomas Soome 200*4a5d661aSToomas Soome /* Remove zero to seven bits as needed to go to a byte boundary */ 201*4a5d661aSToomas Soome #define BYTEBITS() \ 202*4a5d661aSToomas Soome do { \ 203*4a5d661aSToomas Soome hold >>= bits & 7; \ 204*4a5d661aSToomas Soome bits -= bits & 7; \ 205*4a5d661aSToomas Soome } while (0) 206*4a5d661aSToomas Soome 207*4a5d661aSToomas Soome /* Assure that some output space is available, by writing out the window 208*4a5d661aSToomas Soome if it's full. If the write fails, return from inflateBack() with a 209*4a5d661aSToomas Soome Z_BUF_ERROR. */ 210*4a5d661aSToomas Soome #define ROOM() \ 211*4a5d661aSToomas Soome do { \ 212*4a5d661aSToomas Soome if (left == 0) { \ 213*4a5d661aSToomas Soome put = state->window; \ 214*4a5d661aSToomas Soome left = state->wsize; \ 215*4a5d661aSToomas Soome state->whave = left; \ 216*4a5d661aSToomas Soome if (out(out_desc, put, left)) { \ 217*4a5d661aSToomas Soome ret = Z_BUF_ERROR; \ 218*4a5d661aSToomas Soome goto inf_leave; \ 219*4a5d661aSToomas Soome } \ 220*4a5d661aSToomas Soome } \ 221*4a5d661aSToomas Soome } while (0) 222*4a5d661aSToomas Soome 223*4a5d661aSToomas Soome /* 224*4a5d661aSToomas Soome strm provides the memory allocation functions and window buffer on input, 225*4a5d661aSToomas Soome and provides information on the unused input on return. For Z_DATA_ERROR 226*4a5d661aSToomas Soome returns, strm will also provide an error message. 227*4a5d661aSToomas Soome 228*4a5d661aSToomas Soome in() and out() are the call-back input and output functions. When 229*4a5d661aSToomas Soome inflateBack() needs more input, it calls in(). When inflateBack() has 230*4a5d661aSToomas Soome filled the window with output, or when it completes with data in the 231*4a5d661aSToomas Soome window, it calls out() to write out the data. The application must not 232*4a5d661aSToomas Soome change the provided input until in() is called again or inflateBack() 233*4a5d661aSToomas Soome returns. The application must not change the window/output buffer until 234*4a5d661aSToomas Soome inflateBack() returns. 235*4a5d661aSToomas Soome 236*4a5d661aSToomas Soome in() and out() are called with a descriptor parameter provided in the 237*4a5d661aSToomas Soome inflateBack() call. This parameter can be a structure that provides the 238*4a5d661aSToomas Soome information required to do the read or write, as well as accumulated 239*4a5d661aSToomas Soome information on the input and output such as totals and check values. 240*4a5d661aSToomas Soome 241*4a5d661aSToomas Soome in() should return zero on failure. out() should return non-zero on 242*4a5d661aSToomas Soome failure. If either in() or out() fails, than inflateBack() returns a 243*4a5d661aSToomas Soome Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it 244*4a5d661aSToomas Soome was in() or out() that caused in the error. Otherwise, inflateBack() 245*4a5d661aSToomas Soome returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format 246*4a5d661aSToomas Soome error, or Z_MEM_ERROR if it could not allocate memory for the state. 247*4a5d661aSToomas Soome inflateBack() can also return Z_STREAM_ERROR if the input parameters 248*4a5d661aSToomas Soome are not correct, i.e. strm is Z_NULL or the state was not initialized. 249*4a5d661aSToomas Soome */ 250*4a5d661aSToomas Soome int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) 251*4a5d661aSToomas Soome z_streamp strm; 252*4a5d661aSToomas Soome in_func in; 253*4a5d661aSToomas Soome void FAR *in_desc; 254*4a5d661aSToomas Soome out_func out; 255*4a5d661aSToomas Soome void FAR *out_desc; 256*4a5d661aSToomas Soome { 257*4a5d661aSToomas Soome struct inflate_state FAR *state; 258*4a5d661aSToomas Soome z_const unsigned char FAR *next; /* next input */ 259*4a5d661aSToomas Soome unsigned char FAR *put; /* next output */ 260*4a5d661aSToomas Soome unsigned have, left; /* available input and output */ 261*4a5d661aSToomas Soome unsigned long hold; /* bit buffer */ 262*4a5d661aSToomas Soome unsigned bits; /* bits in bit buffer */ 263*4a5d661aSToomas Soome unsigned copy; /* number of stored or match bytes to copy */ 264*4a5d661aSToomas Soome unsigned char FAR *from; /* where to copy match bytes from */ 265*4a5d661aSToomas Soome code here; /* current decoding table entry */ 266*4a5d661aSToomas Soome code last; /* parent table entry */ 267*4a5d661aSToomas Soome unsigned len; /* length to copy for repeats, bits to drop */ 268*4a5d661aSToomas Soome int ret; /* return code */ 269*4a5d661aSToomas Soome static const unsigned short order[19] = /* permutation of code lengths */ 270*4a5d661aSToomas Soome {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; 271*4a5d661aSToomas Soome 272*4a5d661aSToomas Soome /* Check that the strm exists and that the state was initialized */ 273*4a5d661aSToomas Soome if (strm == Z_NULL || strm->state == Z_NULL) 274*4a5d661aSToomas Soome return Z_STREAM_ERROR; 275*4a5d661aSToomas Soome state = (struct inflate_state FAR *)strm->state; 276*4a5d661aSToomas Soome 277*4a5d661aSToomas Soome /* Reset the state */ 278*4a5d661aSToomas Soome strm->msg = Z_NULL; 279*4a5d661aSToomas Soome state->mode = TYPE; 280*4a5d661aSToomas Soome state->last = 0; 281*4a5d661aSToomas Soome state->whave = 0; 282*4a5d661aSToomas Soome next = strm->next_in; 283*4a5d661aSToomas Soome have = next != Z_NULL ? strm->avail_in : 0; 284*4a5d661aSToomas Soome hold = 0; 285*4a5d661aSToomas Soome bits = 0; 286*4a5d661aSToomas Soome put = state->window; 287*4a5d661aSToomas Soome left = state->wsize; 288*4a5d661aSToomas Soome 289*4a5d661aSToomas Soome /* Inflate until end of block marked as last */ 290*4a5d661aSToomas Soome for (;;) 291*4a5d661aSToomas Soome switch (state->mode) { 292*4a5d661aSToomas Soome case TYPE: 293*4a5d661aSToomas Soome /* determine and dispatch block type */ 294*4a5d661aSToomas Soome if (state->last) { 295*4a5d661aSToomas Soome BYTEBITS(); 296*4a5d661aSToomas Soome state->mode = DONE; 297*4a5d661aSToomas Soome break; 298*4a5d661aSToomas Soome } 299*4a5d661aSToomas Soome NEEDBITS(3); 300*4a5d661aSToomas Soome state->last = BITS(1); 301*4a5d661aSToomas Soome DROPBITS(1); 302*4a5d661aSToomas Soome switch (BITS(2)) { 303*4a5d661aSToomas Soome case 0: /* stored block */ 304*4a5d661aSToomas Soome Tracev((stderr, "inflate: stored block%s\n", 305*4a5d661aSToomas Soome state->last ? " (last)" : "")); 306*4a5d661aSToomas Soome state->mode = STORED; 307*4a5d661aSToomas Soome break; 308*4a5d661aSToomas Soome case 1: /* fixed block */ 309*4a5d661aSToomas Soome fixedtables(state); 310*4a5d661aSToomas Soome Tracev((stderr, "inflate: fixed codes block%s\n", 311*4a5d661aSToomas Soome state->last ? " (last)" : "")); 312*4a5d661aSToomas Soome state->mode = LEN; /* decode codes */ 313*4a5d661aSToomas Soome break; 314*4a5d661aSToomas Soome case 2: /* dynamic block */ 315*4a5d661aSToomas Soome Tracev((stderr, "inflate: dynamic codes block%s\n", 316*4a5d661aSToomas Soome state->last ? " (last)" : "")); 317*4a5d661aSToomas Soome state->mode = TABLE; 318*4a5d661aSToomas Soome break; 319*4a5d661aSToomas Soome case 3: 320*4a5d661aSToomas Soome strm->msg = (char *)"invalid block type"; 321*4a5d661aSToomas Soome state->mode = BAD; 322*4a5d661aSToomas Soome } 323*4a5d661aSToomas Soome DROPBITS(2); 324*4a5d661aSToomas Soome break; 325*4a5d661aSToomas Soome 326*4a5d661aSToomas Soome case STORED: 327*4a5d661aSToomas Soome /* get and verify stored block length */ 328*4a5d661aSToomas Soome BYTEBITS(); /* go to byte boundary */ 329*4a5d661aSToomas Soome NEEDBITS(32); 330*4a5d661aSToomas Soome if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { 331*4a5d661aSToomas Soome strm->msg = (char *)"invalid stored block lengths"; 332*4a5d661aSToomas Soome state->mode = BAD; 333*4a5d661aSToomas Soome break; 334*4a5d661aSToomas Soome } 335*4a5d661aSToomas Soome state->length = (unsigned)hold & 0xffff; 336*4a5d661aSToomas Soome Tracev((stderr, "inflate: stored length %u\n", 337*4a5d661aSToomas Soome state->length)); 338*4a5d661aSToomas Soome INITBITS(); 339*4a5d661aSToomas Soome 340*4a5d661aSToomas Soome /* copy stored block from input to output */ 341*4a5d661aSToomas Soome while (state->length != 0) { 342*4a5d661aSToomas Soome copy = state->length; 343*4a5d661aSToomas Soome PULL(); 344*4a5d661aSToomas Soome ROOM(); 345*4a5d661aSToomas Soome if (copy > have) copy = have; 346*4a5d661aSToomas Soome if (copy > left) copy = left; 347*4a5d661aSToomas Soome zmemcpy(put, next, copy); 348*4a5d661aSToomas Soome have -= copy; 349*4a5d661aSToomas Soome next += copy; 350*4a5d661aSToomas Soome left -= copy; 351*4a5d661aSToomas Soome put += copy; 352*4a5d661aSToomas Soome state->length -= copy; 353*4a5d661aSToomas Soome } 354*4a5d661aSToomas Soome Tracev((stderr, "inflate: stored end\n")); 355*4a5d661aSToomas Soome state->mode = TYPE; 356*4a5d661aSToomas Soome break; 357*4a5d661aSToomas Soome 358*4a5d661aSToomas Soome case TABLE: 359*4a5d661aSToomas Soome /* get dynamic table entries descriptor */ 360*4a5d661aSToomas Soome NEEDBITS(14); 361*4a5d661aSToomas Soome state->nlen = BITS(5) + 257; 362*4a5d661aSToomas Soome DROPBITS(5); 363*4a5d661aSToomas Soome state->ndist = BITS(5) + 1; 364*4a5d661aSToomas Soome DROPBITS(5); 365*4a5d661aSToomas Soome state->ncode = BITS(4) + 4; 366*4a5d661aSToomas Soome DROPBITS(4); 367*4a5d661aSToomas Soome #ifndef PKZIP_BUG_WORKAROUND 368*4a5d661aSToomas Soome if (state->nlen > 286 || state->ndist > 30) { 369*4a5d661aSToomas Soome strm->msg = (char *)"too many length or distance symbols"; 370*4a5d661aSToomas Soome state->mode = BAD; 371*4a5d661aSToomas Soome break; 372*4a5d661aSToomas Soome } 373*4a5d661aSToomas Soome #endif 374*4a5d661aSToomas Soome Tracev((stderr, "inflate: table sizes ok\n")); 375*4a5d661aSToomas Soome 376*4a5d661aSToomas Soome /* get code length code lengths (not a typo) */ 377*4a5d661aSToomas Soome state->have = 0; 378*4a5d661aSToomas Soome while (state->have < state->ncode) { 379*4a5d661aSToomas Soome NEEDBITS(3); 380*4a5d661aSToomas Soome state->lens[order[state->have++]] = (unsigned short)BITS(3); 381*4a5d661aSToomas Soome DROPBITS(3); 382*4a5d661aSToomas Soome } 383*4a5d661aSToomas Soome while (state->have < 19) 384*4a5d661aSToomas Soome state->lens[order[state->have++]] = 0; 385*4a5d661aSToomas Soome state->next = state->codes; 386*4a5d661aSToomas Soome state->lencode = (code const FAR *)(state->next); 387*4a5d661aSToomas Soome state->lenbits = 7; 388*4a5d661aSToomas Soome ret = inflate_table(CODES, state->lens, 19, &(state->next), 389*4a5d661aSToomas Soome &(state->lenbits), state->work); 390*4a5d661aSToomas Soome if (ret) { 391*4a5d661aSToomas Soome strm->msg = (char *)"invalid code lengths set"; 392*4a5d661aSToomas Soome state->mode = BAD; 393*4a5d661aSToomas Soome break; 394*4a5d661aSToomas Soome } 395*4a5d661aSToomas Soome Tracev((stderr, "inflate: code lengths ok\n")); 396*4a5d661aSToomas Soome 397*4a5d661aSToomas Soome /* get length and distance code code lengths */ 398*4a5d661aSToomas Soome state->have = 0; 399*4a5d661aSToomas Soome while (state->have < state->nlen + state->ndist) { 400*4a5d661aSToomas Soome for (;;) { 401*4a5d661aSToomas Soome here = state->lencode[BITS(state->lenbits)]; 402*4a5d661aSToomas Soome if ((unsigned)(here.bits) <= bits) break; 403*4a5d661aSToomas Soome PULLBYTE(); 404*4a5d661aSToomas Soome } 405*4a5d661aSToomas Soome if (here.val < 16) { 406*4a5d661aSToomas Soome DROPBITS(here.bits); 407*4a5d661aSToomas Soome state->lens[state->have++] = here.val; 408*4a5d661aSToomas Soome } 409*4a5d661aSToomas Soome else { 410*4a5d661aSToomas Soome if (here.val == 16) { 411*4a5d661aSToomas Soome NEEDBITS(here.bits + 2); 412*4a5d661aSToomas Soome DROPBITS(here.bits); 413*4a5d661aSToomas Soome if (state->have == 0) { 414*4a5d661aSToomas Soome strm->msg = (char *)"invalid bit length repeat"; 415*4a5d661aSToomas Soome state->mode = BAD; 416*4a5d661aSToomas Soome break; 417*4a5d661aSToomas Soome } 418*4a5d661aSToomas Soome len = (unsigned)(state->lens[state->have - 1]); 419*4a5d661aSToomas Soome copy = 3 + BITS(2); 420*4a5d661aSToomas Soome DROPBITS(2); 421*4a5d661aSToomas Soome } 422*4a5d661aSToomas Soome else if (here.val == 17) { 423*4a5d661aSToomas Soome NEEDBITS(here.bits + 3); 424*4a5d661aSToomas Soome DROPBITS(here.bits); 425*4a5d661aSToomas Soome len = 0; 426*4a5d661aSToomas Soome copy = 3 + BITS(3); 427*4a5d661aSToomas Soome DROPBITS(3); 428*4a5d661aSToomas Soome } 429*4a5d661aSToomas Soome else { 430*4a5d661aSToomas Soome NEEDBITS(here.bits + 7); 431*4a5d661aSToomas Soome DROPBITS(here.bits); 432*4a5d661aSToomas Soome len = 0; 433*4a5d661aSToomas Soome copy = 11 + BITS(7); 434*4a5d661aSToomas Soome DROPBITS(7); 435*4a5d661aSToomas Soome } 436*4a5d661aSToomas Soome if (state->have + copy > state->nlen + state->ndist) { 437*4a5d661aSToomas Soome strm->msg = (char *)"invalid bit length repeat"; 438*4a5d661aSToomas Soome state->mode = BAD; 439*4a5d661aSToomas Soome break; 440*4a5d661aSToomas Soome } 441*4a5d661aSToomas Soome while (copy--) 442*4a5d661aSToomas Soome state->lens[state->have++] = (unsigned short)len; 443*4a5d661aSToomas Soome } 444*4a5d661aSToomas Soome } 445*4a5d661aSToomas Soome 446*4a5d661aSToomas Soome /* handle error breaks in while */ 447*4a5d661aSToomas Soome if (state->mode == BAD) break; 448*4a5d661aSToomas Soome 449*4a5d661aSToomas Soome /* check for end-of-block code (better have one) */ 450*4a5d661aSToomas Soome if (state->lens[256] == 0) { 451*4a5d661aSToomas Soome strm->msg = (char *)"invalid code -- missing end-of-block"; 452*4a5d661aSToomas Soome state->mode = BAD; 453*4a5d661aSToomas Soome break; 454*4a5d661aSToomas Soome } 455*4a5d661aSToomas Soome 456*4a5d661aSToomas Soome /* build code tables -- note: do not change the lenbits or distbits 457*4a5d661aSToomas Soome values here (9 and 6) without reading the comments in inftrees.h 458*4a5d661aSToomas Soome concerning the ENOUGH constants, which depend on those values */ 459*4a5d661aSToomas Soome state->next = state->codes; 460*4a5d661aSToomas Soome state->lencode = (code const FAR *)(state->next); 461*4a5d661aSToomas Soome state->lenbits = 9; 462*4a5d661aSToomas Soome ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), 463*4a5d661aSToomas Soome &(state->lenbits), state->work); 464*4a5d661aSToomas Soome if (ret) { 465*4a5d661aSToomas Soome strm->msg = (char *)"invalid literal/lengths set"; 466*4a5d661aSToomas Soome state->mode = BAD; 467*4a5d661aSToomas Soome break; 468*4a5d661aSToomas Soome } 469*4a5d661aSToomas Soome state->distcode = (code const FAR *)(state->next); 470*4a5d661aSToomas Soome state->distbits = 6; 471*4a5d661aSToomas Soome ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, 472*4a5d661aSToomas Soome &(state->next), &(state->distbits), state->work); 473*4a5d661aSToomas Soome if (ret) { 474*4a5d661aSToomas Soome strm->msg = (char *)"invalid distances set"; 475*4a5d661aSToomas Soome state->mode = BAD; 476*4a5d661aSToomas Soome break; 477*4a5d661aSToomas Soome } 478*4a5d661aSToomas Soome Tracev((stderr, "inflate: codes ok\n")); 479*4a5d661aSToomas Soome state->mode = LEN; 480*4a5d661aSToomas Soome 481*4a5d661aSToomas Soome case LEN: 482*4a5d661aSToomas Soome /* use inflate_fast() if we have enough input and output */ 483*4a5d661aSToomas Soome if (have >= 6 && left >= 258) { 484*4a5d661aSToomas Soome RESTORE(); 485*4a5d661aSToomas Soome if (state->whave < state->wsize) 486*4a5d661aSToomas Soome state->whave = state->wsize - left; 487*4a5d661aSToomas Soome inflate_fast(strm, state->wsize); 488*4a5d661aSToomas Soome LOAD(); 489*4a5d661aSToomas Soome break; 490*4a5d661aSToomas Soome } 491*4a5d661aSToomas Soome 492*4a5d661aSToomas Soome /* get a literal, length, or end-of-block code */ 493*4a5d661aSToomas Soome for (;;) { 494*4a5d661aSToomas Soome here = state->lencode[BITS(state->lenbits)]; 495*4a5d661aSToomas Soome if ((unsigned)(here.bits) <= bits) break; 496*4a5d661aSToomas Soome PULLBYTE(); 497*4a5d661aSToomas Soome } 498*4a5d661aSToomas Soome if (here.op && (here.op & 0xf0) == 0) { 499*4a5d661aSToomas Soome last = here; 500*4a5d661aSToomas Soome for (;;) { 501*4a5d661aSToomas Soome here = state->lencode[last.val + 502*4a5d661aSToomas Soome (BITS(last.bits + last.op) >> last.bits)]; 503*4a5d661aSToomas Soome if ((unsigned)(last.bits + here.bits) <= bits) break; 504*4a5d661aSToomas Soome PULLBYTE(); 505*4a5d661aSToomas Soome } 506*4a5d661aSToomas Soome DROPBITS(last.bits); 507*4a5d661aSToomas Soome } 508*4a5d661aSToomas Soome DROPBITS(here.bits); 509*4a5d661aSToomas Soome state->length = (unsigned)here.val; 510*4a5d661aSToomas Soome 511*4a5d661aSToomas Soome /* process literal */ 512*4a5d661aSToomas Soome if (here.op == 0) { 513*4a5d661aSToomas Soome Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? 514*4a5d661aSToomas Soome "inflate: literal '%c'\n" : 515*4a5d661aSToomas Soome "inflate: literal 0x%02x\n", here.val)); 516*4a5d661aSToomas Soome ROOM(); 517*4a5d661aSToomas Soome *put++ = (unsigned char)(state->length); 518*4a5d661aSToomas Soome left--; 519*4a5d661aSToomas Soome state->mode = LEN; 520*4a5d661aSToomas Soome break; 521*4a5d661aSToomas Soome } 522*4a5d661aSToomas Soome 523*4a5d661aSToomas Soome /* process end of block */ 524*4a5d661aSToomas Soome if (here.op & 32) { 525*4a5d661aSToomas Soome Tracevv((stderr, "inflate: end of block\n")); 526*4a5d661aSToomas Soome state->mode = TYPE; 527*4a5d661aSToomas Soome break; 528*4a5d661aSToomas Soome } 529*4a5d661aSToomas Soome 530*4a5d661aSToomas Soome /* invalid code */ 531*4a5d661aSToomas Soome if (here.op & 64) { 532*4a5d661aSToomas Soome strm->msg = (char *)"invalid literal/length code"; 533*4a5d661aSToomas Soome state->mode = BAD; 534*4a5d661aSToomas Soome break; 535*4a5d661aSToomas Soome } 536*4a5d661aSToomas Soome 537*4a5d661aSToomas Soome /* length code -- get extra bits, if any */ 538*4a5d661aSToomas Soome state->extra = (unsigned)(here.op) & 15; 539*4a5d661aSToomas Soome if (state->extra != 0) { 540*4a5d661aSToomas Soome NEEDBITS(state->extra); 541*4a5d661aSToomas Soome state->length += BITS(state->extra); 542*4a5d661aSToomas Soome DROPBITS(state->extra); 543*4a5d661aSToomas Soome } 544*4a5d661aSToomas Soome Tracevv((stderr, "inflate: length %u\n", state->length)); 545*4a5d661aSToomas Soome 546*4a5d661aSToomas Soome /* get distance code */ 547*4a5d661aSToomas Soome for (;;) { 548*4a5d661aSToomas Soome here = state->distcode[BITS(state->distbits)]; 549*4a5d661aSToomas Soome if ((unsigned)(here.bits) <= bits) break; 550*4a5d661aSToomas Soome PULLBYTE(); 551*4a5d661aSToomas Soome } 552*4a5d661aSToomas Soome if ((here.op & 0xf0) == 0) { 553*4a5d661aSToomas Soome last = here; 554*4a5d661aSToomas Soome for (;;) { 555*4a5d661aSToomas Soome here = state->distcode[last.val + 556*4a5d661aSToomas Soome (BITS(last.bits + last.op) >> last.bits)]; 557*4a5d661aSToomas Soome if ((unsigned)(last.bits + here.bits) <= bits) break; 558*4a5d661aSToomas Soome PULLBYTE(); 559*4a5d661aSToomas Soome } 560*4a5d661aSToomas Soome DROPBITS(last.bits); 561*4a5d661aSToomas Soome } 562*4a5d661aSToomas Soome DROPBITS(here.bits); 563*4a5d661aSToomas Soome if (here.op & 64) { 564*4a5d661aSToomas Soome strm->msg = (char *)"invalid distance code"; 565*4a5d661aSToomas Soome state->mode = BAD; 566*4a5d661aSToomas Soome break; 567*4a5d661aSToomas Soome } 568*4a5d661aSToomas Soome state->offset = (unsigned)here.val; 569*4a5d661aSToomas Soome 570*4a5d661aSToomas Soome /* get distance extra bits, if any */ 571*4a5d661aSToomas Soome state->extra = (unsigned)(here.op) & 15; 572*4a5d661aSToomas Soome if (state->extra != 0) { 573*4a5d661aSToomas Soome NEEDBITS(state->extra); 574*4a5d661aSToomas Soome state->offset += BITS(state->extra); 575*4a5d661aSToomas Soome DROPBITS(state->extra); 576*4a5d661aSToomas Soome } 577*4a5d661aSToomas Soome if (state->offset > state->wsize - (state->whave < state->wsize ? 578*4a5d661aSToomas Soome left : 0)) { 579*4a5d661aSToomas Soome strm->msg = (char *)"invalid distance too far back"; 580*4a5d661aSToomas Soome state->mode = BAD; 581*4a5d661aSToomas Soome break; 582*4a5d661aSToomas Soome } 583*4a5d661aSToomas Soome Tracevv((stderr, "inflate: distance %u\n", state->offset)); 584*4a5d661aSToomas Soome 585*4a5d661aSToomas Soome /* copy match from window to output */ 586*4a5d661aSToomas Soome do { 587*4a5d661aSToomas Soome ROOM(); 588*4a5d661aSToomas Soome copy = state->wsize - state->offset; 589*4a5d661aSToomas Soome if (copy < left) { 590*4a5d661aSToomas Soome from = put + copy; 591*4a5d661aSToomas Soome copy = left - copy; 592*4a5d661aSToomas Soome } 593*4a5d661aSToomas Soome else { 594*4a5d661aSToomas Soome from = put - state->offset; 595*4a5d661aSToomas Soome copy = left; 596*4a5d661aSToomas Soome } 597*4a5d661aSToomas Soome if (copy > state->length) copy = state->length; 598*4a5d661aSToomas Soome state->length -= copy; 599*4a5d661aSToomas Soome left -= copy; 600*4a5d661aSToomas Soome do { 601*4a5d661aSToomas Soome *put++ = *from++; 602*4a5d661aSToomas Soome } while (--copy); 603*4a5d661aSToomas Soome } while (state->length != 0); 604*4a5d661aSToomas Soome break; 605*4a5d661aSToomas Soome 606*4a5d661aSToomas Soome case DONE: 607*4a5d661aSToomas Soome /* inflate stream terminated properly -- write leftover output */ 608*4a5d661aSToomas Soome ret = Z_STREAM_END; 609*4a5d661aSToomas Soome if (left < state->wsize) { 610*4a5d661aSToomas Soome if (out(out_desc, state->window, state->wsize - left)) 611*4a5d661aSToomas Soome ret = Z_BUF_ERROR; 612*4a5d661aSToomas Soome } 613*4a5d661aSToomas Soome goto inf_leave; 614*4a5d661aSToomas Soome 615*4a5d661aSToomas Soome case BAD: 616*4a5d661aSToomas Soome ret = Z_DATA_ERROR; 617*4a5d661aSToomas Soome goto inf_leave; 618*4a5d661aSToomas Soome 619*4a5d661aSToomas Soome default: /* can't happen, but makes compilers happy */ 620*4a5d661aSToomas Soome ret = Z_STREAM_ERROR; 621*4a5d661aSToomas Soome goto inf_leave; 622*4a5d661aSToomas Soome } 623*4a5d661aSToomas Soome 624*4a5d661aSToomas Soome /* Return unused input */ 625*4a5d661aSToomas Soome inf_leave: 626*4a5d661aSToomas Soome strm->next_in = next; 627*4a5d661aSToomas Soome strm->avail_in = have; 628*4a5d661aSToomas Soome return ret; 629*4a5d661aSToomas Soome } 630*4a5d661aSToomas Soome 631*4a5d661aSToomas Soome int ZEXPORT inflateBackEnd(strm) 632*4a5d661aSToomas Soome z_streamp strm; 633*4a5d661aSToomas Soome { 634*4a5d661aSToomas Soome if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) 635*4a5d661aSToomas Soome return Z_STREAM_ERROR; 636*4a5d661aSToomas Soome ZFREE(strm, strm->state); 637*4a5d661aSToomas Soome strm->state = Z_NULL; 638*4a5d661aSToomas Soome Tracev((stderr, "inflate: end\n")); 639*4a5d661aSToomas Soome return Z_OK; 640*4a5d661aSToomas Soome } 641