18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* inflate.c -- zlib decompression
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (C) 1995-2005 Mark Adler
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * For conditions of distribution and use, see copyright notice in zlib.h
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Change history:
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 1.2.beta0    24 Nov 2002
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - First version -- complete rewrite of inflate to simplify code, avoid
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *   creation of window when not needed, minimize use of window when it is
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *   needed, make inffast.c even faster, implement gzip decoding, and to
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *   improve code readability and style over the previous zlib inflate code
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 1.2.beta1    25 Nov 2002
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Use pointers for available input and output checking in inffast.c
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Remove input and output counters in inffast.c
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Remove unnecessary second byte pull from length extra in inffast.c
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Unroll direct copy to three copies per loop in inffast.c
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 1.2.beta2    4 Dec 2002
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Change external routine names to reduce potential conflicts
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Correct filename to inffixed.h for fixed tables in inflate.c
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Make hbuf[] unsigned char to match parameter type in inflate.c
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *   to avoid negation problem on Alphas (64 bit) in inflate.c
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 1.2.beta3    22 Dec 2002
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Add comments on state->bits assertion in inffast.c
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Add comments on op field in inftrees.h
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Fix bug in reuse of allocated window after inflateReset()
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Remove bit fields--back to byte structure for speed
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Use local copies of stream next and avail values, as well as local bit
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *   buffer and bit count in inflate()--for speed when inflate_fast() not used
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 1.2.beta4    1 Jan 2003
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Move a comment on output buffer sizes from inffast.c to inflate.c
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Add comments in inffast.c to introduce the inflate_fast() routine
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Rearrange window copies in inflate_fast() for speed and simplification
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Unroll last copy for window match in inflate_fast()
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Use local copies of window variables in inflate_fast() for speed
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Pull out common write == 0 case for speed in inflate_fast()
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Make op and len in inflate_fast() unsigned for consistency
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Add FAR to lcode and dcode declarations in inflate_fast()
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Simplified bad distance check in inflate_fast()
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *   source file infback.c to provide a call-back interface to inflate for
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *   programs like gzip and unzip -- uses window as output buffer to avoid
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *   window copying
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 1.2.beta5    1 Jan 2003
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Improved inflateBack() interface to allow the caller to provide initial
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *   input in strm.
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Fixed stored blocks bug in inflateBack()
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 1.2.beta6    4 Jan 2003
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Added comments in inffast.c on effectiveness of POSTINC
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Typecasting all around to reduce compiler warnings
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Changed loops from while (1) or do {} while (1) to for (;;), again to
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *   make compilers happy
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Changed type of window in inflateBackInit() to unsigned char *
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 1.2.beta7    27 Jan 2003
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Changed many types to unsigned or unsigned short to avoid warnings
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Added inflateCopy() function
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * 1.2.0        9 Mar 2003
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Changed inflateBack() interface to provide separate opaque descriptors
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *   for the in() and out() functions
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Changed inflateBack() argument and in_func typedef to swap the length
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *   and buffer address return values for the input function
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * - Check next_in and next_out for Z_NULL on entry to inflate()
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "zutil.h"
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "inftrees.h"
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "inflate.h"
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "inffast.h"
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef MAKEFIXED
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  ifndef BUILDFIXED
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#    define BUILDFIXED
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  endif
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* function prototypes */
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal void fixedtables OF((struct inflate_state FAR *state));
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal int updatewindow OF((z_streamp strm, unsigned out));
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef BUILDFIXED
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   void makefixed OF((void));
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                              unsigned len));
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT inflateReset(strm)
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectz_streamp strm;
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct inflate_state FAR *state;
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state = (struct inflate_state FAR *)strm->state;
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strm->total_in = strm->total_out = state->total = 0;
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strm->msg = Z_NULL;
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strm->adler = 1;        /* to support ill-conceived Java test suite */
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state->mode = HEAD;
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state->last = 0;
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state->havedict = 0;
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state->dmax = 32768U;
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state->head = Z_NULL;
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state->wsize = 0;
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state->whave = 0;
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state->write = 0;
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state->hold = 0;
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state->bits = 0;
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state->lencode = state->distcode = state->next = state->codes;
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Tracev((stderr, "inflate: reset\n"));
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return Z_OK;
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT inflatePrime(strm, bits, value)
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectz_streamp strm;
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint bits;
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint value;
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct inflate_state FAR *state;
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state = (struct inflate_state FAR *)strm->state;
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    value &= (1L << bits) - 1;
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state->hold += value << state->bits;
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state->bits += bits;
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return Z_OK;
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectz_streamp strm;
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint windowBits;
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char *version;
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint stream_size;
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct inflate_state FAR *state;
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        stream_size != (int)(sizeof(z_stream)))
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return Z_VERSION_ERROR;
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (strm == Z_NULL) return Z_STREAM_ERROR;
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strm->msg = Z_NULL;                 /* in case we return an error */
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (strm->zalloc == (alloc_func)0) {
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        strm->zalloc = zcalloc;
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        strm->opaque = (voidpf)0;
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (strm->zfree == (free_func)0) strm->zfree = zcfree;
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state = (struct inflate_state FAR *)
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ZALLOC(strm, 1, sizeof(struct inflate_state));
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (state == Z_NULL) return Z_MEM_ERROR;
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Tracev((stderr, "inflate: allocated\n"));
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strm->state = (struct internal_state FAR *)state;
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (windowBits < 0) {
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        state->wrap = 0;
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        windowBits = -windowBits;
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        state->wrap = (windowBits >> 4) + 1;
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef GUNZIP
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (windowBits < 48) windowBits &= 15;
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (windowBits < 8 || windowBits > 15) {
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ZFREE(strm, state);
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        strm->state = Z_NULL;
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return Z_STREAM_ERROR;
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state->wbits = (unsigned)windowBits;
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state->window = Z_NULL;
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return inflateReset(strm);
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT inflateInit_(strm, version, stream_size)
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectz_streamp strm;
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char *version;
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint stream_size;
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return inflateInit2_(strm, DEF_WBITS, version, stream_size);
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   Return state with length and distance decoding tables and index sizes set to
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   fixed code decoding.  Normally this returns fixed tables from inffixed.h.
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   If BUILDFIXED is defined, then instead this routine builds the tables the
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   first time it's called, and returns those tables the first time and
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   thereafter.  This reduces the size of the code by about 2K bytes, in
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   exchange for a little execution time.  However, BUILDFIXED should not be
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   used for threaded applications, since the rewriting of the tables and virgin
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   may not be thread-safe.
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal void fixedtables(state)
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct inflate_state FAR *state;
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef BUILDFIXED
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    static int virgin = 1;
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    static code *lenfix, *distfix;
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    static code fixed[544];
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* build fixed huffman tables if first call (may not be thread safe) */
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (virgin) {
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        unsigned sym, bits;
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        static code *next;
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* literal/length table */
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sym = 0;
2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (sym < 144) state->lens[sym++] = 8;
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (sym < 256) state->lens[sym++] = 9;
2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (sym < 280) state->lens[sym++] = 7;
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (sym < 288) state->lens[sym++] = 8;
2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        next = fixed;
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        lenfix = next;
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        bits = 9;
2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* distance table */
2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sym = 0;
2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (sym < 32) state->lens[sym++] = 5;
2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        distfix = next;
2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        bits = 5;
2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* do this just once */
2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        virgin = 0;
2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else /* !BUILDFIXED */
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#   include "inffixed.h"
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* BUILDFIXED */
2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state->lencode = lenfix;
2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state->lenbits = 9;
2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state->distcode = distfix;
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state->distbits = 5;
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef MAKEFIXED
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdio.h>
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   Write out the inffixed.h that is #include'd above.  Defining MAKEFIXED also
2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   defines BUILDFIXED, so the tables are built on the fly.  makefixed() writes
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   those tables to stdout, which would be piped to inffixed.h.  A small program
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   can simply call makefixed to do this:
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    void makefixed(void);
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int main(void)
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        makefixed();
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   Then that can be linked with zlib built with MAKEFIXED defined and run:
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    a.out > inffixed.h
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid makefixed()
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned low, size;
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct inflate_state state;
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    fixedtables(&state);
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    puts("    /* inffixed.h -- table for decoding fixed codes");
2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    puts("     * Generated automatically by makefixed().");
2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    puts("     */");
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    puts("");
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    puts("    /* WARNING: this file should *not* be used by applications.");
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    puts("       It is part of the implementation of this library and is");
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    puts("       subject to change. Applications should only use zlib.h.");
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    puts("     */");
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    puts("");
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    size = 1U << 9;
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf("    static const code lenfix[%u] = {", size);
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    low = 0;
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (;;) {
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ((low % 7) == 0) printf("\n        ");
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               state.lencode[low].val);
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (++low == size) break;
2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        putchar(',');
2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    puts("\n    };");
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    size = 1U << 5;
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf("\n    static const code distfix[%u] = {", size);
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    low = 0;
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (;;) {
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ((low % 6) == 0) printf("\n        ");
3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               state.distcode[low].val);
3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (++low == size) break;
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        putchar(',');
3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    puts("\n    };");
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* MAKEFIXED */
3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   Update the window with the last wsize (normally 32K) bytes written before
3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   returning.  If window does not exist yet, create it.  This is only called
3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   when a window is already in use, or when output has been written during this
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   inflate call, but the end of the deflate stream has not been reached yet.
3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   It is also called to create a window for dictionary data when a dictionary
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   is loaded.
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   Providing output buffers larger than 32K to inflate() should provide a speed
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   advantage, since only the last 32K of output is copied to the sliding window
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   upon return from inflate(), and since all distances after the first 32K of
3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   output will fall in the output data, making match copies simpler and faster.
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   The advantage may be dependent on the size of the processor's data caches.
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal int updatewindow(strm, out)
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectz_streamp strm;
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectunsigned out;
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct inflate_state FAR *state;
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned copy, dist;
3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state = (struct inflate_state FAR *)strm->state;
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* if it hasn't been done already, allocate space for the window */
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (state->window == Z_NULL) {
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        state->window = (unsigned char FAR *)
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        ZALLOC(strm, 1U << state->wbits,
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                               sizeof(unsigned char));
3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (state->window == Z_NULL) return 1;
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* if window not in use yet, initialize */
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (state->wsize == 0) {
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        state->wsize = 1U << state->wbits;
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        state->write = 0;
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        state->whave = 0;
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* copy state->wsize or less output bytes into the circular window */
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    copy = out - strm->avail_out;
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (copy >= state->wsize) {
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        state->write = 0;
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        state->whave = state->wsize;
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dist = state->wsize - state->write;
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (dist > copy) dist = copy;
3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zmemcpy(state->window + state->write, strm->next_out - copy, dist);
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        copy -= dist;
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (copy) {
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            zmemcpy(state->window, strm->next_out - copy, copy);
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->write = copy;
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->whave = state->wsize;
3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else {
3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->write += dist;
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->write == state->wsize) state->write = 0;
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->whave < state->wsize) state->whave += dist;
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Macros for inflate(): */
3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* check function to use adler32() for zlib or crc32() for gzip */
3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef GUNZIP
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define UPDATE(check, buf, len) \
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define UPDATE(check, buf, len) adler32(check, buf, len)
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* check macros for header crc */
3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef GUNZIP
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define CRC2(check, word) \
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do { \
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        hbuf[0] = (unsigned char)(word); \
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        hbuf[1] = (unsigned char)((word) >> 8); \
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        check = crc32(check, hbuf, 2); \
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while (0)
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define CRC4(check, word) \
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do { \
3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        hbuf[0] = (unsigned char)(word); \
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        hbuf[1] = (unsigned char)((word) >> 8); \
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        hbuf[2] = (unsigned char)((word) >> 16); \
3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        hbuf[3] = (unsigned char)((word) >> 24); \
3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        check = crc32(check, hbuf, 4); \
3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while (0)
4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Load registers with state in inflate() for speed */
4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define LOAD() \
4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do { \
4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        put = strm->next_out; \
4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        left = strm->avail_out; \
4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        next = strm->next_in; \
4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        have = strm->avail_in; \
4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        hold = state->hold; \
4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        bits = state->bits; \
4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while (0)
4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Restore state from registers in inflate() */
4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define RESTORE() \
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do { \
4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        strm->next_out = put; \
4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        strm->avail_out = left; \
4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        strm->next_in = next; \
4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        strm->avail_in = have; \
4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        state->hold = hold; \
4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        state->bits = bits; \
4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while (0)
4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Clear the input bit accumulator */
4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define INITBITS() \
4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do { \
4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        hold = 0; \
4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        bits = 0; \
4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while (0)
4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Get a byte of input into the bit accumulator, or return from inflate()
4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if there is no input available. */
4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PULLBYTE() \
4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do { \
4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (have == 0) goto inf_leave; \
4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        have--; \
4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        hold += (unsigned long)(*next++) << bits; \
4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        bits += 8; \
4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while (0)
4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Assure that there are at least n bits in the bit accumulator.  If there is
4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   not enough available input to do that, then return from inflate(). */
4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define NEEDBITS(n) \
4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do { \
4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (bits < (unsigned)(n)) \
4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            PULLBYTE(); \
4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while (0)
4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Return the low n bits of the bit accumulator (n < 16) */
4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define BITS(n) \
4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ((unsigned)hold & ((1U << (n)) - 1))
4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Remove n bits from the bit accumulator */
4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define DROPBITS(n) \
4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do { \
4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        hold >>= (n); \
4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        bits -= (unsigned)(n); \
4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while (0)
4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Remove zero to seven bits as needed to go to a byte boundary */
4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define BYTEBITS() \
4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    do { \
4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        hold >>= bits & 7; \
4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        bits -= bits & 7; \
4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } while (0)
4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Reverse the bytes in a 32-bit value */
4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define REVERSE(q) \
4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   inflate() uses a state machine to process as much input data and generate as
4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   much output data as possible before returning.  The state machine is
4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   structured roughly as follows:
4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (;;) switch (state) {
4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ...
4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case STATEn:
4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (not enough input data or output space to make progress)
4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return;
4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ... make progress ...
4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        state = STATEm;
4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ...
4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   so when inflate() is called again, the same case is attempted again, and
4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if the appropriate resources are provided, the machine proceeds to the
4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   next state.  The NEEDBITS() macro is usually the way the state evaluates
4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   whether it can proceed or should return.  NEEDBITS() does the return if
4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   the requested bits are not available.  The typical use of the BITS macros
4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   is:
4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        NEEDBITS(n);
4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ... do something with BITS(n) ...
4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        DROPBITS(n);
4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   where NEEDBITS(n) either returns from inflate() if there isn't enough
5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   input left to load n bits into the accumulator, or it continues.  BITS(n)
5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   gives the low n bits in the accumulator.  When done, DROPBITS(n) drops
5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   the low n bits off the accumulator.  INITBITS() clears the accumulator
5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   and sets the number of available bits to zero.  BYTEBITS() discards just
5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   enough bits to put the accumulator on a byte boundary.  After BYTEBITS()
5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if there is no input available.  The decoding of variable length codes uses
5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   PULLBYTE() directly in order to pull just enough bytes to decode the next
5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   code, and no more.
5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   Some states loop until they get enough input, making sure that enough
5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   state information is maintained to continue the loop where it left off
5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if NEEDBITS() returns in the loop.  For example, want, need, and keep
5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   would all have to actually be part of the saved state in case NEEDBITS()
5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   returns:
5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case STATEw:
5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (want < need) {
5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            NEEDBITS(n);
5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            keep[want++] = BITS(n);
5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            DROPBITS(n);
5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        state = STATEx;
5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case STATEx:
5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   As shown above, if the next state is also the next case, then the break
5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   is omitted.
5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   A state may also return if there is not enough output space available to
5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   complete that state.  Those states are copying stored data, writing a
5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   literal byte, and copying a matching string.
5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   When returning, a "goto inf_leave" is used to update the total counters,
5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   update the check value, and determine whether any progress has been made
5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   during that inflate() call in order to return the proper return code.
5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   Progress is defined as a change in either strm->avail_in or strm->avail_out.
5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   When there is a window, goto inf_leave will update the window with the last
5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   output written.  If a goto inf_leave occurs in the middle of decompression
5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   and there is no window currently, goto inf_leave will create one and copy
5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   output to the window for the next call of inflate().
5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   In this implementation, the flush parameter of inflate() only affects the
5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   return code (per zlib.h).  inflate() always writes as much as possible to
5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   strm->next_out, given the space available and the provided input--the effect
5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   documented in zlib.h of Z_SYNC_FLUSH.  Furthermore, inflate() always defers
5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   the allocation of and copying into a sliding window until necessary, which
5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   provides the effect documented in zlib.h for Z_FINISH when the entire input
5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   stream available.  So the only thing the flush parameter actually does is:
5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   when flush is set to Z_FINISH, inflate() cannot return Z_OK.  Instead it
5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   will return Z_BUF_ERROR if it has not reached the end of the stream.
5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT inflate(strm, flush)
5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectz_streamp strm;
5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint flush;
5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct inflate_state FAR *state;
5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned char FAR *next;    /* next input */
5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned char FAR *put;     /* next output */
5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned have, left;        /* available input and output */
5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long hold;         /* bit buffer */
5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned bits;              /* bits in bit buffer */
5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned in, out;           /* save starting available input and output */
5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned copy;              /* number of stored or match bytes to copy */
5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned char FAR *from;    /* where to copy match bytes from */
5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    code this;                  /* current decoding table entry */
5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    code last;                  /* parent table entry */
5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned len;               /* length to copy for repeats, bits to drop */
5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret;                    /* return code */
5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef GUNZIP
5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned char hbuf[4];      /* buffer for gzip header crc calculation */
5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    static const unsigned short order[19] = /* permutation of code lengths */
5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        (strm->next_in == Z_NULL && strm->avail_in != 0))
5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return Z_STREAM_ERROR;
5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state = (struct inflate_state FAR *)strm->state;
5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (state->mode == TYPE) state->mode = TYPEDO;      /* skip check */
5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    LOAD();
5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    in = have;
5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    out = left;
5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ret = Z_OK;
5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (;;)
5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch (state->mode) {
5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case HEAD:
5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->wrap == 0) {
5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->mode = TYPEDO;
5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            NEEDBITS(16);
5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef GUNZIP
5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ((state->wrap & 2) && hold == 0x8b1f) {  /* gzip header */
5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->check = crc32(0L, Z_NULL, 0);
5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                CRC2(state->check, hold);
5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                INITBITS();
6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->mode = FLAGS;
6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->flags = 0;           /* expect zlib header */
6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->head != Z_NULL)
6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->head->done = -1;
6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!(state->wrap & 1) ||   /* check if zlib header allowed */
6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (
6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                ((BITS(8) << 8) + (hold >> 8)) % 31) {
6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                strm->msg = (char *)"incorrect header check";
6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->mode = BAD;
6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (BITS(4) != Z_DEFLATED) {
6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                strm->msg = (char *)"unknown compression method";
6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->mode = BAD;
6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            DROPBITS(4);
6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            len = BITS(4) + 8;
6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (len > state->wbits) {
6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                strm->msg = (char *)"invalid window size";
6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->mode = BAD;
6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->dmax = 1U << len;
6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            Tracev((stderr, "inflate:   zlib header ok\n"));
6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            strm->adler = state->check = adler32(0L, Z_NULL, 0);
6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = hold & 0x200 ? DICTID : TYPE;
6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            INITBITS();
6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef GUNZIP
6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case FLAGS:
6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            NEEDBITS(16);
6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->flags = (int)(hold);
6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ((state->flags & 0xff) != Z_DEFLATED) {
6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                strm->msg = (char *)"unknown compression method";
6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->mode = BAD;
6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
6418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->flags & 0xe000) {
6438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                strm->msg = (char *)"unknown header flags set";
6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->mode = BAD;
6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
6468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->head != Z_NULL)
6488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->head->text = (int)((hold >> 8) & 1);
6498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->flags & 0x0200) CRC2(state->check, hold);
6508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            INITBITS();
6518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = TIME;
6528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TIME:
6538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            NEEDBITS(32);
6548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->head != Z_NULL)
6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->head->time = hold;
6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->flags & 0x0200) CRC4(state->check, hold);
6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            INITBITS();
6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = OS;
6598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case OS:
6608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            NEEDBITS(16);
6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->head != Z_NULL) {
6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->head->xflags = (int)(hold & 0xff);
6638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->head->os = (int)(hold >> 8);
6648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->flags & 0x0200) CRC2(state->check, hold);
6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            INITBITS();
6678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = EXLEN;
6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case EXLEN:
6698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->flags & 0x0400) {
6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                NEEDBITS(16);
6718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->length = (unsigned)(hold);
6728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (state->head != Z_NULL)
6738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    state->head->extra_len = (unsigned)hold;
6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (state->flags & 0x0200) CRC2(state->check, hold);
6758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                INITBITS();
6768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
6778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else if (state->head != Z_NULL)
6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->head->extra = Z_NULL;
6798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = EXTRA;
6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case EXTRA:
6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->flags & 0x0400) {
6828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                copy = state->length;
6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (copy > have) copy = have;
6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (copy) {
6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (state->head != Z_NULL &&
6868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        state->head->extra != Z_NULL) {
6878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        len = state->head->extra_len - state->length;
6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        zmemcpy(state->head->extra + len, next,
6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                len + copy > state->head->extra_max ?
6908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                state->head->extra_max - len : copy);
6918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (state->flags & 0x0200)
6938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        state->check = crc32(state->check, next, copy);
6948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    have -= copy;
6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    next += copy;
6968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    state->length -= copy;
6978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (state->length) goto inf_leave;
6998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
7008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->length = 0;
7018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = NAME;
7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case NAME:
7038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->flags & 0x0800) {
7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (have == 0) goto inf_leave;
7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                copy = 0;
7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                do {
7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    len = (unsigned)(next[copy++]);
7088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (state->head != Z_NULL &&
7098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            state->head->name != Z_NULL &&
7108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            state->length < state->head->name_max)
7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        state->head->name[state->length++] = len;
7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                } while (len && copy < have);
7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (state->flags & 0x0200)
7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    state->check = crc32(state->check, next, copy);
7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                have -= copy;
7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                next += copy;
7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (len) goto inf_leave;
7188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else if (state->head != Z_NULL)
7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->head->name = Z_NULL;
7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->length = 0;
7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = COMMENT;
7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case COMMENT:
7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->flags & 0x1000) {
7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (have == 0) goto inf_leave;
7268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                copy = 0;
7278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                do {
7288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    len = (unsigned)(next[copy++]);
7298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (state->head != Z_NULL &&
7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            state->head->comment != Z_NULL &&
7318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            state->length < state->head->comm_max)
7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        state->head->comment[state->length++] = len;
7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                } while (len && copy < have);
7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (state->flags & 0x0200)
7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    state->check = crc32(state->check, next, copy);
7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                have -= copy;
7378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                next += copy;
7388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (len) goto inf_leave;
7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else if (state->head != Z_NULL)
7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->head->comment = Z_NULL;
7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = HCRC;
7438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case HCRC:
7448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->flags & 0x0200) {
7458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                NEEDBITS(16);
7468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (hold != (state->check & 0xffff)) {
7478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    strm->msg = (char *)"header crc mismatch";
7488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    state->mode = BAD;
7498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    break;
7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
7518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                INITBITS();
7528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
7538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->head != Z_NULL) {
7548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->head->hcrc = (int)((state->flags >> 9) & 1);
7558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->head->done = 1;
7568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
7578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            strm->adler = state->check = crc32(0L, Z_NULL, 0);
7588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = TYPE;
7598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case DICTID:
7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            NEEDBITS(32);
7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            strm->adler = state->check = REVERSE(hold);
7648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            INITBITS();
7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = DICT;
7668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case DICT:
7678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->havedict == 0) {
7688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                RESTORE();
7698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return Z_NEED_DICT;
7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            strm->adler = state->check = adler32(0L, Z_NULL, 0);
7728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = TYPE;
7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TYPE:
7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (flush == Z_BLOCK) goto inf_leave;
7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TYPEDO:
7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->last) {
7778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                BYTEBITS();
7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->mode = CHECK;
7798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
7808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
7818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            NEEDBITS(3);
7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->last = BITS(1);
7838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            DROPBITS(1);
7848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            switch (BITS(2)) {
7858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 0:                             /* stored block */
7868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                Tracev((stderr, "inflate:     stored block%s\n",
7878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        state->last ? " (last)" : ""));
7888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->mode = STORED;
7898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 1:                             /* fixed block */
7918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fixedtables(state);
7928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                Tracev((stderr, "inflate:     fixed codes block%s\n",
7938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        state->last ? " (last)" : ""));
7948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->mode = LEN;              /* decode codes */
7958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
7968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 2:                             /* dynamic block */
7978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                Tracev((stderr, "inflate:     dynamic codes block%s\n",
7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        state->last ? " (last)" : ""));
7998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->mode = TABLE;
8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
8018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 3:
8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                strm->msg = (char *)"invalid block type";
8038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->mode = BAD;
8048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
8058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            DROPBITS(2);
8068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
8078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case STORED:
8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            BYTEBITS();                         /* go to byte boundary */
8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            NEEDBITS(32);
8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                strm->msg = (char *)"invalid stored block lengths";
8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->mode = BAD;
8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
8148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
8158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->length = (unsigned)hold & 0xffff;
8168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            Tracev((stderr, "inflate:       stored length %u\n",
8178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    state->length));
8188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            INITBITS();
8198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = COPY;
8208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case COPY:
8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            copy = state->length;
8228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (copy) {
8238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (copy > have) copy = have;
8248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (copy > left) copy = left;
8258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (copy == 0) goto inf_leave;
8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                zmemcpy(put, next, copy);
8278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                have -= copy;
8288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                next += copy;
8298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                left -= copy;
8308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                put += copy;
8318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->length -= copy;
8328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
8338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
8348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            Tracev((stderr, "inflate:       stored end\n"));
8358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = TYPE;
8368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
8378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case TABLE:
8388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            NEEDBITS(14);
8398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->nlen = BITS(5) + 257;
8408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            DROPBITS(5);
8418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->ndist = BITS(5) + 1;
8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            DROPBITS(5);
8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->ncode = BITS(4) + 4;
8448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            DROPBITS(4);
8458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef PKZIP_BUG_WORKAROUND
8468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->nlen > 286 || state->ndist > 30) {
8478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                strm->msg = (char *)"too many length or distance symbols";
8488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->mode = BAD;
8498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
8508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
8518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            Tracev((stderr, "inflate:       table sizes ok\n"));
8538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->have = 0;
8548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = LENLENS;
8558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case LENLENS:
8568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            while (state->have < state->ncode) {
8578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                NEEDBITS(3);
8588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->lens[order[state->have++]] = (unsigned short)BITS(3);
8598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                DROPBITS(3);
8608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
8618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            while (state->have < 19)
8628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->lens[order[state->have++]] = 0;
8638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->next = state->codes;
8648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->lencode = (code const FAR *)(state->next);
8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->lenbits = 7;
8668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ret = inflate_table(CODES, state->lens, 19, &(state->next),
8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                &(state->lenbits), state->work);
8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ret) {
8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                strm->msg = (char *)"invalid code lengths set";
8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->mode = BAD;
8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            Tracev((stderr, "inflate:       code lengths ok\n"));
8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->have = 0;
8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = CODELENS;
8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case CODELENS:
8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            while (state->have < state->nlen + state->ndist) {
8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                for (;;) {
8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    this = state->lencode[BITS(state->lenbits)];
8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if ((unsigned)(this.bits) <= bits) break;
8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    PULLBYTE();
8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (this.val < 16) {
8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    NEEDBITS(this.bits);
8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    DROPBITS(this.bits);
8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    state->lens[state->have++] = this.val;
8878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                else {
8898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (this.val == 16) {
8908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        NEEDBITS(this.bits + 2);
8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        DROPBITS(this.bits);
8928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (state->have == 0) {
8938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            strm->msg = (char *)"invalid bit length repeat";
8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            state->mode = BAD;
8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            break;
8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        }
8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        len = state->lens[state->have - 1];
8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        copy = 3 + BITS(2);
8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        DROPBITS(2);
9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    else if (this.val == 17) {
9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        NEEDBITS(this.bits + 3);
9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        DROPBITS(this.bits);
9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        len = 0;
9058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        copy = 3 + BITS(3);
9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        DROPBITS(3);
9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
9088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    else {
9098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        NEEDBITS(this.bits + 7);
9108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        DROPBITS(this.bits);
9118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        len = 0;
9128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        copy = 11 + BITS(7);
9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        DROPBITS(7);
9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
9158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (state->have + copy > state->nlen + state->ndist) {
9168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        strm->msg = (char *)"invalid bit length repeat";
9178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        state->mode = BAD;
9188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        break;
9198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
9208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    while (copy--)
9218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        state->lens[state->have++] = (unsigned short)len;
9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* handle error breaks in while */
9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->mode == BAD) break;
9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* build code tables */
9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->next = state->codes;
9308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->lencode = (code const FAR *)(state->next);
9318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->lenbits = 9;
9328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
9338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                &(state->lenbits), state->work);
9348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ret) {
9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                strm->msg = (char *)"invalid literal/lengths set";
9368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->mode = BAD;
9378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
9388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->distcode = (code const FAR *)(state->next);
9408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->distbits = 6;
9418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
9428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            &(state->next), &(state->distbits), state->work);
9438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ret) {
9448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                strm->msg = (char *)"invalid distances set";
9458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->mode = BAD;
9468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
9478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            Tracev((stderr, "inflate:       codes ok\n"));
9498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = LEN;
9508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case LEN:
9518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (have >= 6 && left >= 258) {
9528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                RESTORE();
9538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                inflate_fast(strm, out);
9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                LOAD();
9558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
9568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (;;) {
9588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                this = state->lencode[BITS(state->lenbits)];
9598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if ((unsigned)(this.bits) <= bits) break;
9608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                PULLBYTE();
9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (this.op && (this.op & 0xf0) == 0) {
9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                last = this;
9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                for (;;) {
9658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    this = state->lencode[last.val +
9668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            (BITS(last.bits + last.op) >> last.bits)];
9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if ((unsigned)(last.bits + this.bits) <= bits) break;
9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    PULLBYTE();
9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                DROPBITS(last.bits);
9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            DROPBITS(this.bits);
9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->length = (unsigned)this.val;
9748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ((int)(this.op) == 0) {
9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        "inflate:         literal '%c'\n" :
9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        "inflate:         literal 0x%02x\n", this.val));
9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->mode = LIT;
9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (this.op & 32) {
9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                Tracevv((stderr, "inflate:         end of block\n"));
9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->mode = TYPE;
9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
9858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (this.op & 64) {
9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                strm->msg = (char *)"invalid literal/length code";
9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->mode = BAD;
9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->extra = (unsigned)(this.op) & 15;
9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = LENEXT;
9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case LENEXT:
9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->extra) {
9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                NEEDBITS(state->extra);
9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->length += BITS(state->extra);
9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                DROPBITS(state->extra);
9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            Tracevv((stderr, "inflate:         length %u\n", state->length));
10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = DIST;
10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case DIST:
10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (;;) {
10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                this = state->distcode[BITS(state->distbits)];
10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if ((unsigned)(this.bits) <= bits) break;
10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                PULLBYTE();
10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if ((this.op & 0xf0) == 0) {
10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                last = this;
10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                for (;;) {
10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    this = state->distcode[last.val +
10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            (BITS(last.bits + last.op) >> last.bits)];
10128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if ((unsigned)(last.bits + this.bits) <= bits) break;
10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    PULLBYTE();
10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                DROPBITS(last.bits);
10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            DROPBITS(this.bits);
10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (this.op & 64) {
10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                strm->msg = (char *)"invalid distance code";
10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->mode = BAD;
10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->offset = (unsigned)this.val;
10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->extra = (unsigned)(this.op) & 15;
10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = DISTEXT;
10268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case DISTEXT:
10278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->extra) {
10288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                NEEDBITS(state->extra);
10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->offset += BITS(state->extra);
10308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                DROPBITS(state->extra);
10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef INFLATE_STRICT
10338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->offset > state->dmax) {
10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                strm->msg = (char *)"invalid distance too far back";
10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->mode = BAD;
10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
10378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
10398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->offset > state->whave + out - left) {
10408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                strm->msg = (char *)"invalid distance too far back";
10418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->mode = BAD;
10428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
10438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
10458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = MATCH;
10468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case MATCH:
10478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (left == 0) goto inf_leave;
10488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            copy = out - left;
10498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->offset > copy) {         /* copy from window */
10508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                copy = state->offset - copy;
10518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (copy > state->write) {
10528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    copy -= state->write;
10538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    from = state->window + (state->wsize - copy);
10548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
10558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                else
10568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    from = state->window + (state->write - copy);
10578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (copy > state->length) copy = state->length;
10588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else {                              /* copy from output */
10608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                from = put - state->offset;
10618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                copy = state->length;
10628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (copy > left) copy = left;
10648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            left -= copy;
10658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->length -= copy;
10668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            do {
10678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                *put++ = *from++;
10688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } while (--copy);
10698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->length == 0) state->mode = LEN;
10708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
10718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case LIT:
10728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (left == 0) goto inf_leave;
10738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *put++ = (unsigned char)(state->length);
10748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            left--;
10758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = LEN;
10768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
10778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case CHECK:
10788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->wrap) {
10798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                NEEDBITS(32);
10808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                out -= left;
10818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                strm->total_out += out;
10828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->total += out;
10838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (out)
10848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    strm->adler = state->check =
10858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        UPDATE(state->check, put - out, out);
10868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                out = left;
10878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if ((
10888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef GUNZIP
10898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     state->flags ? hold :
10908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
10918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     REVERSE(hold)) != state->check) {
10928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    strm->msg = (char *)"incorrect data check";
10938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    state->mode = BAD;
10948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    break;
10958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
10968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                INITBITS();
10978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                Tracev((stderr, "inflate:   check matches trailer\n"));
10988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
10998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef GUNZIP
11008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = LENGTH;
11018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case LENGTH:
11028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (state->wrap && state->flags) {
11038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                NEEDBITS(32);
11048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (hold != (state->total & 0xffffffffUL)) {
11058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    strm->msg = (char *)"incorrect length check";
11068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    state->mode = BAD;
11078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    break;
11088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
11098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                INITBITS();
11108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                Tracev((stderr, "inflate:   length matches trailer\n"));
11118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
11128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
11138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = DONE;
11148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case DONE:
11158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ret = Z_STREAM_END;
11168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto inf_leave;
11178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case BAD:
11188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ret = Z_DATA_ERROR;
11198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            goto inf_leave;
11208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case MEM:
11218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return Z_MEM_ERROR;
11228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case SYNC:
11238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
11248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return Z_STREAM_ERROR;
11258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
11268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /*
11288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       Return from inflate(), updating the total counts and the check value.
11298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       If there was no progress during the inflate() call, return a buffer
11308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       error.  Call updatewindow() to create and/or update the window state.
11318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       Note: a memory error from inflate() is non-recoverable.
11328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     */
11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  inf_leave:
11348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RESTORE();
11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
11368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (updatewindow(strm, out)) {
11378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->mode = MEM;
11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return Z_MEM_ERROR;
11398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
11408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    in -= strm->avail_in;
11418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    out -= strm->avail_out;
11428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strm->total_in += in;
11438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strm->total_out += out;
11448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state->total += out;
11458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (state->wrap && out)
11468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        strm->adler = state->check =
11478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            UPDATE(state->check, strm->next_out - out, out);
11488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strm->data_type = state->bits + (state->last ? 64 : 0) +
11498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                      (state->mode == TYPE ? 128 : 0);
11508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
11518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ret = Z_BUF_ERROR;
11528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ret;
11538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT inflateEnd(strm)
11568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectz_streamp strm;
11578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct inflate_state FAR *state;
11598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
11608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return Z_STREAM_ERROR;
11618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state = (struct inflate_state FAR *)strm->state;
11628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (state->window != Z_NULL) ZFREE(strm, state->window);
11638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ZFREE(strm, strm->state);
11648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strm->state = Z_NULL;
11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Tracev((stderr, "inflate: end\n"));
11668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return Z_OK;
11678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
11708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectz_streamp strm;
11718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst Bytef *dictionary;
11728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectuInt dictLength;
11738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct inflate_state FAR *state;
11758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long id;
11768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* check state */
11788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
11798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state = (struct inflate_state FAR *)strm->state;
11808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (state->wrap != 0 && state->mode != DICT)
11818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return Z_STREAM_ERROR;
11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* check for correct dictionary id */
11848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (state->mode == DICT) {
11858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        id = adler32(0L, Z_NULL, 0);
11868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        id = adler32(id, dictionary, dictLength);
11878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (id != state->check)
11888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return Z_DATA_ERROR;
11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* copy dictionary to window */
11928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (updatewindow(strm, strm->avail_out)) {
11938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        state->mode = MEM;
11948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return Z_MEM_ERROR;
11958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
11968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (dictLength > state->wsize) {
11978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zmemcpy(state->window, dictionary + dictLength - state->wsize,
11988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                state->wsize);
11998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        state->whave = state->wsize;
12008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
12028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zmemcpy(state->window + state->wsize - dictLength, dictionary,
12038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                dictLength);
12048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        state->whave = dictLength;
12058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state->havedict = 1;
12078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    Tracev((stderr, "inflate:   dictionary set\n"));
12088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return Z_OK;
12098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT inflateGetHeader(strm, head)
12128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectz_streamp strm;
12138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectgz_headerp head;
12148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct inflate_state FAR *state;
12168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* check state */
12188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
12198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state = (struct inflate_state FAR *)strm->state;
12208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
12218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* save header structure */
12238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state->head = head;
12248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    head->done = 0;
12258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return Z_OK;
12268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
12298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff.  Return when found
12308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   or when out of input.  When called, *have is the number of pattern bytes
12318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   found in order so far, in 0..3.  On return *have is updated to the new
12328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   state.  If on return *have equals four, then the pattern was found and the
12338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   return value is how many bytes were read including the last byte of the
12348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   pattern.  If *have is less than four, then the pattern has not been found
12358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   yet and the return value is len.  In the latter case, syncsearch() can be
12368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   called again with more data and the *have state.  *have is initialized to
12378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   zero for the first call.
12388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
12398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectlocal unsigned syncsearch(have, buf, len)
12408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectunsigned FAR *have;
12418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectunsigned char FAR *buf;
12428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectunsigned len;
12438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned got;
12458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned next;
12468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    got = *have;
12488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    next = 0;
12498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (next < len && got < 4) {
12508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
12518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            got++;
12528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else if (buf[next])
12538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            got = 0;
12548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
12558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            got = 4 - got;
12568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        next++;
12578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *have = got;
12598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return next;
12608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT inflateSync(strm)
12638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectz_streamp strm;
12648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned len;               /* number of bytes to look at or looked at */
12668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned long in, out;      /* temporary to save total_in and total_out */
12678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned char buf[4];       /* to restore bit buffer to byte string */
12688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct inflate_state FAR *state;
12698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* check parameters */
12718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
12728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state = (struct inflate_state FAR *)strm->state;
12738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
12748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* if first time, start search in bit buffer */
12768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (state->mode != SYNC) {
12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        state->mode = SYNC;
12788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        state->hold <<= state->bits & 7;
12798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        state->bits -= state->bits & 7;
12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        len = 0;
12818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        while (state->bits >= 8) {
12828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            buf[len++] = (unsigned char)(state->hold);
12838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->hold >>= 8;
12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            state->bits -= 8;
12858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
12868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        state->have = 0;
12878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        syncsearch(&(state->have), buf, len);
12888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
12898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* search available input */
12918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
12928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strm->avail_in -= len;
12938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strm->next_in += len;
12948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strm->total_in += len;
12958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* return no joy or set up to restart inflate() on a new block */
12978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (state->have != 4) return Z_DATA_ERROR;
12988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    in = strm->total_in;  out = strm->total_out;
12998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    inflateReset(strm);
13008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strm->total_in = in;  strm->total_out = out;
13018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state->mode = TYPE;
13028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return Z_OK;
13038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
13068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   Returns true if inflate is currently at the end of a block generated by
13078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
13088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   implementation to provide an additional safety check. PPP uses
13098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
13108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   block. When decompressing, PPP checks that at the end of input packet,
13118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   inflate is waiting for these length bytes.
13128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
13138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT inflateSyncPoint(strm)
13148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectz_streamp strm;
13158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct inflate_state FAR *state;
13178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
13198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state = (struct inflate_state FAR *)strm->state;
13208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return state->mode == STORED && state->bits == 0;
13218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint ZEXPORT inflateCopy(dest, source)
13248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectz_streamp dest;
13258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectz_streamp source;
13268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct inflate_state FAR *state;
13288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    struct inflate_state FAR *copy;
13298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned char FAR *window;
13308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned wsize;
13318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* check input */
13338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
13348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
13358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return Z_STREAM_ERROR;
13368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    state = (struct inflate_state FAR *)source->state;
13378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* allocate space */
13398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    copy = (struct inflate_state FAR *)
13408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           ZALLOC(source, 1, sizeof(struct inflate_state));
13418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (copy == Z_NULL) return Z_MEM_ERROR;
13428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    window = Z_NULL;
13438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (state->window != Z_NULL) {
13448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        window = (unsigned char FAR *)
13458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
13468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (window == Z_NULL) {
13478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ZFREE(source, copy);
13488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return Z_MEM_ERROR;
13498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
13508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* copy state */
13538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zmemcpy(dest, source, sizeof(z_stream));
13548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    zmemcpy(copy, state, sizeof(struct inflate_state));
13558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (state->lencode >= state->codes &&
13568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        state->lencode <= state->codes + ENOUGH - 1) {
13578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        copy->lencode = copy->codes + (state->lencode - state->codes);
13588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        copy->distcode = copy->codes + (state->distcode - state->codes);
13598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    copy->next = copy->codes + (state->next - state->codes);
13618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (window != Z_NULL) {
13628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        wsize = 1U << state->wbits;
13638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        zmemcpy(window, state->window, wsize);
13648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
13658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    copy->window = window;
13668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    dest->state = (struct internal_state FAR *)copy;
13678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return Z_OK;
13688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1369