xref: /openbmc/linux/lib/zlib_inflate/inflate.c (revision f0ac675806441d17303707856f4d23bd27092014)
14f3865fbSRichard Purdie /* inflate.c -- zlib decompression
24f3865fbSRichard Purdie  * Copyright (C) 1995-2005 Mark Adler
31da177e4SLinus Torvalds  * For conditions of distribution and use, see copyright notice in zlib.h
44f3865fbSRichard Purdie  *
54f3865fbSRichard Purdie  * Based on zlib 1.2.3 but modified for the Linux Kernel by
64f3865fbSRichard Purdie  * Richard Purdie <richard@openedhand.com>
74f3865fbSRichard Purdie  *
84f3865fbSRichard Purdie  * Changes mainly for static instead of dynamic memory allocation
94f3865fbSRichard Purdie  *
101da177e4SLinus Torvalds  */
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds #include <linux/zutil.h>
134f3865fbSRichard Purdie #include "inftrees.h"
144f3865fbSRichard Purdie #include "inflate.h"
154f3865fbSRichard Purdie #include "inffast.h"
161da177e4SLinus Torvalds #include "infutil.h"
171da177e4SLinus Torvalds 
181da177e4SLinus Torvalds int zlib_inflate_workspacesize(void)
191da177e4SLinus Torvalds {
201da177e4SLinus Torvalds     return sizeof(struct inflate_workspace);
211da177e4SLinus Torvalds }
221da177e4SLinus Torvalds 
234f3865fbSRichard Purdie int zlib_inflateReset(z_streamp strm)
241da177e4SLinus Torvalds {
254f3865fbSRichard Purdie     struct inflate_state *state;
264f3865fbSRichard Purdie 
274f3865fbSRichard Purdie     if (strm == NULL || strm->state == NULL) return Z_STREAM_ERROR;
284f3865fbSRichard Purdie     state = (struct inflate_state *)strm->state;
294f3865fbSRichard Purdie     strm->total_in = strm->total_out = state->total = 0;
304f3865fbSRichard Purdie     strm->msg = NULL;
314f3865fbSRichard Purdie     strm->adler = 1;        /* to support ill-conceived Java test suite */
324f3865fbSRichard Purdie     state->mode = HEAD;
334f3865fbSRichard Purdie     state->last = 0;
344f3865fbSRichard Purdie     state->havedict = 0;
354f3865fbSRichard Purdie     state->dmax = 32768U;
364f3865fbSRichard Purdie     state->hold = 0;
374f3865fbSRichard Purdie     state->bits = 0;
384f3865fbSRichard Purdie     state->lencode = state->distcode = state->next = state->codes;
394f3865fbSRichard Purdie 
404f3865fbSRichard Purdie     /* Initialise Window */
414f3865fbSRichard Purdie     state->wsize = 1U << state->wbits;
424f3865fbSRichard Purdie     state->write = 0;
434f3865fbSRichard Purdie     state->whave = 0;
444f3865fbSRichard Purdie 
451da177e4SLinus Torvalds     return Z_OK;
461da177e4SLinus Torvalds }
471da177e4SLinus Torvalds 
484f3865fbSRichard Purdie #if 0
494f3865fbSRichard Purdie int zlib_inflatePrime(z_streamp strm, int bits, int value)
501da177e4SLinus Torvalds {
514f3865fbSRichard Purdie     struct inflate_state *state;
524f3865fbSRichard Purdie 
534f3865fbSRichard Purdie     if (strm == NULL || strm->state == NULL) return Z_STREAM_ERROR;
544f3865fbSRichard Purdie     state = (struct inflate_state *)strm->state;
554f3865fbSRichard Purdie     if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
564f3865fbSRichard Purdie     value &= (1L << bits) - 1;
574f3865fbSRichard Purdie     state->hold += value << state->bits;
584f3865fbSRichard Purdie     state->bits += bits;
591da177e4SLinus Torvalds     return Z_OK;
601da177e4SLinus Torvalds }
614f3865fbSRichard Purdie #endif
621da177e4SLinus Torvalds 
634f3865fbSRichard Purdie int zlib_inflateInit2(z_streamp strm, int windowBits)
641da177e4SLinus Torvalds {
654f3865fbSRichard Purdie     struct inflate_state *state;
661da177e4SLinus Torvalds 
674f3865fbSRichard Purdie     if (strm == NULL) return Z_STREAM_ERROR;
684f3865fbSRichard Purdie     strm->msg = NULL;                 /* in case we return an error */
691da177e4SLinus Torvalds 
704f3865fbSRichard Purdie     state = &WS(strm)->inflate_state;
714f3865fbSRichard Purdie     strm->state = (struct internal_state *)state;
724f3865fbSRichard Purdie 
734f3865fbSRichard Purdie     if (windowBits < 0) {
744f3865fbSRichard Purdie         state->wrap = 0;
754f3865fbSRichard Purdie         windowBits = -windowBits;
761da177e4SLinus Torvalds     }
774f3865fbSRichard Purdie     else {
784f3865fbSRichard Purdie         state->wrap = (windowBits >> 4) + 1;
794f3865fbSRichard Purdie     }
804f3865fbSRichard Purdie     if (windowBits < 8 || windowBits > 15) {
811da177e4SLinus Torvalds         return Z_STREAM_ERROR;
821da177e4SLinus Torvalds     }
834f3865fbSRichard Purdie     state->wbits = (unsigned)windowBits;
844f3865fbSRichard Purdie     state->window = &WS(strm)->working_window[0];
851da177e4SLinus Torvalds 
864f3865fbSRichard Purdie     return zlib_inflateReset(strm);
871da177e4SLinus Torvalds }
881da177e4SLinus Torvalds 
894f3865fbSRichard Purdie /*
904f3865fbSRichard Purdie    Return state with length and distance decoding tables and index sizes set to
914f3865fbSRichard Purdie    fixed code decoding.  This returns fixed tables from inffixed.h.
924f3865fbSRichard Purdie  */
934f3865fbSRichard Purdie static void zlib_fixedtables(struct inflate_state *state)
944f3865fbSRichard Purdie {
954f3865fbSRichard Purdie #   include "inffixed.h"
964f3865fbSRichard Purdie     state->lencode = lenfix;
974f3865fbSRichard Purdie     state->lenbits = 9;
984f3865fbSRichard Purdie     state->distcode = distfix;
994f3865fbSRichard Purdie     state->distbits = 5;
1004f3865fbSRichard Purdie }
1014f3865fbSRichard Purdie 
1024f3865fbSRichard Purdie 
1034f3865fbSRichard Purdie /*
1044f3865fbSRichard Purdie    Update the window with the last wsize (normally 32K) bytes written before
1054f3865fbSRichard Purdie    returning. This is only called when a window is already in use, or when
1064f3865fbSRichard Purdie    output has been written during this inflate call, but the end of the deflate
1074f3865fbSRichard Purdie    stream has not been reached yet. It is also called to window dictionary data
1084f3865fbSRichard Purdie    when a dictionary is loaded.
1094f3865fbSRichard Purdie 
1104f3865fbSRichard Purdie    Providing output buffers larger than 32K to inflate() should provide a speed
1114f3865fbSRichard Purdie    advantage, since only the last 32K of output is copied to the sliding window
1124f3865fbSRichard Purdie    upon return from inflate(), and since all distances after the first 32K of
1134f3865fbSRichard Purdie    output will fall in the output data, making match copies simpler and faster.
1144f3865fbSRichard Purdie    The advantage may be dependent on the size of the processor's data caches.
1154f3865fbSRichard Purdie  */
1164f3865fbSRichard Purdie static void zlib_updatewindow(z_streamp strm, unsigned out)
1174f3865fbSRichard Purdie {
1184f3865fbSRichard Purdie     struct inflate_state *state;
1194f3865fbSRichard Purdie     unsigned copy, dist;
1204f3865fbSRichard Purdie 
1214f3865fbSRichard Purdie     state = (struct inflate_state *)strm->state;
1224f3865fbSRichard Purdie 
1234f3865fbSRichard Purdie     /* copy state->wsize or less output bytes into the circular window */
1244f3865fbSRichard Purdie     copy = out - strm->avail_out;
1254f3865fbSRichard Purdie     if (copy >= state->wsize) {
1264f3865fbSRichard Purdie         memcpy(state->window, strm->next_out - state->wsize, state->wsize);
1274f3865fbSRichard Purdie         state->write = 0;
1284f3865fbSRichard Purdie         state->whave = state->wsize;
1294f3865fbSRichard Purdie     }
1304f3865fbSRichard Purdie     else {
1314f3865fbSRichard Purdie         dist = state->wsize - state->write;
1324f3865fbSRichard Purdie         if (dist > copy) dist = copy;
1334f3865fbSRichard Purdie         memcpy(state->window + state->write, strm->next_out - copy, dist);
1344f3865fbSRichard Purdie         copy -= dist;
1354f3865fbSRichard Purdie         if (copy) {
1364f3865fbSRichard Purdie             memcpy(state->window, strm->next_out - copy, copy);
1374f3865fbSRichard Purdie             state->write = copy;
1384f3865fbSRichard Purdie             state->whave = state->wsize;
1394f3865fbSRichard Purdie         }
1404f3865fbSRichard Purdie         else {
1414f3865fbSRichard Purdie             state->write += dist;
1424f3865fbSRichard Purdie             if (state->write == state->wsize) state->write = 0;
1434f3865fbSRichard Purdie             if (state->whave < state->wsize) state->whave += dist;
1444f3865fbSRichard Purdie         }
1454f3865fbSRichard Purdie     }
1461da177e4SLinus Torvalds }
1471da177e4SLinus Torvalds 
1481da177e4SLinus Torvalds 
1491da177e4SLinus Torvalds /*
1501da177e4SLinus Torvalds  * At the end of a Deflate-compressed PPP packet, we expect to have seen
1511da177e4SLinus Torvalds  * a `stored' block type value but not the (zero) length bytes.
1521da177e4SLinus Torvalds  */
1534f3865fbSRichard Purdie /*
1544f3865fbSRichard Purdie    Returns true if inflate is currently at the end of a block generated by
1554f3865fbSRichard Purdie    Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
1564f3865fbSRichard Purdie    implementation to provide an additional safety check. PPP uses
1574f3865fbSRichard Purdie    Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
1584f3865fbSRichard Purdie    block. When decompressing, PPP checks that at the end of input packet,
1594f3865fbSRichard Purdie    inflate is waiting for these length bytes.
1604f3865fbSRichard Purdie  */
1614f3865fbSRichard Purdie static int zlib_inflateSyncPacket(z_streamp strm)
1621da177e4SLinus Torvalds {
1634f3865fbSRichard Purdie     struct inflate_state *state;
1644f3865fbSRichard Purdie 
1654f3865fbSRichard Purdie     if (strm == NULL || strm->state == NULL) return Z_STREAM_ERROR;
1664f3865fbSRichard Purdie     state = (struct inflate_state *)strm->state;
1674f3865fbSRichard Purdie 
1684f3865fbSRichard Purdie     if (state->mode == STORED && state->bits == 0) {
1694f3865fbSRichard Purdie 	state->mode = TYPE;
1701da177e4SLinus Torvalds         return Z_OK;
1711da177e4SLinus Torvalds     }
1721da177e4SLinus Torvalds     return Z_DATA_ERROR;
1734f3865fbSRichard Purdie }
1744f3865fbSRichard Purdie 
1754f3865fbSRichard Purdie /* Macros for inflate(): */
1764f3865fbSRichard Purdie 
1774f3865fbSRichard Purdie /* check function to use adler32() for zlib or crc32() for gzip */
1784f3865fbSRichard Purdie #define UPDATE(check, buf, len) zlib_adler32(check, buf, len)
1794f3865fbSRichard Purdie 
1804f3865fbSRichard Purdie /* Load registers with state in inflate() for speed */
1814f3865fbSRichard Purdie #define LOAD() \
1824f3865fbSRichard Purdie     do { \
1834f3865fbSRichard Purdie         put = strm->next_out; \
1844f3865fbSRichard Purdie         left = strm->avail_out; \
1854f3865fbSRichard Purdie         next = strm->next_in; \
1864f3865fbSRichard Purdie         have = strm->avail_in; \
1874f3865fbSRichard Purdie         hold = state->hold; \
1884f3865fbSRichard Purdie         bits = state->bits; \
1894f3865fbSRichard Purdie     } while (0)
1904f3865fbSRichard Purdie 
1914f3865fbSRichard Purdie /* Restore state from registers in inflate() */
1924f3865fbSRichard Purdie #define RESTORE() \
1934f3865fbSRichard Purdie     do { \
1944f3865fbSRichard Purdie         strm->next_out = put; \
1954f3865fbSRichard Purdie         strm->avail_out = left; \
1964f3865fbSRichard Purdie         strm->next_in = next; \
1974f3865fbSRichard Purdie         strm->avail_in = have; \
1984f3865fbSRichard Purdie         state->hold = hold; \
1994f3865fbSRichard Purdie         state->bits = bits; \
2004f3865fbSRichard Purdie     } while (0)
2014f3865fbSRichard Purdie 
2024f3865fbSRichard Purdie /* Clear the input bit accumulator */
2034f3865fbSRichard Purdie #define INITBITS() \
2044f3865fbSRichard Purdie     do { \
2054f3865fbSRichard Purdie         hold = 0; \
2064f3865fbSRichard Purdie         bits = 0; \
2074f3865fbSRichard Purdie     } while (0)
2084f3865fbSRichard Purdie 
2094f3865fbSRichard Purdie /* Get a byte of input into the bit accumulator, or return from inflate()
2104f3865fbSRichard Purdie    if there is no input available. */
2114f3865fbSRichard Purdie #define PULLBYTE() \
2124f3865fbSRichard Purdie     do { \
2134f3865fbSRichard Purdie         if (have == 0) goto inf_leave; \
2144f3865fbSRichard Purdie         have--; \
2154f3865fbSRichard Purdie         hold += (unsigned long)(*next++) << bits; \
2164f3865fbSRichard Purdie         bits += 8; \
2174f3865fbSRichard Purdie     } while (0)
2184f3865fbSRichard Purdie 
2194f3865fbSRichard Purdie /* Assure that there are at least n bits in the bit accumulator.  If there is
2204f3865fbSRichard Purdie    not enough available input to do that, then return from inflate(). */
2214f3865fbSRichard Purdie #define NEEDBITS(n) \
2224f3865fbSRichard Purdie     do { \
2234f3865fbSRichard Purdie         while (bits < (unsigned)(n)) \
2244f3865fbSRichard Purdie             PULLBYTE(); \
2254f3865fbSRichard Purdie     } while (0)
2264f3865fbSRichard Purdie 
2274f3865fbSRichard Purdie /* Return the low n bits of the bit accumulator (n < 16) */
2284f3865fbSRichard Purdie #define BITS(n) \
2294f3865fbSRichard Purdie     ((unsigned)hold & ((1U << (n)) - 1))
2304f3865fbSRichard Purdie 
2314f3865fbSRichard Purdie /* Remove n bits from the bit accumulator */
2324f3865fbSRichard Purdie #define DROPBITS(n) \
2334f3865fbSRichard Purdie     do { \
2344f3865fbSRichard Purdie         hold >>= (n); \
2354f3865fbSRichard Purdie         bits -= (unsigned)(n); \
2364f3865fbSRichard Purdie     } while (0)
2374f3865fbSRichard Purdie 
2384f3865fbSRichard Purdie /* Remove zero to seven bits as needed to go to a byte boundary */
2394f3865fbSRichard Purdie #define BYTEBITS() \
2404f3865fbSRichard Purdie     do { \
2414f3865fbSRichard Purdie         hold >>= bits & 7; \
2424f3865fbSRichard Purdie         bits -= bits & 7; \
2434f3865fbSRichard Purdie     } while (0)
2444f3865fbSRichard Purdie 
2454f3865fbSRichard Purdie /* Reverse the bytes in a 32-bit value */
2464f3865fbSRichard Purdie #define REVERSE(q) \
2474f3865fbSRichard Purdie     ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
2484f3865fbSRichard Purdie      (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
2494f3865fbSRichard Purdie 
2504f3865fbSRichard Purdie /*
2514f3865fbSRichard Purdie    inflate() uses a state machine to process as much input data and generate as
2524f3865fbSRichard Purdie    much output data as possible before returning.  The state machine is
2534f3865fbSRichard Purdie    structured roughly as follows:
2544f3865fbSRichard Purdie 
2554f3865fbSRichard Purdie     for (;;) switch (state) {
2564f3865fbSRichard Purdie     ...
2574f3865fbSRichard Purdie     case STATEn:
2584f3865fbSRichard Purdie         if (not enough input data or output space to make progress)
2594f3865fbSRichard Purdie             return;
2604f3865fbSRichard Purdie         ... make progress ...
2614f3865fbSRichard Purdie         state = STATEm;
2624f3865fbSRichard Purdie         break;
2634f3865fbSRichard Purdie     ...
2644f3865fbSRichard Purdie     }
2654f3865fbSRichard Purdie 
2664f3865fbSRichard Purdie    so when inflate() is called again, the same case is attempted again, and
2674f3865fbSRichard Purdie    if the appropriate resources are provided, the machine proceeds to the
2684f3865fbSRichard Purdie    next state.  The NEEDBITS() macro is usually the way the state evaluates
2694f3865fbSRichard Purdie    whether it can proceed or should return.  NEEDBITS() does the return if
2704f3865fbSRichard Purdie    the requested bits are not available.  The typical use of the BITS macros
2714f3865fbSRichard Purdie    is:
2724f3865fbSRichard Purdie 
2734f3865fbSRichard Purdie         NEEDBITS(n);
2744f3865fbSRichard Purdie         ... do something with BITS(n) ...
2754f3865fbSRichard Purdie         DROPBITS(n);
2764f3865fbSRichard Purdie 
2774f3865fbSRichard Purdie    where NEEDBITS(n) either returns from inflate() if there isn't enough
2784f3865fbSRichard Purdie    input left to load n bits into the accumulator, or it continues.  BITS(n)
2794f3865fbSRichard Purdie    gives the low n bits in the accumulator.  When done, DROPBITS(n) drops
2804f3865fbSRichard Purdie    the low n bits off the accumulator.  INITBITS() clears the accumulator
2814f3865fbSRichard Purdie    and sets the number of available bits to zero.  BYTEBITS() discards just
2824f3865fbSRichard Purdie    enough bits to put the accumulator on a byte boundary.  After BYTEBITS()
2834f3865fbSRichard Purdie    and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
2844f3865fbSRichard Purdie 
2854f3865fbSRichard Purdie    NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
2864f3865fbSRichard Purdie    if there is no input available.  The decoding of variable length codes uses
2874f3865fbSRichard Purdie    PULLBYTE() directly in order to pull just enough bytes to decode the next
2884f3865fbSRichard Purdie    code, and no more.
2894f3865fbSRichard Purdie 
2904f3865fbSRichard Purdie    Some states loop until they get enough input, making sure that enough
2914f3865fbSRichard Purdie    state information is maintained to continue the loop where it left off
2924f3865fbSRichard Purdie    if NEEDBITS() returns in the loop.  For example, want, need, and keep
2934f3865fbSRichard Purdie    would all have to actually be part of the saved state in case NEEDBITS()
2944f3865fbSRichard Purdie    returns:
2954f3865fbSRichard Purdie 
2964f3865fbSRichard Purdie     case STATEw:
2974f3865fbSRichard Purdie         while (want < need) {
2984f3865fbSRichard Purdie             NEEDBITS(n);
2994f3865fbSRichard Purdie             keep[want++] = BITS(n);
3004f3865fbSRichard Purdie             DROPBITS(n);
3014f3865fbSRichard Purdie         }
3024f3865fbSRichard Purdie         state = STATEx;
3034f3865fbSRichard Purdie     case STATEx:
3044f3865fbSRichard Purdie 
3054f3865fbSRichard Purdie    As shown above, if the next state is also the next case, then the break
3064f3865fbSRichard Purdie    is omitted.
3074f3865fbSRichard Purdie 
3084f3865fbSRichard Purdie    A state may also return if there is not enough output space available to
3094f3865fbSRichard Purdie    complete that state.  Those states are copying stored data, writing a
3104f3865fbSRichard Purdie    literal byte, and copying a matching string.
3114f3865fbSRichard Purdie 
3124f3865fbSRichard Purdie    When returning, a "goto inf_leave" is used to update the total counters,
3134f3865fbSRichard Purdie    update the check value, and determine whether any progress has been made
3144f3865fbSRichard Purdie    during that inflate() call in order to return the proper return code.
3154f3865fbSRichard Purdie    Progress is defined as a change in either strm->avail_in or strm->avail_out.
3164f3865fbSRichard Purdie    When there is a window, goto inf_leave will update the window with the last
3174f3865fbSRichard Purdie    output written.  If a goto inf_leave occurs in the middle of decompression
3184f3865fbSRichard Purdie    and there is no window currently, goto inf_leave will create one and copy
3194f3865fbSRichard Purdie    output to the window for the next call of inflate().
3204f3865fbSRichard Purdie 
3214f3865fbSRichard Purdie    In this implementation, the flush parameter of inflate() only affects the
3224f3865fbSRichard Purdie    return code (per zlib.h).  inflate() always writes as much as possible to
3234f3865fbSRichard Purdie    strm->next_out, given the space available and the provided input--the effect
3244f3865fbSRichard Purdie    documented in zlib.h of Z_SYNC_FLUSH.  Furthermore, inflate() always defers
3254f3865fbSRichard Purdie    the allocation of and copying into a sliding window until necessary, which
3264f3865fbSRichard Purdie    provides the effect documented in zlib.h for Z_FINISH when the entire input
3274f3865fbSRichard Purdie    stream available.  So the only thing the flush parameter actually does is:
3284f3865fbSRichard Purdie    when flush is set to Z_FINISH, inflate() cannot return Z_OK.  Instead it
3294f3865fbSRichard Purdie    will return Z_BUF_ERROR if it has not reached the end of the stream.
3304f3865fbSRichard Purdie  */
3314f3865fbSRichard Purdie 
3324f3865fbSRichard Purdie int zlib_inflate(z_streamp strm, int flush)
3334f3865fbSRichard Purdie {
3344f3865fbSRichard Purdie     struct inflate_state *state;
3354f3865fbSRichard Purdie     unsigned char *next;    /* next input */
3364f3865fbSRichard Purdie     unsigned char *put;     /* next output */
3374f3865fbSRichard Purdie     unsigned have, left;        /* available input and output */
3384f3865fbSRichard Purdie     unsigned long hold;         /* bit buffer */
3394f3865fbSRichard Purdie     unsigned bits;              /* bits in bit buffer */
3404f3865fbSRichard Purdie     unsigned in, out;           /* save starting available input and output */
3414f3865fbSRichard Purdie     unsigned copy;              /* number of stored or match bytes to copy */
3424f3865fbSRichard Purdie     unsigned char *from;    /* where to copy match bytes from */
3434f3865fbSRichard Purdie     code this;                  /* current decoding table entry */
3444f3865fbSRichard Purdie     code last;                  /* parent table entry */
3454f3865fbSRichard Purdie     unsigned len;               /* length to copy for repeats, bits to drop */
3464f3865fbSRichard Purdie     int ret;                    /* return code */
3474f3865fbSRichard Purdie     static const unsigned short order[19] = /* permutation of code lengths */
3484f3865fbSRichard Purdie         {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
3494f3865fbSRichard Purdie 
35031925c88SPeter Korsgaard     /* Do not check for strm->next_out == NULL here as ppc zImage
35131925c88SPeter Korsgaard        inflates to strm->next_out = 0 */
35231925c88SPeter Korsgaard 
35331925c88SPeter Korsgaard     if (strm == NULL || strm->state == NULL ||
3544f3865fbSRichard Purdie         (strm->next_in == NULL && strm->avail_in != 0))
3554f3865fbSRichard Purdie         return Z_STREAM_ERROR;
3564f3865fbSRichard Purdie 
3574f3865fbSRichard Purdie     state = (struct inflate_state *)strm->state;
3584f3865fbSRichard Purdie 
3594f3865fbSRichard Purdie     if (state->mode == TYPE) state->mode = TYPEDO;      /* skip check */
3604f3865fbSRichard Purdie     LOAD();
3614f3865fbSRichard Purdie     in = have;
3624f3865fbSRichard Purdie     out = left;
3634f3865fbSRichard Purdie     ret = Z_OK;
3644f3865fbSRichard Purdie     for (;;)
3654f3865fbSRichard Purdie         switch (state->mode) {
3664f3865fbSRichard Purdie         case HEAD:
3674f3865fbSRichard Purdie             if (state->wrap == 0) {
3684f3865fbSRichard Purdie                 state->mode = TYPEDO;
3694f3865fbSRichard Purdie                 break;
3704f3865fbSRichard Purdie             }
3714f3865fbSRichard Purdie             NEEDBITS(16);
3724f3865fbSRichard Purdie             if (
3734f3865fbSRichard Purdie                 ((BITS(8) << 8) + (hold >> 8)) % 31) {
3744f3865fbSRichard Purdie                 strm->msg = (char *)"incorrect header check";
3754f3865fbSRichard Purdie                 state->mode = BAD;
3764f3865fbSRichard Purdie                 break;
3774f3865fbSRichard Purdie             }
3784f3865fbSRichard Purdie             if (BITS(4) != Z_DEFLATED) {
3794f3865fbSRichard Purdie                 strm->msg = (char *)"unknown compression method";
3804f3865fbSRichard Purdie                 state->mode = BAD;
3814f3865fbSRichard Purdie                 break;
3824f3865fbSRichard Purdie             }
3834f3865fbSRichard Purdie             DROPBITS(4);
3844f3865fbSRichard Purdie             len = BITS(4) + 8;
3854f3865fbSRichard Purdie             if (len > state->wbits) {
3864f3865fbSRichard Purdie                 strm->msg = (char *)"invalid window size";
3874f3865fbSRichard Purdie                 state->mode = BAD;
3884f3865fbSRichard Purdie                 break;
3894f3865fbSRichard Purdie             }
3904f3865fbSRichard Purdie             state->dmax = 1U << len;
3914f3865fbSRichard Purdie             strm->adler = state->check = zlib_adler32(0L, NULL, 0);
3924f3865fbSRichard Purdie             state->mode = hold & 0x200 ? DICTID : TYPE;
3934f3865fbSRichard Purdie             INITBITS();
3944f3865fbSRichard Purdie             break;
3954f3865fbSRichard Purdie         case DICTID:
3964f3865fbSRichard Purdie             NEEDBITS(32);
3974f3865fbSRichard Purdie             strm->adler = state->check = REVERSE(hold);
3984f3865fbSRichard Purdie             INITBITS();
3994f3865fbSRichard Purdie             state->mode = DICT;
4004f3865fbSRichard Purdie         case DICT:
4014f3865fbSRichard Purdie             if (state->havedict == 0) {
4024f3865fbSRichard Purdie                 RESTORE();
4034f3865fbSRichard Purdie                 return Z_NEED_DICT;
4044f3865fbSRichard Purdie             }
4054f3865fbSRichard Purdie             strm->adler = state->check = zlib_adler32(0L, NULL, 0);
4064f3865fbSRichard Purdie             state->mode = TYPE;
4074f3865fbSRichard Purdie         case TYPE:
4084f3865fbSRichard Purdie             if (flush == Z_BLOCK) goto inf_leave;
4094f3865fbSRichard Purdie         case TYPEDO:
4104f3865fbSRichard Purdie             if (state->last) {
4114f3865fbSRichard Purdie                 BYTEBITS();
4124f3865fbSRichard Purdie                 state->mode = CHECK;
4134f3865fbSRichard Purdie                 break;
4144f3865fbSRichard Purdie             }
4154f3865fbSRichard Purdie             NEEDBITS(3);
4164f3865fbSRichard Purdie             state->last = BITS(1);
4174f3865fbSRichard Purdie             DROPBITS(1);
4184f3865fbSRichard Purdie             switch (BITS(2)) {
4194f3865fbSRichard Purdie             case 0:                             /* stored block */
4204f3865fbSRichard Purdie                 state->mode = STORED;
4214f3865fbSRichard Purdie                 break;
4224f3865fbSRichard Purdie             case 1:                             /* fixed block */
4234f3865fbSRichard Purdie                 zlib_fixedtables(state);
4244f3865fbSRichard Purdie                 state->mode = LEN;              /* decode codes */
4254f3865fbSRichard Purdie                 break;
4264f3865fbSRichard Purdie             case 2:                             /* dynamic block */
4274f3865fbSRichard Purdie                 state->mode = TABLE;
4284f3865fbSRichard Purdie                 break;
4294f3865fbSRichard Purdie             case 3:
4304f3865fbSRichard Purdie                 strm->msg = (char *)"invalid block type";
4314f3865fbSRichard Purdie                 state->mode = BAD;
4324f3865fbSRichard Purdie             }
4334f3865fbSRichard Purdie             DROPBITS(2);
4344f3865fbSRichard Purdie             break;
4354f3865fbSRichard Purdie         case STORED:
4364f3865fbSRichard Purdie             BYTEBITS();                         /* go to byte boundary */
4374f3865fbSRichard Purdie             NEEDBITS(32);
4384f3865fbSRichard Purdie             if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
4394f3865fbSRichard Purdie                 strm->msg = (char *)"invalid stored block lengths";
4404f3865fbSRichard Purdie                 state->mode = BAD;
4414f3865fbSRichard Purdie                 break;
4424f3865fbSRichard Purdie             }
4434f3865fbSRichard Purdie             state->length = (unsigned)hold & 0xffff;
4444f3865fbSRichard Purdie             INITBITS();
4454f3865fbSRichard Purdie             state->mode = COPY;
4464f3865fbSRichard Purdie         case COPY:
4474f3865fbSRichard Purdie             copy = state->length;
4484f3865fbSRichard Purdie             if (copy) {
4494f3865fbSRichard Purdie                 if (copy > have) copy = have;
4504f3865fbSRichard Purdie                 if (copy > left) copy = left;
4514f3865fbSRichard Purdie                 if (copy == 0) goto inf_leave;
4524f3865fbSRichard Purdie                 memcpy(put, next, copy);
4534f3865fbSRichard Purdie                 have -= copy;
4544f3865fbSRichard Purdie                 next += copy;
4554f3865fbSRichard Purdie                 left -= copy;
4564f3865fbSRichard Purdie                 put += copy;
4574f3865fbSRichard Purdie                 state->length -= copy;
4584f3865fbSRichard Purdie                 break;
4594f3865fbSRichard Purdie             }
4604f3865fbSRichard Purdie             state->mode = TYPE;
4614f3865fbSRichard Purdie             break;
4624f3865fbSRichard Purdie         case TABLE:
4634f3865fbSRichard Purdie             NEEDBITS(14);
4644f3865fbSRichard Purdie             state->nlen = BITS(5) + 257;
4654f3865fbSRichard Purdie             DROPBITS(5);
4664f3865fbSRichard Purdie             state->ndist = BITS(5) + 1;
4674f3865fbSRichard Purdie             DROPBITS(5);
4684f3865fbSRichard Purdie             state->ncode = BITS(4) + 4;
4694f3865fbSRichard Purdie             DROPBITS(4);
4704f3865fbSRichard Purdie #ifndef PKZIP_BUG_WORKAROUND
4714f3865fbSRichard Purdie             if (state->nlen > 286 || state->ndist > 30) {
4724f3865fbSRichard Purdie                 strm->msg = (char *)"too many length or distance symbols";
4734f3865fbSRichard Purdie                 state->mode = BAD;
4744f3865fbSRichard Purdie                 break;
4754f3865fbSRichard Purdie             }
4764f3865fbSRichard Purdie #endif
4774f3865fbSRichard Purdie             state->have = 0;
4784f3865fbSRichard Purdie             state->mode = LENLENS;
4794f3865fbSRichard Purdie         case LENLENS:
4804f3865fbSRichard Purdie             while (state->have < state->ncode) {
4814f3865fbSRichard Purdie                 NEEDBITS(3);
4824f3865fbSRichard Purdie                 state->lens[order[state->have++]] = (unsigned short)BITS(3);
4834f3865fbSRichard Purdie                 DROPBITS(3);
4844f3865fbSRichard Purdie             }
4854f3865fbSRichard Purdie             while (state->have < 19)
4864f3865fbSRichard Purdie                 state->lens[order[state->have++]] = 0;
4874f3865fbSRichard Purdie             state->next = state->codes;
4884f3865fbSRichard Purdie             state->lencode = (code const *)(state->next);
4894f3865fbSRichard Purdie             state->lenbits = 7;
4904f3865fbSRichard Purdie             ret = zlib_inflate_table(CODES, state->lens, 19, &(state->next),
4914f3865fbSRichard Purdie                                 &(state->lenbits), state->work);
4924f3865fbSRichard Purdie             if (ret) {
4934f3865fbSRichard Purdie                 strm->msg = (char *)"invalid code lengths set";
4944f3865fbSRichard Purdie                 state->mode = BAD;
4954f3865fbSRichard Purdie                 break;
4964f3865fbSRichard Purdie             }
4974f3865fbSRichard Purdie             state->have = 0;
4984f3865fbSRichard Purdie             state->mode = CODELENS;
4994f3865fbSRichard Purdie         case CODELENS:
5004f3865fbSRichard Purdie             while (state->have < state->nlen + state->ndist) {
5014f3865fbSRichard Purdie                 for (;;) {
5024f3865fbSRichard Purdie                     this = state->lencode[BITS(state->lenbits)];
5034f3865fbSRichard Purdie                     if ((unsigned)(this.bits) <= bits) break;
5044f3865fbSRichard Purdie                     PULLBYTE();
5054f3865fbSRichard Purdie                 }
5064f3865fbSRichard Purdie                 if (this.val < 16) {
5074f3865fbSRichard Purdie                     NEEDBITS(this.bits);
5084f3865fbSRichard Purdie                     DROPBITS(this.bits);
5094f3865fbSRichard Purdie                     state->lens[state->have++] = this.val;
5104f3865fbSRichard Purdie                 }
5114f3865fbSRichard Purdie                 else {
5124f3865fbSRichard Purdie                     if (this.val == 16) {
5134f3865fbSRichard Purdie                         NEEDBITS(this.bits + 2);
5144f3865fbSRichard Purdie                         DROPBITS(this.bits);
5154f3865fbSRichard Purdie                         if (state->have == 0) {
5164f3865fbSRichard Purdie                             strm->msg = (char *)"invalid bit length repeat";
5174f3865fbSRichard Purdie                             state->mode = BAD;
5184f3865fbSRichard Purdie                             break;
5194f3865fbSRichard Purdie                         }
5204f3865fbSRichard Purdie                         len = state->lens[state->have - 1];
5214f3865fbSRichard Purdie                         copy = 3 + BITS(2);
5224f3865fbSRichard Purdie                         DROPBITS(2);
5234f3865fbSRichard Purdie                     }
5244f3865fbSRichard Purdie                     else if (this.val == 17) {
5254f3865fbSRichard Purdie                         NEEDBITS(this.bits + 3);
5264f3865fbSRichard Purdie                         DROPBITS(this.bits);
5274f3865fbSRichard Purdie                         len = 0;
5284f3865fbSRichard Purdie                         copy = 3 + BITS(3);
5294f3865fbSRichard Purdie                         DROPBITS(3);
5304f3865fbSRichard Purdie                     }
5314f3865fbSRichard Purdie                     else {
5324f3865fbSRichard Purdie                         NEEDBITS(this.bits + 7);
5334f3865fbSRichard Purdie                         DROPBITS(this.bits);
5344f3865fbSRichard Purdie                         len = 0;
5354f3865fbSRichard Purdie                         copy = 11 + BITS(7);
5364f3865fbSRichard Purdie                         DROPBITS(7);
5374f3865fbSRichard Purdie                     }
5384f3865fbSRichard Purdie                     if (state->have + copy > state->nlen + state->ndist) {
5394f3865fbSRichard Purdie                         strm->msg = (char *)"invalid bit length repeat";
5404f3865fbSRichard Purdie                         state->mode = BAD;
5414f3865fbSRichard Purdie                         break;
5424f3865fbSRichard Purdie                     }
5434f3865fbSRichard Purdie                     while (copy--)
5444f3865fbSRichard Purdie                         state->lens[state->have++] = (unsigned short)len;
5454f3865fbSRichard Purdie                 }
5464f3865fbSRichard Purdie             }
5474f3865fbSRichard Purdie 
5484f3865fbSRichard Purdie             /* handle error breaks in while */
5494f3865fbSRichard Purdie             if (state->mode == BAD) break;
5504f3865fbSRichard Purdie 
5514f3865fbSRichard Purdie             /* build code tables */
5524f3865fbSRichard Purdie             state->next = state->codes;
5534f3865fbSRichard Purdie             state->lencode = (code const *)(state->next);
5544f3865fbSRichard Purdie             state->lenbits = 9;
5554f3865fbSRichard Purdie             ret = zlib_inflate_table(LENS, state->lens, state->nlen, &(state->next),
5564f3865fbSRichard Purdie                                 &(state->lenbits), state->work);
5574f3865fbSRichard Purdie             if (ret) {
5584f3865fbSRichard Purdie                 strm->msg = (char *)"invalid literal/lengths set";
5594f3865fbSRichard Purdie                 state->mode = BAD;
5604f3865fbSRichard Purdie                 break;
5614f3865fbSRichard Purdie             }
5624f3865fbSRichard Purdie             state->distcode = (code const *)(state->next);
5634f3865fbSRichard Purdie             state->distbits = 6;
5644f3865fbSRichard Purdie             ret = zlib_inflate_table(DISTS, state->lens + state->nlen, state->ndist,
5654f3865fbSRichard Purdie                             &(state->next), &(state->distbits), state->work);
5664f3865fbSRichard Purdie             if (ret) {
5674f3865fbSRichard Purdie                 strm->msg = (char *)"invalid distances set";
5684f3865fbSRichard Purdie                 state->mode = BAD;
5694f3865fbSRichard Purdie                 break;
5704f3865fbSRichard Purdie             }
5714f3865fbSRichard Purdie             state->mode = LEN;
5724f3865fbSRichard Purdie         case LEN:
5734f3865fbSRichard Purdie             if (have >= 6 && left >= 258) {
5744f3865fbSRichard Purdie                 RESTORE();
5754f3865fbSRichard Purdie                 inflate_fast(strm, out);
5764f3865fbSRichard Purdie                 LOAD();
5774f3865fbSRichard Purdie                 break;
5784f3865fbSRichard Purdie             }
5794f3865fbSRichard Purdie             for (;;) {
5804f3865fbSRichard Purdie                 this = state->lencode[BITS(state->lenbits)];
5814f3865fbSRichard Purdie                 if ((unsigned)(this.bits) <= bits) break;
5824f3865fbSRichard Purdie                 PULLBYTE();
5834f3865fbSRichard Purdie             }
5844f3865fbSRichard Purdie             if (this.op && (this.op & 0xf0) == 0) {
5854f3865fbSRichard Purdie                 last = this;
5864f3865fbSRichard Purdie                 for (;;) {
5874f3865fbSRichard Purdie                     this = state->lencode[last.val +
5884f3865fbSRichard Purdie                             (BITS(last.bits + last.op) >> last.bits)];
5894f3865fbSRichard Purdie                     if ((unsigned)(last.bits + this.bits) <= bits) break;
5904f3865fbSRichard Purdie                     PULLBYTE();
5914f3865fbSRichard Purdie                 }
5924f3865fbSRichard Purdie                 DROPBITS(last.bits);
5934f3865fbSRichard Purdie             }
5944f3865fbSRichard Purdie             DROPBITS(this.bits);
5954f3865fbSRichard Purdie             state->length = (unsigned)this.val;
5964f3865fbSRichard Purdie             if ((int)(this.op) == 0) {
5974f3865fbSRichard Purdie                 state->mode = LIT;
5984f3865fbSRichard Purdie                 break;
5994f3865fbSRichard Purdie             }
6004f3865fbSRichard Purdie             if (this.op & 32) {
6014f3865fbSRichard Purdie                 state->mode = TYPE;
6024f3865fbSRichard Purdie                 break;
6034f3865fbSRichard Purdie             }
6044f3865fbSRichard Purdie             if (this.op & 64) {
6054f3865fbSRichard Purdie                 strm->msg = (char *)"invalid literal/length code";
6064f3865fbSRichard Purdie                 state->mode = BAD;
6074f3865fbSRichard Purdie                 break;
6084f3865fbSRichard Purdie             }
6094f3865fbSRichard Purdie             state->extra = (unsigned)(this.op) & 15;
6104f3865fbSRichard Purdie             state->mode = LENEXT;
6114f3865fbSRichard Purdie         case LENEXT:
6124f3865fbSRichard Purdie             if (state->extra) {
6134f3865fbSRichard Purdie                 NEEDBITS(state->extra);
6144f3865fbSRichard Purdie                 state->length += BITS(state->extra);
6154f3865fbSRichard Purdie                 DROPBITS(state->extra);
6164f3865fbSRichard Purdie             }
6174f3865fbSRichard Purdie             state->mode = DIST;
6184f3865fbSRichard Purdie         case DIST:
6194f3865fbSRichard Purdie             for (;;) {
6204f3865fbSRichard Purdie                 this = state->distcode[BITS(state->distbits)];
6214f3865fbSRichard Purdie                 if ((unsigned)(this.bits) <= bits) break;
6224f3865fbSRichard Purdie                 PULLBYTE();
6234f3865fbSRichard Purdie             }
6244f3865fbSRichard Purdie             if ((this.op & 0xf0) == 0) {
6254f3865fbSRichard Purdie                 last = this;
6264f3865fbSRichard Purdie                 for (;;) {
6274f3865fbSRichard Purdie                     this = state->distcode[last.val +
6284f3865fbSRichard Purdie                             (BITS(last.bits + last.op) >> last.bits)];
6294f3865fbSRichard Purdie                     if ((unsigned)(last.bits + this.bits) <= bits) break;
6304f3865fbSRichard Purdie                     PULLBYTE();
6314f3865fbSRichard Purdie                 }
6324f3865fbSRichard Purdie                 DROPBITS(last.bits);
6334f3865fbSRichard Purdie             }
6344f3865fbSRichard Purdie             DROPBITS(this.bits);
6354f3865fbSRichard Purdie             if (this.op & 64) {
6364f3865fbSRichard Purdie                 strm->msg = (char *)"invalid distance code";
6374f3865fbSRichard Purdie                 state->mode = BAD;
6384f3865fbSRichard Purdie                 break;
6394f3865fbSRichard Purdie             }
6404f3865fbSRichard Purdie             state->offset = (unsigned)this.val;
6414f3865fbSRichard Purdie             state->extra = (unsigned)(this.op) & 15;
6424f3865fbSRichard Purdie             state->mode = DISTEXT;
6434f3865fbSRichard Purdie         case DISTEXT:
6444f3865fbSRichard Purdie             if (state->extra) {
6454f3865fbSRichard Purdie                 NEEDBITS(state->extra);
6464f3865fbSRichard Purdie                 state->offset += BITS(state->extra);
6474f3865fbSRichard Purdie                 DROPBITS(state->extra);
6484f3865fbSRichard Purdie             }
6494f3865fbSRichard Purdie #ifdef INFLATE_STRICT
6504f3865fbSRichard Purdie             if (state->offset > state->dmax) {
6514f3865fbSRichard Purdie                 strm->msg = (char *)"invalid distance too far back";
6524f3865fbSRichard Purdie                 state->mode = BAD;
6534f3865fbSRichard Purdie                 break;
6544f3865fbSRichard Purdie             }
6554f3865fbSRichard Purdie #endif
6564f3865fbSRichard Purdie             if (state->offset > state->whave + out - left) {
6574f3865fbSRichard Purdie                 strm->msg = (char *)"invalid distance too far back";
6584f3865fbSRichard Purdie                 state->mode = BAD;
6594f3865fbSRichard Purdie                 break;
6604f3865fbSRichard Purdie             }
6614f3865fbSRichard Purdie             state->mode = MATCH;
6624f3865fbSRichard Purdie         case MATCH:
6634f3865fbSRichard Purdie             if (left == 0) goto inf_leave;
6644f3865fbSRichard Purdie             copy = out - left;
6654f3865fbSRichard Purdie             if (state->offset > copy) {         /* copy from window */
6664f3865fbSRichard Purdie                 copy = state->offset - copy;
6674f3865fbSRichard Purdie                 if (copy > state->write) {
6684f3865fbSRichard Purdie                     copy -= state->write;
6694f3865fbSRichard Purdie                     from = state->window + (state->wsize - copy);
6704f3865fbSRichard Purdie                 }
6714f3865fbSRichard Purdie                 else
6724f3865fbSRichard Purdie                     from = state->window + (state->write - copy);
6734f3865fbSRichard Purdie                 if (copy > state->length) copy = state->length;
6744f3865fbSRichard Purdie             }
6754f3865fbSRichard Purdie             else {                              /* copy from output */
6764f3865fbSRichard Purdie                 from = put - state->offset;
6774f3865fbSRichard Purdie                 copy = state->length;
6784f3865fbSRichard Purdie             }
6794f3865fbSRichard Purdie             if (copy > left) copy = left;
6804f3865fbSRichard Purdie             left -= copy;
6814f3865fbSRichard Purdie             state->length -= copy;
6824f3865fbSRichard Purdie             do {
6834f3865fbSRichard Purdie                 *put++ = *from++;
6844f3865fbSRichard Purdie             } while (--copy);
6854f3865fbSRichard Purdie             if (state->length == 0) state->mode = LEN;
6864f3865fbSRichard Purdie             break;
6874f3865fbSRichard Purdie         case LIT:
6884f3865fbSRichard Purdie             if (left == 0) goto inf_leave;
6894f3865fbSRichard Purdie             *put++ = (unsigned char)(state->length);
6904f3865fbSRichard Purdie             left--;
6914f3865fbSRichard Purdie             state->mode = LEN;
6924f3865fbSRichard Purdie             break;
6934f3865fbSRichard Purdie         case CHECK:
6944f3865fbSRichard Purdie             if (state->wrap) {
6954f3865fbSRichard Purdie                 NEEDBITS(32);
6964f3865fbSRichard Purdie                 out -= left;
6974f3865fbSRichard Purdie                 strm->total_out += out;
6984f3865fbSRichard Purdie                 state->total += out;
6994f3865fbSRichard Purdie                 if (out)
7004f3865fbSRichard Purdie                     strm->adler = state->check =
7014f3865fbSRichard Purdie                         UPDATE(state->check, put - out, out);
7024f3865fbSRichard Purdie                 out = left;
7034f3865fbSRichard Purdie                 if ((
7044f3865fbSRichard Purdie                      REVERSE(hold)) != state->check) {
7054f3865fbSRichard Purdie                     strm->msg = (char *)"incorrect data check";
7064f3865fbSRichard Purdie                     state->mode = BAD;
7074f3865fbSRichard Purdie                     break;
7084f3865fbSRichard Purdie                 }
7094f3865fbSRichard Purdie                 INITBITS();
7104f3865fbSRichard Purdie             }
7114f3865fbSRichard Purdie             state->mode = DONE;
7124f3865fbSRichard Purdie         case DONE:
7134f3865fbSRichard Purdie             ret = Z_STREAM_END;
7144f3865fbSRichard Purdie             goto inf_leave;
7154f3865fbSRichard Purdie         case BAD:
7164f3865fbSRichard Purdie             ret = Z_DATA_ERROR;
7174f3865fbSRichard Purdie             goto inf_leave;
7184f3865fbSRichard Purdie         case MEM:
7194f3865fbSRichard Purdie             return Z_MEM_ERROR;
7204f3865fbSRichard Purdie         case SYNC:
7211da177e4SLinus Torvalds         default:
7221da177e4SLinus Torvalds             return Z_STREAM_ERROR;
7231da177e4SLinus Torvalds         }
7244f3865fbSRichard Purdie 
7254f3865fbSRichard Purdie     /*
7264f3865fbSRichard Purdie        Return from inflate(), updating the total counts and the check value.
7274f3865fbSRichard Purdie        If there was no progress during the inflate() call, return a buffer
7284f3865fbSRichard Purdie        error.  Call zlib_updatewindow() to create and/or update the window state.
7294f3865fbSRichard Purdie      */
7304f3865fbSRichard Purdie   inf_leave:
7314f3865fbSRichard Purdie     RESTORE();
7324f3865fbSRichard Purdie     if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
7334f3865fbSRichard Purdie         zlib_updatewindow(strm, out);
7344f3865fbSRichard Purdie 
7354f3865fbSRichard Purdie     in -= strm->avail_in;
7364f3865fbSRichard Purdie     out -= strm->avail_out;
7374f3865fbSRichard Purdie     strm->total_in += in;
7384f3865fbSRichard Purdie     strm->total_out += out;
7394f3865fbSRichard Purdie     state->total += out;
7404f3865fbSRichard Purdie     if (state->wrap && out)
7414f3865fbSRichard Purdie         strm->adler = state->check =
7424f3865fbSRichard Purdie             UPDATE(state->check, strm->next_out - out, out);
7434f3865fbSRichard Purdie 
7444f3865fbSRichard Purdie     strm->data_type = state->bits + (state->last ? 64 : 0) +
7454f3865fbSRichard Purdie                       (state->mode == TYPE ? 128 : 0);
746*f0ac6758SRichard Purdie 
747*f0ac6758SRichard Purdie     if (flush == Z_PACKET_FLUSH && ret == Z_OK &&
748*f0ac6758SRichard Purdie             strm->avail_out != 0 && strm->avail_in == 0)
749*f0ac6758SRichard Purdie 		return zlib_inflateSyncPacket(strm);
750*f0ac6758SRichard Purdie 
7514f3865fbSRichard Purdie     if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
7524f3865fbSRichard Purdie         ret = Z_BUF_ERROR;
7534f3865fbSRichard Purdie 
7544f3865fbSRichard Purdie     return ret;
7554f3865fbSRichard Purdie }
7564f3865fbSRichard Purdie 
7574f3865fbSRichard Purdie int zlib_inflateEnd(z_streamp strm)
7584f3865fbSRichard Purdie {
7594f3865fbSRichard Purdie     if (strm == NULL || strm->state == NULL)
7604f3865fbSRichard Purdie         return Z_STREAM_ERROR;
7614f3865fbSRichard Purdie     return Z_OK;
7624f3865fbSRichard Purdie }
7634f3865fbSRichard Purdie 
7644f3865fbSRichard Purdie #if 0
7654f3865fbSRichard Purdie int zlib_inflateSetDictionary(z_streamp strm, const Byte *dictionary,
7664f3865fbSRichard Purdie         uInt dictLength)
7674f3865fbSRichard Purdie {
7684f3865fbSRichard Purdie     struct inflate_state *state;
7694f3865fbSRichard Purdie     unsigned long id;
7704f3865fbSRichard Purdie 
7714f3865fbSRichard Purdie     /* check state */
7724f3865fbSRichard Purdie     if (strm == NULL || strm->state == NULL) return Z_STREAM_ERROR;
7734f3865fbSRichard Purdie     state = (struct inflate_state *)strm->state;
7744f3865fbSRichard Purdie     if (state->wrap != 0 && state->mode != DICT)
7754f3865fbSRichard Purdie         return Z_STREAM_ERROR;
7764f3865fbSRichard Purdie 
7774f3865fbSRichard Purdie     /* check for correct dictionary id */
7784f3865fbSRichard Purdie     if (state->mode == DICT) {
7794f3865fbSRichard Purdie         id = zlib_adler32(0L, NULL, 0);
7804f3865fbSRichard Purdie         id = zlib_adler32(id, dictionary, dictLength);
7814f3865fbSRichard Purdie         if (id != state->check)
7821da177e4SLinus Torvalds             return Z_DATA_ERROR;
7831da177e4SLinus Torvalds     }
7844f3865fbSRichard Purdie 
7854f3865fbSRichard Purdie     /* copy dictionary to window */
7864f3865fbSRichard Purdie     zlib_updatewindow(strm, strm->avail_out);
7874f3865fbSRichard Purdie 
7884f3865fbSRichard Purdie     if (dictLength > state->wsize) {
7894f3865fbSRichard Purdie         memcpy(state->window, dictionary + dictLength - state->wsize,
7904f3865fbSRichard Purdie                 state->wsize);
7914f3865fbSRichard Purdie         state->whave = state->wsize;
7924f3865fbSRichard Purdie     }
7934f3865fbSRichard Purdie     else {
7944f3865fbSRichard Purdie         memcpy(state->window + state->wsize - dictLength, dictionary,
7954f3865fbSRichard Purdie                 dictLength);
7964f3865fbSRichard Purdie         state->whave = dictLength;
7974f3865fbSRichard Purdie     }
7984f3865fbSRichard Purdie     state->havedict = 1;
7994f3865fbSRichard Purdie     return Z_OK;
8004f3865fbSRichard Purdie }
8014f3865fbSRichard Purdie #endif
8024f3865fbSRichard Purdie 
8034f3865fbSRichard Purdie #if 0
8044f3865fbSRichard Purdie /*
8054f3865fbSRichard Purdie    Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff.  Return when found
8064f3865fbSRichard Purdie    or when out of input.  When called, *have is the number of pattern bytes
8074f3865fbSRichard Purdie    found in order so far, in 0..3.  On return *have is updated to the new
8084f3865fbSRichard Purdie    state.  If on return *have equals four, then the pattern was found and the
8094f3865fbSRichard Purdie    return value is how many bytes were read including the last byte of the
8104f3865fbSRichard Purdie    pattern.  If *have is less than four, then the pattern has not been found
8114f3865fbSRichard Purdie    yet and the return value is len.  In the latter case, zlib_syncsearch() can be
8124f3865fbSRichard Purdie    called again with more data and the *have state.  *have is initialized to
8134f3865fbSRichard Purdie    zero for the first call.
8144f3865fbSRichard Purdie  */
8154f3865fbSRichard Purdie static unsigned zlib_syncsearch(unsigned *have, unsigned char *buf,
8164f3865fbSRichard Purdie         unsigned len)
8174f3865fbSRichard Purdie {
8184f3865fbSRichard Purdie     unsigned got;
8194f3865fbSRichard Purdie     unsigned next;
8204f3865fbSRichard Purdie 
8214f3865fbSRichard Purdie     got = *have;
8224f3865fbSRichard Purdie     next = 0;
8234f3865fbSRichard Purdie     while (next < len && got < 4) {
8244f3865fbSRichard Purdie         if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
8254f3865fbSRichard Purdie             got++;
8264f3865fbSRichard Purdie         else if (buf[next])
8274f3865fbSRichard Purdie             got = 0;
8284f3865fbSRichard Purdie         else
8294f3865fbSRichard Purdie             got = 4 - got;
8304f3865fbSRichard Purdie         next++;
8314f3865fbSRichard Purdie     }
8324f3865fbSRichard Purdie     *have = got;
8334f3865fbSRichard Purdie     return next;
8344f3865fbSRichard Purdie }
8354f3865fbSRichard Purdie #endif
8364f3865fbSRichard Purdie 
8374f3865fbSRichard Purdie #if 0
8384f3865fbSRichard Purdie int zlib_inflateSync(z_streamp strm)
8394f3865fbSRichard Purdie {
8404f3865fbSRichard Purdie     unsigned len;               /* number of bytes to look at or looked at */
8414f3865fbSRichard Purdie     unsigned long in, out;      /* temporary to save total_in and total_out */
8424f3865fbSRichard Purdie     unsigned char buf[4];       /* to restore bit buffer to byte string */
8434f3865fbSRichard Purdie     struct inflate_state *state;
8444f3865fbSRichard Purdie 
8454f3865fbSRichard Purdie     /* check parameters */
8464f3865fbSRichard Purdie     if (strm == NULL || strm->state == NULL) return Z_STREAM_ERROR;
8474f3865fbSRichard Purdie     state = (struct inflate_state *)strm->state;
8484f3865fbSRichard Purdie     if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
8494f3865fbSRichard Purdie 
8504f3865fbSRichard Purdie     /* if first time, start search in bit buffer */
8514f3865fbSRichard Purdie     if (state->mode != SYNC) {
8524f3865fbSRichard Purdie         state->mode = SYNC;
8534f3865fbSRichard Purdie         state->hold <<= state->bits & 7;
8544f3865fbSRichard Purdie         state->bits -= state->bits & 7;
8554f3865fbSRichard Purdie         len = 0;
8564f3865fbSRichard Purdie         while (state->bits >= 8) {
8574f3865fbSRichard Purdie             buf[len++] = (unsigned char)(state->hold);
8584f3865fbSRichard Purdie             state->hold >>= 8;
8594f3865fbSRichard Purdie             state->bits -= 8;
8604f3865fbSRichard Purdie         }
8614f3865fbSRichard Purdie         state->have = 0;
8624f3865fbSRichard Purdie         zlib_syncsearch(&(state->have), buf, len);
8634f3865fbSRichard Purdie     }
8644f3865fbSRichard Purdie 
8654f3865fbSRichard Purdie     /* search available input */
8664f3865fbSRichard Purdie     len = zlib_syncsearch(&(state->have), strm->next_in, strm->avail_in);
8674f3865fbSRichard Purdie     strm->avail_in -= len;
8684f3865fbSRichard Purdie     strm->next_in += len;
8694f3865fbSRichard Purdie     strm->total_in += len;
8704f3865fbSRichard Purdie 
8714f3865fbSRichard Purdie     /* return no joy or set up to restart inflate() on a new block */
8724f3865fbSRichard Purdie     if (state->have != 4) return Z_DATA_ERROR;
8734f3865fbSRichard Purdie     in = strm->total_in;  out = strm->total_out;
8744f3865fbSRichard Purdie     zlib_inflateReset(strm);
8754f3865fbSRichard Purdie     strm->total_in = in;  strm->total_out = out;
8764f3865fbSRichard Purdie     state->mode = TYPE;
8774f3865fbSRichard Purdie     return Z_OK;
8784f3865fbSRichard Purdie }
8794f3865fbSRichard Purdie #endif
8804f3865fbSRichard Purdie 
8814f3865fbSRichard Purdie /*
8824f3865fbSRichard Purdie  * This subroutine adds the data at next_in/avail_in to the output history
8834f3865fbSRichard Purdie  * without performing any output.  The output buffer must be "caught up";
8844f3865fbSRichard Purdie  * i.e. no pending output but this should always be the case. The state must
8854f3865fbSRichard Purdie  * be waiting on the start of a block (i.e. mode == TYPE or HEAD).  On exit,
8864f3865fbSRichard Purdie  * the output will also be caught up, and the checksum will have been updated
8874f3865fbSRichard Purdie  * if need be.
8884f3865fbSRichard Purdie  */
8894f3865fbSRichard Purdie int zlib_inflateIncomp(z_stream *z)
8904f3865fbSRichard Purdie {
8914f3865fbSRichard Purdie     struct inflate_state *state = (struct inflate_state *)z->state;
8924f3865fbSRichard Purdie     Byte *saved_no = z->next_out;
8934f3865fbSRichard Purdie     uInt saved_ao = z->avail_out;
8944f3865fbSRichard Purdie 
8954f3865fbSRichard Purdie     if (state->mode != TYPE && state->mode != HEAD)
8964f3865fbSRichard Purdie 	return Z_DATA_ERROR;
8974f3865fbSRichard Purdie 
8984f3865fbSRichard Purdie     /* Setup some variables to allow misuse of updateWindow */
8994f3865fbSRichard Purdie     z->avail_out = 0;
9004f3865fbSRichard Purdie     z->next_out = z->next_in + z->avail_in;
9014f3865fbSRichard Purdie 
9024f3865fbSRichard Purdie     zlib_updatewindow(z, z->avail_in);
9034f3865fbSRichard Purdie 
9044f3865fbSRichard Purdie     /* Restore saved variables */
9054f3865fbSRichard Purdie     z->avail_out = saved_ao;
9064f3865fbSRichard Purdie     z->next_out = saved_no;
9074f3865fbSRichard Purdie 
9084f3865fbSRichard Purdie     z->adler = state->check =
9094f3865fbSRichard Purdie         UPDATE(state->check, z->next_in, z->avail_in);
9104f3865fbSRichard Purdie 
9114f3865fbSRichard Purdie     z->total_out += z->avail_in;
9124f3865fbSRichard Purdie     z->total_in += z->avail_in;
9134f3865fbSRichard Purdie     z->next_in += z->avail_in;
9144f3865fbSRichard Purdie     state->total += z->avail_in;
9154f3865fbSRichard Purdie     z->avail_in = 0;
9164f3865fbSRichard Purdie 
9174f3865fbSRichard Purdie     return Z_OK;
9184f3865fbSRichard Purdie }
919