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