17eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* inflate.c -- zlib decompression
27eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * Copyright (C) 1995-2012 Mark Adler
37eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * For conditions of distribution and use, see copyright notice in zlib.h
47eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
57eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
67eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*
77eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * Change history:
87eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
97eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 1.2.beta0    24 Nov 2002
107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - First version -- complete rewrite of inflate to simplify code, avoid
117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *   creation of window when not needed, minimize use of window when it is
127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *   needed, make inffast.c even faster, implement gzip decoding, and to
137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *   improve code readability and style over the previous zlib inflate code
147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 1.2.beta1    25 Nov 2002
167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Use pointers for available input and output checking in inffast.c
177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Remove input and output counters in inffast.c
187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Remove unnecessary second byte pull from length extra in inffast.c
207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Unroll direct copy to three copies per loop in inffast.c
217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 1.2.beta2    4 Dec 2002
237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Change external routine names to reduce potential conflicts
247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Correct filename to inffixed.h for fixed tables in inflate.c
257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Make hbuf[] unsigned char to match parameter type in inflate.c
267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *   to avoid negation problem on Alphas (64 bit) in inflate.c
287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 1.2.beta3    22 Dec 2002
307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Add comments on state->bits assertion in inffast.c
317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Add comments on op field in inftrees.h
327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Fix bug in reuse of allocated window after inflateReset()
337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Remove bit fields--back to byte structure for speed
347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Use local copies of stream next and avail values, as well as local bit
397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *   buffer and bit count in inflate()--for speed when inflate_fast() not used
407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 1.2.beta4    1 Jan 2003
427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Move a comment on output buffer sizes from inffast.c to inflate.c
447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Add comments in inffast.c to introduce the inflate_fast() routine
457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Rearrange window copies in inflate_fast() for speed and simplification
467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Unroll last copy for window match in inflate_fast()
477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Use local copies of window variables in inflate_fast() for speed
487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Pull out common wnext == 0 case for speed in inflate_fast()
497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Make op and len in inflate_fast() unsigned for consistency
507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Add FAR to lcode and dcode declarations in inflate_fast()
517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Simplified bad distance check in inflate_fast()
527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *   source file infback.c to provide a call-back interface to inflate for
547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *   programs like gzip and unzip -- uses window as output buffer to avoid
557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *   window copying
567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 1.2.beta5    1 Jan 2003
587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Improved inflateBack() interface to allow the caller to provide initial
597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *   input in strm.
607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Fixed stored blocks bug in inflateBack()
617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 1.2.beta6    4 Jan 2003
637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Added comments in inffast.c on effectiveness of POSTINC
647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Typecasting all around to reduce compiler warnings
657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Changed loops from while (1) or do {} while (1) to for (;;), again to
667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *   make compilers happy
677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Changed type of window in inflateBackInit() to unsigned char *
687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 1.2.beta7    27 Jan 2003
707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Changed many types to unsigned or unsigned short to avoid warnings
717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Added inflateCopy() function
727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 1.2.0        9 Mar 2003
747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Changed inflateBack() interface to provide separate opaque descriptors
757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *   for the in() and out() functions
767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Changed inflateBack() argument and in_func typedef to swap the length
777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *   and buffer address return values for the input function
787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Check next_in and next_out for Z_NULL on entry to inflate()
797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *
807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "zutil.h"
847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "inftrees.h"
857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "inflate.h"
867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "inffast.h"
877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef MAKEFIXED
897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#  ifndef BUILDFIXED
907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#    define BUILDFIXED
917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#  endif
927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* function prototypes */
957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniellocal void fixedtables OF((struct inflate_state FAR *state));
967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniellocal int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                           unsigned copy));
987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef BUILDFIXED
997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   void makefixed OF((void));
1007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
1017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniellocal unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
1027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                              unsigned len));
1037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateResetKeep(strm)
1057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm;
1067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
1077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    struct inflate_state FAR *state;
1087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
1107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state = (struct inflate_state FAR *)strm->state;
1117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    strm->total_in = strm->total_out = state->total = 0;
1127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    strm->msg = Z_NULL;
1137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->wrap)        /* to support ill-conceived Java test suite */
1147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        strm->adler = state->wrap & 1;
1157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->mode = HEAD;
1167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->last = 0;
1177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->havedict = 0;
1187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->dmax = 32768U;
1197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->head = Z_NULL;
1207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->hold = 0;
1217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->bits = 0;
1227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->lencode = state->distcode = state->next = state->codes;
1237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->sane = 1;
1247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->back = -1;
1257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Tracev((stderr, "inflate: reset\n"));
1267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Z_OK;
1277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
1287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateReset(strm)
1307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm;
1317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
1327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    struct inflate_state FAR *state;
1337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
1357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state = (struct inflate_state FAR *)strm->state;
1367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->wsize = 0;
1377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->whave = 0;
1387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->wnext = 0;
1397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return inflateResetKeep(strm);
1407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
1417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateReset2(strm, windowBits)
1437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm;
1447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint windowBits;
1457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
1467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int wrap;
1477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    struct inflate_state FAR *state;
1487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* get the state */
1507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
1517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state = (struct inflate_state FAR *)strm->state;
1527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* extract wrap request from windowBits parameter */
1547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (windowBits < 0) {
1557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        wrap = 0;
1567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        windowBits = -windowBits;
1577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
1587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else {
1597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        wrap = (windowBits >> 4) + 1;
1607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef GUNZIP
1617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (windowBits < 48)
1627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            windowBits &= 15;
1637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
1647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
1657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* set number of window bits, free window if different */
1677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (windowBits && (windowBits < 8 || windowBits > 15))
1687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return Z_STREAM_ERROR;
1697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
1707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ZFREE(strm, state->window);
1717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->window = Z_NULL;
1727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
1737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* update state and reset the rest of it */
1757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->wrap = wrap;
1767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->wbits = (unsigned)windowBits;
1777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return inflateReset(strm);
1787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
1797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
1817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm;
1827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint windowBits;
1837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielconst char *version;
1847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint stream_size;
1857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
1867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ret;
1877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    struct inflate_state FAR *state;
1887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
1897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
1907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        stream_size != (int)(sizeof(z_stream)))
1917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return Z_VERSION_ERROR;
1927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strm == Z_NULL) return Z_STREAM_ERROR;
1937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    strm->msg = Z_NULL;                 /* in case we return an error */
1947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strm->zalloc == (alloc_func)0) {
1957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef Z_SOLO
1967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return Z_STREAM_ERROR;
1977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
1987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        strm->zalloc = zcalloc;
1997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        strm->opaque = (voidpf)0;
2007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
2017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
2027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strm->zfree == (free_func)0)
2037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef Z_SOLO
2047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return Z_STREAM_ERROR;
2057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
2067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        strm->zfree = zcfree;
2077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
2087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state = (struct inflate_state FAR *)
2097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ZALLOC(strm, 1, sizeof(struct inflate_state));
2107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state == Z_NULL) return Z_MEM_ERROR;
2117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Tracev((stderr, "inflate: allocated\n"));
2127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    strm->state = (struct internal_state FAR *)state;
2137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->window = Z_NULL;
2147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ret = inflateReset2(strm, windowBits);
2157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (ret != Z_OK) {
2167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ZFREE(strm, state);
2177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        strm->state = Z_NULL;
2187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
2197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return ret;
2207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
2217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateInit_(strm, version, stream_size)
2237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm;
2247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielconst char *version;
2257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint stream_size;
2267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
2277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return inflateInit2_(strm, DEF_WBITS, version, stream_size);
2287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
2297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflatePrime(strm, bits, value)
2317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm;
2327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint bits;
2337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint value;
2347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
2357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    struct inflate_state FAR *state;
2367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
2387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state = (struct inflate_state FAR *)strm->state;
2397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (bits < 0) {
2407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->hold = 0;
2417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->bits = 0;
2427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return Z_OK;
2437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
2447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
2457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    value &= (1L << bits) - 1;
2467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->hold += value << state->bits;
2477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->bits += bits;
2487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Z_OK;
2497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
2507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*
2527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   Return state with length and distance decoding tables and index sizes set to
2537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   fixed code decoding.  Normally this returns fixed tables from inffixed.h.
2547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   If BUILDFIXED is defined, then instead this routine builds the tables the
2557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   first time it's called, and returns those tables the first time and
2567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   thereafter.  This reduces the size of the code by about 2K bytes, in
2577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   exchange for a little execution time.  However, BUILDFIXED should not be
2587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   used for threaded applications, since the rewriting of the tables and virgin
2597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   may not be thread-safe.
2607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
2617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniellocal void fixedtables(state)
2627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstruct inflate_state FAR *state;
2637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
2647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef BUILDFIXED
2657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    static int virgin = 1;
2667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    static code *lenfix, *distfix;
2677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    static code fixed[544];
2687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* build fixed huffman tables if first call (may not be thread safe) */
2707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (virgin) {
2717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        unsigned sym, bits;
2727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        static code *next;
2737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* literal/length table */
2757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        sym = 0;
2767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        while (sym < 144) state->lens[sym++] = 8;
2777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        while (sym < 256) state->lens[sym++] = 9;
2787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        while (sym < 280) state->lens[sym++] = 7;
2797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        while (sym < 288) state->lens[sym++] = 8;
2807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        next = fixed;
2817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        lenfix = next;
2827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        bits = 9;
2837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
2847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* distance table */
2867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        sym = 0;
2877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        while (sym < 32) state->lens[sym++] = 5;
2887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        distfix = next;
2897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        bits = 5;
2907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
2917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
2927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        /* do this just once */
2937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        virgin = 0;
2947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
2957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else /* !BUILDFIXED */
2967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#   include "inffixed.h"
2977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif /* BUILDFIXED */
2987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->lencode = lenfix;
2997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->lenbits = 9;
3007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->distcode = distfix;
3017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->distbits = 5;
3027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
3037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef MAKEFIXED
3057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include <stdio.h>
3067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*
3087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   Write out the inffixed.h that is #include'd above.  Defining MAKEFIXED also
3097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   defines BUILDFIXED, so the tables are built on the fly.  makefixed() writes
3107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   those tables to stdout, which would be piped to inffixed.h.  A small program
3117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   can simply call makefixed to do this:
3127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    void makefixed(void);
3147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int main(void)
3167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    {
3177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        makefixed();
3187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return 0;
3197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   Then that can be linked with zlib built with MAKEFIXED defined and run:
3227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    a.out > inffixed.h
3247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
3257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvoid makefixed()
3267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
3277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned low, size;
3287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    struct inflate_state state;
3297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    fixedtables(&state);
3317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    puts("    /* inffixed.h -- table for decoding fixed codes");
3327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    puts("     * Generated automatically by makefixed().");
3337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    puts("     */");
3347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    puts("");
3357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    puts("    /* WARNING: this file should *not* be used by applications.");
3367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    puts("       It is part of the implementation of this library and is");
3377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    puts("       subject to change. Applications should only use zlib.h.");
3387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    puts("     */");
3397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    puts("");
3407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    size = 1U << 9;
3417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    printf("    static const code lenfix[%u] = {", size);
3427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    low = 0;
3437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (;;) {
3447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if ((low % 7) == 0) printf("\n        ");
3457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
3467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               state.lencode[low].bits, state.lencode[low].val);
3477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (++low == size) break;
3487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        putchar(',');
3497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    puts("\n    };");
3517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    size = 1U << 5;
3527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    printf("\n    static const code distfix[%u] = {", size);
3537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    low = 0;
3547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (;;) {
3557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if ((low % 6) == 0) printf("\n        ");
3567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
3577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               state.distcode[low].val);
3587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (++low == size) break;
3597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        putchar(',');
3607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    puts("\n    };");
3627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
3637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif /* MAKEFIXED */
3647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*
3667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   Update the window with the last wsize (normally 32K) bytes written before
3677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   returning.  If window does not exist yet, create it.  This is only called
3687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   when a window is already in use, or when output has been written during this
3697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   inflate call, but the end of the deflate stream has not been reached yet.
3707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   It is also called to create a window for dictionary data when a dictionary
3717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   is loaded.
3727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   Providing output buffers larger than 32K to inflate() should provide a speed
3747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   advantage, since only the last 32K of output is copied to the sliding window
3757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   upon return from inflate(), and since all distances after the first 32K of
3767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   output will fall in the output data, making match copies simpler and faster.
3777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   The advantage may be dependent on the size of the processor's data caches.
3787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
3797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniellocal int updatewindow(strm, end, copy)
3807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm;
3817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielconst Bytef *end;
3827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielunsigned copy;
3837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
3847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    struct inflate_state FAR *state;
3857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned dist;
3867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state = (struct inflate_state FAR *)strm->state;
3887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* if it hasn't been done already, allocate space for the window */
3907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->window == Z_NULL) {
3917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->window = (unsigned char FAR *)
3927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        ZALLOC(strm, 1U << state->wbits,
3937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                               sizeof(unsigned char));
3947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (state->window == Z_NULL) return 1;
3957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
3967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
3977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* if window not in use yet, initialize */
3987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->wsize == 0) {
3997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->wsize = 1U << state->wbits;
4007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->wnext = 0;
4017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->whave = 0;
4027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* copy state->wsize or less output bytes into the circular window */
4057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (copy >= state->wsize) {
4067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        zmemcpy(state->window, end - state->wsize, state->wsize);
4077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->wnext = 0;
4087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->whave = state->wsize;
4097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    else {
4117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        dist = state->wsize - state->wnext;
4127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (dist > copy) dist = copy;
4137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        zmemcpy(state->window + state->wnext, end - copy, dist);
4147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        copy -= dist;
4157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (copy) {
4167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            zmemcpy(state->window, end - copy, copy);
4177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->wnext = copy;
4187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->whave = state->wsize;
4197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
4207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else {
4217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->wnext += dist;
4227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->wnext == state->wsize) state->wnext = 0;
4237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->whave < state->wsize) state->whave += dist;
4247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
4257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
4267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return 0;
4277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
4287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Macros for inflate(): */
4307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* check function to use adler32() for zlib or crc32() for gzip */
4327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef GUNZIP
4337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#  define UPDATE(check, buf, len) \
4347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
4357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
4367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#  define UPDATE(check, buf, len) adler32(check, buf, len)
4377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
4387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* check macros for header crc */
4407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef GUNZIP
4417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#  define CRC2(check, word) \
4427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    do { \
4437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        hbuf[0] = (unsigned char)(word); \
4447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        hbuf[1] = (unsigned char)((word) >> 8); \
4457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        check = crc32(check, hbuf, 2); \
4467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    } while (0)
4477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#  define CRC4(check, word) \
4497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    do { \
4507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        hbuf[0] = (unsigned char)(word); \
4517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        hbuf[1] = (unsigned char)((word) >> 8); \
4527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        hbuf[2] = (unsigned char)((word) >> 16); \
4537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        hbuf[3] = (unsigned char)((word) >> 24); \
4547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        check = crc32(check, hbuf, 4); \
4557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    } while (0)
4567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
4577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Load registers with state in inflate() for speed */
4597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define LOAD() \
4607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    do { \
4617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        put = strm->next_out; \
4627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        left = strm->avail_out; \
4637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        next = strm->next_in; \
4647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        have = strm->avail_in; \
4657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        hold = state->hold; \
4667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        bits = state->bits; \
4677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    } while (0)
4687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Restore state from registers in inflate() */
4707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define RESTORE() \
4717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    do { \
4727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        strm->next_out = put; \
4737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        strm->avail_out = left; \
4747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        strm->next_in = next; \
4757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        strm->avail_in = have; \
4767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->hold = hold; \
4777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->bits = bits; \
4787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    } while (0)
4797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Clear the input bit accumulator */
4817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define INITBITS() \
4827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    do { \
4837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        hold = 0; \
4847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        bits = 0; \
4857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    } while (0)
4867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Get a byte of input into the bit accumulator, or return from inflate()
4887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   if there is no input available. */
4897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define PULLBYTE() \
4907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    do { \
4917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (have == 0) goto inf_leave; \
4927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        have--; \
4937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        hold += (unsigned long)(*next++) << bits; \
4947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        bits += 8; \
4957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    } while (0)
4967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
4977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Assure that there are at least n bits in the bit accumulator.  If there is
4987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   not enough available input to do that, then return from inflate(). */
4997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define NEEDBITS(n) \
5007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    do { \
5017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        while (bits < (unsigned)(n)) \
5027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            PULLBYTE(); \
5037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    } while (0)
5047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Return the low n bits of the bit accumulator (n < 16) */
5067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define BITS(n) \
5077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ((unsigned)hold & ((1U << (n)) - 1))
5087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Remove n bits from the bit accumulator */
5107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define DROPBITS(n) \
5117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    do { \
5127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        hold >>= (n); \
5137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        bits -= (unsigned)(n); \
5147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    } while (0)
5157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Remove zero to seven bits as needed to go to a byte boundary */
5177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define BYTEBITS() \
5187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    do { \
5197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        hold >>= bits & 7; \
5207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        bits -= bits & 7; \
5217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    } while (0)
5227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*
5247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   inflate() uses a state machine to process as much input data and generate as
5257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   much output data as possible before returning.  The state machine is
5267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   structured roughly as follows:
5277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (;;) switch (state) {
5297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ...
5307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    case STATEn:
5317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (not enough input data or output space to make progress)
5327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return;
5337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ... make progress ...
5347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state = STATEm;
5357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        break;
5367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ...
5377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
5387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   so when inflate() is called again, the same case is attempted again, and
5407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   if the appropriate resources are provided, the machine proceeds to the
5417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   next state.  The NEEDBITS() macro is usually the way the state evaluates
5427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   whether it can proceed or should return.  NEEDBITS() does the return if
5437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   the requested bits are not available.  The typical use of the BITS macros
5447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   is:
5457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        NEEDBITS(n);
5477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ... do something with BITS(n) ...
5487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        DROPBITS(n);
5497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   where NEEDBITS(n) either returns from inflate() if there isn't enough
5517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   input left to load n bits into the accumulator, or it continues.  BITS(n)
5527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   gives the low n bits in the accumulator.  When done, DROPBITS(n) drops
5537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   the low n bits off the accumulator.  INITBITS() clears the accumulator
5547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   and sets the number of available bits to zero.  BYTEBITS() discards just
5557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   enough bits to put the accumulator on a byte boundary.  After BYTEBITS()
5567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
5577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
5597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   if there is no input available.  The decoding of variable length codes uses
5607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   PULLBYTE() directly in order to pull just enough bytes to decode the next
5617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   code, and no more.
5627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   Some states loop until they get enough input, making sure that enough
5647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   state information is maintained to continue the loop where it left off
5657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   if NEEDBITS() returns in the loop.  For example, want, need, and keep
5667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   would all have to actually be part of the saved state in case NEEDBITS()
5677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   returns:
5687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    case STATEw:
5707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        while (want < need) {
5717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            NEEDBITS(n);
5727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            keep[want++] = BITS(n);
5737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            DROPBITS(n);
5747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
5757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state = STATEx;
5767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    case STATEx:
5777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   As shown above, if the next state is also the next case, then the break
5797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   is omitted.
5807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   A state may also return if there is not enough output space available to
5827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   complete that state.  Those states are copying stored data, writing a
5837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   literal byte, and copying a matching string.
5847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   When returning, a "goto inf_leave" is used to update the total counters,
5867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   update the check value, and determine whether any progress has been made
5877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   during that inflate() call in order to return the proper return code.
5887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   Progress is defined as a change in either strm->avail_in or strm->avail_out.
5897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   When there is a window, goto inf_leave will update the window with the last
5907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   output written.  If a goto inf_leave occurs in the middle of decompression
5917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   and there is no window currently, goto inf_leave will create one and copy
5927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   output to the window for the next call of inflate().
5937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
5947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   In this implementation, the flush parameter of inflate() only affects the
5957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   return code (per zlib.h).  inflate() always writes as much as possible to
5967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   strm->next_out, given the space available and the provided input--the effect
5977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   documented in zlib.h of Z_SYNC_FLUSH.  Furthermore, inflate() always defers
5987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   the allocation of and copying into a sliding window until necessary, which
5997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   provides the effect documented in zlib.h for Z_FINISH when the entire input
6007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   stream available.  So the only thing the flush parameter actually does is:
6017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   when flush is set to Z_FINISH, inflate() cannot return Z_OK.  Instead it
6027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   will return Z_BUF_ERROR if it has not reached the end of the stream.
6037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
6047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflate(strm, flush)
6067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm;
6077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint flush;
6087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
6097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    struct inflate_state FAR *state;
6107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    z_const unsigned char FAR *next;    /* next input */
6117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned char FAR *put;     /* next output */
6127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned have, left;        /* available input and output */
6137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned long hold;         /* bit buffer */
6147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned bits;              /* bits in bit buffer */
6157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned in, out;           /* save starting available input and output */
6167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned copy;              /* number of stored or match bytes to copy */
6177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned char FAR *from;    /* where to copy match bytes from */
6187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    code here;                  /* current decoding table entry */
6197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    code last;                  /* parent table entry */
6207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned len;               /* length to copy for repeats, bits to drop */
6217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ret;                    /* return code */
6227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef GUNZIP
6237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned char hbuf[4];      /* buffer for gzip header crc calculation */
6247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
6257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    static const unsigned short order[19] = /* permutation of code lengths */
6267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
6277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
6297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (strm->next_in == Z_NULL && strm->avail_in != 0))
6307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return Z_STREAM_ERROR;
6317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
6327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state = (struct inflate_state FAR *)strm->state;
6337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->mode == TYPE) state->mode = TYPEDO;      /* skip check */
6347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    LOAD();
6357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    in = have;
6367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    out = left;
6377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ret = Z_OK;
6387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    for (;;)
6397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        switch (state->mode) {
6407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case HEAD:
6417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->wrap == 0) {
6427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->mode = TYPEDO;
6437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
6447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
6457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            NEEDBITS(16);
6467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef GUNZIP
6477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if ((state->wrap & 2) && hold == 0x8b1f) {  /* gzip header */
6487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->check = crc32(0L, Z_NULL, 0);
6497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                CRC2(state->check, hold);
6507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                INITBITS();
6517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->mode = FLAGS;
6527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
6537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
6547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->flags = 0;           /* expect zlib header */
6557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->head != Z_NULL)
6567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->head->done = -1;
6577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (!(state->wrap & 1) ||   /* check if zlib header allowed */
6587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
6597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (
6607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
6617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                ((BITS(8) << 8) + (hold >> 8)) % 31) {
6627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                strm->msg = (char *)"incorrect header check";
6637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->mode = BAD;
6647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
6657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
6667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (BITS(4) != Z_DEFLATED) {
6677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                strm->msg = (char *)"unknown compression method";
6687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->mode = BAD;
6697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
6707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
6717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            DROPBITS(4);
6727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            len = BITS(4) + 8;
6737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->wbits == 0)
6747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->wbits = len;
6757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            else if (len > state->wbits) {
6767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                strm->msg = (char *)"invalid window size";
6777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->mode = BAD;
6787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
6797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
6807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->dmax = 1U << len;
6817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Tracev((stderr, "inflate:   zlib header ok\n"));
6827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            strm->adler = state->check = adler32(0L, Z_NULL, 0);
6837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = hold & 0x200 ? DICTID : TYPE;
6847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            INITBITS();
6857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
6867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef GUNZIP
6877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case FLAGS:
6887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            NEEDBITS(16);
6897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->flags = (int)(hold);
6907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if ((state->flags & 0xff) != Z_DEFLATED) {
6917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                strm->msg = (char *)"unknown compression method";
6927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->mode = BAD;
6937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
6947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
6957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->flags & 0xe000) {
6967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                strm->msg = (char *)"unknown header flags set";
6977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->mode = BAD;
6987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
6997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
7007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->head != Z_NULL)
7017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->head->text = (int)((hold >> 8) & 1);
7027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->flags & 0x0200) CRC2(state->check, hold);
7037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            INITBITS();
7047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = TIME;
7057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case TIME:
7067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            NEEDBITS(32);
7077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->head != Z_NULL)
7087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->head->time = hold;
7097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->flags & 0x0200) CRC4(state->check, hold);
7107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            INITBITS();
7117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = OS;
7127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case OS:
7137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            NEEDBITS(16);
7147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->head != Z_NULL) {
7157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->head->xflags = (int)(hold & 0xff);
7167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->head->os = (int)(hold >> 8);
7177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
7187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->flags & 0x0200) CRC2(state->check, hold);
7197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            INITBITS();
7207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = EXLEN;
7217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case EXLEN:
7227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->flags & 0x0400) {
7237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                NEEDBITS(16);
7247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->length = (unsigned)(hold);
7257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (state->head != Z_NULL)
7267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    state->head->extra_len = (unsigned)hold;
7277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (state->flags & 0x0200) CRC2(state->check, hold);
7287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                INITBITS();
7297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
7307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            else if (state->head != Z_NULL)
7317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->head->extra = Z_NULL;
7327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = EXTRA;
7337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case EXTRA:
7347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->flags & 0x0400) {
7357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                copy = state->length;
7367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (copy > have) copy = have;
7377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (copy) {
7387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    if (state->head != Z_NULL &&
7397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        state->head->extra != Z_NULL) {
7407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        len = state->head->extra_len - state->length;
7417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        zmemcpy(state->head->extra + len, next,
7427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                len + copy > state->head->extra_max ?
7437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                state->head->extra_max - len : copy);
7447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    }
7457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    if (state->flags & 0x0200)
7467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        state->check = crc32(state->check, next, copy);
7477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    have -= copy;
7487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    next += copy;
7497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    state->length -= copy;
7507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                }
7517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (state->length) goto inf_leave;
7527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
7537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->length = 0;
7547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = NAME;
7557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case NAME:
7567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->flags & 0x0800) {
7577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (have == 0) goto inf_leave;
7587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                copy = 0;
7597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                do {
7607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    len = (unsigned)(next[copy++]);
7617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    if (state->head != Z_NULL &&
7627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                            state->head->name != Z_NULL &&
7637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                            state->length < state->head->name_max)
7647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        state->head->name[state->length++] = len;
7657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                } while (len && copy < have);
7667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (state->flags & 0x0200)
7677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    state->check = crc32(state->check, next, copy);
7687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                have -= copy;
7697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                next += copy;
7707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (len) goto inf_leave;
7717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
7727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            else if (state->head != Z_NULL)
7737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->head->name = Z_NULL;
7747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->length = 0;
7757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = COMMENT;
7767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case COMMENT:
7777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->flags & 0x1000) {
7787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (have == 0) goto inf_leave;
7797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                copy = 0;
7807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                do {
7817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    len = (unsigned)(next[copy++]);
7827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    if (state->head != Z_NULL &&
7837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                            state->head->comment != Z_NULL &&
7847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                            state->length < state->head->comm_max)
7857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        state->head->comment[state->length++] = len;
7867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                } while (len && copy < have);
7877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (state->flags & 0x0200)
7887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    state->check = crc32(state->check, next, copy);
7897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                have -= copy;
7907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                next += copy;
7917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (len) goto inf_leave;
7927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
7937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            else if (state->head != Z_NULL)
7947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->head->comment = Z_NULL;
7957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = HCRC;
7967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case HCRC:
7977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->flags & 0x0200) {
7987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                NEEDBITS(16);
7997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (hold != (state->check & 0xffff)) {
8007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    strm->msg = (char *)"header crc mismatch";
8017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    state->mode = BAD;
8027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    break;
8037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                }
8047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                INITBITS();
8057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
8067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->head != Z_NULL) {
8077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->head->hcrc = (int)((state->flags >> 9) & 1);
8087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->head->done = 1;
8097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
8107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            strm->adler = state->check = crc32(0L, Z_NULL, 0);
8117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = TYPE;
8127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
8137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
8147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case DICTID:
8157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            NEEDBITS(32);
8167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            strm->adler = state->check = ZSWAP32(hold);
8177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            INITBITS();
8187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = DICT;
8197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case DICT:
8207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->havedict == 0) {
8217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                RESTORE();
8227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                return Z_NEED_DICT;
8237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
8247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            strm->adler = state->check = adler32(0L, Z_NULL, 0);
8257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = TYPE;
8267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case TYPE:
8277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
8287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case TYPEDO:
8297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->last) {
8307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                BYTEBITS();
8317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->mode = CHECK;
8327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
8337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
8347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            NEEDBITS(3);
8357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->last = BITS(1);
8367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            DROPBITS(1);
8377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            switch (BITS(2)) {
8387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            case 0:                             /* stored block */
8397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Tracev((stderr, "inflate:     stored block%s\n",
8407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        state->last ? " (last)" : ""));
8417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->mode = STORED;
8427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
8437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            case 1:                             /* fixed block */
8447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                fixedtables(state);
8457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Tracev((stderr, "inflate:     fixed codes block%s\n",
8467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        state->last ? " (last)" : ""));
8477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->mode = LEN_;             /* decode codes */
8487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (flush == Z_TREES) {
8497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    DROPBITS(2);
8507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    goto inf_leave;
8517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                }
8527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
8537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            case 2:                             /* dynamic block */
8547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Tracev((stderr, "inflate:     dynamic codes block%s\n",
8557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        state->last ? " (last)" : ""));
8567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->mode = TABLE;
8577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
8587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            case 3:
8597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                strm->msg = (char *)"invalid block type";
8607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->mode = BAD;
8617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
8627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            DROPBITS(2);
8637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
8647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case STORED:
8657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            BYTEBITS();                         /* go to byte boundary */
8667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            NEEDBITS(32);
8677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
8687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                strm->msg = (char *)"invalid stored block lengths";
8697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->mode = BAD;
8707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
8717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
8727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->length = (unsigned)hold & 0xffff;
8737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Tracev((stderr, "inflate:       stored length %u\n",
8747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    state->length));
8757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            INITBITS();
8767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = COPY_;
8777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (flush == Z_TREES) goto inf_leave;
8787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case COPY_:
8797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = COPY;
8807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case COPY:
8817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            copy = state->length;
8827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (copy) {
8837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (copy > have) copy = have;
8847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (copy > left) copy = left;
8857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (copy == 0) goto inf_leave;
8867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                zmemcpy(put, next, copy);
8877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                have -= copy;
8887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                next += copy;
8897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                left -= copy;
8907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                put += copy;
8917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->length -= copy;
8927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
8937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
8947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Tracev((stderr, "inflate:       stored end\n"));
8957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = TYPE;
8967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
8977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case TABLE:
8987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            NEEDBITS(14);
8997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->nlen = BITS(5) + 257;
9007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            DROPBITS(5);
9017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->ndist = BITS(5) + 1;
9027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            DROPBITS(5);
9037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->ncode = BITS(4) + 4;
9047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            DROPBITS(4);
9057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifndef PKZIP_BUG_WORKAROUND
9067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->nlen > 286 || state->ndist > 30) {
9077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                strm->msg = (char *)"too many length or distance symbols";
9087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->mode = BAD;
9097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
9107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
9117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
9127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Tracev((stderr, "inflate:       table sizes ok\n"));
9137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->have = 0;
9147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = LENLENS;
9157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case LENLENS:
9167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            while (state->have < state->ncode) {
9177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                NEEDBITS(3);
9187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->lens[order[state->have++]] = (unsigned short)BITS(3);
9197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                DROPBITS(3);
9207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
9217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            while (state->have < 19)
9227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->lens[order[state->have++]] = 0;
9237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->next = state->codes;
9247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->lencode = (const code FAR *)(state->next);
9257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->lenbits = 7;
9267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ret = inflate_table(CODES, state->lens, 19, &(state->next),
9277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                &(state->lenbits), state->work);
9287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (ret) {
9297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                strm->msg = (char *)"invalid code lengths set";
9307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->mode = BAD;
9317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
9327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
9337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Tracev((stderr, "inflate:       code lengths ok\n"));
9347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->have = 0;
9357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = CODELENS;
9367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case CODELENS:
9377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            while (state->have < state->nlen + state->ndist) {
9387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                for (;;) {
9397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    here = state->lencode[BITS(state->lenbits)];
9407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    if ((unsigned)(here.bits) <= bits) break;
9417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    PULLBYTE();
9427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                }
9437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (here.val < 16) {
9447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    DROPBITS(here.bits);
9457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    state->lens[state->have++] = here.val;
9467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                }
9477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                else {
9487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    if (here.val == 16) {
9497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        NEEDBITS(here.bits + 2);
9507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        DROPBITS(here.bits);
9517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        if (state->have == 0) {
9527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                            strm->msg = (char *)"invalid bit length repeat";
9537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                            state->mode = BAD;
9547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                            break;
9557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        }
9567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        len = state->lens[state->have - 1];
9577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        copy = 3 + BITS(2);
9587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        DROPBITS(2);
9597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    }
9607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    else if (here.val == 17) {
9617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        NEEDBITS(here.bits + 3);
9627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        DROPBITS(here.bits);
9637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        len = 0;
9647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        copy = 3 + BITS(3);
9657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        DROPBITS(3);
9667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    }
9677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    else {
9687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        NEEDBITS(here.bits + 7);
9697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        DROPBITS(here.bits);
9707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        len = 0;
9717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        copy = 11 + BITS(7);
9727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        DROPBITS(7);
9737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    }
9747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    if (state->have + copy > state->nlen + state->ndist) {
9757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        strm->msg = (char *)"invalid bit length repeat";
9767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        state->mode = BAD;
9777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        break;
9787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    }
9797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    while (copy--)
9807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        state->lens[state->have++] = (unsigned short)len;
9817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                }
9827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
9837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /* handle error breaks in while */
9857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->mode == BAD) break;
9867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /* check for end-of-block code (better have one) */
9887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->lens[256] == 0) {
9897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                strm->msg = (char *)"invalid code -- missing end-of-block";
9907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->mode = BAD;
9917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
9927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
9937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
9947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            /* build code tables -- note: do not change the lenbits or distbits
9957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               values here (9 and 6) without reading the comments in inftrees.h
9967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel               concerning the ENOUGH constants, which depend on those values */
9977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->next = state->codes;
9987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->lencode = (const code FAR *)(state->next);
9997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->lenbits = 9;
10007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
10017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                                &(state->lenbits), state->work);
10027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (ret) {
10037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                strm->msg = (char *)"invalid literal/lengths set";
10047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->mode = BAD;
10057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
10067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
10077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->distcode = (const code FAR *)(state->next);
10087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->distbits = 6;
10097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
10107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                            &(state->next), &(state->distbits), state->work);
10117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (ret) {
10127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                strm->msg = (char *)"invalid distances set";
10137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->mode = BAD;
10147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
10157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
10167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Tracev((stderr, "inflate:       codes ok\n"));
10177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = LEN_;
10187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (flush == Z_TREES) goto inf_leave;
10197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case LEN_:
10207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = LEN;
10217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case LEN:
10227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (have >= 6 && left >= 258) {
10237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                RESTORE();
10247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                inflate_fast(strm, out);
10257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                LOAD();
10267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (state->mode == TYPE)
10277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    state->back = -1;
10287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
10297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
10307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->back = 0;
10317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            for (;;) {
10327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                here = state->lencode[BITS(state->lenbits)];
10337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if ((unsigned)(here.bits) <= bits) break;
10347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                PULLBYTE();
10357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
10367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (here.op && (here.op & 0xf0) == 0) {
10377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                last = here;
10387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                for (;;) {
10397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    here = state->lencode[last.val +
10407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                            (BITS(last.bits + last.op) >> last.bits)];
10417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    if ((unsigned)(last.bits + here.bits) <= bits) break;
10427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    PULLBYTE();
10437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                }
10447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                DROPBITS(last.bits);
10457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->back += last.bits;
10467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
10477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            DROPBITS(here.bits);
10487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->back += here.bits;
10497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->length = (unsigned)here.val;
10507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if ((int)(here.op) == 0) {
10517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
10527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        "inflate:         literal '%c'\n" :
10537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        "inflate:         literal 0x%02x\n", here.val));
10547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->mode = LIT;
10557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
10567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
10577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (here.op & 32) {
10587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Tracevv((stderr, "inflate:         end of block\n"));
10597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->back = -1;
10607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->mode = TYPE;
10617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
10627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
10637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (here.op & 64) {
10647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                strm->msg = (char *)"invalid literal/length code";
10657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->mode = BAD;
10667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
10677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
10687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->extra = (unsigned)(here.op) & 15;
10697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = LENEXT;
10707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case LENEXT:
10717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->extra) {
10727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                NEEDBITS(state->extra);
10737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->length += BITS(state->extra);
10747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                DROPBITS(state->extra);
10757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->back += state->extra;
10767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
10777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Tracevv((stderr, "inflate:         length %u\n", state->length));
10787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->was = state->length;
10797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = DIST;
10807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case DIST:
10817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            for (;;) {
10827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                here = state->distcode[BITS(state->distbits)];
10837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if ((unsigned)(here.bits) <= bits) break;
10847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                PULLBYTE();
10857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
10867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if ((here.op & 0xf0) == 0) {
10877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                last = here;
10887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                for (;;) {
10897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    here = state->distcode[last.val +
10907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                            (BITS(last.bits + last.op) >> last.bits)];
10917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    if ((unsigned)(last.bits + here.bits) <= bits) break;
10927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    PULLBYTE();
10937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                }
10947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                DROPBITS(last.bits);
10957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->back += last.bits;
10967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
10977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            DROPBITS(here.bits);
10987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->back += here.bits;
10997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (here.op & 64) {
11007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                strm->msg = (char *)"invalid distance code";
11017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->mode = BAD;
11027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
11037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
11047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->offset = (unsigned)here.val;
11057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->extra = (unsigned)(here.op) & 15;
11067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = DISTEXT;
11077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case DISTEXT:
11087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->extra) {
11097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                NEEDBITS(state->extra);
11107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->offset += BITS(state->extra);
11117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                DROPBITS(state->extra);
11127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->back += state->extra;
11137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
11147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef INFLATE_STRICT
11157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->offset > state->dmax) {
11167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                strm->msg = (char *)"invalid distance too far back";
11177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->mode = BAD;
11187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                break;
11197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
11207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
11217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
11227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = MATCH;
11237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case MATCH:
11247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (left == 0) goto inf_leave;
11257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            copy = out - left;
11267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->offset > copy) {         /* copy from window */
11277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                copy = state->offset - copy;
11287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (copy > state->whave) {
11297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    if (state->sane) {
11307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        strm->msg = (char *)"invalid distance too far back";
11317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        state->mode = BAD;
11327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        break;
11337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    }
11347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
11357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    Trace((stderr, "inflate.c too far\n"));
11367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    copy -= state->whave;
11377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    if (copy > state->length) copy = state->length;
11387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    if (copy > left) copy = left;
11397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    left -= copy;
11407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    state->length -= copy;
11417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    do {
11427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        *put++ = 0;
11437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    } while (--copy);
11447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    if (state->length == 0) state->mode = LEN;
11457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    break;
11467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
11477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                }
11487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (copy > state->wnext) {
11497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    copy -= state->wnext;
11507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    from = state->window + (state->wsize - copy);
11517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                }
11527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                else
11537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    from = state->window + (state->wnext - copy);
11547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (copy > state->length) copy = state->length;
11557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
11567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            else {                              /* copy from output */
11577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                from = put - state->offset;
11587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                copy = state->length;
11597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
11607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (copy > left) copy = left;
11617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            left -= copy;
11627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->length -= copy;
11637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            do {
11647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                *put++ = *from++;
11657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            } while (--copy);
11667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->length == 0) state->mode = LEN;
11677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
11687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case LIT:
11697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (left == 0) goto inf_leave;
11707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            *put++ = (unsigned char)(state->length);
11717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            left--;
11727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = LEN;
11737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            break;
11747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case CHECK:
11757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->wrap) {
11767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                NEEDBITS(32);
11777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                out -= left;
11787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                strm->total_out += out;
11797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->total += out;
11807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (out)
11817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    strm->adler = state->check =
11827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                        UPDATE(state->check, put - out, out);
11837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                out = left;
11847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if ((
11857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef GUNZIP
11867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     state->flags ? hold :
11877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
11887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                     ZSWAP32(hold)) != state->check) {
11897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    strm->msg = (char *)"incorrect data check";
11907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    state->mode = BAD;
11917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    break;
11927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                }
11937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                INITBITS();
11947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Tracev((stderr, "inflate:   check matches trailer\n"));
11957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
11967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef GUNZIP
11977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = LENGTH;
11987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case LENGTH:
11997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            if (state->wrap && state->flags) {
12007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                NEEDBITS(32);
12017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                if (hold != (state->total & 0xffffffffUL)) {
12027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    strm->msg = (char *)"incorrect length check";
12037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    state->mode = BAD;
12047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                    break;
12057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                }
12067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                INITBITS();
12077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                Tracev((stderr, "inflate:   length matches trailer\n"));
12087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            }
12097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
12107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = DONE;
12117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case DONE:
12127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ret = Z_STREAM_END;
12137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            goto inf_leave;
12147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case BAD:
12157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ret = Z_DATA_ERROR;
12167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            goto inf_leave;
12177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case MEM:
12187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return Z_MEM_ERROR;
12197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        case SYNC:
12207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        default:
12217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return Z_STREAM_ERROR;
12227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
12237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /*
12257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel       Return from inflate(), updating the total counts and the check value.
12267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel       If there was no progress during the inflate() call, return a buffer
12277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel       error.  Call updatewindow() to create and/or update the window state.
12287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel       Note: a memory error from inflate() is non-recoverable.
12297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel     */
12307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel  inf_leave:
12317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    RESTORE();
12327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
12337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            (state->mode < CHECK || flush != Z_FINISH)))
12347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {
12357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->mode = MEM;
12367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return Z_MEM_ERROR;
12377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
12387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    in -= strm->avail_in;
12397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    out -= strm->avail_out;
12407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    strm->total_in += in;
12417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    strm->total_out += out;
12427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->total += out;
12437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->wrap && out)
12447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        strm->adler = state->check =
12457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            UPDATE(state->check, strm->next_out - out, out);
12467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    strm->data_type = state->bits + (state->last ? 64 : 0) +
12477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                      (state->mode == TYPE ? 128 : 0) +
12487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                      (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
12497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
12507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        ret = Z_BUF_ERROR;
12517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return ret;
12527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
12537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateEnd(strm)
12557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm;
12567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
12577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    struct inflate_state FAR *state;
12587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
12597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return Z_STREAM_ERROR;
12607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state = (struct inflate_state FAR *)strm->state;
12617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->window != Z_NULL) ZFREE(strm, state->window);
12627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ZFREE(strm, strm->state);
12637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    strm->state = Z_NULL;
12647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Tracev((stderr, "inflate: end\n"));
12657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Z_OK;
12667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
12677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)
12697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm;
12707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielBytef *dictionary;
12717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieluInt *dictLength;
12727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
12737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    struct inflate_state FAR *state;
12747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check state */
12767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
12777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state = (struct inflate_state FAR *)strm->state;
12787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* copy dictionary */
12807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->whave && dictionary != Z_NULL) {
12817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        zmemcpy(dictionary, state->window + state->wnext,
12827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->whave - state->wnext);
12837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        zmemcpy(dictionary + state->whave - state->wnext,
12847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                state->window, state->wnext);
12857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
12867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (dictLength != Z_NULL)
12877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        *dictLength = state->whave;
12887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Z_OK;
12897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
12907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
12917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
12927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm;
12937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielconst Bytef *dictionary;
12947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieluInt dictLength;
12957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
12967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    struct inflate_state FAR *state;
12977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned long dictid;
12987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    int ret;
12997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check state */
13017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
13027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state = (struct inflate_state FAR *)strm->state;
13037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->wrap != 0 && state->mode != DICT)
13047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return Z_STREAM_ERROR;
13057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check for correct dictionary identifier */
13077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->mode == DICT) {
13087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        dictid = adler32(0L, Z_NULL, 0);
13097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        dictid = adler32(dictid, dictionary, dictLength);
13107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (dictid != state->check)
13117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return Z_DATA_ERROR;
13127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
13137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* copy dictionary to window using updatewindow(), which will amend the
13157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel       existing dictionary if appropriate */
13167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    ret = updatewindow(strm, dictionary + dictLength, dictLength);
13177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (ret) {
13187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->mode = MEM;
13197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return Z_MEM_ERROR;
13207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
13217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->havedict = 1;
13227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    Tracev((stderr, "inflate:   dictionary set\n"));
13237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Z_OK;
13247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
13257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateGetHeader(strm, head)
13277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm;
13287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielgz_headerp head;
13297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
13307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    struct inflate_state FAR *state;
13317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check state */
13337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
13347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state = (struct inflate_state FAR *)strm->state;
13357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
13367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* save header structure */
13387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->head = head;
13397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    head->done = 0;
13407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Z_OK;
13417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
13427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*
13447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff.  Return when found
13457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   or when out of input.  When called, *have is the number of pattern bytes
13467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   found in order so far, in 0..3.  On return *have is updated to the new
13477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   state.  If on return *have equals four, then the pattern was found and the
13487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   return value is how many bytes were read including the last byte of the
13497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   pattern.  If *have is less than four, then the pattern has not been found
13507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   yet and the return value is len.  In the latter case, syncsearch() can be
13517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   called again with more data and the *have state.  *have is initialized to
13527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   zero for the first call.
13537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
13547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniellocal unsigned syncsearch(have, buf, len)
13557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielunsigned FAR *have;
13567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielconst unsigned char FAR *buf;
13577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielunsigned len;
13587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
13597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned got;
13607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned next;
13617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    got = *have;
13637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    next = 0;
13647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    while (next < len && got < 4) {
13657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
13667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            got++;
13677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else if (buf[next])
13687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            got = 0;
13697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        else
13707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            got = 4 - got;
13717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        next++;
13727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
13737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    *have = got;
13747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return next;
13757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
13767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateSync(strm)
13787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm;
13797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
13807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned len;               /* number of bytes to look at or looked at */
13817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned long in, out;      /* temporary to save total_in and total_out */
13827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned char buf[4];       /* to restore bit buffer to byte string */
13837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    struct inflate_state FAR *state;
13847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check parameters */
13867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
13877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state = (struct inflate_state FAR *)strm->state;
13887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
13897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
13907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* if first time, start search in bit buffer */
13917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->mode != SYNC) {
13927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->mode = SYNC;
13937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->hold <<= state->bits & 7;
13947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->bits -= state->bits & 7;
13957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        len = 0;
13967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        while (state->bits >= 8) {
13977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            buf[len++] = (unsigned char)(state->hold);
13987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->hold >>= 8;
13997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            state->bits -= 8;
14007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
14017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->have = 0;
14027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        syncsearch(&(state->have), buf, len);
14037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
14047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* search available input */
14067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
14077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    strm->avail_in -= len;
14087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    strm->next_in += len;
14097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    strm->total_in += len;
14107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* return no joy or set up to restart inflate() on a new block */
14127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->have != 4) return Z_DATA_ERROR;
14137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    in = strm->total_in;  out = strm->total_out;
14147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    inflateReset(strm);
14157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    strm->total_in = in;  strm->total_out = out;
14167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->mode = TYPE;
14177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Z_OK;
14187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
14197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/*
14217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   Returns true if inflate is currently at the end of a block generated by
14227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
14237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   implementation to provide an additional safety check. PPP uses
14247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
14257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   block. When decompressing, PPP checks that at the end of input packet,
14267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel   inflate is waiting for these length bytes.
14277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */
14287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateSyncPoint(strm)
14297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm;
14307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
14317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    struct inflate_state FAR *state;
14327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
14347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state = (struct inflate_state FAR *)strm->state;
14357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return state->mode == STORED && state->bits == 0;
14367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
14377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateCopy(dest, source)
14397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp dest;
14407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp source;
14417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
14427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    struct inflate_state FAR *state;
14437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    struct inflate_state FAR *copy;
14447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned char FAR *window;
14457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    unsigned wsize;
14467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* check input */
14487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
14497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
14507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        return Z_STREAM_ERROR;
14517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state = (struct inflate_state FAR *)source->state;
14527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* allocate space */
14547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    copy = (struct inflate_state FAR *)
14557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel           ZALLOC(source, 1, sizeof(struct inflate_state));
14567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (copy == Z_NULL) return Z_MEM_ERROR;
14577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    window = Z_NULL;
14587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->window != Z_NULL) {
14597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        window = (unsigned char FAR *)
14607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel                 ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
14617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        if (window == Z_NULL) {
14627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            ZFREE(source, copy);
14637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            return Z_MEM_ERROR;
14647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        }
14657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
14667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    /* copy state */
14687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
14697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
14707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (state->lencode >= state->codes &&
14717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        state->lencode <= state->codes + ENOUGH - 1) {
14727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        copy->lencode = copy->codes + (state->lencode - state->codes);
14737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        copy->distcode = copy->codes + (state->distcode - state->codes);
14747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
14757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    copy->next = copy->codes + (state->next - state->codes);
14767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (window != Z_NULL) {
14777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        wsize = 1U << state->wbits;
14787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        zmemcpy(window, state->window, wsize);
14797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    }
14807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    copy->window = window;
14817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    dest->state = (struct internal_state FAR *)copy;
14827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Z_OK;
14837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
14847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateUndermine(strm, subvert)
14867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm;
14877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint subvert;
14887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
14897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    struct inflate_state FAR *state;
14907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
14917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
14927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state = (struct inflate_state FAR *)strm->state;
14937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->sane = !subvert;
14947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
14957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Z_OK;
14967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else
14977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state->sane = 1;
14987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return Z_DATA_ERROR;
14997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif
15007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
15017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
15027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniellong ZEXPORT inflateMark(strm)
15037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm;
15047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{
15057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    struct inflate_state FAR *state;
15067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel
15077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16;
15087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    state = (struct inflate_state FAR *)strm->state;
15097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel    return ((long)(state->back) << 16) +
15107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel        (state->mode == COPY ? state->length :
15117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel            (state->mode == MATCH ? state->was - state->length : 0));
15127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel}
1513