1275793eaSopenharmony_ci/* infback9.c -- inflate deflate64 data using a call-back interface 2275793eaSopenharmony_ci * Copyright (C) 1995-2008 Mark Adler 3275793eaSopenharmony_ci * For conditions of distribution and use, see copyright notice in zlib.h 4275793eaSopenharmony_ci */ 5275793eaSopenharmony_ci 6275793eaSopenharmony_ci#include "zutil.h" 7275793eaSopenharmony_ci#include "infback9.h" 8275793eaSopenharmony_ci#include "inftree9.h" 9275793eaSopenharmony_ci#include "inflate9.h" 10275793eaSopenharmony_ci 11275793eaSopenharmony_ci#define WSIZE 65536UL 12275793eaSopenharmony_ci 13275793eaSopenharmony_ci/* 14275793eaSopenharmony_ci strm provides memory allocation functions in zalloc and zfree, or 15275793eaSopenharmony_ci Z_NULL to use the library memory allocation functions. 16275793eaSopenharmony_ci 17275793eaSopenharmony_ci window is a user-supplied window and output buffer that is 64K bytes. 18275793eaSopenharmony_ci */ 19275793eaSopenharmony_ciint ZEXPORT inflateBack9Init_(z_stream FAR *strm, unsigned char FAR *window, 20275793eaSopenharmony_ci const char *version, int stream_size) { 21275793eaSopenharmony_ci struct inflate_state FAR *state; 22275793eaSopenharmony_ci 23275793eaSopenharmony_ci if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || 24275793eaSopenharmony_ci stream_size != (int)(sizeof(z_stream))) 25275793eaSopenharmony_ci return Z_VERSION_ERROR; 26275793eaSopenharmony_ci if (strm == Z_NULL || window == Z_NULL) 27275793eaSopenharmony_ci return Z_STREAM_ERROR; 28275793eaSopenharmony_ci strm->msg = Z_NULL; /* in case we return an error */ 29275793eaSopenharmony_ci if (strm->zalloc == (alloc_func)0) { 30275793eaSopenharmony_ci strm->zalloc = zcalloc; 31275793eaSopenharmony_ci strm->opaque = (voidpf)0; 32275793eaSopenharmony_ci } 33275793eaSopenharmony_ci if (strm->zfree == (free_func)0) strm->zfree = zcfree; 34275793eaSopenharmony_ci state = (struct inflate_state FAR *)ZALLOC(strm, 1, 35275793eaSopenharmony_ci sizeof(struct inflate_state)); 36275793eaSopenharmony_ci if (state == Z_NULL) return Z_MEM_ERROR; 37275793eaSopenharmony_ci Tracev((stderr, "inflate: allocated\n")); 38275793eaSopenharmony_ci strm->state = (voidpf)state; 39275793eaSopenharmony_ci state->window = window; 40275793eaSopenharmony_ci return Z_OK; 41275793eaSopenharmony_ci} 42275793eaSopenharmony_ci 43275793eaSopenharmony_ci/* 44275793eaSopenharmony_ci Build and output length and distance decoding tables for fixed code 45275793eaSopenharmony_ci decoding. 46275793eaSopenharmony_ci */ 47275793eaSopenharmony_ci#ifdef MAKEFIXED 48275793eaSopenharmony_ci#include <stdio.h> 49275793eaSopenharmony_ci 50275793eaSopenharmony_civoid makefixed9(void) 51275793eaSopenharmony_ci{ 52275793eaSopenharmony_ci unsigned sym, bits, low, size; 53275793eaSopenharmony_ci code *next, *lenfix, *distfix; 54275793eaSopenharmony_ci struct inflate_state state; 55275793eaSopenharmony_ci code fixed[544]; 56275793eaSopenharmony_ci 57275793eaSopenharmony_ci /* literal/length table */ 58275793eaSopenharmony_ci sym = 0; 59275793eaSopenharmony_ci while (sym < 144) state.lens[sym++] = 8; 60275793eaSopenharmony_ci while (sym < 256) state.lens[sym++] = 9; 61275793eaSopenharmony_ci while (sym < 280) state.lens[sym++] = 7; 62275793eaSopenharmony_ci while (sym < 288) state.lens[sym++] = 8; 63275793eaSopenharmony_ci next = fixed; 64275793eaSopenharmony_ci lenfix = next; 65275793eaSopenharmony_ci bits = 9; 66275793eaSopenharmony_ci inflate_table9(LENS, state.lens, 288, &(next), &(bits), state.work); 67275793eaSopenharmony_ci 68275793eaSopenharmony_ci /* distance table */ 69275793eaSopenharmony_ci sym = 0; 70275793eaSopenharmony_ci while (sym < 32) state.lens[sym++] = 5; 71275793eaSopenharmony_ci distfix = next; 72275793eaSopenharmony_ci bits = 5; 73275793eaSopenharmony_ci inflate_table9(DISTS, state.lens, 32, &(next), &(bits), state.work); 74275793eaSopenharmony_ci 75275793eaSopenharmony_ci /* write tables */ 76275793eaSopenharmony_ci puts(" /* inffix9.h -- table for decoding deflate64 fixed codes"); 77275793eaSopenharmony_ci puts(" * Generated automatically by makefixed9()."); 78275793eaSopenharmony_ci puts(" */"); 79275793eaSopenharmony_ci puts(""); 80275793eaSopenharmony_ci puts(" /* WARNING: this file should *not* be used by applications."); 81275793eaSopenharmony_ci puts(" It is part of the implementation of this library and is"); 82275793eaSopenharmony_ci puts(" subject to change. Applications should only use zlib.h."); 83275793eaSopenharmony_ci puts(" */"); 84275793eaSopenharmony_ci puts(""); 85275793eaSopenharmony_ci size = 1U << 9; 86275793eaSopenharmony_ci printf(" static const code lenfix[%u] = {", size); 87275793eaSopenharmony_ci low = 0; 88275793eaSopenharmony_ci for (;;) { 89275793eaSopenharmony_ci if ((low % 6) == 0) printf("\n "); 90275793eaSopenharmony_ci printf("{%u,%u,%d}", lenfix[low].op, lenfix[low].bits, 91275793eaSopenharmony_ci lenfix[low].val); 92275793eaSopenharmony_ci if (++low == size) break; 93275793eaSopenharmony_ci putchar(','); 94275793eaSopenharmony_ci } 95275793eaSopenharmony_ci puts("\n };"); 96275793eaSopenharmony_ci size = 1U << 5; 97275793eaSopenharmony_ci printf("\n static const code distfix[%u] = {", size); 98275793eaSopenharmony_ci low = 0; 99275793eaSopenharmony_ci for (;;) { 100275793eaSopenharmony_ci if ((low % 5) == 0) printf("\n "); 101275793eaSopenharmony_ci printf("{%u,%u,%d}", distfix[low].op, distfix[low].bits, 102275793eaSopenharmony_ci distfix[low].val); 103275793eaSopenharmony_ci if (++low == size) break; 104275793eaSopenharmony_ci putchar(','); 105275793eaSopenharmony_ci } 106275793eaSopenharmony_ci puts("\n };"); 107275793eaSopenharmony_ci} 108275793eaSopenharmony_ci#endif /* MAKEFIXED */ 109275793eaSopenharmony_ci 110275793eaSopenharmony_ci/* Macros for inflateBack(): */ 111275793eaSopenharmony_ci 112275793eaSopenharmony_ci/* Clear the input bit accumulator */ 113275793eaSopenharmony_ci#define INITBITS() \ 114275793eaSopenharmony_ci do { \ 115275793eaSopenharmony_ci hold = 0; \ 116275793eaSopenharmony_ci bits = 0; \ 117275793eaSopenharmony_ci } while (0) 118275793eaSopenharmony_ci 119275793eaSopenharmony_ci/* Assure that some input is available. If input is requested, but denied, 120275793eaSopenharmony_ci then return a Z_BUF_ERROR from inflateBack(). */ 121275793eaSopenharmony_ci#define PULL() \ 122275793eaSopenharmony_ci do { \ 123275793eaSopenharmony_ci if (have == 0) { \ 124275793eaSopenharmony_ci have = in(in_desc, &next); \ 125275793eaSopenharmony_ci if (have == 0) { \ 126275793eaSopenharmony_ci next = Z_NULL; \ 127275793eaSopenharmony_ci ret = Z_BUF_ERROR; \ 128275793eaSopenharmony_ci goto inf_leave; \ 129275793eaSopenharmony_ci } \ 130275793eaSopenharmony_ci } \ 131275793eaSopenharmony_ci } while (0) 132275793eaSopenharmony_ci 133275793eaSopenharmony_ci/* Get a byte of input into the bit accumulator, or return from inflateBack() 134275793eaSopenharmony_ci with an error if there is no input available. */ 135275793eaSopenharmony_ci#define PULLBYTE() \ 136275793eaSopenharmony_ci do { \ 137275793eaSopenharmony_ci PULL(); \ 138275793eaSopenharmony_ci have--; \ 139275793eaSopenharmony_ci hold += (unsigned long)(*next++) << bits; \ 140275793eaSopenharmony_ci bits += 8; \ 141275793eaSopenharmony_ci } while (0) 142275793eaSopenharmony_ci 143275793eaSopenharmony_ci/* Assure that there are at least n bits in the bit accumulator. If there is 144275793eaSopenharmony_ci not enough available input to do that, then return from inflateBack() with 145275793eaSopenharmony_ci an error. */ 146275793eaSopenharmony_ci#define NEEDBITS(n) \ 147275793eaSopenharmony_ci do { \ 148275793eaSopenharmony_ci while (bits < (unsigned)(n)) \ 149275793eaSopenharmony_ci PULLBYTE(); \ 150275793eaSopenharmony_ci } while (0) 151275793eaSopenharmony_ci 152275793eaSopenharmony_ci/* Return the low n bits of the bit accumulator (n <= 16) */ 153275793eaSopenharmony_ci#define BITS(n) \ 154275793eaSopenharmony_ci ((unsigned)hold & ((1U << (n)) - 1)) 155275793eaSopenharmony_ci 156275793eaSopenharmony_ci/* Remove n bits from the bit accumulator */ 157275793eaSopenharmony_ci#define DROPBITS(n) \ 158275793eaSopenharmony_ci do { \ 159275793eaSopenharmony_ci hold >>= (n); \ 160275793eaSopenharmony_ci bits -= (unsigned)(n); \ 161275793eaSopenharmony_ci } while (0) 162275793eaSopenharmony_ci 163275793eaSopenharmony_ci/* Remove zero to seven bits as needed to go to a byte boundary */ 164275793eaSopenharmony_ci#define BYTEBITS() \ 165275793eaSopenharmony_ci do { \ 166275793eaSopenharmony_ci hold >>= bits & 7; \ 167275793eaSopenharmony_ci bits -= bits & 7; \ 168275793eaSopenharmony_ci } while (0) 169275793eaSopenharmony_ci 170275793eaSopenharmony_ci/* Assure that some output space is available, by writing out the window 171275793eaSopenharmony_ci if it's full. If the write fails, return from inflateBack() with a 172275793eaSopenharmony_ci Z_BUF_ERROR. */ 173275793eaSopenharmony_ci#define ROOM() \ 174275793eaSopenharmony_ci do { \ 175275793eaSopenharmony_ci if (left == 0) { \ 176275793eaSopenharmony_ci put = window; \ 177275793eaSopenharmony_ci left = WSIZE; \ 178275793eaSopenharmony_ci wrap = 1; \ 179275793eaSopenharmony_ci if (out(out_desc, put, (unsigned)left)) { \ 180275793eaSopenharmony_ci ret = Z_BUF_ERROR; \ 181275793eaSopenharmony_ci goto inf_leave; \ 182275793eaSopenharmony_ci } \ 183275793eaSopenharmony_ci } \ 184275793eaSopenharmony_ci } while (0) 185275793eaSopenharmony_ci 186275793eaSopenharmony_ci/* 187275793eaSopenharmony_ci strm provides the memory allocation functions and window buffer on input, 188275793eaSopenharmony_ci and provides information on the unused input on return. For Z_DATA_ERROR 189275793eaSopenharmony_ci returns, strm will also provide an error message. 190275793eaSopenharmony_ci 191275793eaSopenharmony_ci in() and out() are the call-back input and output functions. When 192275793eaSopenharmony_ci inflateBack() needs more input, it calls in(). When inflateBack() has 193275793eaSopenharmony_ci filled the window with output, or when it completes with data in the 194275793eaSopenharmony_ci window, it calls out() to write out the data. The application must not 195275793eaSopenharmony_ci change the provided input until in() is called again or inflateBack() 196275793eaSopenharmony_ci returns. The application must not change the window/output buffer until 197275793eaSopenharmony_ci inflateBack() returns. 198275793eaSopenharmony_ci 199275793eaSopenharmony_ci in() and out() are called with a descriptor parameter provided in the 200275793eaSopenharmony_ci inflateBack() call. This parameter can be a structure that provides the 201275793eaSopenharmony_ci information required to do the read or write, as well as accumulated 202275793eaSopenharmony_ci information on the input and output such as totals and check values. 203275793eaSopenharmony_ci 204275793eaSopenharmony_ci in() should return zero on failure. out() should return non-zero on 205275793eaSopenharmony_ci failure. If either in() or out() fails, than inflateBack() returns a 206275793eaSopenharmony_ci Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it 207275793eaSopenharmony_ci was in() or out() that caused in the error. Otherwise, inflateBack() 208275793eaSopenharmony_ci returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format 209275793eaSopenharmony_ci error, or Z_MEM_ERROR if it could not allocate memory for the state. 210275793eaSopenharmony_ci inflateBack() can also return Z_STREAM_ERROR if the input parameters 211275793eaSopenharmony_ci are not correct, i.e. strm is Z_NULL or the state was not initialized. 212275793eaSopenharmony_ci */ 213275793eaSopenharmony_ciint ZEXPORT inflateBack9(z_stream FAR *strm, in_func in, void FAR *in_desc, 214275793eaSopenharmony_ci out_func out, void FAR *out_desc) { 215275793eaSopenharmony_ci struct inflate_state FAR *state; 216275793eaSopenharmony_ci z_const unsigned char FAR *next; /* next input */ 217275793eaSopenharmony_ci unsigned char FAR *put; /* next output */ 218275793eaSopenharmony_ci unsigned have; /* available input */ 219275793eaSopenharmony_ci unsigned long left; /* available output */ 220275793eaSopenharmony_ci inflate_mode mode; /* current inflate mode */ 221275793eaSopenharmony_ci int lastblock; /* true if processing last block */ 222275793eaSopenharmony_ci int wrap; /* true if the window has wrapped */ 223275793eaSopenharmony_ci unsigned char FAR *window; /* allocated sliding window, if needed */ 224275793eaSopenharmony_ci unsigned long hold; /* bit buffer */ 225275793eaSopenharmony_ci unsigned bits; /* bits in bit buffer */ 226275793eaSopenharmony_ci unsigned extra; /* extra bits needed */ 227275793eaSopenharmony_ci unsigned long length; /* literal or length of data to copy */ 228275793eaSopenharmony_ci unsigned long offset; /* distance back to copy string from */ 229275793eaSopenharmony_ci unsigned long copy; /* number of stored or match bytes to copy */ 230275793eaSopenharmony_ci unsigned char FAR *from; /* where to copy match bytes from */ 231275793eaSopenharmony_ci code const FAR *lencode; /* starting table for length/literal codes */ 232275793eaSopenharmony_ci code const FAR *distcode; /* starting table for distance codes */ 233275793eaSopenharmony_ci unsigned lenbits; /* index bits for lencode */ 234275793eaSopenharmony_ci unsigned distbits; /* index bits for distcode */ 235275793eaSopenharmony_ci code here; /* current decoding table entry */ 236275793eaSopenharmony_ci code last; /* parent table entry */ 237275793eaSopenharmony_ci unsigned len; /* length to copy for repeats, bits to drop */ 238275793eaSopenharmony_ci int ret; /* return code */ 239275793eaSopenharmony_ci static const unsigned short order[19] = /* permutation of code lengths */ 240275793eaSopenharmony_ci {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; 241275793eaSopenharmony_ci#include "inffix9.h" 242275793eaSopenharmony_ci 243275793eaSopenharmony_ci /* Check that the strm exists and that the state was initialized */ 244275793eaSopenharmony_ci if (strm == Z_NULL || strm->state == Z_NULL) 245275793eaSopenharmony_ci return Z_STREAM_ERROR; 246275793eaSopenharmony_ci state = (struct inflate_state FAR *)strm->state; 247275793eaSopenharmony_ci 248275793eaSopenharmony_ci /* Reset the state */ 249275793eaSopenharmony_ci strm->msg = Z_NULL; 250275793eaSopenharmony_ci mode = TYPE; 251275793eaSopenharmony_ci lastblock = 0; 252275793eaSopenharmony_ci wrap = 0; 253275793eaSopenharmony_ci window = state->window; 254275793eaSopenharmony_ci next = strm->next_in; 255275793eaSopenharmony_ci have = next != Z_NULL ? strm->avail_in : 0; 256275793eaSopenharmony_ci hold = 0; 257275793eaSopenharmony_ci bits = 0; 258275793eaSopenharmony_ci put = window; 259275793eaSopenharmony_ci left = WSIZE; 260275793eaSopenharmony_ci lencode = Z_NULL; 261275793eaSopenharmony_ci distcode = Z_NULL; 262275793eaSopenharmony_ci 263275793eaSopenharmony_ci /* Inflate until end of block marked as last */ 264275793eaSopenharmony_ci for (;;) 265275793eaSopenharmony_ci switch (mode) { 266275793eaSopenharmony_ci case TYPE: 267275793eaSopenharmony_ci /* determine and dispatch block type */ 268275793eaSopenharmony_ci if (lastblock) { 269275793eaSopenharmony_ci BYTEBITS(); 270275793eaSopenharmony_ci mode = DONE; 271275793eaSopenharmony_ci break; 272275793eaSopenharmony_ci } 273275793eaSopenharmony_ci NEEDBITS(3); 274275793eaSopenharmony_ci lastblock = BITS(1); 275275793eaSopenharmony_ci DROPBITS(1); 276275793eaSopenharmony_ci switch (BITS(2)) { 277275793eaSopenharmony_ci case 0: /* stored block */ 278275793eaSopenharmony_ci Tracev((stderr, "inflate: stored block%s\n", 279275793eaSopenharmony_ci lastblock ? " (last)" : "")); 280275793eaSopenharmony_ci mode = STORED; 281275793eaSopenharmony_ci break; 282275793eaSopenharmony_ci case 1: /* fixed block */ 283275793eaSopenharmony_ci lencode = lenfix; 284275793eaSopenharmony_ci lenbits = 9; 285275793eaSopenharmony_ci distcode = distfix; 286275793eaSopenharmony_ci distbits = 5; 287275793eaSopenharmony_ci Tracev((stderr, "inflate: fixed codes block%s\n", 288275793eaSopenharmony_ci lastblock ? " (last)" : "")); 289275793eaSopenharmony_ci mode = LEN; /* decode codes */ 290275793eaSopenharmony_ci break; 291275793eaSopenharmony_ci case 2: /* dynamic block */ 292275793eaSopenharmony_ci Tracev((stderr, "inflate: dynamic codes block%s\n", 293275793eaSopenharmony_ci lastblock ? " (last)" : "")); 294275793eaSopenharmony_ci mode = TABLE; 295275793eaSopenharmony_ci break; 296275793eaSopenharmony_ci case 3: 297275793eaSopenharmony_ci strm->msg = (char *)"invalid block type"; 298275793eaSopenharmony_ci mode = BAD; 299275793eaSopenharmony_ci } 300275793eaSopenharmony_ci DROPBITS(2); 301275793eaSopenharmony_ci break; 302275793eaSopenharmony_ci 303275793eaSopenharmony_ci case STORED: 304275793eaSopenharmony_ci /* get and verify stored block length */ 305275793eaSopenharmony_ci BYTEBITS(); /* go to byte boundary */ 306275793eaSopenharmony_ci NEEDBITS(32); 307275793eaSopenharmony_ci if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { 308275793eaSopenharmony_ci strm->msg = (char *)"invalid stored block lengths"; 309275793eaSopenharmony_ci mode = BAD; 310275793eaSopenharmony_ci break; 311275793eaSopenharmony_ci } 312275793eaSopenharmony_ci length = (unsigned)hold & 0xffff; 313275793eaSopenharmony_ci Tracev((stderr, "inflate: stored length %lu\n", 314275793eaSopenharmony_ci length)); 315275793eaSopenharmony_ci INITBITS(); 316275793eaSopenharmony_ci 317275793eaSopenharmony_ci /* copy stored block from input to output */ 318275793eaSopenharmony_ci while (length != 0) { 319275793eaSopenharmony_ci copy = length; 320275793eaSopenharmony_ci PULL(); 321275793eaSopenharmony_ci ROOM(); 322275793eaSopenharmony_ci if (copy > have) copy = have; 323275793eaSopenharmony_ci if (copy > left) copy = left; 324275793eaSopenharmony_ci zmemcpy(put, next, copy); 325275793eaSopenharmony_ci have -= copy; 326275793eaSopenharmony_ci next += copy; 327275793eaSopenharmony_ci left -= copy; 328275793eaSopenharmony_ci put += copy; 329275793eaSopenharmony_ci length -= copy; 330275793eaSopenharmony_ci } 331275793eaSopenharmony_ci Tracev((stderr, "inflate: stored end\n")); 332275793eaSopenharmony_ci mode = TYPE; 333275793eaSopenharmony_ci break; 334275793eaSopenharmony_ci 335275793eaSopenharmony_ci case TABLE: 336275793eaSopenharmony_ci /* get dynamic table entries descriptor */ 337275793eaSopenharmony_ci NEEDBITS(14); 338275793eaSopenharmony_ci state->nlen = BITS(5) + 257; 339275793eaSopenharmony_ci DROPBITS(5); 340275793eaSopenharmony_ci state->ndist = BITS(5) + 1; 341275793eaSopenharmony_ci DROPBITS(5); 342275793eaSopenharmony_ci state->ncode = BITS(4) + 4; 343275793eaSopenharmony_ci DROPBITS(4); 344275793eaSopenharmony_ci if (state->nlen > 286) { 345275793eaSopenharmony_ci strm->msg = (char *)"too many length symbols"; 346275793eaSopenharmony_ci mode = BAD; 347275793eaSopenharmony_ci break; 348275793eaSopenharmony_ci } 349275793eaSopenharmony_ci Tracev((stderr, "inflate: table sizes ok\n")); 350275793eaSopenharmony_ci 351275793eaSopenharmony_ci /* get code length code lengths (not a typo) */ 352275793eaSopenharmony_ci state->have = 0; 353275793eaSopenharmony_ci while (state->have < state->ncode) { 354275793eaSopenharmony_ci NEEDBITS(3); 355275793eaSopenharmony_ci state->lens[order[state->have++]] = (unsigned short)BITS(3); 356275793eaSopenharmony_ci DROPBITS(3); 357275793eaSopenharmony_ci } 358275793eaSopenharmony_ci while (state->have < 19) 359275793eaSopenharmony_ci state->lens[order[state->have++]] = 0; 360275793eaSopenharmony_ci state->next = state->codes; 361275793eaSopenharmony_ci lencode = (code const FAR *)(state->next); 362275793eaSopenharmony_ci lenbits = 7; 363275793eaSopenharmony_ci ret = inflate_table9(CODES, state->lens, 19, &(state->next), 364275793eaSopenharmony_ci &(lenbits), state->work); 365275793eaSopenharmony_ci if (ret) { 366275793eaSopenharmony_ci strm->msg = (char *)"invalid code lengths set"; 367275793eaSopenharmony_ci mode = BAD; 368275793eaSopenharmony_ci break; 369275793eaSopenharmony_ci } 370275793eaSopenharmony_ci Tracev((stderr, "inflate: code lengths ok\n")); 371275793eaSopenharmony_ci 372275793eaSopenharmony_ci /* get length and distance code code lengths */ 373275793eaSopenharmony_ci state->have = 0; 374275793eaSopenharmony_ci while (state->have < state->nlen + state->ndist) { 375275793eaSopenharmony_ci for (;;) { 376275793eaSopenharmony_ci here = lencode[BITS(lenbits)]; 377275793eaSopenharmony_ci if ((unsigned)(here.bits) <= bits) break; 378275793eaSopenharmony_ci PULLBYTE(); 379275793eaSopenharmony_ci } 380275793eaSopenharmony_ci if (here.val < 16) { 381275793eaSopenharmony_ci NEEDBITS(here.bits); 382275793eaSopenharmony_ci DROPBITS(here.bits); 383275793eaSopenharmony_ci state->lens[state->have++] = here.val; 384275793eaSopenharmony_ci } 385275793eaSopenharmony_ci else { 386275793eaSopenharmony_ci if (here.val == 16) { 387275793eaSopenharmony_ci NEEDBITS(here.bits + 2); 388275793eaSopenharmony_ci DROPBITS(here.bits); 389275793eaSopenharmony_ci if (state->have == 0) { 390275793eaSopenharmony_ci strm->msg = (char *)"invalid bit length repeat"; 391275793eaSopenharmony_ci mode = BAD; 392275793eaSopenharmony_ci break; 393275793eaSopenharmony_ci } 394275793eaSopenharmony_ci len = (unsigned)(state->lens[state->have - 1]); 395275793eaSopenharmony_ci copy = 3 + BITS(2); 396275793eaSopenharmony_ci DROPBITS(2); 397275793eaSopenharmony_ci } 398275793eaSopenharmony_ci else if (here.val == 17) { 399275793eaSopenharmony_ci NEEDBITS(here.bits + 3); 400275793eaSopenharmony_ci DROPBITS(here.bits); 401275793eaSopenharmony_ci len = 0; 402275793eaSopenharmony_ci copy = 3 + BITS(3); 403275793eaSopenharmony_ci DROPBITS(3); 404275793eaSopenharmony_ci } 405275793eaSopenharmony_ci else { 406275793eaSopenharmony_ci NEEDBITS(here.bits + 7); 407275793eaSopenharmony_ci DROPBITS(here.bits); 408275793eaSopenharmony_ci len = 0; 409275793eaSopenharmony_ci copy = 11 + BITS(7); 410275793eaSopenharmony_ci DROPBITS(7); 411275793eaSopenharmony_ci } 412275793eaSopenharmony_ci if (state->have + copy > state->nlen + state->ndist) { 413275793eaSopenharmony_ci strm->msg = (char *)"invalid bit length repeat"; 414275793eaSopenharmony_ci mode = BAD; 415275793eaSopenharmony_ci break; 416275793eaSopenharmony_ci } 417275793eaSopenharmony_ci while (copy--) 418275793eaSopenharmony_ci state->lens[state->have++] = (unsigned short)len; 419275793eaSopenharmony_ci } 420275793eaSopenharmony_ci } 421275793eaSopenharmony_ci 422275793eaSopenharmony_ci /* handle error breaks in while */ 423275793eaSopenharmony_ci if (mode == BAD) break; 424275793eaSopenharmony_ci 425275793eaSopenharmony_ci /* check for end-of-block code (better have one) */ 426275793eaSopenharmony_ci if (state->lens[256] == 0) { 427275793eaSopenharmony_ci strm->msg = (char *)"invalid code -- missing end-of-block"; 428275793eaSopenharmony_ci mode = BAD; 429275793eaSopenharmony_ci break; 430275793eaSopenharmony_ci } 431275793eaSopenharmony_ci 432275793eaSopenharmony_ci /* build code tables -- note: do not change the lenbits or distbits 433275793eaSopenharmony_ci values here (9 and 6) without reading the comments in inftree9.h 434275793eaSopenharmony_ci concerning the ENOUGH constants, which depend on those values */ 435275793eaSopenharmony_ci state->next = state->codes; 436275793eaSopenharmony_ci lencode = (code const FAR *)(state->next); 437275793eaSopenharmony_ci lenbits = 9; 438275793eaSopenharmony_ci ret = inflate_table9(LENS, state->lens, state->nlen, 439275793eaSopenharmony_ci &(state->next), &(lenbits), state->work); 440275793eaSopenharmony_ci if (ret) { 441275793eaSopenharmony_ci strm->msg = (char *)"invalid literal/lengths set"; 442275793eaSopenharmony_ci mode = BAD; 443275793eaSopenharmony_ci break; 444275793eaSopenharmony_ci } 445275793eaSopenharmony_ci distcode = (code const FAR *)(state->next); 446275793eaSopenharmony_ci distbits = 6; 447275793eaSopenharmony_ci ret = inflate_table9(DISTS, state->lens + state->nlen, 448275793eaSopenharmony_ci state->ndist, &(state->next), &(distbits), 449275793eaSopenharmony_ci state->work); 450275793eaSopenharmony_ci if (ret) { 451275793eaSopenharmony_ci strm->msg = (char *)"invalid distances set"; 452275793eaSopenharmony_ci mode = BAD; 453275793eaSopenharmony_ci break; 454275793eaSopenharmony_ci } 455275793eaSopenharmony_ci Tracev((stderr, "inflate: codes ok\n")); 456275793eaSopenharmony_ci mode = LEN; 457275793eaSopenharmony_ci 458275793eaSopenharmony_ci case LEN: 459275793eaSopenharmony_ci /* get a literal, length, or end-of-block code */ 460275793eaSopenharmony_ci for (;;) { 461275793eaSopenharmony_ci here = lencode[BITS(lenbits)]; 462275793eaSopenharmony_ci if ((unsigned)(here.bits) <= bits) break; 463275793eaSopenharmony_ci PULLBYTE(); 464275793eaSopenharmony_ci } 465275793eaSopenharmony_ci if (here.op && (here.op & 0xf0) == 0) { 466275793eaSopenharmony_ci last = here; 467275793eaSopenharmony_ci for (;;) { 468275793eaSopenharmony_ci here = lencode[last.val + 469275793eaSopenharmony_ci (BITS(last.bits + last.op) >> last.bits)]; 470275793eaSopenharmony_ci if ((unsigned)(last.bits + here.bits) <= bits) break; 471275793eaSopenharmony_ci PULLBYTE(); 472275793eaSopenharmony_ci } 473275793eaSopenharmony_ci DROPBITS(last.bits); 474275793eaSopenharmony_ci } 475275793eaSopenharmony_ci DROPBITS(here.bits); 476275793eaSopenharmony_ci length = (unsigned)here.val; 477275793eaSopenharmony_ci 478275793eaSopenharmony_ci /* process literal */ 479275793eaSopenharmony_ci if (here.op == 0) { 480275793eaSopenharmony_ci Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? 481275793eaSopenharmony_ci "inflate: literal '%c'\n" : 482275793eaSopenharmony_ci "inflate: literal 0x%02x\n", here.val)); 483275793eaSopenharmony_ci ROOM(); 484275793eaSopenharmony_ci *put++ = (unsigned char)(length); 485275793eaSopenharmony_ci left--; 486275793eaSopenharmony_ci mode = LEN; 487275793eaSopenharmony_ci break; 488275793eaSopenharmony_ci } 489275793eaSopenharmony_ci 490275793eaSopenharmony_ci /* process end of block */ 491275793eaSopenharmony_ci if (here.op & 32) { 492275793eaSopenharmony_ci Tracevv((stderr, "inflate: end of block\n")); 493275793eaSopenharmony_ci mode = TYPE; 494275793eaSopenharmony_ci break; 495275793eaSopenharmony_ci } 496275793eaSopenharmony_ci 497275793eaSopenharmony_ci /* invalid code */ 498275793eaSopenharmony_ci if (here.op & 64) { 499275793eaSopenharmony_ci strm->msg = (char *)"invalid literal/length code"; 500275793eaSopenharmony_ci mode = BAD; 501275793eaSopenharmony_ci break; 502275793eaSopenharmony_ci } 503275793eaSopenharmony_ci 504275793eaSopenharmony_ci /* length code -- get extra bits, if any */ 505275793eaSopenharmony_ci extra = (unsigned)(here.op) & 31; 506275793eaSopenharmony_ci if (extra != 0) { 507275793eaSopenharmony_ci NEEDBITS(extra); 508275793eaSopenharmony_ci length += BITS(extra); 509275793eaSopenharmony_ci DROPBITS(extra); 510275793eaSopenharmony_ci } 511275793eaSopenharmony_ci Tracevv((stderr, "inflate: length %lu\n", length)); 512275793eaSopenharmony_ci 513275793eaSopenharmony_ci /* get distance code */ 514275793eaSopenharmony_ci for (;;) { 515275793eaSopenharmony_ci here = distcode[BITS(distbits)]; 516275793eaSopenharmony_ci if ((unsigned)(here.bits) <= bits) break; 517275793eaSopenharmony_ci PULLBYTE(); 518275793eaSopenharmony_ci } 519275793eaSopenharmony_ci if ((here.op & 0xf0) == 0) { 520275793eaSopenharmony_ci last = here; 521275793eaSopenharmony_ci for (;;) { 522275793eaSopenharmony_ci here = distcode[last.val + 523275793eaSopenharmony_ci (BITS(last.bits + last.op) >> last.bits)]; 524275793eaSopenharmony_ci if ((unsigned)(last.bits + here.bits) <= bits) break; 525275793eaSopenharmony_ci PULLBYTE(); 526275793eaSopenharmony_ci } 527275793eaSopenharmony_ci DROPBITS(last.bits); 528275793eaSopenharmony_ci } 529275793eaSopenharmony_ci DROPBITS(here.bits); 530275793eaSopenharmony_ci if (here.op & 64) { 531275793eaSopenharmony_ci strm->msg = (char *)"invalid distance code"; 532275793eaSopenharmony_ci mode = BAD; 533275793eaSopenharmony_ci break; 534275793eaSopenharmony_ci } 535275793eaSopenharmony_ci offset = (unsigned)here.val; 536275793eaSopenharmony_ci 537275793eaSopenharmony_ci /* get distance extra bits, if any */ 538275793eaSopenharmony_ci extra = (unsigned)(here.op) & 15; 539275793eaSopenharmony_ci if (extra != 0) { 540275793eaSopenharmony_ci NEEDBITS(extra); 541275793eaSopenharmony_ci offset += BITS(extra); 542275793eaSopenharmony_ci DROPBITS(extra); 543275793eaSopenharmony_ci } 544275793eaSopenharmony_ci if (offset > WSIZE - (wrap ? 0: left)) { 545275793eaSopenharmony_ci strm->msg = (char *)"invalid distance too far back"; 546275793eaSopenharmony_ci mode = BAD; 547275793eaSopenharmony_ci break; 548275793eaSopenharmony_ci } 549275793eaSopenharmony_ci Tracevv((stderr, "inflate: distance %lu\n", offset)); 550275793eaSopenharmony_ci 551275793eaSopenharmony_ci /* copy match from window to output */ 552275793eaSopenharmony_ci do { 553275793eaSopenharmony_ci ROOM(); 554275793eaSopenharmony_ci copy = WSIZE - offset; 555275793eaSopenharmony_ci if (copy < left) { 556275793eaSopenharmony_ci from = put + copy; 557275793eaSopenharmony_ci copy = left - copy; 558275793eaSopenharmony_ci } 559275793eaSopenharmony_ci else { 560275793eaSopenharmony_ci from = put - offset; 561275793eaSopenharmony_ci copy = left; 562275793eaSopenharmony_ci } 563275793eaSopenharmony_ci if (copy > length) copy = length; 564275793eaSopenharmony_ci length -= copy; 565275793eaSopenharmony_ci left -= copy; 566275793eaSopenharmony_ci do { 567275793eaSopenharmony_ci *put++ = *from++; 568275793eaSopenharmony_ci } while (--copy); 569275793eaSopenharmony_ci } while (length != 0); 570275793eaSopenharmony_ci break; 571275793eaSopenharmony_ci 572275793eaSopenharmony_ci case DONE: 573275793eaSopenharmony_ci /* inflate stream terminated properly -- write leftover output */ 574275793eaSopenharmony_ci ret = Z_STREAM_END; 575275793eaSopenharmony_ci if (left < WSIZE) { 576275793eaSopenharmony_ci if (out(out_desc, window, (unsigned)(WSIZE - left))) 577275793eaSopenharmony_ci ret = Z_BUF_ERROR; 578275793eaSopenharmony_ci } 579275793eaSopenharmony_ci goto inf_leave; 580275793eaSopenharmony_ci 581275793eaSopenharmony_ci case BAD: 582275793eaSopenharmony_ci ret = Z_DATA_ERROR; 583275793eaSopenharmony_ci goto inf_leave; 584275793eaSopenharmony_ci 585275793eaSopenharmony_ci default: /* can't happen, but makes compilers happy */ 586275793eaSopenharmony_ci ret = Z_STREAM_ERROR; 587275793eaSopenharmony_ci goto inf_leave; 588275793eaSopenharmony_ci } 589275793eaSopenharmony_ci 590275793eaSopenharmony_ci /* Return unused input */ 591275793eaSopenharmony_ci inf_leave: 592275793eaSopenharmony_ci strm->next_in = next; 593275793eaSopenharmony_ci strm->avail_in = have; 594275793eaSopenharmony_ci return ret; 595275793eaSopenharmony_ci} 596275793eaSopenharmony_ci 597275793eaSopenharmony_ciint ZEXPORT inflateBack9End(z_stream FAR *strm) { 598275793eaSopenharmony_ci if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) 599275793eaSopenharmony_ci return Z_STREAM_ERROR; 600275793eaSopenharmony_ci ZFREE(strm, strm->state); 601275793eaSopenharmony_ci strm->state = Z_NULL; 602275793eaSopenharmony_ci Tracev((stderr, "inflate: end\n")); 603275793eaSopenharmony_ci return Z_OK; 604275793eaSopenharmony_ci} 605