19e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* inflate.c -- zlib decompression 209eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes * Copyright (C) 1995-2012 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/* 79e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * Change history: 89e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * 99e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * 1.2.beta0 24 Nov 2002 109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - First version -- complete rewrite of inflate to simplify code, avoid 119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * creation of window when not needed, minimize use of window when it is 129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * needed, make inffast.c even faster, implement gzip decoding, and to 139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * improve code readability and style over the previous zlib inflate code 149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * 159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * 1.2.beta1 25 Nov 2002 169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Use pointers for available input and output checking in inffast.c 179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Remove input and output counters in inffast.c 189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Remove unnecessary second byte pull from length extra in inffast.c 209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Unroll direct copy to three copies per loop in inffast.c 219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * 229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * 1.2.beta2 4 Dec 2002 239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Change external routine names to reduce potential conflicts 249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Correct filename to inffixed.h for fixed tables in inflate.c 259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Make hbuf[] unsigned char to match parameter type in inflate.c 269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) 279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * to avoid negation problem on Alphas (64 bit) in inflate.c 289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * 299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * 1.2.beta3 22 Dec 2002 309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Add comments on state->bits assertion in inffast.c 319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Add comments on op field in inftrees.h 329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Fix bug in reuse of allocated window after inflateReset() 339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Remove bit fields--back to byte structure for speed 349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths 359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Change post-increments to pre-increments in inflate_fast(), PPC biased? 369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Add compile time option, POSTINC, to use post-increments instead (Intel?) 379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Make MATCH copy in inflate() much faster for when inflate_fast() not used 389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Use local copies of stream next and avail values, as well as local bit 399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * buffer and bit count in inflate()--for speed when inflate_fast() not used 409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * 419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * 1.2.beta4 1 Jan 2003 429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings 439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Move a comment on output buffer sizes from inffast.c to inflate.c 449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Add comments in inffast.c to introduce the inflate_fast() routine 459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Rearrange window copies in inflate_fast() for speed and simplification 469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Unroll last copy for window match in inflate_fast() 479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Use local copies of window variables in inflate_fast() for speed 48381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes * - Pull out common wnext == 0 case for speed in inflate_fast() 499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Make op and len in inflate_fast() unsigned for consistency 509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Add FAR to lcode and dcode declarations in inflate_fast() 519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Simplified bad distance check in inflate_fast() 529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new 539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * source file infback.c to provide a call-back interface to inflate for 549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * programs like gzip and unzip -- uses window as output buffer to avoid 559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * window copying 569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * 579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * 1.2.beta5 1 Jan 2003 589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Improved inflateBack() interface to allow the caller to provide initial 599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * input in strm. 609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Fixed stored blocks bug in inflateBack() 619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * 629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * 1.2.beta6 4 Jan 2003 639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Added comments in inffast.c on effectiveness of POSTINC 649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Typecasting all around to reduce compiler warnings 659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Changed loops from while (1) or do {} while (1) to for (;;), again to 669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * make compilers happy 679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Changed type of window in inflateBackInit() to unsigned char * 689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * 699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * 1.2.beta7 27 Jan 2003 709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Changed many types to unsigned or unsigned short to avoid warnings 719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Added inflateCopy() function 729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * 739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * 1.2.0 9 Mar 2003 749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Changed inflateBack() interface to provide separate opaque descriptors 759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * for the in() and out() functions 769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Changed inflateBack() argument and in_func typedef to swap the length 779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * and buffer address return values for the input function 789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * - Check next_in and next_out for Z_NULL on entry to inflate() 799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * 809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. 819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "zutil.h" 849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "inftrees.h" 859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "inflate.h" 869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "inffast.h" 879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef MAKEFIXED 899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project# ifndef BUILDFIXED 909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project# define BUILDFIXED 919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project# endif 929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif 939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* function prototypes */ 959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal void fixedtables OF((struct inflate_state FAR *state)); 9604351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hugheslocal int updatewindow OF((z_streamp strm, const unsigned char FAR *end, 9704351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes unsigned copy)); 989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef BUILDFIXED 999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project void makefixed OF((void)); 1009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif 10104351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hugheslocal unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, 1029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned len)); 1039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 104ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesint ZEXPORT inflateResetKeep(strm) 1059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectz_streamp strm; 1069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 1079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project struct inflate_state FAR *state; 1089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 1109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state = (struct inflate_state FAR *)strm->state; 1119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->total_in = strm->total_out = state->total = 0; 1129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = Z_NULL; 113ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (state->wrap) /* to support ill-conceived Java test suite */ 114ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes strm->adler = state->wrap & 1; 1159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = HEAD; 1169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->last = 0; 1179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->havedict = 0; 1189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->dmax = 32768U; 1199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->head = Z_NULL; 1209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->hold = 0; 1219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->bits = 0; 1229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->lencode = state->distcode = state->next = state->codes; 123381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->sane = 1; 124381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->back = -1; 1259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: reset\n")); 1269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_OK; 1279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 1289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 129ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesint ZEXPORT inflateReset(strm) 130ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughesz_streamp strm; 131ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes{ 132ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes struct inflate_state FAR *state; 133ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes 134ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 135ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state = (struct inflate_state FAR *)strm->state; 136ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->wsize = 0; 137ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->whave = 0; 138ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state->wnext = 0; 139ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes return inflateResetKeep(strm); 140ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes} 141ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes 142381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT inflateReset2(strm, windowBits) 1439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectz_streamp strm; 144381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint windowBits; 1459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 146381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int wrap; 1479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project struct inflate_state FAR *state; 1489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 149381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* get the state */ 1509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 1519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state = (struct inflate_state FAR *)strm->state; 152381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 153381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* extract wrap request from windowBits parameter */ 154381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (windowBits < 0) { 155381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes wrap = 0; 156381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes windowBits = -windowBits; 157381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 158381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes else { 159381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes wrap = (windowBits >> 4) + 1; 160381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifdef GUNZIP 161381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (windowBits < 48) 162381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes windowBits &= 15; 163381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif 164381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 165381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 166381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* set number of window bits, free window if different */ 167381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (windowBits && (windowBits < 8 || windowBits > 15)) 168381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_STREAM_ERROR; 169381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { 170381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes ZFREE(strm, state->window); 171381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->window = Z_NULL; 172381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 173381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 174381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* update state and reset the rest of it */ 175381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->wrap = wrap; 176381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->wbits = (unsigned)windowBits; 177381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return inflateReset(strm); 1789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 1799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) 1819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectz_streamp strm; 1829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint windowBits; 1839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectconst char *version; 1849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint stream_size; 1859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 186381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes int ret; 1879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project struct inflate_state FAR *state; 1889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || 1909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project stream_size != (int)(sizeof(z_stream))) 1919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_VERSION_ERROR; 1929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (strm == Z_NULL) return Z_STREAM_ERROR; 1939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = Z_NULL; /* in case we return an error */ 1949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (strm->zalloc == (alloc_func)0) { 195ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#ifdef Z_SOLO 196ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes return Z_STREAM_ERROR; 197ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#else 1989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->zalloc = zcalloc; 1999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->opaque = (voidpf)0; 200ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#endif 2019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 202ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (strm->zfree == (free_func)0) 203ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#ifdef Z_SOLO 204ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes return Z_STREAM_ERROR; 205ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#else 206ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes strm->zfree = zcfree; 207ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes#endif 2089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state = (struct inflate_state FAR *) 2099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ZALLOC(strm, 1, sizeof(struct inflate_state)); 2109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state == Z_NULL) return Z_MEM_ERROR; 2119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: allocated\n")); 2129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->state = (struct internal_state FAR *)state; 213381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->window = Z_NULL; 214381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes ret = inflateReset2(strm, windowBits); 215381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (ret != Z_OK) { 2169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ZFREE(strm, state); 2179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->state = Z_NULL; 2189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 219381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return ret; 2209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 2219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint ZEXPORT inflateInit_(strm, version, stream_size) 2239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectz_streamp strm; 2249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectconst char *version; 2259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint stream_size; 2269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 2279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return inflateInit2_(strm, DEF_WBITS, version, stream_size); 2289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 2299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 230381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT inflatePrime(strm, bits, value) 231381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesz_streamp strm; 232381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint bits; 233381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint value; 234381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 235381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes struct inflate_state FAR *state; 236381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 237381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 238381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (struct inflate_state FAR *)strm->state; 239381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (bits < 0) { 240381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->hold = 0; 241381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->bits = 0; 242381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_OK; 243381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 244381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; 245381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes value &= (1L << bits) - 1; 246381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->hold += value << state->bits; 247381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->bits += bits; 248381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_OK; 249381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 250381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 2519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* 2529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Return state with length and distance decoding tables and index sizes set to 2539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fixed code decoding. Normally this returns fixed tables from inffixed.h. 2549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project If BUILDFIXED is defined, then instead this routine builds the tables the 2559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project first time it's called, and returns those tables the first time and 2569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project thereafter. This reduces the size of the code by about 2K bytes, in 2579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project exchange for a little execution time. However, BUILDFIXED should not be 2589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project used for threaded applications, since the rewriting of the tables and virgin 2599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project may not be thread-safe. 2609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 2619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal void fixedtables(state) 2629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectstruct inflate_state FAR *state; 2639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 2649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef BUILDFIXED 2659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project static int virgin = 1; 2669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project static code *lenfix, *distfix; 2679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project static code fixed[544]; 2689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* build fixed huffman tables if first call (may not be thread safe) */ 2709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (virgin) { 2719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned sym, bits; 2729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project static code *next; 2739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* literal/length table */ 2759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project sym = 0; 2769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (sym < 144) state->lens[sym++] = 8; 2779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (sym < 256) state->lens[sym++] = 9; 2789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (sym < 280) state->lens[sym++] = 7; 2799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (sym < 288) state->lens[sym++] = 8; 2809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project next = fixed; 2819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project lenfix = next; 2829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bits = 9; 2839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); 2849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* distance table */ 2869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project sym = 0; 2879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (sym < 32) state->lens[sym++] = 5; 2889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project distfix = next; 2899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bits = 5; 2909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); 2919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 2929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* do this just once */ 2939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project virgin = 0; 2949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 2959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#else /* !BUILDFIXED */ 2969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project# include "inffixed.h" 2979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* BUILDFIXED */ 2989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->lencode = lenfix; 2999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->lenbits = 9; 3009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->distcode = distfix; 3019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->distbits = 5; 3029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 3039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef MAKEFIXED 3059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <stdio.h> 3069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* 3089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also 3099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project defines BUILDFIXED, so the tables are built on the fly. makefixed() writes 3109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project those tables to stdout, which would be piped to inffixed.h. A small program 3119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project can simply call makefixed to do this: 3129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project void makefixed(void); 3149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int main(void) 3169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project { 3179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project makefixed(); 3189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return 0; 3199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Then that can be linked with zlib built with MAKEFIXED defined and run: 3229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project a.out > inffixed.h 3249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 3259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid makefixed() 3269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 3279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned low, size; 3289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project struct inflate_state state; 3299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fixedtables(&state); 3319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project puts(" /* inffixed.h -- table for decoding fixed codes"); 3329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project puts(" * Generated automatically by makefixed()."); 3339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project puts(" */"); 3349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project puts(""); 3359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project puts(" /* WARNING: this file should *not* be used by applications."); 3369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project puts(" It is part of the implementation of this library and is"); 3379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project puts(" subject to change. Applications should only use zlib.h."); 3389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project puts(" */"); 3399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project puts(""); 3409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project size = 1U << 9; 3419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project printf(" static const code lenfix[%u] = {", size); 3429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project low = 0; 3439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (;;) { 3449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if ((low % 7) == 0) printf("\n "); 345ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, 346ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes state.lencode[low].bits, state.lencode[low].val); 3479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (++low == size) break; 3489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project putchar(','); 3499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project puts("\n };"); 3519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project size = 1U << 5; 3529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project printf("\n static const code distfix[%u] = {", size); 3539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project low = 0; 3549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (;;) { 3559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if ((low % 6) == 0) printf("\n "); 3569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, 3579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state.distcode[low].val); 3589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (++low == size) break; 3599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project putchar(','); 3609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project puts("\n };"); 3629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 3639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif /* MAKEFIXED */ 3649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* 3669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Update the window with the last wsize (normally 32K) bytes written before 3679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project returning. If window does not exist yet, create it. This is only called 3689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project when a window is already in use, or when output has been written during this 3699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inflate call, but the end of the deflate stream has not been reached yet. 3709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project It is also called to create a window for dictionary data when a dictionary 3719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project is loaded. 3729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Providing output buffers larger than 32K to inflate() should provide a speed 3749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project advantage, since only the last 32K of output is copied to the sliding window 3759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project upon return from inflate(), and since all distances after the first 32K of 3769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project output will fall in the output data, making match copies simpler and faster. 3779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project The advantage may be dependent on the size of the processor's data caches. 3789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 37904351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hugheslocal int updatewindow(strm, end, copy) 3809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectz_streamp strm; 38104351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughesconst Bytef *end; 38204351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughesunsigned copy; 3839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 3849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project struct inflate_state FAR *state; 38504351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes unsigned dist; 3869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state = (struct inflate_state FAR *)strm->state; 3889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* if it hasn't been done already, allocate space for the window */ 3909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->window == Z_NULL) { 3919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->window = (unsigned char FAR *) 3929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ZALLOC(strm, 1U << state->wbits, 3939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project sizeof(unsigned char)); 3949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->window == Z_NULL) return 1; 3959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 3969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 3979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* if window not in use yet, initialize */ 3989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->wsize == 0) { 3999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->wsize = 1U << state->wbits; 400381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->wnext = 0; 4019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->whave = 0; 4029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* copy state->wsize or less output bytes into the circular window */ 4059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (copy >= state->wsize) { 40604351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes zmemcpy(state->window, end - state->wsize, state->wsize); 407381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->wnext = 0; 4089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->whave = state->wsize; 4099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else { 411381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes dist = state->wsize - state->wnext; 4129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (dist > copy) dist = copy; 41304351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes zmemcpy(state->window + state->wnext, end - copy, dist); 4149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copy -= dist; 4159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (copy) { 41604351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes zmemcpy(state->window, end - copy, copy); 417381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->wnext = copy; 4189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->whave = state->wsize; 4199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else { 421381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->wnext += dist; 422381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->wnext == state->wsize) state->wnext = 0; 4239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->whave < state->wsize) state->whave += dist; 4249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 4269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return 0; 4279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 4289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Macros for inflate(): */ 4309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* check function to use adler32() for zlib or crc32() for gzip */ 4329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef GUNZIP 4339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project# define UPDATE(check, buf, len) \ 4349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) 4359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#else 4369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project# define UPDATE(check, buf, len) adler32(check, buf, len) 4379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif 4389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* check macros for header crc */ 4409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef GUNZIP 4419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project# define CRC2(check, word) \ 4429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { \ 4439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project hbuf[0] = (unsigned char)(word); \ 4449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project hbuf[1] = (unsigned char)((word) >> 8); \ 4459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project check = crc32(check, hbuf, 2); \ 4469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (0) 4479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project# define CRC4(check, word) \ 4499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { \ 4509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project hbuf[0] = (unsigned char)(word); \ 4519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project hbuf[1] = (unsigned char)((word) >> 8); \ 4529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project hbuf[2] = (unsigned char)((word) >> 16); \ 4539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project hbuf[3] = (unsigned char)((word) >> 24); \ 4549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project check = crc32(check, hbuf, 4); \ 4559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (0) 4569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif 4579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Load registers with state in inflate() for speed */ 4599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define LOAD() \ 4609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { \ 4619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project put = strm->next_out; \ 4629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project left = strm->avail_out; \ 4639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project next = strm->next_in; \ 4649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project have = strm->avail_in; \ 4659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project hold = state->hold; \ 4669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bits = state->bits; \ 4679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (0) 4689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Restore state from registers in inflate() */ 4709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define RESTORE() \ 4719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { \ 4729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->next_out = put; \ 4739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->avail_out = left; \ 4749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->next_in = next; \ 4759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->avail_in = have; \ 4769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->hold = hold; \ 4779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->bits = bits; \ 4789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (0) 4799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Clear the input bit accumulator */ 4819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define INITBITS() \ 4829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { \ 4839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project hold = 0; \ 4849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bits = 0; \ 4859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (0) 4869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Get a byte of input into the bit accumulator, or return from inflate() 4889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if there is no input available. */ 4899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define PULLBYTE() \ 4909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { \ 4919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (have == 0) goto inf_leave; \ 4929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project have--; \ 4939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project hold += (unsigned long)(*next++) << bits; \ 4949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bits += 8; \ 4959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (0) 4969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 4979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Assure that there are at least n bits in the bit accumulator. If there is 4989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project not enough available input to do that, then return from inflate(). */ 4999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define NEEDBITS(n) \ 5009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { \ 5019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (bits < (unsigned)(n)) \ 5029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project PULLBYTE(); \ 5039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (0) 5049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Return the low n bits of the bit accumulator (n < 16) */ 5069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define BITS(n) \ 5079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ((unsigned)hold & ((1U << (n)) - 1)) 5089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Remove n bits from the bit accumulator */ 5109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define DROPBITS(n) \ 5119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { \ 5129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project hold >>= (n); \ 5139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bits -= (unsigned)(n); \ 5149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (0) 5159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* Remove zero to seven bits as needed to go to a byte boundary */ 5179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define BYTEBITS() \ 5189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { \ 5199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project hold >>= bits & 7; \ 5209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project bits -= bits & 7; \ 5219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (0) 5229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* 5249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inflate() uses a state machine to process as much input data and generate as 5259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project much output data as possible before returning. The state machine is 5269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project structured roughly as follows: 5279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (;;) switch (state) { 5299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ... 5309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case STATEn: 5319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (not enough input data or output space to make progress) 5329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return; 5339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ... make progress ... 5349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state = STATEm; 5359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 5369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ... 5379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 5389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project so when inflate() is called again, the same case is attempted again, and 5409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if the appropriate resources are provided, the machine proceeds to the 5419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project next state. The NEEDBITS() macro is usually the way the state evaluates 5429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project whether it can proceed or should return. NEEDBITS() does the return if 5439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project the requested bits are not available. The typical use of the BITS macros 5449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project is: 5459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(n); 5479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ... do something with BITS(n) ... 5489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(n); 5499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project where NEEDBITS(n) either returns from inflate() if there isn't enough 5519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project input left to load n bits into the accumulator, or it continues. BITS(n) 5529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project gives the low n bits in the accumulator. When done, DROPBITS(n) drops 5539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project the low n bits off the accumulator. INITBITS() clears the accumulator 5549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project and sets the number of available bits to zero. BYTEBITS() discards just 5559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project enough bits to put the accumulator on a byte boundary. After BYTEBITS() 5569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. 5579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return 5599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if there is no input available. The decoding of variable length codes uses 5609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project PULLBYTE() directly in order to pull just enough bytes to decode the next 5619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project code, and no more. 5629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Some states loop until they get enough input, making sure that enough 5649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state information is maintained to continue the loop where it left off 5659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if NEEDBITS() returns in the loop. For example, want, need, and keep 5669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project would all have to actually be part of the saved state in case NEEDBITS() 5679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project returns: 5689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case STATEw: 5709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (want < need) { 5719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(n); 5729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project keep[want++] = BITS(n); 5739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(n); 5749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 5759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state = STATEx; 5769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case STATEx: 5779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project As shown above, if the next state is also the next case, then the break 5799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project is omitted. 5809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project A state may also return if there is not enough output space available to 5829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project complete that state. Those states are copying stored data, writing a 5839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project literal byte, and copying a matching string. 5849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project When returning, a "goto inf_leave" is used to update the total counters, 5869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project update the check value, and determine whether any progress has been made 5879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project during that inflate() call in order to return the proper return code. 5889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Progress is defined as a change in either strm->avail_in or strm->avail_out. 5899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project When there is a window, goto inf_leave will update the window with the last 5909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project output written. If a goto inf_leave occurs in the middle of decompression 5919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project and there is no window currently, goto inf_leave will create one and copy 5929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project output to the window for the next call of inflate(). 5939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 5949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project In this implementation, the flush parameter of inflate() only affects the 5959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return code (per zlib.h). inflate() always writes as much as possible to 5969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->next_out, given the space available and the provided input--the effect 5979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers 5989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project the allocation of and copying into a sliding window until necessary, which 5999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project provides the effect documented in zlib.h for Z_FINISH when the entire input 6009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project stream available. So the only thing the flush parameter actually does is: 6019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it 6029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project will return Z_BUF_ERROR if it has not reached the end of the stream. 6039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 6049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 6059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint ZEXPORT inflate(strm, flush) 6069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectz_streamp strm; 6079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint flush; 6089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 6099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project struct inflate_state FAR *state; 61004351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes z_const unsigned char FAR *next; /* next input */ 6119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned char FAR *put; /* next output */ 6129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned have, left; /* available input and output */ 6139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned long hold; /* bit buffer */ 6149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned bits; /* bits in bit buffer */ 6159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned in, out; /* save starting available input and output */ 6169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned copy; /* number of stored or match bytes to copy */ 6179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned char FAR *from; /* where to copy match bytes from */ 618381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes code here; /* current decoding table entry */ 6199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project code last; /* parent table entry */ 6209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned len; /* length to copy for repeats, bits to drop */ 6219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project int ret; /* return code */ 6229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef GUNZIP 6239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ 6249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif 6259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project static const unsigned short order[19] = /* permutation of code lengths */ 6269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; 6279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 6289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || 6299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project (strm->next_in == Z_NULL && strm->avail_in != 0)) 6309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_STREAM_ERROR; 6319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 6329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state = (struct inflate_state FAR *)strm->state; 6339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ 6349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project LOAD(); 6359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in = have; 6369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project out = left; 6379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = Z_OK; 6389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (;;) 6399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project switch (state->mode) { 6409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case HEAD: 6419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->wrap == 0) { 6429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = TYPEDO; 6439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 6449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 6459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(16); 6469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef GUNZIP 6479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ 6489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->check = crc32(0L, Z_NULL, 0); 6499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project CRC2(state->check, hold); 6509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project INITBITS(); 6519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = FLAGS; 6529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 6539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 6549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->flags = 0; /* expect zlib header */ 6559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->head != Z_NULL) 6569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->head->done = -1; 6579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (!(state->wrap & 1) || /* check if zlib header allowed */ 6589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#else 6599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if ( 6609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif 6619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ((BITS(8) << 8) + (hold >> 8)) % 31) { 6629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"incorrect header check"; 6639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = BAD; 6649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 6659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 6669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (BITS(4) != Z_DEFLATED) { 6679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"unknown compression method"; 6689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = BAD; 6699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 6709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 6719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(4); 6729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len = BITS(4) + 8; 673381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->wbits == 0) 674381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->wbits = len; 675381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes else if (len > state->wbits) { 6769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"invalid window size"; 6779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = BAD; 6789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 6799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 6809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->dmax = 1U << len; 6819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: zlib header ok\n")); 6829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->adler = state->check = adler32(0L, Z_NULL, 0); 6839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = hold & 0x200 ? DICTID : TYPE; 6849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project INITBITS(); 6859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 6869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef GUNZIP 6879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case FLAGS: 6889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(16); 6899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->flags = (int)(hold); 6909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if ((state->flags & 0xff) != Z_DEFLATED) { 6919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"unknown compression method"; 6929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = BAD; 6939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 6949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 6959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->flags & 0xe000) { 6969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"unknown header flags set"; 6979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = BAD; 6989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 6999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 7009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->head != Z_NULL) 7019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->head->text = (int)((hold >> 8) & 1); 7029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->flags & 0x0200) CRC2(state->check, hold); 7039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project INITBITS(); 7049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = TIME; 7059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case TIME: 7069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(32); 7079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->head != Z_NULL) 7089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->head->time = hold; 7099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->flags & 0x0200) CRC4(state->check, hold); 7109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project INITBITS(); 7119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = OS; 7129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case OS: 7139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(16); 7149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->head != Z_NULL) { 7159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->head->xflags = (int)(hold & 0xff); 7169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->head->os = (int)(hold >> 8); 7179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 7189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->flags & 0x0200) CRC2(state->check, hold); 7199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project INITBITS(); 7209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = EXLEN; 7219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case EXLEN: 7229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->flags & 0x0400) { 7239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(16); 7249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->length = (unsigned)(hold); 7259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->head != Z_NULL) 7269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->head->extra_len = (unsigned)hold; 7279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->flags & 0x0200) CRC2(state->check, hold); 7289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project INITBITS(); 7299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 7309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else if (state->head != Z_NULL) 7319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->head->extra = Z_NULL; 7329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = EXTRA; 7339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case EXTRA: 7349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->flags & 0x0400) { 7359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copy = state->length; 7369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (copy > have) copy = have; 7379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (copy) { 7389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->head != Z_NULL && 7399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->head->extra != Z_NULL) { 7409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len = state->head->extra_len - state->length; 7419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project zmemcpy(state->head->extra + len, next, 7429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len + copy > state->head->extra_max ? 7439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->head->extra_max - len : copy); 7449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 7459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->flags & 0x0200) 7469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->check = crc32(state->check, next, copy); 7479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project have -= copy; 7489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project next += copy; 7499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->length -= copy; 7509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 7519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->length) goto inf_leave; 7529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 7539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->length = 0; 7549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = NAME; 7559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case NAME: 7569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->flags & 0x0800) { 7579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (have == 0) goto inf_leave; 7589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copy = 0; 7599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { 7609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len = (unsigned)(next[copy++]); 7619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->head != Z_NULL && 7629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->head->name != Z_NULL && 7639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->length < state->head->name_max) 7649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->head->name[state->length++] = len; 7659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (len && copy < have); 7669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->flags & 0x0200) 7679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->check = crc32(state->check, next, copy); 7689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project have -= copy; 7699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project next += copy; 7709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (len) goto inf_leave; 7719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 7729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else if (state->head != Z_NULL) 7739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->head->name = Z_NULL; 7749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->length = 0; 7759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = COMMENT; 7769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case COMMENT: 7779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->flags & 0x1000) { 7789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (have == 0) goto inf_leave; 7799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copy = 0; 7809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { 7819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len = (unsigned)(next[copy++]); 7829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->head != Z_NULL && 7839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->head->comment != Z_NULL && 7849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->length < state->head->comm_max) 7859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->head->comment[state->length++] = len; 7869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (len && copy < have); 7879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->flags & 0x0200) 7889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->check = crc32(state->check, next, copy); 7899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project have -= copy; 7909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project next += copy; 7919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (len) goto inf_leave; 7929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 7939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else if (state->head != Z_NULL) 7949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->head->comment = Z_NULL; 7959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = HCRC; 7969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case HCRC: 7979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->flags & 0x0200) { 7989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(16); 7999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (hold != (state->check & 0xffff)) { 8009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"header crc mismatch"; 8019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = BAD; 8029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 8039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 8049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project INITBITS(); 8059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 8069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->head != Z_NULL) { 8079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->head->hcrc = (int)((state->flags >> 9) & 1); 8089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->head->done = 1; 8099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 8109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->adler = state->check = crc32(0L, Z_NULL, 0); 8119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = TYPE; 8129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 8139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif 8149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case DICTID: 8159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(32); 81609eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes strm->adler = state->check = ZSWAP32(hold); 8179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project INITBITS(); 8189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = DICT; 8199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case DICT: 8209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->havedict == 0) { 8219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project RESTORE(); 8229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_NEED_DICT; 8239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 8249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->adler = state->check = adler32(0L, Z_NULL, 0); 8259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = TYPE; 8269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case TYPE: 827381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; 8289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case TYPEDO: 8299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->last) { 8309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project BYTEBITS(); 8319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = CHECK; 8329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 8339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 8349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(3); 8359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->last = BITS(1); 8369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(1); 8379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project switch (BITS(2)) { 8389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case 0: /* stored block */ 8399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: stored block%s\n", 8409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->last ? " (last)" : "")); 8419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = STORED; 8429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 8439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case 1: /* fixed block */ 8449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project fixedtables(state); 8459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: fixed codes block%s\n", 8469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->last ? " (last)" : "")); 847381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->mode = LEN_; /* decode codes */ 848381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (flush == Z_TREES) { 849381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes DROPBITS(2); 850381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes goto inf_leave; 851381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 8529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 8539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case 2: /* dynamic block */ 8549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: dynamic codes block%s\n", 8559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->last ? " (last)" : "")); 8569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = TABLE; 8579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 8589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case 3: 8599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"invalid block type"; 8609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = BAD; 8619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 8629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(2); 8639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 8649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case STORED: 8659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project BYTEBITS(); /* go to byte boundary */ 8669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(32); 8679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { 8689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"invalid stored block lengths"; 8699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = BAD; 8709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 8719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 8729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->length = (unsigned)hold & 0xffff; 8739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: stored length %u\n", 8749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->length)); 8759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project INITBITS(); 876381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->mode = COPY_; 877381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (flush == Z_TREES) goto inf_leave; 878381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes case COPY_: 8799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = COPY; 8809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case COPY: 8819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copy = state->length; 8829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (copy) { 8839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (copy > have) copy = have; 8849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (copy > left) copy = left; 8859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (copy == 0) goto inf_leave; 8869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project zmemcpy(put, next, copy); 8879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project have -= copy; 8889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project next += copy; 8899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project left -= copy; 8909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project put += copy; 8919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->length -= copy; 8929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 8939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 8949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: stored end\n")); 8959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = TYPE; 8969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 8979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case TABLE: 8989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(14); 8999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->nlen = BITS(5) + 257; 9009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(5); 9019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->ndist = BITS(5) + 1; 9029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(5); 9039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->ncode = BITS(4) + 4; 9049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(4); 9059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifndef PKZIP_BUG_WORKAROUND 9069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->nlen > 286 || state->ndist > 30) { 9079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"too many length or distance symbols"; 9089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = BAD; 9099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 9109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 9119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif 9129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: table sizes ok\n")); 9139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->have = 0; 9149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = LENLENS; 9159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case LENLENS: 9169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (state->have < state->ncode) { 9179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(3); 9189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->lens[order[state->have++]] = (unsigned short)BITS(3); 9199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(3); 9209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 9219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (state->have < 19) 9229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->lens[order[state->have++]] = 0; 9239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->next = state->codes; 92404351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes state->lencode = (const code FAR *)(state->next); 9259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->lenbits = 7; 9269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = inflate_table(CODES, state->lens, 19, &(state->next), 9279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project &(state->lenbits), state->work); 9289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (ret) { 9299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"invalid code lengths set"; 9309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = BAD; 9319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 9329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 9339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: code lengths ok\n")); 9349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->have = 0; 9359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = CODELENS; 9369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case CODELENS: 9379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (state->have < state->nlen + state->ndist) { 9389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (;;) { 939381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes here = state->lencode[BITS(state->lenbits)]; 940381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if ((unsigned)(here.bits) <= bits) break; 9419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project PULLBYTE(); 9429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 943381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (here.val < 16) { 944381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes DROPBITS(here.bits); 945381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->lens[state->have++] = here.val; 9469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 9479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else { 948381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (here.val == 16) { 949381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes NEEDBITS(here.bits + 2); 950381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes DROPBITS(here.bits); 9519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->have == 0) { 9529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"invalid bit length repeat"; 9539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = BAD; 9549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 9559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 9569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len = state->lens[state->have - 1]; 9579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copy = 3 + BITS(2); 9589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(2); 9599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 960381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes else if (here.val == 17) { 961381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes NEEDBITS(here.bits + 3); 962381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes DROPBITS(here.bits); 9639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len = 0; 9649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copy = 3 + BITS(3); 9659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(3); 9669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 9679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else { 968381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes NEEDBITS(here.bits + 7); 969381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes DROPBITS(here.bits); 9709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len = 0; 9719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copy = 11 + BITS(7); 9729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(7); 9739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 9749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->have + copy > state->nlen + state->ndist) { 9759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"invalid bit length repeat"; 9769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = BAD; 9779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 9789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 9799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (copy--) 9809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->lens[state->have++] = (unsigned short)len; 9819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 9829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 9839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 9849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* handle error breaks in while */ 9859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->mode == BAD) break; 9869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 987381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* check for end-of-block code (better have one) */ 988381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->lens[256] == 0) { 989381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->msg = (char *)"invalid code -- missing end-of-block"; 990381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->mode = BAD; 991381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes break; 992381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 993381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 994381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes /* build code tables -- note: do not change the lenbits or distbits 995381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes values here (9 and 6) without reading the comments in inftrees.h 996381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes concerning the ENOUGH constants, which depend on those values */ 9979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->next = state->codes; 99804351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes state->lencode = (const code FAR *)(state->next); 9999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->lenbits = 9; 10009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), 10019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project &(state->lenbits), state->work); 10029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (ret) { 10039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"invalid literal/lengths set"; 10049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = BAD; 10059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 10069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 100704351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes state->distcode = (const code FAR *)(state->next); 10089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->distbits = 6; 10099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, 10109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project &(state->next), &(state->distbits), state->work); 10119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (ret) { 10129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"invalid distances set"; 10139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = BAD; 10149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 10159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 10169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: codes ok\n")); 1017381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->mode = LEN_; 1018381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (flush == Z_TREES) goto inf_leave; 1019381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes case LEN_: 10209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = LEN; 10219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case LEN: 10229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (have >= 6 && left >= 258) { 10239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project RESTORE(); 10249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inflate_fast(strm, out); 10259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project LOAD(); 1026381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->mode == TYPE) 1027381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->back = -1; 10289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 10299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1030381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->back = 0; 10319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (;;) { 1032381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes here = state->lencode[BITS(state->lenbits)]; 1033381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if ((unsigned)(here.bits) <= bits) break; 10349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project PULLBYTE(); 10359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1036381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (here.op && (here.op & 0xf0) == 0) { 1037381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes last = here; 10389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (;;) { 1039381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes here = state->lencode[last.val + 10409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project (BITS(last.bits + last.op) >> last.bits)]; 1041381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if ((unsigned)(last.bits + here.bits) <= bits) break; 10429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project PULLBYTE(); 10439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 10449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(last.bits); 1045381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->back += last.bits; 10469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1047381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes DROPBITS(here.bits); 1048381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->back += here.bits; 1049381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->length = (unsigned)here.val; 1050381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if ((int)(here.op) == 0) { 1051381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? 10529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project "inflate: literal '%c'\n" : 1053381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes "inflate: literal 0x%02x\n", here.val)); 10549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = LIT; 10559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 10569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1057381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (here.op & 32) { 10589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracevv((stderr, "inflate: end of block\n")); 1059381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->back = -1; 10609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = TYPE; 10619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 10629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1063381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (here.op & 64) { 10649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"invalid literal/length code"; 10659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = BAD; 10669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 10679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1068381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->extra = (unsigned)(here.op) & 15; 10699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = LENEXT; 10709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case LENEXT: 10719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->extra) { 10729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(state->extra); 10739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->length += BITS(state->extra); 10749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(state->extra); 1075381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->back += state->extra; 10769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 10779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracevv((stderr, "inflate: length %u\n", state->length)); 1078381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->was = state->length; 10799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = DIST; 10809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case DIST: 10819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (;;) { 1082381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes here = state->distcode[BITS(state->distbits)]; 1083381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if ((unsigned)(here.bits) <= bits) break; 10849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project PULLBYTE(); 10859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1086381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if ((here.op & 0xf0) == 0) { 1087381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes last = here; 10889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project for (;;) { 1089381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes here = state->distcode[last.val + 10909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project (BITS(last.bits + last.op) >> last.bits)]; 1091381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if ((unsigned)(last.bits + here.bits) <= bits) break; 10929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project PULLBYTE(); 10939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 10949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(last.bits); 1095381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->back += last.bits; 10969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1097381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes DROPBITS(here.bits); 1098381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->back += here.bits; 1099381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (here.op & 64) { 11009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"invalid distance code"; 11019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = BAD; 11029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 11039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 1104381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->offset = (unsigned)here.val; 1105381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->extra = (unsigned)(here.op) & 15; 11069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = DISTEXT; 11079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case DISTEXT: 11089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->extra) { 11099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(state->extra); 11109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->offset += BITS(state->extra); 11119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project DROPBITS(state->extra); 1112381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->back += state->extra; 11139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 11149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef INFLATE_STRICT 11159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->offset > state->dmax) { 11169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"invalid distance too far back"; 11179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = BAD; 11189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 11199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 11209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif 11219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracevv((stderr, "inflate: distance %u\n", state->offset)); 11229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = MATCH; 11239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case MATCH: 11249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (left == 0) goto inf_leave; 11259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copy = out - left; 11269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->offset > copy) { /* copy from window */ 11279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copy = state->offset - copy; 1128381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (copy > state->whave) { 1129381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->sane) { 1130381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes strm->msg = (char *)"invalid distance too far back"; 1131381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->mode = BAD; 1132381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes break; 1133381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 1134381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR 1135381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes Trace((stderr, "inflate.c too far\n")); 1136381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes copy -= state->whave; 1137381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (copy > state->length) copy = state->length; 1138381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (copy > left) copy = left; 1139381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes left -= copy; 1140381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->length -= copy; 1141381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes do { 1142381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes *put++ = 0; 1143381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } while (--copy); 1144381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (state->length == 0) state->mode = LEN; 1145381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes break; 1146381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif 1147381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes } 1148381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (copy > state->wnext) { 1149381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes copy -= state->wnext; 11509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project from = state->window + (state->wsize - copy); 11519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 11529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else 1153381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes from = state->window + (state->wnext - copy); 11549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (copy > state->length) copy = state->length; 11559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 11569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else { /* copy from output */ 11579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project from = put - state->offset; 11589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copy = state->length; 11599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 11609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (copy > left) copy = left; 11619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project left -= copy; 11629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->length -= copy; 11639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project do { 11649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *put++ = *from++; 11659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } while (--copy); 11669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->length == 0) state->mode = LEN; 11679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 11689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case LIT: 11699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (left == 0) goto inf_leave; 11709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *put++ = (unsigned char)(state->length); 11719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project left--; 11729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = LEN; 11739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 11749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case CHECK: 11759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->wrap) { 11769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(32); 11779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project out -= left; 11789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->total_out += out; 11799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->total += out; 11809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (out) 11819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->adler = state->check = 11829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project UPDATE(state->check, put - out, out); 11839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project out = left; 11849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (( 11859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef GUNZIP 11869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->flags ? hold : 11879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif 118809eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes ZSWAP32(hold)) != state->check) { 11899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"incorrect data check"; 11909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = BAD; 11919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 11929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 11939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project INITBITS(); 11949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: check matches trailer\n")); 11959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 11969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#ifdef GUNZIP 11979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = LENGTH; 11989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case LENGTH: 11999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->wrap && state->flags) { 12009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project NEEDBITS(32); 12019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (hold != (state->total & 0xffffffffUL)) { 12029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->msg = (char *)"incorrect length check"; 12039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = BAD; 12049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project break; 12059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 12069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project INITBITS(); 12079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: length matches trailer\n")); 12089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 12099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#endif 12109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = DONE; 12119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case DONE: 12129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = Z_STREAM_END; 12139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project goto inf_leave; 12149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case BAD: 12159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = Z_DATA_ERROR; 12169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project goto inf_leave; 12179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case MEM: 12189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_MEM_ERROR; 12199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project case SYNC: 12209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project default: 12219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_STREAM_ERROR; 12229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 12239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 12249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* 12259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Return from inflate(), updating the total counts and the check value. 12269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project If there was no progress during the inflate() call, return a buffer 12279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project error. Call updatewindow() to create and/or update the window state. 12289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Note: a memory error from inflate() is non-recoverable. 12299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 12309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inf_leave: 12319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project RESTORE(); 1232ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (state->wsize || (out != strm->avail_out && state->mode < BAD && 1233ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes (state->mode < CHECK || flush != Z_FINISH))) 123404351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { 12359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = MEM; 12369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_MEM_ERROR; 12379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 12389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in -= strm->avail_in; 12399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project out -= strm->avail_out; 12409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->total_in += in; 12419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->total_out += out; 12429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->total += out; 12439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->wrap && out) 12449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->adler = state->check = 12459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project UPDATE(state->check, strm->next_out - out, out); 12469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->data_type = state->bits + (state->last ? 64 : 0) + 1247381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes (state->mode == TYPE ? 128 : 0) + 1248381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); 12499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) 12509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ret = Z_BUF_ERROR; 12519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return ret; 12529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 12539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 12549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint ZEXPORT inflateEnd(strm) 12559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectz_streamp strm; 12569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 12579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project struct inflate_state FAR *state; 12589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) 12599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_STREAM_ERROR; 12609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state = (struct inflate_state FAR *)strm->state; 12619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->window != Z_NULL) ZFREE(strm, state->window); 12629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ZFREE(strm, strm->state); 12639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->state = Z_NULL; 12649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: end\n")); 12659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_OK; 12669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 12679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 126804351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughesint ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) 126904351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughesz_streamp strm; 127004351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott HughesBytef *dictionary; 127104351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott HughesuInt *dictLength; 127204351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes{ 127304351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes struct inflate_state FAR *state; 127404351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes 127504351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes /* check state */ 127604351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 127704351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes state = (struct inflate_state FAR *)strm->state; 127804351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes 127904351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes /* copy dictionary */ 128004351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes if (state->whave && dictionary != Z_NULL) { 128104351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes zmemcpy(dictionary, state->window + state->wnext, 128204351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes state->whave - state->wnext); 128304351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes zmemcpy(dictionary + state->whave - state->wnext, 128404351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes state->window, state->wnext); 128504351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes } 128604351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes if (dictLength != Z_NULL) 128704351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes *dictLength = state->whave; 128804351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes return Z_OK; 128904351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes} 129004351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes 12919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) 12929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectz_streamp strm; 12939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectconst Bytef *dictionary; 12949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source ProjectuInt dictLength; 12959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 12969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project struct inflate_state FAR *state; 129709eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes unsigned long dictid; 1298ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes int ret; 12999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 13009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* check state */ 13019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 13029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state = (struct inflate_state FAR *)strm->state; 13039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->wrap != 0 && state->mode != DICT) 13049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_STREAM_ERROR; 13059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 130609eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes /* check for correct dictionary identifier */ 13079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->mode == DICT) { 130809eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes dictid = adler32(0L, Z_NULL, 0); 130909eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes dictid = adler32(dictid, dictionary, dictLength); 131009eb358bbbb9aad3fe48dd3368c8a7a481cbda1cElliott Hughes if (dictid != state->check) 13119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_DATA_ERROR; 13129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 13139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 1314ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes /* copy dictionary to window using updatewindow(), which will amend the 1315ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes existing dictionary if appropriate */ 131604351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughes ret = updatewindow(strm, dictionary + dictLength, dictLength); 1317ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes if (ret) { 13189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = MEM; 13199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_MEM_ERROR; 13209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 13219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->havedict = 1; 13229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Tracev((stderr, "inflate: dictionary set\n")); 13239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_OK; 13249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 13259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 13269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint ZEXPORT inflateGetHeader(strm, head) 13279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectz_streamp strm; 13289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgz_headerp head; 13299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 13309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project struct inflate_state FAR *state; 13319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 13329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* check state */ 13339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 13349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state = (struct inflate_state FAR *)strm->state; 13359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; 13369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 13379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* save header structure */ 13389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->head = head; 13399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project head->done = 0; 13409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_OK; 13419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 13429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 13439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* 13449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found 13459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project or when out of input. When called, *have is the number of pattern bytes 13469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project found in order so far, in 0..3. On return *have is updated to the new 13479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state. If on return *have equals four, then the pattern was found and the 13489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return value is how many bytes were read including the last byte of the 13499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project pattern. If *have is less than four, then the pattern has not been found 13509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project yet and the return value is len. In the latter case, syncsearch() can be 13519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project called again with more data and the *have state. *have is initialized to 13529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project zero for the first call. 13539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 13549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectlocal unsigned syncsearch(have, buf, len) 13559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectunsigned FAR *have; 135604351a92ecc8429c999acbfc5dfe5aa8bee1d19dElliott Hughesconst unsigned char FAR *buf; 13579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectunsigned len; 13589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 13599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned got; 13609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned next; 13619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 13629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project got = *have; 13639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project next = 0; 13649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (next < len && got < 4) { 13659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) 13669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project got++; 13679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else if (buf[next]) 13689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project got = 0; 13699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project else 13709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project got = 4 - got; 13719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project next++; 13729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 13739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *have = got; 13749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return next; 13759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 13769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 13779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint ZEXPORT inflateSync(strm) 13789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectz_streamp strm; 13799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 13809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned len; /* number of bytes to look at or looked at */ 13819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned long in, out; /* temporary to save total_in and total_out */ 13829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned char buf[4]; /* to restore bit buffer to byte string */ 13839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project struct inflate_state FAR *state; 13849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 13859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* check parameters */ 13869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 13879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state = (struct inflate_state FAR *)strm->state; 13889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; 13899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 13909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* if first time, start search in bit buffer */ 13919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->mode != SYNC) { 13929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = SYNC; 13939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->hold <<= state->bits & 7; 13949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->bits -= state->bits & 7; 13959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len = 0; 13969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project while (state->bits >= 8) { 13979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project buf[len++] = (unsigned char)(state->hold); 13989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->hold >>= 8; 13999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->bits -= 8; 14009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 14019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->have = 0; 14029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project syncsearch(&(state->have), buf, len); 14039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 14049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 14059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* search available input */ 14069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project len = syncsearch(&(state->have), strm->next_in, strm->avail_in); 14079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->avail_in -= len; 14089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->next_in += len; 14099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->total_in += len; 14109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 14119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* return no joy or set up to restart inflate() on a new block */ 14129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->have != 4) return Z_DATA_ERROR; 14139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project in = strm->total_in; out = strm->total_out; 14149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inflateReset(strm); 14159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project strm->total_in = in; strm->total_out = out; 14169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->mode = TYPE; 14179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_OK; 14189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 14199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 14209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* 14219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Returns true if inflate is currently at the end of a block generated by 14229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP 14239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project implementation to provide an additional safety check. PPP uses 14249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored 14259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project block. When decompressing, PPP checks that at the end of input packet, 14269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project inflate is waiting for these length bytes. 14279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */ 14289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint ZEXPORT inflateSyncPoint(strm) 14299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectz_streamp strm; 14309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 14319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project struct inflate_state FAR *state; 14329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 14339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 14349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state = (struct inflate_state FAR *)strm->state; 14359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return state->mode == STORED && state->bits == 0; 14369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 14379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 14389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint ZEXPORT inflateCopy(dest, source) 14399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectz_streamp dest; 14409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectz_streamp source; 14419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ 14429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project struct inflate_state FAR *state; 14439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project struct inflate_state FAR *copy; 14449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned char FAR *window; 14459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project unsigned wsize; 14469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 14479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* check input */ 14489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || 14499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) 14509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_STREAM_ERROR; 14519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state = (struct inflate_state FAR *)source->state; 14529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 14539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* allocate space */ 14549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copy = (struct inflate_state FAR *) 14559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ZALLOC(source, 1, sizeof(struct inflate_state)); 14569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (copy == Z_NULL) return Z_MEM_ERROR; 14579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project window = Z_NULL; 14589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->window != Z_NULL) { 14599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project window = (unsigned char FAR *) 14609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); 14619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (window == Z_NULL) { 14629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project ZFREE(source, copy); 14639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_MEM_ERROR; 14649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 14659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 14669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project 14679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project /* copy state */ 1468ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); 1469ee9e11d0d4e3361533860bf04896abb86a291bfbElliott Hughes zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); 14709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (state->lencode >= state->codes && 14719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project state->lencode <= state->codes + ENOUGH - 1) { 14729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copy->lencode = copy->codes + (state->lencode - state->codes); 14739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copy->distcode = copy->codes + (state->distcode - state->codes); 14749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 14759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copy->next = copy->codes + (state->next - state->codes); 14769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project if (window != Z_NULL) { 14779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project wsize = 1U << state->wbits; 14789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project zmemcpy(window, state->window, wsize); 14799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project } 14809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project copy->window = window; 14819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project dest->state = (struct internal_state FAR *)copy; 14829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project return Z_OK; 14839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project} 1484381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 1485381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint ZEXPORT inflateUndermine(strm, subvert) 1486381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesz_streamp strm; 1487381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesint subvert; 1488381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 1489381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes struct inflate_state FAR *state; 1490381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 1491381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 1492381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (struct inflate_state FAR *)strm->state; 1493381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->sane = !subvert; 1494381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR 1495381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_OK; 1496381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#else 1497381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state->sane = 1; 1498381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return Z_DATA_ERROR; 1499381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes#endif 1500381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 1501381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 1502381716e9396b55b1adb8235b020c37344f60ab07Elliott Hugheslong ZEXPORT inflateMark(strm) 1503381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughesz_streamp strm; 1504381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes{ 1505381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes struct inflate_state FAR *state; 1506381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes 1507381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; 1508381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes state = (struct inflate_state FAR *)strm->state; 1509381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes return ((long)(state->back) << 16) + 1510381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes (state->mode == COPY ? state->length : 1511381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes (state->mode == MATCH ? state->was - state->length : 0)); 1512381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes} 1513