kusano fc6ab3
/* inflate.c -- zlib decompression
kusano fc6ab3
 * Copyright (C) 1995-2012 Mark Adler
kusano fc6ab3
 * For conditions of distribution and use, see copyright notice in zlib.h
kusano fc6ab3
 */
kusano fc6ab3
kusano fc6ab3
/*
kusano fc6ab3
 * Change history:
kusano fc6ab3
 *
kusano fc6ab3
 * 1.2.beta0    24 Nov 2002
kusano fc6ab3
 * - First version -- complete rewrite of inflate to simplify code, avoid
kusano fc6ab3
 *   creation of window when not needed, minimize use of window when it is
kusano fc6ab3
 *   needed, make inffast.c even faster, implement gzip decoding, and to
kusano fc6ab3
 *   improve code readability and style over the previous zlib inflate code
kusano fc6ab3
 *
kusano fc6ab3
 * 1.2.beta1    25 Nov 2002
kusano fc6ab3
 * - Use pointers for available input and output checking in inffast.c
kusano fc6ab3
 * - Remove input and output counters in inffast.c
kusano fc6ab3
 * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
kusano fc6ab3
 * - Remove unnecessary second byte pull from length extra in inffast.c
kusano fc6ab3
 * - Unroll direct copy to three copies per loop in inffast.c
kusano fc6ab3
 *
kusano fc6ab3
 * 1.2.beta2    4 Dec 2002
kusano fc6ab3
 * - Change external routine names to reduce potential conflicts
kusano fc6ab3
 * - Correct filename to inffixed.h for fixed tables in inflate.c
kusano fc6ab3
 * - Make hbuf[] unsigned char to match parameter type in inflate.c
kusano fc6ab3
 * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
kusano fc6ab3
 *   to avoid negation problem on Alphas (64 bit) in inflate.c
kusano fc6ab3
 *
kusano fc6ab3
 * 1.2.beta3    22 Dec 2002
kusano fc6ab3
 * - Add comments on state->bits assertion in inffast.c
kusano fc6ab3
 * - Add comments on op field in inftrees.h
kusano fc6ab3
 * - Fix bug in reuse of allocated window after inflateReset()
kusano fc6ab3
 * - Remove bit fields--back to byte structure for speed
kusano fc6ab3
 * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
kusano fc6ab3
 * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
kusano fc6ab3
 * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
kusano fc6ab3
 * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
kusano fc6ab3
 * - Use local copies of stream next and avail values, as well as local bit
kusano fc6ab3
 *   buffer and bit count in inflate()--for speed when inflate_fast() not used
kusano fc6ab3
 *
kusano fc6ab3
 * 1.2.beta4    1 Jan 2003
kusano fc6ab3
 * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
kusano fc6ab3
 * - Move a comment on output buffer sizes from inffast.c to inflate.c
kusano fc6ab3
 * - Add comments in inffast.c to introduce the inflate_fast() routine
kusano fc6ab3
 * - Rearrange window copies in inflate_fast() for speed and simplification
kusano fc6ab3
 * - Unroll last copy for window match in inflate_fast()
kusano fc6ab3
 * - Use local copies of window variables in inflate_fast() for speed
kusano fc6ab3
 * - Pull out common wnext == 0 case for speed in inflate_fast()
kusano fc6ab3
 * - Make op and len in inflate_fast() unsigned for consistency
kusano fc6ab3
 * - Add FAR to lcode and dcode declarations in inflate_fast()
kusano fc6ab3
 * - Simplified bad distance check in inflate_fast()
kusano fc6ab3
 * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
kusano fc6ab3
 *   source file infback.c to provide a call-back interface to inflate for
kusano fc6ab3
 *   programs like gzip and unzip -- uses window as output buffer to avoid
kusano fc6ab3
 *   window copying
kusano fc6ab3
 *
kusano fc6ab3
 * 1.2.beta5    1 Jan 2003
kusano fc6ab3
 * - Improved inflateBack() interface to allow the caller to provide initial
kusano fc6ab3
 *   input in strm.
kusano fc6ab3
 * - Fixed stored blocks bug in inflateBack()
kusano fc6ab3
 *
kusano fc6ab3
 * 1.2.beta6    4 Jan 2003
kusano fc6ab3
 * - Added comments in inffast.c on effectiveness of POSTINC
kusano fc6ab3
 * - Typecasting all around to reduce compiler warnings
kusano fc6ab3
 * - Changed loops from while (1) or do {} while (1) to for (;;), again to
kusano fc6ab3
 *   make compilers happy
kusano fc6ab3
 * - Changed type of window in inflateBackInit() to unsigned char *
kusano fc6ab3
 *
kusano fc6ab3
 * 1.2.beta7    27 Jan 2003
kusano fc6ab3
 * - Changed many types to unsigned or unsigned short to avoid warnings
kusano fc6ab3
 * - Added inflateCopy() function
kusano fc6ab3
 *
kusano fc6ab3
 * 1.2.0        9 Mar 2003
kusano fc6ab3
 * - Changed inflateBack() interface to provide separate opaque descriptors
kusano fc6ab3
 *   for the in() and out() functions
kusano fc6ab3
 * - Changed inflateBack() argument and in_func typedef to swap the length
kusano fc6ab3
 *   and buffer address return values for the input function
kusano fc6ab3
 * - Check next_in and next_out for Z_NULL on entry to inflate()
kusano fc6ab3
 *
kusano fc6ab3
 * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
kusano fc6ab3
 */
kusano fc6ab3
kusano fc6ab3
#include "zutil.h"
kusano fc6ab3
#include "inftrees.h"
kusano fc6ab3
#include "inflate.h"
kusano fc6ab3
#include "inffast.h"
kusano fc6ab3
kusano fc6ab3
#ifdef MAKEFIXED
kusano fc6ab3
#  ifndef BUILDFIXED
kusano fc6ab3
#    define BUILDFIXED
kusano fc6ab3
#  endif
kusano fc6ab3
#endif
kusano fc6ab3
kusano fc6ab3
/* function prototypes */
kusano fc6ab3
local void fixedtables OF((struct inflate_state FAR *state));
kusano fc6ab3
local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
kusano fc6ab3
                           unsigned copy));
kusano fc6ab3
#ifdef BUILDFIXED
kusano fc6ab3
   void makefixed OF((void));
kusano fc6ab3
#endif
kusano fc6ab3
local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
kusano fc6ab3
                              unsigned len));
