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