18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* infback.c -- inflate using a call-back interface 217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner * Copyright (C) 1995-2011 Mark Adler 38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * For conditions of distribution and use, see copyright notice in zlib.h 48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project This code is largely copied from inflate.c. Normally either infback.o or 88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project inflate.o would be linked into an application--not both. The interface 98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project with inffast.c is retained so that optimized assembler-coded versions of 108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project inflate_fast() can be used with either inflate.c or infback.c. 118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "zutil.h" 148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "inftrees.h" 158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "inflate.h" 168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "inffast.h" 178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* function prototypes */ 198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal void fixedtables OF((struct inflate_state FAR *state)); 208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm provides memory allocation functions in zalloc and zfree, or 238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Z_NULL to use the library memory allocation functions. 248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project windowBits is in the range 8..15, and window is a user-supplied 268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project window and output buffer that is 2**windowBits bytes. 278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) 298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectz_streamp strm; 308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint windowBits; 318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectunsigned char FAR *window; 328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char *version; 338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint stream_size; 348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct inflate_state FAR *state; 368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || 388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project stream_size != (int)(sizeof(z_stream))) 398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return Z_VERSION_ERROR; 408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (strm == Z_NULL || window == Z_NULL || 418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project windowBits < 8 || windowBits > 15) 428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return Z_STREAM_ERROR; 438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm->msg = Z_NULL; /* in case we return an error */ 448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (strm->zalloc == (alloc_func)0) { 4517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#ifdef Z_SOLO 4617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return Z_STREAM_ERROR; 4717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#else 488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm->zalloc = zcalloc; 498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm->opaque = (voidpf)0; 5017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#endif 518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (strm->zfree == (free_func)0) 5317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#ifdef Z_SOLO 5417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner return Z_STREAM_ERROR; 5517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#else 5617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner strm->zfree = zcfree; 5717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner#endif 588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state = (struct inflate_state FAR *)ZALLOC(strm, 1, 598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sizeof(struct inflate_state)); 608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (state == Z_NULL) return Z_MEM_ERROR; 618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Tracev((stderr, "inflate: allocated\n")); 628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm->state = (struct internal_state FAR *)state; 638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->dmax = 32768U; 648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->wbits = windowBits; 658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->wsize = 1U << windowBits; 668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->window = window; 6717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->wnext = 0; 688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->whave = 0; 698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return Z_OK; 708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Return state with length and distance decoding tables and index sizes set to 748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fixed code decoding. Normally this returns fixed tables from inffixed.h. 758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project If BUILDFIXED is defined, then instead this routine builds the tables the 768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project first time it's called, and returns those tables the first time and 778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project thereafter. This reduces the size of the code by about 2K bytes, in 788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project exchange for a little execution time. However, BUILDFIXED should not be 798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project used for threaded applications, since the rewriting of the tables and virgin 808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project may not be thread-safe. 818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal void fixedtables(state) 838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct inflate_state FAR *state; 848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef BUILDFIXED 868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project static int virgin = 1; 878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project static code *lenfix, *distfix; 888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project static code fixed[544]; 898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* build fixed huffman tables if first call (may not be thread safe) */ 918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (virgin) { 928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned sym, bits; 938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project static code *next; 948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* literal/length table */ 968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sym = 0; 978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (sym < 144) state->lens[sym++] = 8; 988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (sym < 256) state->lens[sym++] = 9; 998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (sym < 280) state->lens[sym++] = 7; 1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (sym < 288) state->lens[sym++] = 8; 1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project next = fixed; 1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project lenfix = next; 1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bits = 9; 1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); 1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* distance table */ 1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project sym = 0; 1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (sym < 32) state->lens[sym++] = 5; 1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project distfix = next; 1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bits = 5; 1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); 1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* do this just once */ 1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project virgin = 0; 1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else /* !BUILDFIXED */ 1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project# include "inffixed.h" 1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* BUILDFIXED */ 1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->lencode = lenfix; 1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->lenbits = 9; 1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->distcode = distfix; 1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->distbits = 5; 1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Macros for inflateBack(): */ 1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Load returned state from inflate_fast() */ 1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define LOAD() \ 1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project do { \ 1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project put = strm->next_out; \ 1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project left = strm->avail_out; \ 1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project next = strm->next_in; \ 1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project have = strm->avail_in; \ 1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hold = state->hold; \ 1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bits = state->bits; \ 1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while (0) 1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Set state from registers for inflate_fast() */ 1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define RESTORE() \ 1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project do { \ 1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm->next_out = put; \ 1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm->avail_out = left; \ 1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm->next_in = next; \ 1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm->avail_in = have; \ 1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->hold = hold; \ 1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->bits = bits; \ 1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while (0) 1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Clear the input bit accumulator */ 1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define INITBITS() \ 1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project do { \ 1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hold = 0; \ 1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bits = 0; \ 1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while (0) 1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Assure that some input is available. If input is requested, but denied, 1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project then return a Z_BUF_ERROR from inflateBack(). */ 1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PULL() \ 1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project do { \ 1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (have == 0) { \ 1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project have = in(in_desc, &next); \ 1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (have == 0) { \ 1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project next = Z_NULL; \ 1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = Z_BUF_ERROR; \ 1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto inf_leave; \ 1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } \ 1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } \ 1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while (0) 1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Get a byte of input into the bit accumulator, or return from inflateBack() 1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project with an error if there is no input available. */ 1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PULLBYTE() \ 1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project do { \ 1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PULL(); \ 1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project have--; \ 1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hold += (unsigned long)(*next++) << bits; \ 1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bits += 8; \ 1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while (0) 1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Assure that there are at least n bits in the bit accumulator. If there is 1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project not enough available input to do that, then return from inflateBack() with 1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project an error. */ 1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEEDBITS(n) \ 1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project do { \ 1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (bits < (unsigned)(n)) \ 1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PULLBYTE(); \ 1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while (0) 1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Return the low n bits of the bit accumulator (n < 16) */ 1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define BITS(n) \ 1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ((unsigned)hold & ((1U << (n)) - 1)) 1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Remove n bits from the bit accumulator */ 1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DROPBITS(n) \ 1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project do { \ 1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hold >>= (n); \ 1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bits -= (unsigned)(n); \ 1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while (0) 1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Remove zero to seven bits as needed to go to a byte boundary */ 2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define BYTEBITS() \ 2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project do { \ 2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hold >>= bits & 7; \ 2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bits -= bits & 7; \ 2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while (0) 2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Assure that some output space is available, by writing out the window 2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if it's full. If the write fails, return from inflateBack() with a 2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Z_BUF_ERROR. */ 2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define ROOM() \ 2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project do { \ 2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (left == 0) { \ 2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project put = state->window; \ 2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project left = state->wsize; \ 2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->whave = left; \ 2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (out(out_desc, put, left)) { \ 2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = Z_BUF_ERROR; \ 2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto inf_leave; \ 2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } \ 2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } \ 2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while (0) 2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* 2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm provides the memory allocation functions and window buffer on input, 2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project and provides information on the unused input on return. For Z_DATA_ERROR 2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project returns, strm will also provide an error message. 2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project in() and out() are the call-back input and output functions. When 2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project inflateBack() needs more input, it calls in(). When inflateBack() has 2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project filled the window with output, or when it completes with data in the 2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project window, it calls out() to write out the data. The application must not 2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project change the provided input until in() is called again or inflateBack() 2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project returns. The application must not change the window/output buffer until 2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project inflateBack() returns. 2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project in() and out() are called with a descriptor parameter provided in the 2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project inflateBack() call. This parameter can be a structure that provides the 2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project information required to do the read or write, as well as accumulated 2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project information on the input and output such as totals and check values. 2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project in() should return zero on failure. out() should return non-zero on 2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project failure. If either in() or out() fails, than inflateBack() returns a 2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it 2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project was in() or out() that caused in the error. Otherwise, inflateBack() 2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format 2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project error, or Z_MEM_ERROR if it could not allocate memory for the state. 2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project inflateBack() can also return Z_STREAM_ERROR if the input parameters 2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project are not correct, i.e. strm is Z_NULL or the state was not initialized. 2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */ 2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) 2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectz_streamp strm; 2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectin_func in; 2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid FAR *in_desc; 2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectout_func out; 2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid FAR *out_desc; 2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project struct inflate_state FAR *state; 25817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner z_const unsigned char FAR *next; /* next input */ 2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned char FAR *put; /* next output */ 2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned have, left; /* available input and output */ 2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned long hold; /* bit buffer */ 2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned bits; /* bits in bit buffer */ 2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned copy; /* number of stored or match bytes to copy */ 2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned char FAR *from; /* where to copy match bytes from */ 26517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner code here; /* current decoding table entry */ 2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project code last; /* parent table entry */ 2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project unsigned len; /* length to copy for repeats, bits to drop */ 2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project int ret; /* return code */ 2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project static const unsigned short order[19] = /* permutation of code lengths */ 2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; 2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Check that the strm exists and that the state was initialized */ 2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (strm == Z_NULL || strm->state == Z_NULL) 2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return Z_STREAM_ERROR; 2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state = (struct inflate_state FAR *)strm->state; 2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Reset the state */ 2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm->msg = Z_NULL; 2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->mode = TYPE; 2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->last = 0; 2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->whave = 0; 2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project next = strm->next_in; 2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project have = next != Z_NULL ? strm->avail_in : 0; 2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project hold = 0; 2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project bits = 0; 2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project put = state->window; 2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project left = state->wsize; 2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Inflate until end of block marked as last */ 2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (;;) 2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (state->mode) { 2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TYPE: 2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* determine and dispatch block type */ 2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (state->last) { 2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BYTEBITS(); 2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->mode = DONE; 2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NEEDBITS(3); 3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->last = BITS(1); 3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DROPBITS(1); 3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project switch (BITS(2)) { 3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 0: /* stored block */ 3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Tracev((stderr, "inflate: stored block%s\n", 3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->last ? " (last)" : "")); 3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->mode = STORED; 3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 1: /* fixed block */ 3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project fixedtables(state); 3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Tracev((stderr, "inflate: fixed codes block%s\n", 3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->last ? " (last)" : "")); 3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->mode = LEN; /* decode codes */ 3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 2: /* dynamic block */ 3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Tracev((stderr, "inflate: dynamic codes block%s\n", 3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->last ? " (last)" : "")); 3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->mode = TABLE; 3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case 3: 3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm->msg = (char *)"invalid block type"; 3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->mode = BAD; 3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DROPBITS(2); 3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case STORED: 3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* get and verify stored block length */ 3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project BYTEBITS(); /* go to byte boundary */ 3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NEEDBITS(32); 3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { 3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm->msg = (char *)"invalid stored block lengths"; 3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->mode = BAD; 3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->length = (unsigned)hold & 0xffff; 3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Tracev((stderr, "inflate: stored length %u\n", 3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->length)); 3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project INITBITS(); 3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* copy stored block from input to output */ 3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (state->length != 0) { 3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project copy = state->length; 3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PULL(); 3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ROOM(); 3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (copy > have) copy = have; 3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (copy > left) copy = left; 3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project zmemcpy(put, next, copy); 3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project have -= copy; 3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project next += copy; 3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project left -= copy; 3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project put += copy; 3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->length -= copy; 3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Tracev((stderr, "inflate: stored end\n")); 3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->mode = TYPE; 3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case TABLE: 3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* get dynamic table entries descriptor */ 3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NEEDBITS(14); 3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->nlen = BITS(5) + 257; 3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DROPBITS(5); 3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->ndist = BITS(5) + 1; 3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DROPBITS(5); 3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->ncode = BITS(4) + 4; 3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DROPBITS(4); 3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef PKZIP_BUG_WORKAROUND 3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (state->nlen > 286 || state->ndist > 30) { 3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm->msg = (char *)"too many length or distance symbols"; 3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->mode = BAD; 3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif 3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Tracev((stderr, "inflate: table sizes ok\n")); 3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* get code length code lengths (not a typo) */ 3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->have = 0; 3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (state->have < state->ncode) { 3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NEEDBITS(3); 3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->lens[order[state->have++]] = (unsigned short)BITS(3); 3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DROPBITS(3); 3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (state->have < 19) 3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->lens[order[state->have++]] = 0; 3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->next = state->codes; 3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->lencode = (code const FAR *)(state->next); 3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->lenbits = 7; 3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = inflate_table(CODES, state->lens, 19, &(state->next), 3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &(state->lenbits), state->work); 3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret) { 3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm->msg = (char *)"invalid code lengths set"; 3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->mode = BAD; 3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Tracev((stderr, "inflate: code lengths ok\n")); 3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* get length and distance code code lengths */ 3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->have = 0; 3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (state->have < state->nlen + state->ndist) { 4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (;;) { 40117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner here = state->lencode[BITS(state->lenbits)]; 40217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if ((unsigned)(here.bits) <= bits) break; 4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PULLBYTE(); 4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 40517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (here.val < 16) { 40617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner DROPBITS(here.bits); 40717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->lens[state->have++] = here.val; 4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 41017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (here.val == 16) { 41117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner NEEDBITS(here.bits + 2); 41217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner DROPBITS(here.bits); 4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (state->have == 0) { 4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm->msg = (char *)"invalid bit length repeat"; 4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->mode = BAD; 4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = (unsigned)(state->lens[state->have - 1]); 4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project copy = 3 + BITS(2); 4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DROPBITS(2); 4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 42217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner else if (here.val == 17) { 42317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner NEEDBITS(here.bits + 3); 42417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner DROPBITS(here.bits); 4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = 0; 4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project copy = 3 + BITS(3); 4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DROPBITS(3); 4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 43017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner NEEDBITS(here.bits + 7); 43117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner DROPBITS(here.bits); 4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project len = 0; 4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project copy = 11 + BITS(7); 4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DROPBITS(7); 4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (state->have + copy > state->nlen + state->ndist) { 4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm->msg = (char *)"invalid bit length repeat"; 4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->mode = BAD; 4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project while (copy--) 4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->lens[state->have++] = (unsigned short)len; 4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* handle error breaks in while */ 4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (state->mode == BAD) break; 4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 44917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* check for end-of-block code (better have one) */ 45017b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (state->lens[256] == 0) { 45117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner strm->msg = (char *)"invalid code -- missing end-of-block"; 45217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->mode = BAD; 45317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner break; 45417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner } 45517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner 45617b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner /* build code tables -- note: do not change the lenbits or distbits 45717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner values here (9 and 6) without reading the comments in inftrees.h 45817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner concerning the ENOUGH constants, which depend on those values */ 4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->next = state->codes; 4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->lencode = (code const FAR *)(state->next); 4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->lenbits = 9; 4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), 4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &(state->lenbits), state->work); 4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret) { 4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm->msg = (char *)"invalid literal/lengths set"; 4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->mode = BAD; 4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->distcode = (code const FAR *)(state->next); 4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->distbits = 6; 4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, 4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project &(state->next), &(state->distbits), state->work); 4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (ret) { 4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm->msg = (char *)"invalid distances set"; 4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->mode = BAD; 4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Tracev((stderr, "inflate: codes ok\n")); 4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->mode = LEN; 4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case LEN: 4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* use inflate_fast() if we have enough input and output */ 4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (have >= 6 && left >= 258) { 4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project RESTORE(); 4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (state->whave < state->wsize) 4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->whave = state->wsize - left; 4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project inflate_fast(strm, state->wsize); 4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project LOAD(); 4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* get a literal, length, or end-of-block code */ 4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (;;) { 49417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner here = state->lencode[BITS(state->lenbits)]; 49517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if ((unsigned)(here.bits) <= bits) break; 4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PULLBYTE(); 4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 49817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (here.op && (here.op & 0xf0) == 0) { 49917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner last = here; 5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (;;) { 50117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner here = state->lencode[last.val + 5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (BITS(last.bits + last.op) >> last.bits)]; 50317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if ((unsigned)(last.bits + here.bits) <= bits) break; 5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PULLBYTE(); 5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DROPBITS(last.bits); 5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 50817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner DROPBITS(here.bits); 50917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->length = (unsigned)here.val; 5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* process literal */ 51217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (here.op == 0) { 51317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? 5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project "inflate: literal '%c'\n" : 51517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner "inflate: literal 0x%02x\n", here.val)); 5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ROOM(); 5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *put++ = (unsigned char)(state->length); 5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project left--; 5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->mode = LEN; 5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* process end of block */ 52417b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (here.op & 32) { 5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Tracevv((stderr, "inflate: end of block\n")); 5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->mode = TYPE; 5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* invalid code */ 53117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (here.op & 64) { 5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm->msg = (char *)"invalid literal/length code"; 5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->mode = BAD; 5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* length code -- get extra bits, if any */ 53817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->extra = (unsigned)(here.op) & 15; 5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (state->extra != 0) { 5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NEEDBITS(state->extra); 5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->length += BITS(state->extra); 5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DROPBITS(state->extra); 5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Tracevv((stderr, "inflate: length %u\n", state->length)); 5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* get distance code */ 5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (;;) { 54817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner here = state->distcode[BITS(state->distbits)]; 54917b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if ((unsigned)(here.bits) <= bits) break; 5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PULLBYTE(); 5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 55217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if ((here.op & 0xf0) == 0) { 55317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner last = here; 5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project for (;;) { 55517b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner here = state->distcode[last.val + 5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project (BITS(last.bits + last.op) >> last.bits)]; 55717b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if ((unsigned)(last.bits + here.bits) <= bits) break; 5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project PULLBYTE(); 5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DROPBITS(last.bits); 5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 56217b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner DROPBITS(here.bits); 56317b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner if (here.op & 64) { 5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm->msg = (char *)"invalid distance code"; 5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->mode = BAD; 5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 56817b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->offset = (unsigned)here.val; 5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* get distance extra bits, if any */ 57117b20e6f38ad2263e47a6884c4f68ce9773d8b29David 'Digit' Turner state->extra = (unsigned)(here.op) & 15; 5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (state->extra != 0) { 5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project NEEDBITS(state->extra); 5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->offset += BITS(state->extra); 5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project DROPBITS(state->extra); 5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (state->offset > state->wsize - (state->whave < state->wsize ? 5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project left : 0)) { 5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm->msg = (char *)"invalid distance too far back"; 5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->mode = BAD; 5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Tracevv((stderr, "inflate: distance %u\n", state->offset)); 5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* copy match from window to output */ 5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project do { 5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ROOM(); 5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project copy = state->wsize - state->offset; 5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (copy < left) { 5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project from = put + copy; 5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project copy = left - copy; 5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project else { 5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project from = put - state->offset; 5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project copy = left; 5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (copy > state->length) copy = state->length; 5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project state->length -= copy; 5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project left -= copy; 6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project do { 6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *put++ = *from++; 6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while (--copy); 6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } while (state->length != 0); 6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project break; 6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case DONE: 6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* inflate stream terminated properly -- write leftover output */ 6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = Z_STREAM_END; 6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (left < state->wsize) { 6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (out(out_desc, state->window, state->wsize - left)) 6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = Z_BUF_ERROR; 6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto inf_leave; 6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project case BAD: 6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = Z_DATA_ERROR; 6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto inf_leave; 6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project default: /* can't happen, but makes compilers happy */ 6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ret = Z_STREAM_ERROR; 6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project goto inf_leave; 6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project } 6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project /* Return unused input */ 6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project inf_leave: 6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm->next_in = next; 6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm->avail_in = have; 6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return ret; 6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project 6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT inflateBackEnd(strm) 6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectz_streamp strm; 6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{ 6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) 6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return Z_STREAM_ERROR; 6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project ZFREE(strm, strm->state); 6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project strm->state = Z_NULL; 6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project Tracev((stderr, "inflate: end\n")); 6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project return Z_OK; 6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} 641