kusano fc6ab3
kusano fc6ab3
int ZEXPORT inflateResetKeep(strm)
kusano fc6ab3
z_streamp strm;
kusano fc6ab3
{
kusano fc6ab3
    struct inflate_state FAR *state;
kusano fc6ab3
kusano fc6ab3
    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
kusano fc6ab3
    state = (struct inflate_state FAR *)strm->state;
kusano fc6ab3
    strm->total_in = strm->total_out = state->total = 0;
kusano fc6ab3
    strm->msg = Z_NULL;
kusano fc6ab3
    if (state->wrap)        /* to support ill-conceived Java test suite */
kusano fc6ab3
        strm->adler = state->wrap & 1;
kusano fc6ab3
    state->mode = HEAD;
kusano fc6ab3
    state->last = 0;
kusano fc6ab3
    state->havedict = 0;
kusano fc6ab3
    state->dmax = 32768U;
kusano fc6ab3
    state->head = Z_NULL;
kusano fc6ab3
    state->hold = 0;
kusano fc6ab3
    state->bits = 0;
kusano fc6ab3
    state->lencode = state->distcode = state->next = state->codes;
kusano fc6ab3
    state->sane = 1;
kusano fc6ab3
    state->back = -1;
kusano fc6ab3
    Tracev((stderr, "inflate: reset\n"));
kusano fc6ab3
    return Z_OK;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
int ZEXPORT inflateReset(strm)
kusano fc6ab3
z_streamp strm;
kusano fc6ab3
{
kusano fc6ab3
    struct inflate_state FAR *state;
kusano fc6ab3
kusano fc6ab3
    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
kusano fc6ab3
    state = (struct inflate_state FAR *)strm->state;
kusano fc6ab3
    state->wsize = 0;
kusano fc6ab3
    state->whave = 0;
kusano fc6ab3
    state->wnext = 0;
kusano fc6ab3
    return inflateResetKeep(strm);
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
int ZEXPORT inflateReset2(strm, windowBits)
kusano fc6ab3
z_streamp strm;
kusano fc6ab3
int windowBits;
kusano fc6ab3
{
kusano fc6ab3
    int wrap;
kusano fc6ab3
    struct inflate_state FAR *state;
kusano fc6ab3
kusano fc6ab3
    /* get the state */
kusano fc6ab3
    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
kusano fc6ab3
    state = (struct inflate_state FAR *)strm->state;
kusano fc6ab3
kusano fc6ab3
    /* extract wrap request from windowBits parameter */
kusano fc6ab3
    if (windowBits < 0) {
kusano fc6ab3
        wrap = 0;
kusano fc6ab3
        windowBits = -windowBits;
kusano fc6ab3
    }
kusano fc6ab3
    else {
kusano fc6ab3
        wrap = (windowBits >> 4) + 1;
kusano fc6ab3
#ifdef GUNZIP
kusano fc6ab3
        if (windowBits < 48)
kusano fc6ab3
            windowBits &= 15;
kusano fc6ab3
#endif
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
    /* set number of window bits, free window if different */
kusano fc6ab3
    if (windowBits && (windowBits < 8 || windowBits > 15))
kusano fc6ab3
        return Z_STREAM_ERROR;
kusano fc6ab3
    if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
kusano fc6ab3
        ZFREE(strm, state->window);
kusano fc6ab3
        state->window = Z_NULL;
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
    /* update state and reset the rest of it */
kusano fc6ab3
    state->wrap = wrap;
kusano fc6ab3
    state->wbits = (unsigned)windowBits;
kusano fc6ab3
    return inflateReset(strm);
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
kusano fc6ab3
z_streamp strm;
kusano fc6ab3
int windowBits;
kusano fc6ab3
const char *version;
kusano fc6ab3
int stream_size;
kusano fc6ab3
{
kusano fc6ab3
    int ret;
kusano fc6ab3
    struct inflate_state FAR *state;
kusano fc6ab3
kusano fc6ab3
    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
kusano fc6ab3
        stream_size != (int)(sizeof(z_stream)))
kusano fc6ab3
        return Z_VERSION_ERROR;
kusano fc6ab3
    if (strm == Z_NULL) return Z_STREAM_ERROR;
kusano fc6ab3
    strm->msg = Z_NULL;                 /* in case we return an error */
kusano fc6ab3
    if (strm->zalloc == (alloc_func)0) {
kusano fc6ab3
#ifdef Z_SOLO
kusano fc6ab3
        return Z_STREAM_ERROR;
kusano fc6ab3
#else
kusano fc6ab3
        strm->zalloc = zcalloc;
kusano fc6ab3
        strm->opaque = (voidpf)0;
kusano fc6ab3
#endif
kusano fc6ab3
    }
kusano fc6ab3
    if (strm->zfree == (free_func)0)
kusano fc6ab3
#ifdef Z_SOLO
kusano fc6ab3
        return Z_STREAM_ERROR;
kusano fc6ab3
#else
kusano fc6ab3
        strm->zfree = zcfree;
kusano fc6ab3
#endif
kusano fc6ab3
    state = (struct inflate_state FAR *)
kusano fc6ab3
            ZALLOC(strm, 1, sizeof(struct inflate_state));
kusano fc6ab3
    if (state == Z_NULL) return Z_MEM_ERROR;
kusano fc6ab3
    Tracev((stderr, "inflate: allocated\n"));
kusano fc6ab3
    strm->state = (struct internal_state FAR *)state;
kusano fc6ab3
    state->window = Z_NULL;
kusano fc6ab3
    ret = inflateReset2(strm, windowBits);
kusano fc6ab3
    if (ret != Z_OK) {
kusano fc6ab3
        ZFREE(strm, state);
kusano fc6ab3
        strm->state = Z_NULL;
kusano fc6ab3
    }
kusano fc6ab3
    return ret;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
int ZEXPORT inflateInit_(strm, version, stream_size)
kusano fc6ab3
z_streamp strm;
kusano fc6ab3
const char *version;
kusano fc6ab3
int stream_size;
kusano fc6ab3
{
kusano fc6ab3
    return inflateInit2_(strm, DEF_WBITS, version, stream_size);
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
int ZEXPORT inflatePrime(strm, bits, value)
kusano fc6ab3
z_streamp strm;
kusano fc6ab3
int bits;
kusano fc6ab3
int value;
kusano fc6ab3
{
kusano fc6ab3
    struct inflate_state FAR *state;
kusano fc6ab3
kusano fc6ab3
    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
kusano fc6ab3
    state = (struct inflate_state FAR *)strm->state;
kusano fc6ab3
    if (bits < 0) {
kusano fc6ab3
        state->hold = 0;
kusano fc6ab3
        state->bits = 0;
kusano fc6ab3
        return Z_OK;
kusano fc6ab3
    }
kusano fc6ab3
    if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
kusano fc6ab3
    value &= (1L << bits) - 1;
kusano fc6ab3
    state->hold += value << state->bits;
kusano fc6ab3
    state->bits += bits;
kusano fc6ab3
    return Z_OK;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
/*
kusano fc6ab3
   Return state with length and distance decoding tables and index sizes set to
kusano fc6ab3
   fixed code decoding.  Normally this returns fixed tables from inffixed.h.
kusano fc6ab3
   If BUILDFIXED is defined, then instead this routine builds the tables the
kusano fc6ab3
   first time it's called, and returns those tables the first time and
kusano fc6ab3
   thereafter.  This reduces the size of the code by about 2K bytes, in
kusano fc6ab3
   exchange for a little execution time.  However, BUILDFIXED should not be
kusano fc6ab3
   used for threaded applications, since the rewriting of the tables and virgin
kusano fc6ab3
   may not be thread-safe.
kusano fc6ab3
 */
kusano fc6ab3
local void fixedtables(state)
kusano fc6ab3
struct inflate_state FAR *state;
kusano fc6ab3
{
kusano fc6ab3
#ifdef BUILDFIXED
kusano fc6ab3
    static int virgin = 1;
kusano fc6ab3
    static code *lenfix, *distfix;
kusano fc6ab3
    static code fixed[544];
kusano fc6ab3
kusano fc6ab3
    /* build fixed huffman tables if first call (may not be thread safe) */
kusano fc6ab3
    if (virgin) {
kusano fc6ab3
        unsigned sym, bits;
kusano fc6ab3
        static code *next;
kusano fc6ab3
kusano fc6ab3
        /* literal/length table */
kusano fc6ab3
        sym = 0;
kusano fc6ab3
        while (sym < 144) state->lens[sym++] = 8;
kusano fc6ab3
        while (sym < 256) state->lens[sym++] = 9;
kusano fc6ab3
        while (sym < 280) state->lens[sym++] = 7;
kusano fc6ab3
        while (sym < 288) state->lens[sym++] = 8;
kusano fc6ab3
        next = fixed;
kusano fc6ab3
        lenfix = next;
kusano fc6ab3
        bits = 9;
kusano fc6ab3
        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
kusano fc6ab3
kusano fc6ab3
        /* distance table */
kusano fc6ab3
        sym = 0;
kusano fc6ab3
        while (sym < 32) state->lens[sym++] = 5;
kusano fc6ab3
        distfix = next;
kusano fc6ab3
        bits = 5;
kusano fc6ab3
        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
kusano fc6ab3
kusano fc6ab3
        /* do this just once */
kusano fc6ab3
        virgin = 0;
kusano fc6ab3
    }
kusano fc6ab3
#else /* !BUILDFIXED */
kusano fc6ab3
#   include "inffixed.h"
kusano fc6ab3
#endif /* BUILDFIXED */
kusano fc6ab3
    state->lencode = lenfix;
kusano fc6ab3
    state->lenbits = 9;
kusano fc6ab3
    state->distcode = distfix;
kusano fc6ab3
    state->distbits = 5;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
#ifdef MAKEFIXED
kusano fc6ab3
#include <stdio.h></stdio.h>
kusano fc6ab3
kusano fc6ab3
/*
kusano fc6ab3
   Write out the inffixed.h that is #include'd above.  Defining MAKEFIXED also
kusano fc6ab3
   defines BUILDFIXED, so the tables are built on the fly.  makefixed() writes
kusano fc6ab3
   those tables to stdout, which would be piped to inffixed.h.  A small program
kusano fc6ab3
   can simply call makefixed to do this:
kusano fc6ab3
kusano fc6ab3
    void makefixed(void);
kusano fc6ab3
kusano fc6ab3
    int main(void)
kusano fc6ab3
    {
kusano fc6ab3
        makefixed();
kusano fc6ab3
        return 0;
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
   Then that can be linked with zlib built with MAKEFIXED defined and run:
kusano fc6ab3
kusano fc6ab3
    a.out > inffixed.h
kusano fc6ab3
 */
kusano fc6ab3
void makefixed()
kusano fc6ab3
{
kusano fc6ab3
    unsigned low, size;
kusano fc6ab3
    struct inflate_state state;
kusano fc6ab3
kusano fc6ab3
    fixedtables(&state);
kusano fc6ab3
    puts("    /* inffixed.h -- table for decoding fixed codes");
kusano fc6ab3
    puts("     * Generated automatically by makefixed().");
kusano fc6ab3
    puts("     */");
kusano fc6ab3
    puts("");
kusano fc6ab3
    puts("    /* WARNING: this file should *not* be used by applications.");
kusano fc6ab3
    puts("       It is part of the implementation of this library and is");
kusano fc6ab3
    puts("       subject to change. Applications should only use zlib.h.");
kusano fc6ab3
    puts("     */");
kusano fc6ab3
    puts("");
kusano fc6ab3
    size = 1U << 9;
kusano fc6ab3
    printf("    static const code lenfix[%u] = {", size);
kusano fc6ab3
    low = 0;
kusano fc6ab3
    for (;;) {
kusano fc6ab3
        if ((low % 7) == 0) printf("\n        ");
kusano fc6ab3
        printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
kusano fc6ab3
               state.lencode[low].bits, state.lencode[low].val);
kusano fc6ab3
        if (++low == size) break;
kusano fc6ab3
        putchar(',');
kusano fc6ab3
    }
kusano fc6ab3
    puts("\n    };");
kusano fc6ab3
    size = 1U << 5;
kusano fc6ab3
    printf("\n    static const code distfix[%u] = {", size);
kusano fc6ab3
    low = 0;
kusano fc6ab3
    for (;;) {
kusano fc6ab3
        if ((low % 6) == 0) printf("\n        ");
kusano fc6ab3
        printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
kusano fc6ab3
               state.distcode[low].val);
kusano fc6ab3
        if (++low == size) break;
kusano fc6ab3
        putchar(',');
kusano fc6ab3
    }
kusano fc6ab3
    puts("\n    };");
kusano fc6ab3
}
kusano fc6ab3
#endif /* MAKEFIXED */
kusano fc6ab3
kusano fc6ab3
/*
kusano fc6ab3
   Update the window with the last wsize (normally 32K) bytes written before
kusano fc6ab3
   returning.  If window does not exist yet, create it.  This is only called
kusano fc6ab3
   when a window is already in use, or when output has been written during this
kusano fc6ab3
   inflate call, but the end of the deflate stream has not been reached yet.
kusano fc6ab3
   It is also called to create a window for dictionary data when a dictionary
kusano fc6ab3
   is loaded.
kusano fc6ab3
kusano fc6ab3
   Providing output buffers larger than 32K to inflate() should provide a speed
kusano fc6ab3
   advantage, since only the last 32K of output is copied to the sliding window
kusano fc6ab3
   upon return from inflate(), and since all distances after the first 32K of
kusano fc6ab3
   output will fall in the output data, making match copies simpler and faster.
kusano fc6ab3
   The advantage may be dependent on the size of the processor's data caches.
kusano fc6ab3
 */
kusano fc6ab3
local int updatewindow(strm, end, copy)
kusano fc6ab3
z_streamp strm;
kusano fc6ab3
const Bytef *end;
kusano fc6ab3
unsigned copy;
kusano fc6ab3
{
kusano fc6ab3
    struct inflate_state FAR *state;
kusano fc6ab3
    unsigned dist;
kusano fc6ab3
kusano fc6ab3
    state = (struct inflate_state FAR *)strm->state;
kusano fc6ab3
kusano fc6ab3
    /* if it hasn't been done already, allocate space for the window */
kusano fc6ab3
    if (state->window == Z_NULL) {
kusano fc6ab3
        state->window = (unsigned char FAR *)
kusano fc6ab3
                        ZALLOC(strm, 1U << state->wbits,
kusano fc6ab3
                               sizeof(unsigned char));
kusano fc6ab3
        if (state->window == Z_NULL) return 1;
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
    /* if window not in use yet, initialize */
kusano fc6ab3
    if (state->wsize == 0) {
kusano fc6ab3
        state->wsize = 1U << state->wbits;
kusano fc6ab3
        state->wnext = 0;
kusano fc6ab3
        state->whave = 0;
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
    /* copy state->wsize or less output bytes into the circular window */
kusano fc6ab3
    if (copy >= state->wsize) {
kusano fc6ab3
        zmemcpy(state->window, end - state->wsize, state->wsize);
kusano fc6ab3
        state->wnext = 0;
kusano fc6ab3
        state->whave = state->wsize;
kusano fc6ab3
    }
kusano fc6ab3
    else {
kusano fc6ab3
        dist = state->wsize - state->wnext;
kusano fc6ab3
        if (dist > copy) dist = copy;
kusano fc6ab3
        zmemcpy(state->window + state->wnext, end - copy, dist);
kusano fc6ab3
        copy -= dist;
kusano fc6ab3
        if (copy) {
kusano fc6ab3
            zmemcpy(state->window, end - copy, copy);
kusano fc6ab3
            state->wnext = copy;
kusano fc6ab3
            state->whave = state->wsize;
kusano fc6ab3
        }
kusano fc6ab3
        else {
kusano fc6ab3
            state->wnext += dist;
kusano fc6ab3
            if (state->wnext == state->wsize) state->wnext = 0;
kusano fc6ab3
            if (state->whave < state->wsize) state->whave += dist;
kusano fc6ab3
        }
kusano fc6ab3
    }
kusano fc6ab3
    return 0;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
/* Macros for inflate(): */
kusano fc6ab3
kusano fc6ab3
/* check function to use adler32() for zlib or crc32() for gzip */
kusano fc6ab3
#ifdef GUNZIP
kusano fc6ab3
#  define UPDATE(check, buf, len) \
kusano fc6ab3
    (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
kusano fc6ab3
#else
kusano fc6ab3
#  define UPDATE(check, buf, len) adler32(check, buf, len)
kusano fc6ab3
#endif
kusano fc6ab3
kusano fc6ab3
/* check macros for header crc */
kusano fc6ab3
#ifdef GUNZIP
kusano fc6ab3
#  define CRC2(check, word) \
kusano fc6ab3
    do { \
kusano fc6ab3
        hbuf[0] = (unsigned char)(word); \
kusano fc6ab3
        hbuf[1] = (unsigned char)((word) >> 8); \
kusano fc6ab3
        check = crc32(check, hbuf, 2); \
kusano fc6ab3
    } while (0)
kusano fc6ab3
kusano fc6ab3
#  define CRC4(check, word) \
kusano fc6ab3
    do { \
kusano fc6ab3
        hbuf[0] = (unsigned char)(word); \
kusano fc6ab3
        hbuf[1] = (unsigned char)((word) >> 8); \
kusano fc6ab3
        hbuf[2] = (unsigned char)((word) >> 16); \
kusano fc6ab3
        hbuf[3] = (unsigned char)((word) >> 24); \
kusano fc6ab3
        check = crc32(check, hbuf, 4); \
kusano fc6ab3
    } while (0)
kusano fc6ab3
#endif
kusano fc6ab3
kusano fc6ab3
/* Load registers with state in inflate() for speed */
kusano fc6ab3
#define LOAD() \
kusano fc6ab3
    do { \
kusano fc6ab3
        put = strm->next_out; \
kusano fc6ab3
        left = strm->avail_out; \
kusano fc6ab3
        next = strm->next_in; \
kusano fc6ab3
        have = strm->avail_in; \
kusano fc6ab3
        hold = state->hold; \
kusano fc6ab3
        bits = state->bits; \
kusano fc6ab3
    } while (0)
kusano fc6ab3
kusano fc6ab3
/* Restore state from registers in inflate() */
kusano fc6ab3
#define RESTORE() \
kusano fc6ab3
    do { \
kusano fc6ab3
        strm->next_out = put; \
kusano fc6ab3
        strm->avail_out = left; \
kusano fc6ab3
        strm->next_in = next; \
kusano fc6ab3
        strm->avail_in = have; \
kusano fc6ab3
        state->hold = hold; \
kusano fc6ab3
        state->bits = bits; \
kusano fc6ab3
    } while (0)
kusano fc6ab3
kusano fc6ab3
/* Clear the input bit accumulator */
kusano fc6ab3
#define INITBITS() \
kusano fc6ab3
    do { \
kusano fc6ab3
        hold = 0; \
kusano fc6ab3
        bits = 0; \
kusano fc6ab3
    } while (0)
kusano fc6ab3
kusano fc6ab3
/* Get a byte of input into the bit accumulator, or return from inflate()
kusano fc6ab3
   if there is no input available. */
kusano fc6ab3
#define PULLBYTE() \
kusano fc6ab3
    do { \
kusano fc6ab3
        if (have == 0) goto inf_leave; \
kusano fc6ab3
        have--; \
kusano fc6ab3
        hold += (unsigned long)(*next++) << bits; \
kusano fc6ab3
        bits += 8; \
kusano fc6ab3
    } while (0)
kusano fc6ab3
kusano fc6ab3
/* Assure that there are at least n bits in the bit accumulator.  If there is
kusano fc6ab3
   not enough available input to do that, then return from inflate(). */
kusano fc6ab3
#define NEEDBITS(n) \
kusano fc6ab3
    do { \
kusano fc6ab3
        while (bits < (unsigned)(n)) \
kusano fc6ab3
            PULLBYTE(); \
kusano fc6ab3
    } while (0)
kusano fc6ab3
kusano fc6ab3
/* Return the low n bits of the bit accumulator (n < 16) */
kusano fc6ab3
#define BITS(n) \
kusano fc6ab3
    ((unsigned)hold & ((1U << (n)) - 1))
kusano fc6ab3
kusano fc6ab3
/* Remove n bits from the bit accumulator */
kusano fc6ab3
#define DROPBITS(n) \
kusano fc6ab3
    do { \
kusano fc6ab3
        hold >>= (n); \
kusano fc6ab3
        bits -= (unsigned)(n); \
kusano fc6ab3
    } while (0)
kusano fc6ab3
kusano fc6ab3
/* Remove zero to seven bits as needed to go to a byte boundary */
kusano fc6ab3
#define BYTEBITS() \
kusano fc6ab3
    do { \
kusano fc6ab3
        hold >>= bits & 7; \
kusano fc6ab3
        bits -= bits & 7; \
kusano fc6ab3
    } while (0)
kusano fc6ab3
kusano fc6ab3
/*
kusano fc6ab3
   inflate() uses a state machine to process as much input data and generate as
kusano fc6ab3
   much output data as possible before returning.  The state machine is
kusano fc6ab3
   structured roughly as follows:
kusano fc6ab3
kusano fc6ab3
    for (;;) switch (state) {
kusano fc6ab3
    ...
kusano fc6ab3
    case STATEn:
kusano fc6ab3
        if (not enough input data or output space to make progress)
kusano fc6ab3
            return;
kusano fc6ab3
        ... make progress ...
kusano fc6ab3
        state = STATEm;
kusano fc6ab3
        break;
kusano fc6ab3
    ...
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
   so when inflate() is called again, the same case is attempted again, and
kusano fc6ab3
   if the appropriate resources are provided, the machine proceeds to the
kusano fc6ab3
   next state.  The NEEDBITS() macro is usually the way the state evaluates
kusano fc6ab3
   whether it can proceed or should return.  NEEDBITS() does the return if
kusano fc6ab3
   the requested bits are not available.  The typical use of the BITS macros
kusano fc6ab3
   is:
kusano fc6ab3
kusano fc6ab3
        NEEDBITS(n);
kusano fc6ab3
        ... do something with BITS(n) ...
kusano fc6ab3
        DROPBITS(n);
kusano fc6ab3
kusano fc6ab3
   where NEEDBITS(n) either returns from inflate() if there isn't enough
kusano fc6ab3
   input left to load n bits into the accumulator, or it continues.  BITS(n)
kusano fc6ab3
   gives the low n bits in the accumulator.  When done, DROPBITS(n) drops
kusano fc6ab3
   the low n bits off the accumulator.  INITBITS() clears the accumulator
kusano fc6ab3
   and sets the number of available bits to zero.  BYTEBITS() discards just
kusano fc6ab3
   enough bits to put the accumulator on a byte boundary.  After BYTEBITS()
kusano fc6ab3
   and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
kusano fc6ab3
kusano fc6ab3
   NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
kusano fc6ab3
   if there is no input available.  The decoding of variable length codes uses
kusano fc6ab3
   PULLBYTE() directly in order to pull just enough bytes to decode the next
kusano fc6ab3
   code, and no more.
kusano fc6ab3
kusano fc6ab3
   Some states loop until they get enough input, making sure that enough
kusano fc6ab3
   state information is maintained to continue the loop where it left off
kusano fc6ab3
   if NEEDBITS() returns in the loop.  For example, want, need, and keep
kusano fc6ab3
   would all have to actually be part of the saved state in case NEEDBITS()
kusano fc6ab3
   returns:
kusano fc6ab3
kusano fc6ab3
    case STATEw:
kusano fc6ab3
        while (want < need) {
kusano fc6ab3
            NEEDBITS(n);
kusano fc6ab3
            keep[want++] = BITS(n);
kusano fc6ab3
            DROPBITS(n);
kusano fc6ab3
        }
kusano fc6ab3
        state = STATEx;
kusano fc6ab3
    case STATEx:
kusano fc6ab3
kusano fc6ab3
   As shown above, if the next state is also the next case, then the break
kusano fc6ab3
   is omitted.
kusano fc6ab3
kusano fc6ab3
   A state may also return if there is not enough output space available to
kusano fc6ab3
   complete that state.  Those states are copying stored data, writing a
kusano fc6ab3
   literal byte, and copying a matching string.
kusano fc6ab3
kusano fc6ab3
   When returning, a "goto inf_leave" is used to update the total counters,
kusano fc6ab3
   update the check value, and determine whether any progress has been made
kusano fc6ab3
   during that inflate() call in order to return the proper return code.
kusano fc6ab3
   Progress is defined as a change in either strm->avail_in or strm->avail_out.
kusano fc6ab3
   When there is a window, goto inf_leave will update the window with the last
kusano fc6ab3
   output written.  If a goto inf_leave occurs in the middle of decompression
kusano fc6ab3
   and there is no window currently, goto inf_leave will create one and copy
kusano fc6ab3
   output to the window for the next call of inflate().
kusano fc6ab3
kusano fc6ab3
   In this implementation, the flush parameter of inflate() only affects the
kusano fc6ab3
   return code (per zlib.h).  inflate() always writes as much as possible to
kusano fc6ab3
   strm->next_out, given the space available and the provided input--the effect
kusano fc6ab3
   documented in zlib.h of Z_SYNC_FLUSH.  Furthermore, inflate() always defers
kusano fc6ab3
   the allocation of and copying into a sliding window until necessary, which
kusano fc6ab3
   provides the effect documented in zlib.h for Z_FINISH when the entire input
kusano fc6ab3
   stream available.  So the only thing the flush parameter actually does is:
kusano fc6ab3
   when flush is set to Z_FINISH, inflate() cannot return Z_OK.  Instead it
kusano fc6ab3
   will return Z_BUF_ERROR if it has not reached the end of the stream.
kusano fc6ab3
 */
kusano fc6ab3
kusano fc6ab3
int ZEXPORT inflate(strm, flush)
kusano fc6ab3
z_streamp strm;
kusano fc6ab3
int flush;
kusano fc6ab3
{
kusano fc6ab3
    struct inflate_state FAR *state;
kusano fc6ab3
    z_const unsigned char FAR *next;    /* next input */
kusano fc6ab3
    unsigned char FAR *put;     /* next output */
kusano fc6ab3
    unsigned have, left;        /* available input and output */
kusano fc6ab3
    unsigned long hold;         /* bit buffer */
kusano fc6ab3
    unsigned bits;              /* bits in bit buffer */
kusano fc6ab3
    unsigned in, out;           /* save starting available input and output */
kusano fc6ab3
    unsigned copy;              /* number of stored or match bytes to copy */
kusano fc6ab3
    unsigned char FAR *from;    /* where to copy match bytes from */
kusano fc6ab3
    code here;                  /* current decoding table entry */
kusano fc6ab3
    code last;                  /* parent table entry */
kusano fc6ab3
    unsigned len;               /* length to copy for repeats, bits to drop */
kusano fc6ab3
    int ret;                    /* return code */
kusano fc6ab3
#ifdef GUNZIP
kusano fc6ab3
    unsigned char hbuf[4];      /* buffer for gzip header crc calculation */
kusano fc6ab3
#endif
kusano fc6ab3
    static const unsigned short order[19] = /* permutation of code lengths */
kusano fc6ab3
        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
kusano fc6ab3
kusano fc6ab3
    if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
kusano fc6ab3
        (strm->next_in == Z_NULL && strm->avail_in != 0))
kusano fc6ab3
        return Z_STREAM_ERROR;
kusano fc6ab3
kusano fc6ab3
    state = (struct inflate_state FAR *)strm->state;
kusano fc6ab3
    if (state->mode == TYPE) state->mode = TYPEDO;      /* skip check */
kusano fc6ab3
    LOAD();
kusano fc6ab3
    in = have;
kusano fc6ab3
    out = left;
kusano fc6ab3
    ret = Z_OK;
kusano fc6ab3
    for (;;)
kusano fc6ab3
        switch (state->mode) {
kusano fc6ab3
        case HEAD:
kusano fc6ab3
            if (state->wrap == 0) {
kusano fc6ab3
                state->mode = TYPEDO;
kusano fc6ab3
                break;
kusano fc6ab3
            }
kusano fc6ab3
            NEEDBITS(16);
kusano fc6ab3
#ifdef GUNZIP
kusano fc6ab3
            if ((state->wrap & 2) && hold == 0x8b1f) {  /* gzip header */
kusano fc6ab3
                state->check = crc32(0L, Z_NULL, 0);
kusano fc6ab3
                CRC2(state->check, hold);
kusano fc6ab3
                INITBITS();
kusano fc6ab3
                state->mode = FLAGS;
kusano fc6ab3
                break;
kusano fc6ab3
            }
kusano fc6ab3
            state->flags = 0;           /* expect zlib header */
kusano fc6ab3
            if (state->head != Z_NULL)
kusano fc6ab3
                state->head->done = -1;
kusano fc6ab3
            if (!(state->wrap & 1) ||   /* check if zlib header allowed */
kusano fc6ab3
#else
kusano fc6ab3
            if (
kusano fc6ab3
#endif
kusano fc6ab3
                ((BITS(8) << 8) + (hold >> 8)) % 31) {
kusano fc6ab3
                strm->msg = (char *)"incorrect header check";
kusano fc6ab3
                state->mode = BAD;
kusano fc6ab3
                break;
kusano fc6ab3
            }
kusano fc6ab3
            if (BITS(4) != Z_DEFLATED) {
kusano fc6ab3
                strm->msg = (char *)"unknown compression method";
kusano fc6ab3
                state->mode = BAD;
kusano fc6ab3
                break;
kusano fc6ab3
            }
kusano fc6ab3
            DROPBITS(4);
kusano fc6ab3
            len = BITS(4) + 8;
kusano fc6ab3
            if (state->wbits == 0)
kusano fc6ab3
                state->wbits = len;
kusano fc6ab3
            else if (len > state->wbits) {
kusano fc6ab3
                strm->msg = (char *)"invalid window size";
kusano fc6ab3
                state->mode = BAD;
kusano fc6ab3
                break;
kusano fc6ab3
            }
kusano fc6ab3
            state->dmax = 1U << len;
kusano fc6ab3
            Tracev((stderr, "inflate:   zlib header ok\n"));
kusano fc6ab3
            strm->adler = state->check = adler32(0L, Z_NULL, 0);
kusano fc6ab3
            state->mode = hold & 0x200 ? DICTID : TYPE;
kusano fc6ab3
            INITBITS();
kusano fc6ab3
            break;
kusano fc6ab3
#ifdef GUNZIP
kusano fc6ab3
        case FLAGS:
kusano fc6ab3
            NEEDBITS(16);
kusano fc6ab3
            state->flags = (int)(hold);
kusano fc6ab3
            if ((state->flags & 0xff) != Z_DEFLATED) {
kusano fc6ab3
                strm->msg = (char *)"unknown compression method";
kusano fc6ab3
                state->mode = BAD;
kusano fc6ab3
                break;
kusano fc6ab3
            }
kusano fc6ab3
            if (state->flags & 0xe000) {
kusano fc6ab3
                strm->msg = (char *)"unknown header flags set";
kusano fc6ab3
                state->mode = BAD;
kusano fc6ab3
                break;
kusano fc6ab3
            }
kusano fc6ab3
            if (state->head != Z_NULL)
kusano fc6ab3
                state->head->text = (int)((hold >> 8) & 1);
kusano fc6ab3
            if (state->flags & 0x0200) CRC2(state->check, hold);
kusano fc6ab3
            INITBITS();
kusano fc6ab3
            state->mode = TIME;
kusano fc6ab3
        case TIME:
kusano fc6ab3
            NEEDBITS(32);
kusano fc6ab3
            if (state->head != Z_NULL)
kusano fc6ab3
                state->head->time = hold;
kusano fc6ab3
            if (state->flags & 0x0200) CRC4(state->check, hold);
kusano fc6ab3
            INITBITS();
kusano fc6ab3
            state->mode = OS;
kusano fc6ab3
        case OS:
kusano fc6ab3
            NEEDBITS(16);
kusano fc6ab3
            if (state->head != Z_NULL) {
kusano fc6ab3
                state->head->xflags = (int)(hold & 0xff);
kusano fc6ab3
                state->head->os = (int)(hold >> 8);
kusano fc6ab3
            }
kusano fc6ab3
            if (state->flags & 0x0200) CRC2(state->check, hold);
kusano fc6ab3
            INITBITS();
kusano fc6ab3
            state->mode = EXLEN;
kusano fc6ab3
        case EXLEN:
kusano fc6ab3
            if (state->flags & 0x0400) {
kusano fc6ab3
                NEEDBITS(16);
kusano fc6ab3
                state->length = (unsigned)(hold);
kusano fc6ab3
                if (state->head != Z_NULL)
kusano fc6ab3
                    state->head->extra_len = (unsigned)hold;
kusano fc6ab3
                if (state->flags & 0x0200) CRC2(state->check, hold);
kusano fc6ab3
                INITBITS();
kusano fc6ab3
            }
kusano fc6ab3
            else if (state->head != Z_NULL)
kusano fc6ab3
                state->head->extra = Z_NULL;
kusano fc6ab3
            state->mode = EXTRA;
kusano fc6ab3
        case EXTRA:
kusano fc6ab3
            if (state->flags & 0x0400) {
kusano fc6ab3
                copy = state->length;
kusano fc6ab3
                if (copy > have) copy = have;
kusano fc6ab3
                if (copy) {
kusano fc6ab3
                    if (state->head != Z_NULL &&
kusano fc6ab3
                        state->head->extra != Z_NULL) {
kusano fc6ab3
                        len = state->head->extra_len - state->length;
kusano fc6ab3
                        zmemcpy(state->head->extra + len, next,
kusano fc6ab3
                                len + copy > state->head->extra_max ?
kusano fc6ab3
                                state->head->extra_max - len : copy);
kusano fc6ab3
                    }
kusano fc6ab3
                    if (state->flags & 0x0200)
kusano fc6ab3
                        state->check = crc32(state->check, next, copy);
kusano fc6ab3
                    have -= copy;
kusano fc6ab3
                    next += copy;
kusano fc6ab3
                    state->length -= copy;
kusano fc6ab3
                }
kusano fc6ab3
                if (state->length) goto inf_leave;
kusano fc6ab3
            }
kusano fc6ab3
            state->length = 0;
kusano fc6ab3
            state->mode = NAME;
kusano fc6ab3
        case NAME:
kusano fc6ab3
            if (state->flags & 0x0800) {
kusano fc6ab3
                if (have == 0) goto inf_leave;
kusano fc6ab3
                copy = 0;
kusano fc6ab3
                do {
kusano fc6ab3
                    len = (unsigned)(next[copy++]);
kusano fc6ab3
                    if (state->head != Z_NULL &&
kusano fc6ab3
                            state->head->name != Z_NULL &&
kusano fc6ab3
                            state->length < state->head->name_max)
kusano fc6ab3
                        state->head->name[state->length++] = len;
kusano fc6ab3
                } while (len && copy < have);
kusano fc6ab3
                if (state->flags & 0x0200)
kusano fc6ab3
                    state->check = crc32(state->check, next, copy);
kusano fc6ab3
                have -= copy;
kusano fc6ab3
                next += copy;
kusano fc6ab3
                if (len) goto inf_leave;
kusano fc6ab3
            }
kusano fc6ab3
            else if (state->head != Z_NULL)
kusano fc6ab3
                state->head->name = Z_NULL;
kusano fc6ab3
            state->length = 0;
kusano fc6ab3
            state->mode = COMMENT;
kusano fc6ab3
        case COMMENT:
kusano fc6ab3
            if (state->flags & 0x1000) {
kusano fc6ab3
                if (have == 0) goto inf_leave;
kusano fc6ab3
                copy = 0;
kusano fc6ab3
                do {
kusano fc6ab3
                    len = (unsigned)(next[copy++]);
kusano fc6ab3
                    if (state->head != Z_NULL &&
kusano fc6ab3
                            state->head->comment != Z_NULL &&
kusano fc6ab3
                            state->length < state->head->comm_max)
kusano fc6ab3
                        state->head->comment[state->length++] = len;
kusano fc6ab3
                } while (len && copy < have);
kusano fc6ab3
                if (state->flags & 0x0200)
kusano fc6ab3
                    state->check = crc32(state->check, next, copy);
kusano fc6ab3
                have -= copy;
kusano fc6ab3
                next += copy;
kusano fc6ab3
                if (len) goto inf_leave;
kusano fc6ab3
            }
kusano fc6ab3
            else if (state->head != Z_NULL)
kusano fc6ab3
                state->head->comment = Z_NULL;
kusano fc6ab3
            state->mode = HCRC;
kusano fc6ab3
        case HCRC:
kusano fc6ab3
            if (state->flags & 0x0200) {
kusano fc6ab3
                NEEDBITS(16);
kusano fc6ab3
                if (hold != (state->check & 0xffff)) {
kusano fc6ab3
                    strm->msg = (char *)"header crc mismatch";
kusano fc6ab3
                    state->mode = BAD;
kusano fc6ab3
                    break;
kusano fc6ab3
                }
kusano fc6ab3
                INITBITS();
kusano fc6ab3
            }
kusano fc6ab3
            if (state->head != Z_NULL) {
kusano fc6ab3
                state->head->hcrc = (int)((state->flags >> 9) & 1);
kusano fc6ab3
                state->head->done = 1;
kusano fc6ab3
            }
kusano fc6ab3
            strm->adler = state->check = crc32(0L, Z_NULL, 0);
kusano fc6ab3
            state->mode = TYPE;
kusano fc6ab3
            break;
kusano fc6ab3
#endif
kusano fc6ab3
        case DICTID:
kusano fc6ab3
            NEEDBITS(32);
kusano fc6ab3
            strm->adler = state->check = ZSWAP32(hold);
kusano fc6ab3
            INITBITS();
kusano fc6ab3
            state->mode = DICT;
kusano fc6ab3
        case DICT:
kusano fc6ab3
            if (state->havedict == 0) {
kusano fc6ab3
                RESTORE();
kusano fc6ab3
                return Z_NEED_DICT;
kusano fc6ab3
            }
kusano fc6ab3
            strm->adler = state->check = adler32(0L, Z_NULL, 0);
kusano fc6ab3
            state->mode = TYPE;
kusano fc6ab3
        case TYPE:
kusano fc6ab3
            if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
kusano fc6ab3
        case TYPEDO:
kusano fc6ab3
            if (state->last) {
kusano fc6ab3
                BYTEBITS();
kusano fc6ab3
                state->mode = CHECK;
kusano fc6ab3
                break;
kusano fc6ab3
            }
kusano fc6ab3
            NEEDBITS(3);
kusano fc6ab3
            state->last = BITS(1);
kusano fc6ab3
            DROPBITS(1);
kusano fc6ab3
            switch (BITS(2)) {
kusano fc6ab3
            case 0:                             /* stored block */
kusano fc6ab3
                Tracev((stderr, "inflate:     stored block%s\n",
kusano fc6ab3
                        state->last ? " (last)" : ""));
kusano fc6ab3
                state->mode = STORED;
kusano fc6ab3
                break;
kusano fc6ab3
            case 1:                             /* fixed block */
kusano fc6ab3
                fixedtables(state);
kusano fc6ab3
                Tracev((stderr, "inflate:     fixed codes block%s\n",
kusano fc6ab3
                        state->last ? " (last)" : ""));
kusano fc6ab3
                state->mode = LEN_;             /* decode codes */
kusano fc6ab3
                if (flush == Z_TREES) {
kusano fc6ab3
                    DROPBITS(2);
kusano fc6ab3
                    goto inf_leave;
kusano fc6ab3
                }
kusano fc6ab3
                break;
kusano fc6ab3
            case 2:                             /* dynamic block */
kusano fc6ab3
                Tracev((stderr, "inflate:     dynamic codes block%s\n",
kusano fc6ab3
                        state->last ? " (last)" : ""));
kusano fc6ab3
                state->mode = TABLE;
kusano fc6ab3
                break;
kusano fc6ab3
            case 3:
kusano fc6ab3
                strm->msg = (char *)"invalid block type";
kusano fc6ab3
                state->mode = BAD;
kusano fc6ab3
            }
kusano fc6ab3
            DROPBITS(2);
kusano fc6ab3
            break;
kusano fc6ab3
        case STORED:
kusano fc6ab3
            BYTEBITS();                         /* go to byte boundary */
kusano fc6ab3
            NEEDBITS(32);
kusano fc6ab3
            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
kusano fc6ab3
                strm->msg = (char *)"invalid stored block lengths";
kusano fc6ab3
                state->mode = BAD;
kusano fc6ab3
                break;
kusano fc6ab3
            }
kusano fc6ab3
            state->length = (unsigned)hold & 0xffff;
kusano fc6ab3
            Tracev((stderr, "inflate:       stored length %u\n",
kusano fc6ab3
                    state->length));
kusano fc6ab3
            INITBITS();
kusano fc6ab3
            state->mode = COPY_;
kusano fc6ab3
            if (flush == Z_TREES) goto inf_leave;
kusano fc6ab3
        case COPY_:
kusano fc6ab3
            state->mode = COPY;
kusano fc6ab3
        case COPY:
kusano fc6ab3
            copy = state->length;
kusano fc6ab3
            if (copy) {
kusano fc6ab3
                if (copy > have) copy = have;
kusano fc6ab3
                if (copy > left) copy = left;
kusano fc6ab3
                if (copy == 0) goto inf_leave;
kusano fc6ab3
                zmemcpy(put, next, copy);
kusano fc6ab3
                have -= copy;
kusano fc6ab3
                next += copy;
kusano fc6ab3
                left -= copy;
kusano fc6ab3
                put += copy;
kusano fc6ab3
                state->length -= copy;
kusano fc6ab3
                break;
kusano fc6ab3
            }
kusano fc6ab3
            Tracev((stderr, "inflate:       stored end\n"));
kusano fc6ab3
            state->mode = TYPE;
kusano fc6ab3
            break;
kusano fc6ab3
        case TABLE:
kusano fc6ab3
            NEEDBITS(14);
kusano fc6ab3
            state->nlen = BITS(5) + 257;
kusano fc6ab3
            DROPBITS(5);
kusano fc6ab3
            state->ndist = BITS(5) + 1;
kusano fc6ab3
            DROPBITS(5);
kusano fc6ab3
            state->ncode = BITS(4) + 4;
kusano fc6ab3
            DROPBITS(4);
kusano fc6ab3
#ifndef PKZIP_BUG_WORKAROUND
kusano fc6ab3
            if (state->nlen > 286 || state->ndist > 30) {
kusano fc6ab3
                strm->msg = (char *)"too many length or distance symbols";
kusano fc6ab3
                state->mode = BAD;
kusano fc6ab3
                break;
kusano fc6ab3
            }
kusano fc6ab3
#endif
kusano fc6ab3
            Tracev((stderr, "inflate:       table sizes ok\n"));
kusano fc6ab3
            state->have = 0;
kusano fc6ab3
            state->mode = LENLENS;
kusano fc6ab3
        case LENLENS:
kusano fc6ab3
            while (state->have < state->ncode) {
kusano fc6ab3
                NEEDBITS(3);
kusano fc6ab3
                state->lens[order[state->have++]] = (unsigned short)BITS(3);
kusano fc6ab3
                DROPBITS(3);
kusano fc6ab3
            }
kusano fc6ab3
            while (state->have < 19)
kusano fc6ab3
                state->lens[order[state->have++]] = 0;
kusano fc6ab3
            state->next = state->codes;
kusano fc6ab3
            state->lencode = (const code FAR *)(state->next);
kusano fc6ab3
            state->lenbits = 7;
kusano fc6ab3
            ret = inflate_table(CODES, state->lens, 19, &(state->next),
kusano fc6ab3
                                &(state->lenbits), state->work);
kusano fc6ab3
            if (ret) {
kusano fc6ab3
                strm->msg = (char *)"invalid code lengths set";
kusano fc6ab3
                state->mode = BAD;
kusano fc6ab3
                break;
kusano fc6ab3
            }
kusano fc6ab3
            Tracev((stderr, "inflate:       code lengths ok\n"));
kusano fc6ab3
            state->have = 0;
kusano fc6ab3
            state->mode = CODELENS;
kusano fc6ab3
        case CODELENS:
kusano fc6ab3
            while (state->have < state->nlen + state->ndist) {
kusano fc6ab3
                for (;;) {
kusano fc6ab3
                    here = state->lencode[BITS(state->lenbits)];
kusano fc6ab3
                    if ((unsigned)(here.bits) <= bits) break;
kusano fc6ab3
                    PULLBYTE();
kusano fc6ab3
                }
kusano fc6ab3
                if (here.val < 16) {
kusano fc6ab3
                    DROPBITS(here.bits);
kusano fc6ab3
                    state->lens[state->have++] = here.val;
kusano fc6ab3
                }
kusano fc6ab3
                else {
kusano fc6ab3
                    if (here.val == 16) {
kusano fc6ab3
                        NEEDBITS(here.bits + 2);
kusano fc6ab3
                        DROPBITS(here.bits);
kusano fc6ab3
                        if (state->have == 0) {
kusano fc6ab3
                            strm->msg = (char *)"invalid bit length repeat";
kusano fc6ab3
                            state->mode = BAD;
kusano fc6ab3
                            break;
kusano fc6ab3
                        }
kusano fc6ab3
                        len = state->lens[state->have - 1];
kusano fc6ab3
                        copy = 3 + BITS(2);
kusano fc6ab3
                        DROPBITS(2);
kusano fc6ab3
                    }
kusano fc6ab3
                    else if (here.val == 17) {
kusano fc6ab3
                        NEEDBITS(here.bits + 3);
kusano fc6ab3
                        DROPBITS(here.bits);
kusano fc6ab3
                        len = 0;
kusano fc6ab3
                        copy = 3 + BITS(3);
kusano fc6ab3
                        DROPBITS(3);
kusano fc6ab3
                    }
kusano fc6ab3
                    else {
kusano fc6ab3
                        NEEDBITS(here.bits + 7);
kusano fc6ab3
                        DROPBITS(here.bits);
kusano fc6ab3
                        len = 0;
kusano fc6ab3
                        copy = 11 + BITS(7);
kusano fc6ab3
                        DROPBITS(7);
kusano fc6ab3
                    }
kusano fc6ab3
                    if (state->have + copy > state->nlen + state->ndist) {
kusano fc6ab3
                        strm->msg = (char *)"invalid bit length repeat";
kusano fc6ab3
                        state->mode = BAD;
kusano fc6ab3
                        break;
kusano fc6ab3
                    }
kusano fc6ab3
                    while (copy--)
kusano fc6ab3
                        state->lens[state->have++] = (unsigned short)len;
kusano fc6ab3
                }
kusano fc6ab3
            }
kusano fc6ab3
kusano fc6ab3
            /* handle error breaks in while */
kusano fc6ab3
            if (state->mode == BAD) break;
kusano fc6ab3
kusano fc6ab3
            /* check for end-of-block code (better have one) */
kusano fc6ab3
            if (state->lens[256] == 0) {
kusano fc6ab3
                strm->msg = (char *)"invalid code -- missing end-of-block";
kusano fc6ab3
                state->mode = BAD;
kusano fc6ab3
                break;
kusano fc6ab3
            }
kusano fc6ab3
kusano fc6ab3
            /* build code tables -- note: do not change the lenbits or distbits
kusano fc6ab3
               values here (9 and 6) without reading the comments in inftrees.h
kusano fc6ab3
               concerning the ENOUGH constants, which depend on those values */
kusano fc6ab3
            state->next = state->codes;
kusano fc6ab3
            state->lencode = (const code FAR *)(state->next);
kusano fc6ab3
            state->lenbits = 9;
kusano fc6ab3
            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
kusano fc6ab3
                                &(state->lenbits), state->work);
kusano fc6ab3
            if (ret) {
kusano fc6ab3
                strm->msg = (char *)"invalid literal/lengths set";
kusano fc6ab3
                state->mode = BAD;
kusano fc6ab3
                break;
kusano fc6ab3
            }
kusano fc6ab3
            state->distcode = (const code FAR *)(state->next);
kusano fc6ab3
            state->distbits = 6;
kusano fc6ab3
            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
kusano fc6ab3
                            &(state->next), &(state->distbits), state->work);
kusano fc6ab3
            if (ret) {
kusano fc6ab3
                strm->msg = (char *)"invalid distances set";
kusano fc6ab3
                state->mode = BAD;
kusano fc6ab3
                break;
kusano fc6ab3
            }
kusano fc6ab3
            Tracev((stderr, "inflate:       codes ok\n"));
kusano fc6ab3
            state->mode = LEN_;
kusano fc6ab3
            if (flush == Z_TREES) goto inf_leave;
kusano fc6ab3
        case LEN_:
kusano fc6ab3
            state->mode = LEN;
kusano fc6ab3
        case LEN:
kusano fc6ab3
            if (have >= 6 && left >= 258) {
kusano fc6ab3
                RESTORE();
kusano fc6ab3
                inflate_fast(strm, out);
kusano fc6ab3
                LOAD();
kusano fc6ab3
                if (state->mode == TYPE)
kusano fc6ab3
                    state->back = -1;
kusano fc6ab3
                break;
kusano fc6ab3
            }
kusano fc6ab3
            state->back = 0;
kusano fc6ab3
            for (;;) {
kusano fc6ab3
                here = state->lencode[BITS(state->lenbits)];
kusano fc6ab3
                if ((unsigned)(here.bits) <= bits) break;
kusano fc6ab3
                PULLBYTE();
kusano fc6ab3
            }
kusano fc6ab3
            if (here.op && (here.op & 0xf0) == 0) {
kusano fc6ab3
                last = here;
kusano fc6ab3
                for (;;) {
kusano fc6ab3
                    here = state->lencode[last.val +
kusano fc6ab3
                            (BITS(last.bits + last.op) >> last.bits)];
kusano fc6ab3
                    if ((unsigned)(last.bits + here.bits) <= bits) break;
kusano fc6ab3
                    PULLBYTE();
kusano fc6ab3
                }
kusano fc6ab3
                DROPBITS(last.bits);
kusano fc6ab3
                state->back += last.bits;
kusano fc6ab3
            }
kusano fc6ab3
            DROPBITS(here.bits);
kusano fc6ab3
            state->back += here.bits;
kusano fc6ab3
            state->length = (unsigned)here.val;
kusano fc6ab3
            if ((int)(here.op) == 0) {
kusano fc6ab3
                Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
kusano fc6ab3
                        "inflate:         literal '%c'\n" :
kusano fc6ab3
                        "inflate:         literal 0x%02x\n", here.val));
kusano fc6ab3
                state->mode = LIT;
kusano fc6ab3
                break;
kusano fc6ab3
            }
kusano fc6ab3
            if (here.op & 32) {
kusano fc6ab3
                Tracevv((stderr, "inflate:         end of block\n"));
kusano fc6ab3
                state->back = -1;
kusano fc6ab3
                state->mode = TYPE;
kusano fc6ab3
                break;
kusano fc6ab3
            }
kusano fc6ab3
            if (here.op & 64) {
kusano fc6ab3
                strm->msg = (char *)"invalid literal/length code";
kusano fc6ab3
                state->mode = BAD;
kusano fc6ab3
                break;
kusano fc6ab3
            }
kusano fc6ab3
            state->extra = (unsigned)(here.op) & 15;
kusano fc6ab3
            state->mode = LENEXT;
kusano fc6ab3
        case LENEXT:
kusano fc6ab3
            if (state->extra) {
kusano fc6ab3
                NEEDBITS(state->extra);
kusano fc6ab3
                state->length += BITS(state->extra);
kusano fc6ab3
                DROPBITS(state->extra);
kusano fc6ab3
                state->back += state->extra;
kusano fc6ab3
            }
kusano fc6ab3
            Tracevv((stderr, "inflate:         length %u\n", state->length));
kusano fc6ab3
            state->was = state->length;
kusano fc6ab3
            state->mode = DIST;
kusano fc6ab3
        case DIST:
kusano fc6ab3
            for (;;) {
kusano fc6ab3
                here = state->distcode[BITS(state->distbits)];
kusano fc6ab3
                if ((unsigned)(here.bits) <= bits) break;
kusano fc6ab3
                PULLBYTE();
kusano fc6ab3
            }
kusano fc6ab3
            if ((here.op & 0xf0) == 0) {
kusano fc6ab3
                last = here;
kusano fc6ab3
                for (;;) {
kusano fc6ab3
                    here = state->distcode[last.val +
kusano fc6ab3
                            (BITS(last.bits + last.op) >> last.bits)];
kusano fc6ab3
                    if ((unsigned)(last.bits + here.bits) <= bits) break;
kusano fc6ab3
                    PULLBYTE();
kusano fc6ab3
                }
kusano fc6ab3
                DROPBITS(last.bits);
kusano fc6ab3
                state->back += last.bits;
kusano fc6ab3
            }
kusano fc6ab3
            DROPBITS(here.bits);
kusano fc6ab3
            state->back += here.bits;
kusano fc6ab3
            if (here.op & 64) {
kusano fc6ab3
                strm->msg = (char *)"invalid distance code";
kusano fc6ab3
                state->mode = BAD;
kusano fc6ab3
                break;
kusano fc6ab3
            }
kusano fc6ab3
            state->offset = (unsigned)here.val;
kusano fc6ab3
            state->extra = (unsigned)(here.op) & 15;
kusano fc6ab3
            state->mode = DISTEXT;
kusano fc6ab3
        case DISTEXT:
kusano fc6ab3
            if (state->extra) {
kusano fc6ab3
                NEEDBITS(state->extra);
kusano fc6ab3
                state->offset += BITS(state->extra);
kusano fc6ab3
                DROPBITS(state->extra);
kusano fc6ab3
                state->back += state->extra;
kusano fc6ab3
            }
kusano fc6ab3
#ifdef INFLATE_STRICT
kusano fc6ab3
            if (state->offset > state->dmax) {
kusano fc6ab3
                strm->msg = (char *)"invalid distance too far back";
kusano fc6ab3
                state->mode = BAD;
kusano fc6ab3
                break;
kusano fc6ab3
            }
kusano fc6ab3
#endif
kusano fc6ab3
            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
kusano fc6ab3
            state->mode = MATCH;
kusano fc6ab3
        case MATCH:
kusano fc6ab3
            if (left == 0) goto inf_leave;
kusano fc6ab3
            copy = out - left;
kusano fc6ab3
            if (state->offset > copy) {         /* copy from window */
kusano fc6ab3
                copy = state->offset - copy;
kusano fc6ab3
                if (copy > state->whave) {
kusano fc6ab3
                    if (state->sane) {
kusano fc6ab3
                        strm->msg = (char *)"invalid distance too far back";
kusano fc6ab3
                        state->mode = BAD;
kusano fc6ab3
                        break;
kusano fc6ab3
                    }
kusano fc6ab3
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
kusano fc6ab3
                    Trace((stderr, "inflate.c too far\n"));
kusano fc6ab3
                    copy -= state->whave;
kusano fc6ab3
                    if (copy > state->length) copy = state->length;
kusano fc6ab3
                    if (copy > left) copy = left;
kusano fc6ab3
                    left -= copy;
kusano fc6ab3
                    state->length -= copy;
kusano fc6ab3
                    do {
kusano fc6ab3
                        *put++ = 0;
kusano fc6ab3
                    } while (--copy);
kusano fc6ab3
                    if (state->length == 0) state->mode = LEN;
kusano fc6ab3
                    break;
kusano fc6ab3
#endif
kusano fc6ab3
                }
kusano fc6ab3
                if (copy > state->wnext) {
kusano fc6ab3
                    copy -= state->wnext;
kusano fc6ab3
                    from = state->window + (state->wsize - copy);
kusano fc6ab3
                }
kusano fc6ab3
                else
kusano fc6ab3
                    from = state->window + (state->wnext - copy);
kusano fc6ab3
                if (copy > state->length) copy = state->length;
kusano fc6ab3
            }
kusano fc6ab3
            else {                              /* copy from output */
kusano fc6ab3
                from = put - state->offset;
kusano fc6ab3
                copy = state->length;
kusano fc6ab3
            }
kusano fc6ab3
            if (copy > left) copy = left;
kusano fc6ab3
            left -= copy;
kusano fc6ab3
            state->length -= copy;
kusano fc6ab3
            do {
kusano fc6ab3
                *put++ = *from++;
kusano fc6ab3
            } while (--copy);
kusano fc6ab3
            if (state->length == 0) state->mode = LEN;
kusano fc6ab3
            break;
kusano fc6ab3
        case LIT:
kusano fc6ab3
            if (left == 0) goto inf_leave;
kusano fc6ab3
            *put++ = (unsigned char)(state->length);
kusano fc6ab3
            left--;
kusano fc6ab3
            state->mode = LEN;
kusano fc6ab3
            break;
kusano fc6ab3
        case CHECK:
kusano fc6ab3
            if (state->wrap) {
kusano fc6ab3
                NEEDBITS(32);
kusano fc6ab3
                out -= left;
kusano fc6ab3
                strm->total_out += out;
kusano fc6ab3
                state->total += out;
kusano fc6ab3
                if (out)
kusano fc6ab3
                    strm->adler = state->check =
kusano fc6ab3
                        UPDATE(state->check, put - out, out);
kusano fc6ab3
                out = left;
kusano fc6ab3
                if ((
kusano fc6ab3
#ifdef GUNZIP
kusano fc6ab3
                     state->flags ? hold :
kusano fc6ab3
#endif
kusano fc6ab3
                     ZSWAP32(hold)) != state->check) {
kusano fc6ab3
                    strm->msg = (char *)"incorrect data check";
kusano fc6ab3
                    state->mode = BAD;
kusano fc6ab3
                    break;
kusano fc6ab3
                }
kusano fc6ab3
                INITBITS();
kusano fc6ab3
                Tracev((stderr, "inflate:   check matches trailer\n"));
kusano fc6ab3
            }
kusano fc6ab3
#ifdef GUNZIP
kusano fc6ab3
            state->mode = LENGTH;
kusano fc6ab3
        case LENGTH:
kusano fc6ab3
            if (state->wrap && state->flags) {
kusano fc6ab3
                NEEDBITS(32);
kusano fc6ab3
                if (hold != (state->total & 0xffffffffUL)) {
kusano fc6ab3
                    strm->msg = (char *)"incorrect length check";
kusano fc6ab3
                    state->mode = BAD;
kusano fc6ab3
                    break;
kusano fc6ab3
                }
kusano fc6ab3
                INITBITS();
kusano fc6ab3
                Tracev((stderr, "inflate:   length matches trailer\n"));
kusano fc6ab3
            }
kusano fc6ab3
#endif
kusano fc6ab3
            state->mode = DONE;
kusano fc6ab3
        case DONE:
kusano fc6ab3
            ret = Z_STREAM_END;
kusano fc6ab3
            goto inf_leave;
kusano fc6ab3
        case BAD:
kusano fc6ab3
            ret = Z_DATA_ERROR;
kusano fc6ab3
            goto inf_leave;
kusano fc6ab3
        case MEM:
kusano fc6ab3
            return Z_MEM_ERROR;
kusano fc6ab3
        case SYNC:
kusano fc6ab3
        default:
kusano fc6ab3
            return Z_STREAM_ERROR;
kusano fc6ab3
        }
kusano fc6ab3
kusano fc6ab3
    /*
kusano fc6ab3
       Return from inflate(), updating the total counts and the check value.
kusano fc6ab3
       If there was no progress during the inflate() call, return a buffer
kusano fc6ab3
       error.  Call updatewindow() to create and/or update the window state.
kusano fc6ab3
       Note: a memory error from inflate() is non-recoverable.
kusano fc6ab3
     */
kusano fc6ab3
  inf_leave:
kusano fc6ab3
    RESTORE();
kusano fc6ab3
    if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
kusano fc6ab3
            (state->mode < CHECK || flush != Z_FINISH)))
kusano fc6ab3
        if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {
kusano fc6ab3
            state->mode = MEM;
kusano fc6ab3
            return Z_MEM_ERROR;
kusano fc6ab3
        }
kusano fc6ab3
    in -= strm->avail_in;
kusano fc6ab3
    out -= strm->avail_out;
kusano fc6ab3
    strm->total_in += in;
kusano fc6ab3
    strm->total_out += out;
kusano fc6ab3
    state->total += out;
kusano fc6ab3
    if (state->wrap && out)
kusano fc6ab3
        strm->adler = state->check =
kusano fc6ab3
            UPDATE(state->check, strm->next_out - out, out);
kusano fc6ab3
    strm->data_type = state->bits + (state->last ? 64 : 0) +
kusano fc6ab3
                      (state->mode == TYPE ? 128 : 0) +
kusano fc6ab3
                      (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
kusano fc6ab3
    if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
kusano fc6ab3
        ret = Z_BUF_ERROR;
kusano fc6ab3
    return ret;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
int ZEXPORT inflateEnd(strm)
kusano fc6ab3
z_streamp strm;
kusano fc6ab3
{
kusano fc6ab3
    struct inflate_state FAR *state;
kusano fc6ab3
    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
kusano fc6ab3
        return Z_STREAM_ERROR;
kusano fc6ab3
    state = (struct inflate_state FAR *)strm->state;
kusano fc6ab3
    if (state->window != Z_NULL) ZFREE(strm, state->window);
kusano fc6ab3
    ZFREE(strm, strm->state);
kusano fc6ab3
    strm->state = Z_NULL;
kusano fc6ab3
    Tracev((stderr, "inflate: end\n"));
kusano fc6ab3
    return Z_OK;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)
kusano fc6ab3
z_streamp strm;
kusano fc6ab3
Bytef *dictionary;
kusano fc6ab3
uInt *dictLength;
kusano fc6ab3
{
kusano fc6ab3
    struct inflate_state FAR *state;
kusano fc6ab3
kusano fc6ab3
    /* check state */
kusano fc6ab3
    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
kusano fc6ab3
    state = (struct inflate_state FAR *)strm->state;
kusano fc6ab3
kusano fc6ab3
    /* copy dictionary */
kusano fc6ab3
    if (state->whave && dictionary != Z_NULL) {
kusano fc6ab3
        zmemcpy(dictionary, state->window + state->wnext,
kusano fc6ab3
                state->whave - state->wnext);
kusano fc6ab3
        zmemcpy(dictionary + state->whave - state->wnext,
kusano fc6ab3
                state->window, state->wnext);
kusano fc6ab3
    }
kusano fc6ab3
    if (dictLength != Z_NULL)
kusano fc6ab3
        *dictLength = state->whave;
kusano fc6ab3
    return Z_OK;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
kusano fc6ab3
z_streamp strm;
kusano fc6ab3
const Bytef *dictionary;
kusano fc6ab3
uInt dictLength;
kusano fc6ab3
{
kusano fc6ab3
    struct inflate_state FAR *state;
kusano fc6ab3
    unsigned long dictid;
kusano fc6ab3
    int ret;
kusano fc6ab3
kusano fc6ab3
    /* check state */
kusano fc6ab3
    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
kusano fc6ab3
    state = (struct inflate_state FAR *)strm->state;
kusano fc6ab3
    if (state->wrap != 0 && state->mode != DICT)
kusano fc6ab3
        return Z_STREAM_ERROR;
kusano fc6ab3
kusano fc6ab3
    /* check for correct dictionary identifier */
kusano fc6ab3
    if (state->mode == DICT) {
kusano fc6ab3
        dictid = adler32(0L, Z_NULL, 0);
kusano fc6ab3
        dictid = adler32(dictid, dictionary, dictLength);
kusano fc6ab3
        if (dictid != state->check)
kusano fc6ab3
            return Z_DATA_ERROR;
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
    /* copy dictionary to window using updatewindow(), which will amend the
kusano fc6ab3
       existing dictionary if appropriate */
kusano fc6ab3
    ret = updatewindow(strm, dictionary + dictLength, dictLength);
kusano fc6ab3
    if (ret) {
kusano fc6ab3
        state->mode = MEM;
kusano fc6ab3
        return Z_MEM_ERROR;
kusano fc6ab3
    }
kusano fc6ab3
    state->havedict = 1;
kusano fc6ab3
    Tracev((stderr, "inflate:   dictionary set\n"));
kusano fc6ab3
    return Z_OK;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
int ZEXPORT inflateGetHeader(strm, head)
kusano fc6ab3
z_streamp strm;
kusano fc6ab3
gz_headerp head;
kusano fc6ab3
{
kusano fc6ab3
    struct inflate_state FAR *state;
kusano fc6ab3
kusano fc6ab3
    /* check state */
kusano fc6ab3
    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
kusano fc6ab3
    state = (struct inflate_state FAR *)strm->state;
kusano fc6ab3
    if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
kusano fc6ab3
kusano fc6ab3
    /* save header structure */
kusano fc6ab3
    state->head = head;
kusano fc6ab3
    head->done = 0;
kusano fc6ab3
    return Z_OK;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
/*
kusano fc6ab3
   Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff.  Return when found
kusano fc6ab3
   or when out of input.  When called, *have is the number of pattern bytes
kusano fc6ab3
   found in order so far, in 0..3.  On return *have is updated to the new
kusano fc6ab3
   state.  If on return *have equals four, then the pattern was found and the
kusano fc6ab3
   return value is how many bytes were read including the last byte of the
kusano fc6ab3
   pattern.  If *have is less than four, then the pattern has not been found
kusano fc6ab3
   yet and the return value is len.  In the latter case, syncsearch() can be
kusano fc6ab3
   called again with more data and the *have state.  *have is initialized to
kusano fc6ab3
   zero for the first call.
kusano fc6ab3
 */
kusano fc6ab3
local unsigned syncsearch(have, buf, len)
kusano fc6ab3
unsigned FAR *have;
kusano fc6ab3
const unsigned char FAR *buf;
kusano fc6ab3
unsigned len;
kusano fc6ab3
{
kusano fc6ab3
    unsigned got;
kusano fc6ab3
    unsigned next;
kusano fc6ab3
kusano fc6ab3
    got = *have;
kusano fc6ab3
    next = 0;
kusano fc6ab3
    while (next < len && got < 4) {
kusano fc6ab3
        if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
kusano fc6ab3
            got++;
kusano fc6ab3
        else if (buf[next])
kusano fc6ab3
            got = 0;
kusano fc6ab3
        else
kusano fc6ab3
            got = 4 - got;
kusano fc6ab3
        next++;
kusano fc6ab3
    }
kusano fc6ab3
    *have = got;
kusano fc6ab3
    return next;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
int ZEXPORT inflateSync(strm)
kusano fc6ab3
z_streamp strm;
kusano fc6ab3
{
kusano fc6ab3
    unsigned len;               /* number of bytes to look at or looked at */
kusano fc6ab3
    unsigned long in, out;      /* temporary to save total_in and total_out */
kusano fc6ab3
    unsigned char buf[4];       /* to restore bit buffer to byte string */
kusano fc6ab3
    struct inflate_state FAR *state;
kusano fc6ab3
kusano fc6ab3
    /* check parameters */
kusano fc6ab3
    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
kusano fc6ab3
    state = (struct inflate_state FAR *)strm->state;
kusano fc6ab3
    if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
kusano fc6ab3
kusano fc6ab3
    /* if first time, start search in bit buffer */
kusano fc6ab3
    if (state->mode != SYNC) {
kusano fc6ab3
        state->mode = SYNC;
kusano fc6ab3
        state->hold <<= state->bits & 7;
kusano fc6ab3
        state->bits -= state->bits & 7;
kusano fc6ab3
        len = 0;
kusano fc6ab3
        while (state->bits >= 8) {
kusano fc6ab3
            buf[len++] = (unsigned char)(state->hold);
kusano fc6ab3
            state->hold >>= 8;
kusano fc6ab3
            state->bits -= 8;
kusano fc6ab3
        }
kusano fc6ab3
        state->have = 0;
kusano fc6ab3
        syncsearch(&(state->have), buf, len);
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
    /* search available input */
kusano fc6ab3
    len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
kusano fc6ab3
    strm->avail_in -= len;
kusano fc6ab3
    strm->next_in += len;
kusano fc6ab3
    strm->total_in += len;
kusano fc6ab3
kusano fc6ab3
    /* return no joy or set up to restart inflate() on a new block */
kusano fc6ab3
    if (state->have != 4) return Z_DATA_ERROR;
kusano fc6ab3
    in = strm->total_in;  out = strm->total_out;
kusano fc6ab3
    inflateReset(strm);
kusano fc6ab3
    strm->total_in = in;  strm->total_out = out;
kusano fc6ab3
    state->mode = TYPE;
kusano fc6ab3
    return Z_OK;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
/*
kusano fc6ab3
   Returns true if inflate is currently at the end of a block generated by
kusano fc6ab3
   Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
kusano fc6ab3
   implementation to provide an additional safety check. PPP uses
kusano fc6ab3
   Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
kusano fc6ab3
   block. When decompressing, PPP checks that at the end of input packet,
kusano fc6ab3
   inflate is waiting for these length bytes.
kusano fc6ab3
 */
kusano fc6ab3
int ZEXPORT inflateSyncPoint(strm)
kusano fc6ab3
z_streamp strm;
kusano fc6ab3
{
kusano fc6ab3
    struct inflate_state FAR *state;
kusano fc6ab3
kusano fc6ab3
    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
kusano fc6ab3
    state = (struct inflate_state FAR *)strm->state;
kusano fc6ab3
    return state->mode == STORED && state->bits == 0;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
int ZEXPORT inflateCopy(dest, source)
kusano fc6ab3
z_streamp dest;
kusano fc6ab3
z_streamp source;
kusano fc6ab3
{
kusano fc6ab3
    struct inflate_state FAR *state;
kusano fc6ab3
    struct inflate_state FAR *copy;
kusano fc6ab3
    unsigned char FAR *window;
kusano fc6ab3
    unsigned wsize;
kusano fc6ab3
kusano fc6ab3
    /* check input */
kusano fc6ab3
    if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
kusano fc6ab3
        source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
kusano fc6ab3
        return Z_STREAM_ERROR;
kusano fc6ab3
    state = (struct inflate_state FAR *)source->state;
kusano fc6ab3
kusano fc6ab3
    /* allocate space */
kusano fc6ab3
    copy = (struct inflate_state FAR *)
kusano fc6ab3
           ZALLOC(source, 1, sizeof(struct inflate_state));
kusano fc6ab3
    if (copy == Z_NULL) return Z_MEM_ERROR;
kusano fc6ab3
    window = Z_NULL;
kusano fc6ab3
    if (state->window != Z_NULL) {
kusano fc6ab3
        window = (unsigned char FAR *)
kusano fc6ab3
                 ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
kusano fc6ab3
        if (window == Z_NULL) {
kusano fc6ab3
            ZFREE(source, copy);
kusano fc6ab3
            return Z_MEM_ERROR;
kusano fc6ab3
        }
kusano fc6ab3
    }
kusano fc6ab3
kusano fc6ab3
    /* copy state */
kusano fc6ab3
    zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
kusano fc6ab3
    zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
kusano fc6ab3
    if (state->lencode >= state->codes &&
kusano fc6ab3
        state->lencode <= state->codes + ENOUGH - 1) {
kusano fc6ab3
        copy->lencode = copy->codes + (state->lencode - state->codes);
kusano fc6ab3
        copy->distcode = copy->codes + (state->distcode - state->codes);
kusano fc6ab3
    }
kusano fc6ab3
    copy->next = copy->codes + (state->next - state->codes);
kusano fc6ab3
    if (window != Z_NULL) {
kusano fc6ab3
        wsize = 1U << state->wbits;
kusano fc6ab3
        zmemcpy(window, state->window, wsize);
kusano fc6ab3
    }
kusano fc6ab3
    copy->window = window;
kusano fc6ab3
    dest->state = (struct internal_state FAR *)copy;
kusano fc6ab3
    return Z_OK;
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
int ZEXPORT inflateUndermine(strm, subvert)
kusano fc6ab3
z_streamp strm;
kusano fc6ab3
int subvert;
kusano fc6ab3
{
kusano fc6ab3
    struct inflate_state FAR *state;
kusano fc6ab3
kusano fc6ab3
    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
kusano fc6ab3
    state = (struct inflate_state FAR *)strm->state;
kusano fc6ab3
    state->sane = !subvert;
kusano fc6ab3
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
kusano fc6ab3
    return Z_OK;
kusano fc6ab3
#else
kusano fc6ab3
    state->sane = 1;
kusano fc6ab3
    return Z_DATA_ERROR;
kusano fc6ab3
#endif
kusano fc6ab3
}
kusano fc6ab3
kusano fc6ab3
long ZEXPORT inflateMark(strm)
kusano fc6ab3
z_streamp strm;
kusano fc6ab3
{
kusano fc6ab3
    struct inflate_state FAR *state;
kusano fc6ab3
kusano fc6ab3
    if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16;
kusano fc6ab3
    state = (struct inflate_state FAR *)strm->state;
kusano fc6ab3
    return ((long)(state->back) << 16) +
kusano fc6ab3
        (state->mode == COPY ? state->length :
kusano fc6ab3
            (state->mode == MATCH ? state->was - state->length : 0));
kusano fc6ab3
}