19e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* infback9.c -- inflate deflate64 data using a call-back interface 2381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes * Copyright (C) 1995-2008 Mark Adler 39e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * For conditions of distribution and use, see copyright notice in zlib.h 49e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 59e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 69e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "zutil.h" 79e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "infback9.h" 89e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "inftree9.h" 99e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "inflate9.h" 109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define WSIZE 65536UL 129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* 149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm provides memory allocation functions in zalloc and zfree, or 159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Z_NULL to use the library memory allocation functions. 169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project window is a user-supplied window and output buffer that is 64K bytes. 189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint ZEXPORT inflateBack9Init_(strm, window, version, stream_size) 209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectz_stream FAR *strm; 219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectunsigned char FAR *window; 229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectconst char *version; 239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint stream_size; 249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project struct inflate_state FAR *state; 269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || 289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project stream_size != (int)(sizeof(z_stream))) 299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_VERSION_ERROR; 309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (strm == Z_NULL || window == Z_NULL) 319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_STREAM_ERROR; 329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = Z_NULL; /* in case we return an error */ 339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (strm->zalloc == (alloc_func)0) { 349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->zalloc = zcalloc; 359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->opaque = (voidpf)0; 369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (strm->zfree == (free_func)0) strm->zfree = zcfree; 389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state = (struct inflate_state FAR *)ZALLOC(strm, 1, 399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project sizeof(struct inflate_state)); 409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state == Z_NULL) return Z_MEM_ERROR; 419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: allocated\n")); 429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->state = (voidpf)state; 439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->window = window; 449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_OK; 459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* 489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Build and output length and distance decoding tables for fixed code 499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project decoding. 509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef MAKEFIXED 529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <stdio.h> 539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid makefixed9(void) 559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned sym, bits, low, size; 579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project code *next, *lenfix, *distfix; 589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project struct inflate_state state; 599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project code fixed[544]; 609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* literal/length table */ 629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project sym = 0; 639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (sym < 144) state.lens[sym++] = 8; 649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (sym < 256) state.lens[sym++] = 9; 659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (sym < 280) state.lens[sym++] = 7; 669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (sym < 288) state.lens[sym++] = 8; 679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project next = fixed; 689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project lenfix = next; 699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bits = 9; 709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inflate_table9(LENS, state.lens, 288, &(next), &(bits), state.work); 719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* distance table */ 739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project sym = 0; 749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (sym < 32) state.lens[sym++] = 5; 759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project distfix = next; 769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bits = 5; 779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inflate_table9(DISTS, state.lens, 32, &(next), &(bits), state.work); 789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* write tables */ 809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project puts(" /* inffix9.h -- table for decoding deflate64 fixed codes"); 819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project puts(" * Generated automatically by makefixed9()."); 829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project puts(" */"); 839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project puts(""); 849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project puts(" /* WARNING: this file should *not* be used by applications."); 859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project puts(" It is part of the implementation of this library and is"); 869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project puts(" subject to change. Applications should only use zlib.h."); 879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project puts(" */"); 889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project puts(""); 899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project size = 1U << 9; 909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project printf(" static const code lenfix[%u] = {", size); 919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project low = 0; 929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (;;) { 939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if ((low % 6) == 0) printf("\n "); 949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project printf("{%u,%u,%d}", lenfix[low].op, lenfix[low].bits, 959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project lenfix[low].val); 969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (++low == size) break; 979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project putchar(','); 989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project puts("\n };"); 1009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project size = 1U << 5; 1019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project printf("\n static const code distfix[%u] = {", size); 1029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project low = 0; 1039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (;;) { 1049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if ((low % 5) == 0) printf("\n "); 1059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project printf("{%u,%u,%d}", distfix[low].op, distfix[low].bits, 1069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project distfix[low].val); 1079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (++low == size) break; 1089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project putchar(','); 1099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project puts("\n };"); 1119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 1129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* MAKEFIXED */ 1139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Macros for inflateBack(): */ 1159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Clear the input bit accumulator */ 1179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define INITBITS() \ 1189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { \ 1199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project hold = 0; \ 1209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bits = 0; \ 1219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (0) 1229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Assure that some input is available. If input is requested, but denied, 1249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project then return a Z_BUF_ERROR from inflateBack(). */ 1259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define PULL() \ 1269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { \ 1279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (have == 0) { \ 1289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project have = in(in_desc, &next); \ 1299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (have == 0) { \ 1309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project next = Z_NULL; \ 1319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = Z_BUF_ERROR; \ 1329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project goto inf_leave; \ 1339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } \ 1349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } \ 1359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (0) 1369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Get a byte of input into the bit accumulator, or return from inflateBack() 1389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project with an error if there is no input available. */ 1399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define PULLBYTE() \ 1409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { \ 1419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project PULL(); \ 1429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project have--; \ 1439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project hold += (unsigned long)(*next++) << bits; \ 1449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bits += 8; \ 1459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (0) 1469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Assure that there are at least n bits in the bit accumulator. If there is 1489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project not enough available input to do that, then return from inflateBack() with 1499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project an error. */ 1509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define NEEDBITS(n) \ 1519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { \ 1529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (bits < (unsigned)(n)) \ 1539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project PULLBYTE(); \ 1549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (0) 1559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Return the low n bits of the bit accumulator (n <= 16) */ 1579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define BITS(n) \ 1589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ((unsigned)hold & ((1U << (n)) - 1)) 1599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Remove n bits from the bit accumulator */ 1619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define DROPBITS(n) \ 1629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { \ 1639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project hold >>= (n); \ 1649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bits -= (unsigned)(n); \ 1659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (0) 1669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Remove zero to seven bits as needed to go to a byte boundary */ 1689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define BYTEBITS() \ 1699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { \ 1709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project hold >>= bits & 7; \ 1719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bits -= bits & 7; \ 1729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (0) 1739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Assure that some output space is available, by writing out the window 1759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if it's full. If the write fails, return from inflateBack() with a 1769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Z_BUF_ERROR. */ 1779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define ROOM() \ 1789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { \ 1799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (left == 0) { \ 1809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project put = window; \ 1819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project left = WSIZE; \ 1829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project wrap = 1; \ 1839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (out(out_desc, put, (unsigned)left)) { \ 1849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = Z_BUF_ERROR; \ 1859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project goto inf_leave; \ 1869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } \ 1879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } \ 1889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (0) 1899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* 1919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm provides the memory allocation functions and window buffer on input, 1929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project and provides information on the unused input on return. For Z_DATA_ERROR 1939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project returns, strm will also provide an error message. 1949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in() and out() are the call-back input and output functions. When 1969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inflateBack() needs more input, it calls in(). When inflateBack() has 1979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project filled the window with output, or when it completes with data in the 1989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project window, it calls out() to write out the data. The application must not 1999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project change the provided input until in() is called again or inflateBack() 2009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project returns. The application must not change the window/output buffer until 2019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inflateBack() returns. 2029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in() and out() are called with a descriptor parameter provided in the 2049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inflateBack() call. This parameter can be a structure that provides the 2059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project information required to do the read or write, as well as accumulated 2069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project information on the input and output such as totals and check values. 2079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in() should return zero on failure. out() should return non-zero on 2099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project failure. If either in() or out() fails, than inflateBack() returns a 2109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it 2119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project was in() or out() that caused in the error. Otherwise, inflateBack() 2129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format 2139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project error, or Z_MEM_ERROR if it could not allocate memory for the state. 2149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inflateBack() can also return Z_STREAM_ERROR if the input parameters 2159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project are not correct, i.e. strm is Z_NULL or the state was not initialized. 2169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 2179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint ZEXPORT inflateBack9(strm, in, in_desc, out, out_desc) 2189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectz_stream FAR *strm; 2199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectin_func in; 2209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid FAR *in_desc; 2219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectout_func out; 2229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid FAR *out_desc; 2239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 2249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project struct inflate_state FAR *state; 22504351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes z_const unsigned char FAR *next; /* next input */ 2269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned char FAR *put; /* next output */ 2279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned have; /* available input */ 2289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned long left; /* available output */ 2299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inflate_mode mode; /* current inflate mode */ 2309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int lastblock; /* true if processing last block */ 2319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int wrap; /* true if the window has wrapped */ 2329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned char FAR *window; /* allocated sliding window, if needed */ 2339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned long hold; /* bit buffer */ 2349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned bits; /* bits in bit buffer */ 2359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned extra; /* extra bits needed */ 2369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned long length; /* literal or length of data to copy */ 2379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned long offset; /* distance back to copy string from */ 2389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned long copy; /* number of stored or match bytes to copy */ 2399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned char FAR *from; /* where to copy match bytes from */ 2409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project code const FAR *lencode; /* starting table for length/literal codes */ 2419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project code const FAR *distcode; /* starting table for distance codes */ 2429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned lenbits; /* index bits for lencode */ 2439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned distbits; /* index bits for distcode */ 244381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes code here; /* current decoding table entry */ 2459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project code last; /* parent table entry */ 2469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned len; /* length to copy for repeats, bits to drop */ 2479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int ret; /* return code */ 2489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project static const unsigned short order[19] = /* permutation of code lengths */ 2499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; 2509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "inffix9.h" 2519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* Check that the strm exists and that the state was initialized */ 2539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (strm == Z_NULL || strm->state == Z_NULL) 2549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_STREAM_ERROR; 2559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state = (struct inflate_state FAR *)strm->state; 2569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* Reset the state */ 2589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = Z_NULL; 2599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mode = TYPE; 2609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project lastblock = 0; 2619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project wrap = 0; 2629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project window = state->window; 2639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project next = strm->next_in; 2649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project have = next != Z_NULL ? strm->avail_in : 0; 2659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project hold = 0; 2669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bits = 0; 2679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project put = window; 2689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project left = WSIZE; 2699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project lencode = Z_NULL; 2709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project distcode = Z_NULL; 2719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* Inflate until end of block marked as last */ 2739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (;;) 2749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project switch (mode) { 2759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case TYPE: 2769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* determine and dispatch block type */ 2779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (lastblock) { 2789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project BYTEBITS(); 2799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mode = DONE; 2809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 2819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(3); 2839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project lastblock = BITS(1); 2849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(1); 2859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project switch (BITS(2)) { 2869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case 0: /* stored block */ 2879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: stored block%s\n", 2889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project lastblock ? " (last)" : "")); 2899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mode = STORED; 2909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 2919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case 1: /* fixed block */ 2929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project lencode = lenfix; 2939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project lenbits = 9; 2949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project distcode = distfix; 2959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project distbits = 5; 2969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: fixed codes block%s\n", 2979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project lastblock ? " (last)" : "")); 2989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mode = LEN; /* decode codes */ 2999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 3009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case 2: /* dynamic block */ 3019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: dynamic codes block%s\n", 3029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project lastblock ? " (last)" : "")); 3039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mode = TABLE; 3049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 3059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case 3: 3069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"invalid block type"; 3079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mode = BAD; 3089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(2); 3109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 3119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case STORED: 3139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* get and verify stored block length */ 3149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project BYTEBITS(); /* go to byte boundary */ 3159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(32); 3169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { 3179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"invalid stored block lengths"; 3189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mode = BAD; 3199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 3209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project length = (unsigned)hold & 0xffff; 3229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: stored length %lu\n", 3239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project length)); 3249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project INITBITS(); 3259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* copy stored block from input to output */ 3279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (length != 0) { 3289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copy = length; 3299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project PULL(); 3309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ROOM(); 3319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (copy > have) copy = have; 3329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (copy > left) copy = left; 3339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project zmemcpy(put, next, copy); 3349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project have -= copy; 3359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project next += copy; 3369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project left -= copy; 3379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project put += copy; 3389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project length -= copy; 3399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: stored end\n")); 3419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mode = TYPE; 3429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 3439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case TABLE: 3459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* get dynamic table entries descriptor */ 3469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(14); 3479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->nlen = BITS(5) + 257; 3489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(5); 3499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->ndist = BITS(5) + 1; 3509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(5); 3519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->ncode = BITS(4) + 4; 3529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(4); 3539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->nlen > 286) { 3549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"too many length symbols"; 3559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mode = BAD; 3569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 3579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: table sizes ok\n")); 3599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* get code length code lengths (not a typo) */ 3619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->have = 0; 3629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (state->have < state->ncode) { 3639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(3); 3649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->lens[order[state->have++]] = (unsigned short)BITS(3); 3659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(3); 3669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (state->have < 19) 3689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->lens[order[state->have++]] = 0; 3699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->next = state->codes; 3709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project lencode = (code const FAR *)(state->next); 3719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project lenbits = 7; 3729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = inflate_table9(CODES, state->lens, 19, &(state->next), 3739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project &(lenbits), state->work); 3749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (ret) { 3759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"invalid code lengths set"; 3769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mode = BAD; 3779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 3789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: code lengths ok\n")); 3809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* get length and distance code code lengths */ 3829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->have = 0; 3839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (state->have < state->nlen + state->ndist) { 3849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (;;) { 385381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes here = lencode[BITS(lenbits)]; 386381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if ((unsigned)(here.bits) <= bits) break; 3879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project PULLBYTE(); 3889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 389381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (here.val < 16) { 390381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes NEEDBITS(here.bits); 391381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes DROPBITS(here.bits); 392381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->lens[state->have++] = here.val; 3939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else { 395381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (here.val == 16) { 396381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes NEEDBITS(here.bits + 2); 397381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes DROPBITS(here.bits); 3989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->have == 0) { 3999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"invalid bit length repeat"; 4009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mode = BAD; 4019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 4029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len = (unsigned)(state->lens[state->have - 1]); 4049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copy = 3 + BITS(2); 4059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(2); 4069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 407381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes else if (here.val == 17) { 408381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes NEEDBITS(here.bits + 3); 409381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes DROPBITS(here.bits); 4109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len = 0; 4119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copy = 3 + BITS(3); 4129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(3); 4139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else { 415381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes NEEDBITS(here.bits + 7); 416381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes DROPBITS(here.bits); 4179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len = 0; 4189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copy = 11 + BITS(7); 4199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(7); 4209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->have + copy > state->nlen + state->ndist) { 4229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"invalid bit length repeat"; 4239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mode = BAD; 4249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 4259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (copy--) 4279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->lens[state->have++] = (unsigned short)len; 4289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* handle error breaks in while */ 4329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (mode == BAD) break; 4339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 434381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check for end-of-block code (better have one) */ 435381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->lens[256] == 0) { 436381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->msg = (char *)"invalid code -- missing end-of-block"; 437381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes mode = BAD; 438381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes break; 439381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 440381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 441381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* build code tables -- note: do not change the lenbits or distbits 442381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes values here (9 and 6) without reading the comments in inftree9.h 443381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes concerning the ENOUGH constants, which depend on those values */ 4449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->next = state->codes; 4459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project lencode = (code const FAR *)(state->next); 4469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project lenbits = 9; 4479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = inflate_table9(LENS, state->lens, state->nlen, 4489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project &(state->next), &(lenbits), state->work); 4499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (ret) { 4509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"invalid literal/lengths set"; 4519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mode = BAD; 4529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 4539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project distcode = (code const FAR *)(state->next); 4559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project distbits = 6; 4569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = inflate_table9(DISTS, state->lens + state->nlen, 4579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->ndist, &(state->next), &(distbits), 4589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->work); 4599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (ret) { 4609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"invalid distances set"; 4619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mode = BAD; 4629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 4639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: codes ok\n")); 4659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mode = LEN; 4669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case LEN: 4689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* get a literal, length, or end-of-block code */ 4699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (;;) { 470381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes here = lencode[BITS(lenbits)]; 471381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if ((unsigned)(here.bits) <= bits) break; 4729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project PULLBYTE(); 4739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 474381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (here.op && (here.op & 0xf0) == 0) { 475381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes last = here; 4769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (;;) { 477381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes here = lencode[last.val + 4789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project (BITS(last.bits + last.op) >> last.bits)]; 479381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if ((unsigned)(last.bits + here.bits) <= bits) break; 4809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project PULLBYTE(); 4819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(last.bits); 4839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 484381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes DROPBITS(here.bits); 485381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes length = (unsigned)here.val; 4869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* process literal */ 488381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (here.op == 0) { 489381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? 4909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project "inflate: literal '%c'\n" : 491381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes "inflate: literal 0x%02x\n", here.val)); 4929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ROOM(); 4939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *put++ = (unsigned char)(length); 4949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project left--; 4959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mode = LEN; 4969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 4979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* process end of block */ 500381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (here.op & 32) { 5019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracevv((stderr, "inflate: end of block\n")); 5029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mode = TYPE; 5039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 5049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 5059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* invalid code */ 507381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (here.op & 64) { 5089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"invalid literal/length code"; 5099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mode = BAD; 5109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 5119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 5129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* length code -- get extra bits, if any */ 514381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes extra = (unsigned)(here.op) & 31; 5159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (extra != 0) { 5169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(extra); 5179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project length += BITS(extra); 5189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(extra); 5199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 5209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracevv((stderr, "inflate: length %lu\n", length)); 5219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* get distance code */ 5239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (;;) { 524381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes here = distcode[BITS(distbits)]; 525381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if ((unsigned)(here.bits) <= bits) break; 5269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project PULLBYTE(); 5279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 528381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if ((here.op & 0xf0) == 0) { 529381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes last = here; 5309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (;;) { 531381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes here = distcode[last.val + 5329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project (BITS(last.bits + last.op) >> last.bits)]; 533381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if ((unsigned)(last.bits + here.bits) <= bits) break; 5349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project PULLBYTE(); 5359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 5369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(last.bits); 5379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 538381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes DROPBITS(here.bits); 539381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (here.op & 64) { 5409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"invalid distance code"; 5419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mode = BAD; 5429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 5439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 544381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes offset = (unsigned)here.val; 5459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* get distance extra bits, if any */ 547381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes extra = (unsigned)(here.op) & 15; 5489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (extra != 0) { 5499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(extra); 5509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project offset += BITS(extra); 5519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(extra); 5529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 5539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (offset > WSIZE - (wrap ? 0: left)) { 5549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"invalid distance too far back"; 5559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project mode = BAD; 5569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 5579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 5589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracevv((stderr, "inflate: distance %lu\n", offset)); 5599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* copy match from window to output */ 5619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { 5629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ROOM(); 5639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copy = WSIZE - offset; 5649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (copy < left) { 5659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project from = put + copy; 5669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copy = left - copy; 5679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 5689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else { 5699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project from = put - offset; 5709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copy = left; 5719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 5729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (copy > length) copy = length; 5739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project length -= copy; 5749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project left -= copy; 5759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { 5769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *put++ = *from++; 5779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (--copy); 5789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (length != 0); 5799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 5809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case DONE: 5829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* inflate stream terminated properly -- write leftover output */ 5839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = Z_STREAM_END; 5849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (left < WSIZE) { 5859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (out(out_desc, window, (unsigned)(WSIZE - left))) 5869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = Z_BUF_ERROR; 5879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 5889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project goto inf_leave; 5899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case BAD: 5919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = Z_DATA_ERROR; 5929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project goto inf_leave; 5939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project default: /* can't happen, but makes compilers happy */ 5959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = Z_STREAM_ERROR; 5969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project goto inf_leave; 5979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 5989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* Return unused input */ 6009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inf_leave: 6019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->next_in = next; 6029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->avail_in = have; 6039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return ret; 6049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 6059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 6069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint ZEXPORT inflateBack9End(strm) 6079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectz_stream FAR *strm; 6089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 6099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) 6109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_STREAM_ERROR; 6119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ZFREE(strm, strm->state); 6129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->state = Z_NULL; 6139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: end\n")); 6149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_OK; 6159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 616