Home | History | Annotate | Line # | Download | only in infback9
infback9.c revision 1.1.1.1.2.2
      1  1.1.1.1.2.2  pgoyette /* infback9.c -- inflate deflate64 data using a call-back interface
      2  1.1.1.1.2.2  pgoyette  * Copyright (C) 1995-2008 Mark Adler
      3  1.1.1.1.2.2  pgoyette  * For conditions of distribution and use, see copyright notice in zlib.h
      4  1.1.1.1.2.2  pgoyette  */
      5  1.1.1.1.2.2  pgoyette 
      6  1.1.1.1.2.2  pgoyette #include "zutil.h"
      7  1.1.1.1.2.2  pgoyette #include "infback9.h"
      8  1.1.1.1.2.2  pgoyette #include "inftree9.h"
      9  1.1.1.1.2.2  pgoyette #include "inflate9.h"
     10  1.1.1.1.2.2  pgoyette 
     11  1.1.1.1.2.2  pgoyette #define WSIZE 65536UL
     12  1.1.1.1.2.2  pgoyette 
     13  1.1.1.1.2.2  pgoyette /*
     14  1.1.1.1.2.2  pgoyette    strm provides memory allocation functions in zalloc and zfree, or
     15  1.1.1.1.2.2  pgoyette    Z_NULL to use the library memory allocation functions.
     16  1.1.1.1.2.2  pgoyette 
     17  1.1.1.1.2.2  pgoyette    window is a user-supplied window and output buffer that is 64K bytes.
     18  1.1.1.1.2.2  pgoyette  */
     19  1.1.1.1.2.2  pgoyette int ZEXPORT inflateBack9Init_(strm, window, version, stream_size)
     20  1.1.1.1.2.2  pgoyette z_stream FAR *strm;
     21  1.1.1.1.2.2  pgoyette unsigned char FAR *window;
     22  1.1.1.1.2.2  pgoyette const char *version;
     23  1.1.1.1.2.2  pgoyette int stream_size;
     24  1.1.1.1.2.2  pgoyette {
     25  1.1.1.1.2.2  pgoyette     struct inflate_state FAR *state;
     26  1.1.1.1.2.2  pgoyette 
     27  1.1.1.1.2.2  pgoyette     if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
     28  1.1.1.1.2.2  pgoyette         stream_size != (int)(sizeof(z_stream)))
     29  1.1.1.1.2.2  pgoyette         return Z_VERSION_ERROR;
     30  1.1.1.1.2.2  pgoyette     if (strm == Z_NULL || window == Z_NULL)
     31  1.1.1.1.2.2  pgoyette         return Z_STREAM_ERROR;
     32  1.1.1.1.2.2  pgoyette     strm->msg = Z_NULL;                 /* in case we return an error */
     33  1.1.1.1.2.2  pgoyette     if (strm->zalloc == (alloc_func)0) {
     34  1.1.1.1.2.2  pgoyette         strm->zalloc = zcalloc;
     35  1.1.1.1.2.2  pgoyette         strm->opaque = (voidpf)0;
     36  1.1.1.1.2.2  pgoyette     }
     37  1.1.1.1.2.2  pgoyette     if (strm->zfree == (free_func)0) strm->zfree = zcfree;
     38  1.1.1.1.2.2  pgoyette     state = (struct inflate_state FAR *)ZALLOC(strm, 1,
     39  1.1.1.1.2.2  pgoyette                                                sizeof(struct inflate_state));
     40  1.1.1.1.2.2  pgoyette     if (state == Z_NULL) return Z_MEM_ERROR;
     41  1.1.1.1.2.2  pgoyette     Tracev((stderr, "inflate: allocated\n"));
     42  1.1.1.1.2.2  pgoyette     strm->state = (voidpf)state;
     43  1.1.1.1.2.2  pgoyette     state->window = window;
     44  1.1.1.1.2.2  pgoyette     return Z_OK;
     45  1.1.1.1.2.2  pgoyette }
     46  1.1.1.1.2.2  pgoyette 
     47  1.1.1.1.2.2  pgoyette /*
     48  1.1.1.1.2.2  pgoyette    Build and output length and distance decoding tables for fixed code
     49  1.1.1.1.2.2  pgoyette    decoding.
     50  1.1.1.1.2.2  pgoyette  */
     51  1.1.1.1.2.2  pgoyette #ifdef MAKEFIXED
     52  1.1.1.1.2.2  pgoyette #include <stdio.h>
     53  1.1.1.1.2.2  pgoyette 
     54  1.1.1.1.2.2  pgoyette void makefixed9(void)
     55  1.1.1.1.2.2  pgoyette {
     56  1.1.1.1.2.2  pgoyette     unsigned sym, bits, low, size;
     57  1.1.1.1.2.2  pgoyette     code *next, *lenfix, *distfix;
     58  1.1.1.1.2.2  pgoyette     struct inflate_state state;
     59  1.1.1.1.2.2  pgoyette     code fixed[544];
     60  1.1.1.1.2.2  pgoyette 
     61  1.1.1.1.2.2  pgoyette     /* literal/length table */
     62  1.1.1.1.2.2  pgoyette     sym = 0;
     63  1.1.1.1.2.2  pgoyette     while (sym < 144) state.lens[sym++] = 8;
     64  1.1.1.1.2.2  pgoyette     while (sym < 256) state.lens[sym++] = 9;
     65  1.1.1.1.2.2  pgoyette     while (sym < 280) state.lens[sym++] = 7;
     66  1.1.1.1.2.2  pgoyette     while (sym < 288) state.lens[sym++] = 8;
     67  1.1.1.1.2.2  pgoyette     next = fixed;
     68  1.1.1.1.2.2  pgoyette     lenfix = next;
     69  1.1.1.1.2.2  pgoyette     bits = 9;
     70  1.1.1.1.2.2  pgoyette     inflate_table9(LENS, state.lens, 288, &(next), &(bits), state.work);
     71  1.1.1.1.2.2  pgoyette 
     72  1.1.1.1.2.2  pgoyette     /* distance table */
     73  1.1.1.1.2.2  pgoyette     sym = 0;
     74  1.1.1.1.2.2  pgoyette     while (sym < 32) state.lens[sym++] = 5;
     75  1.1.1.1.2.2  pgoyette     distfix = next;
     76  1.1.1.1.2.2  pgoyette     bits = 5;
     77  1.1.1.1.2.2  pgoyette     inflate_table9(DISTS, state.lens, 32, &(next), &(bits), state.work);
     78  1.1.1.1.2.2  pgoyette 
     79  1.1.1.1.2.2  pgoyette     /* write tables */
     80  1.1.1.1.2.2  pgoyette     puts("    /* inffix9.h -- table for decoding deflate64 fixed codes");
     81  1.1.1.1.2.2  pgoyette     puts("     * Generated automatically by makefixed9().");
     82  1.1.1.1.2.2  pgoyette     puts("     */");
     83  1.1.1.1.2.2  pgoyette     puts("");
     84  1.1.1.1.2.2  pgoyette     puts("    /* WARNING: this file should *not* be used by applications.");
     85  1.1.1.1.2.2  pgoyette     puts("       It is part of the implementation of this library and is");
     86  1.1.1.1.2.2  pgoyette     puts("       subject to change. Applications should only use zlib.h.");
     87  1.1.1.1.2.2  pgoyette     puts("     */");
     88  1.1.1.1.2.2  pgoyette     puts("");
     89  1.1.1.1.2.2  pgoyette     size = 1U << 9;
     90  1.1.1.1.2.2  pgoyette     printf("    static const code lenfix[%u] = {", size);
     91  1.1.1.1.2.2  pgoyette     low = 0;
     92  1.1.1.1.2.2  pgoyette     for (;;) {
     93  1.1.1.1.2.2  pgoyette         if ((low % 6) == 0) printf("\n        ");
     94  1.1.1.1.2.2  pgoyette         printf("{%u,%u,%d}", lenfix[low].op, lenfix[low].bits,
     95  1.1.1.1.2.2  pgoyette                lenfix[low].val);
     96  1.1.1.1.2.2  pgoyette         if (++low == size) break;
     97  1.1.1.1.2.2  pgoyette         putchar(',');
     98  1.1.1.1.2.2  pgoyette     }
     99  1.1.1.1.2.2  pgoyette     puts("\n    };");
    100  1.1.1.1.2.2  pgoyette     size = 1U << 5;
    101  1.1.1.1.2.2  pgoyette     printf("\n    static const code distfix[%u] = {", size);
    102  1.1.1.1.2.2  pgoyette     low = 0;
    103  1.1.1.1.2.2  pgoyette     for (;;) {
    104  1.1.1.1.2.2  pgoyette         if ((low % 5) == 0) printf("\n        ");
    105  1.1.1.1.2.2  pgoyette         printf("{%u,%u,%d}", distfix[low].op, distfix[low].bits,
    106  1.1.1.1.2.2  pgoyette                distfix[low].val);
    107  1.1.1.1.2.2  pgoyette         if (++low == size) break;
    108  1.1.1.1.2.2  pgoyette         putchar(',');
    109  1.1.1.1.2.2  pgoyette     }
    110  1.1.1.1.2.2  pgoyette     puts("\n    };");
    111  1.1.1.1.2.2  pgoyette }
    112  1.1.1.1.2.2  pgoyette #endif /* MAKEFIXED */
    113  1.1.1.1.2.2  pgoyette 
    114  1.1.1.1.2.2  pgoyette /* Macros for inflateBack(): */
    115  1.1.1.1.2.2  pgoyette 
    116  1.1.1.1.2.2  pgoyette /* Clear the input bit accumulator */
    117  1.1.1.1.2.2  pgoyette #define INITBITS() \
    118  1.1.1.1.2.2  pgoyette     do { \
    119  1.1.1.1.2.2  pgoyette         hold = 0; \
    120  1.1.1.1.2.2  pgoyette         bits = 0; \
    121  1.1.1.1.2.2  pgoyette     } while (0)
    122  1.1.1.1.2.2  pgoyette 
    123  1.1.1.1.2.2  pgoyette /* Assure that some input is available.  If input is requested, but denied,
    124  1.1.1.1.2.2  pgoyette    then return a Z_BUF_ERROR from inflateBack(). */
    125  1.1.1.1.2.2  pgoyette #define PULL() \
    126  1.1.1.1.2.2  pgoyette     do { \
    127  1.1.1.1.2.2  pgoyette         if (have == 0) { \
    128  1.1.1.1.2.2  pgoyette             have = in(in_desc, &next); \
    129  1.1.1.1.2.2  pgoyette             if (have == 0) { \
    130  1.1.1.1.2.2  pgoyette                 next = Z_NULL; \
    131  1.1.1.1.2.2  pgoyette                 ret = Z_BUF_ERROR; \
    132  1.1.1.1.2.2  pgoyette                 goto inf_leave; \
    133  1.1.1.1.2.2  pgoyette             } \
    134  1.1.1.1.2.2  pgoyette         } \
    135  1.1.1.1.2.2  pgoyette     } while (0)
    136  1.1.1.1.2.2  pgoyette 
    137  1.1.1.1.2.2  pgoyette /* Get a byte of input into the bit accumulator, or return from inflateBack()
    138  1.1.1.1.2.2  pgoyette    with an error if there is no input available. */
    139  1.1.1.1.2.2  pgoyette #define PULLBYTE() \
    140  1.1.1.1.2.2  pgoyette     do { \
    141  1.1.1.1.2.2  pgoyette         PULL(); \
    142  1.1.1.1.2.2  pgoyette         have--; \
    143  1.1.1.1.2.2  pgoyette         hold += (unsigned long)(*next++) << bits; \
    144  1.1.1.1.2.2  pgoyette         bits += 8; \
    145  1.1.1.1.2.2  pgoyette     } while (0)
    146  1.1.1.1.2.2  pgoyette 
    147  1.1.1.1.2.2  pgoyette /* Assure that there are at least n bits in the bit accumulator.  If there is
    148  1.1.1.1.2.2  pgoyette    not enough available input to do that, then return from inflateBack() with
    149  1.1.1.1.2.2  pgoyette    an error. */
    150  1.1.1.1.2.2  pgoyette #define NEEDBITS(n) \
    151  1.1.1.1.2.2  pgoyette     do { \
    152  1.1.1.1.2.2  pgoyette         while (bits < (unsigned)(n)) \
    153  1.1.1.1.2.2  pgoyette             PULLBYTE(); \
    154  1.1.1.1.2.2  pgoyette     } while (0)
    155  1.1.1.1.2.2  pgoyette 
    156  1.1.1.1.2.2  pgoyette /* Return the low n bits of the bit accumulator (n <= 16) */
    157  1.1.1.1.2.2  pgoyette #define BITS(n) \
    158  1.1.1.1.2.2  pgoyette     ((unsigned)hold & ((1U << (n)) - 1))
    159  1.1.1.1.2.2  pgoyette 
    160  1.1.1.1.2.2  pgoyette /* Remove n bits from the bit accumulator */
    161  1.1.1.1.2.2  pgoyette #define DROPBITS(n) \
    162  1.1.1.1.2.2  pgoyette     do { \
    163  1.1.1.1.2.2  pgoyette         hold >>= (n); \
    164  1.1.1.1.2.2  pgoyette         bits -= (unsigned)(n); \
    165  1.1.1.1.2.2  pgoyette     } while (0)
    166  1.1.1.1.2.2  pgoyette 
    167  1.1.1.1.2.2  pgoyette /* Remove zero to seven bits as needed to go to a byte boundary */
    168  1.1.1.1.2.2  pgoyette #define BYTEBITS() \
    169  1.1.1.1.2.2  pgoyette     do { \
    170  1.1.1.1.2.2  pgoyette         hold >>= bits & 7; \
    171  1.1.1.1.2.2  pgoyette         bits -= bits & 7; \
    172  1.1.1.1.2.2  pgoyette     } while (0)
    173  1.1.1.1.2.2  pgoyette 
    174  1.1.1.1.2.2  pgoyette /* Assure that some output space is available, by writing out the window
    175  1.1.1.1.2.2  pgoyette    if it's full.  If the write fails, return from inflateBack() with a
    176  1.1.1.1.2.2  pgoyette    Z_BUF_ERROR. */
    177  1.1.1.1.2.2  pgoyette #define ROOM() \
    178  1.1.1.1.2.2  pgoyette     do { \
    179  1.1.1.1.2.2  pgoyette         if (left == 0) { \
    180  1.1.1.1.2.2  pgoyette             put = window; \
    181  1.1.1.1.2.2  pgoyette             left = WSIZE; \
    182  1.1.1.1.2.2  pgoyette             wrap = 1; \
    183  1.1.1.1.2.2  pgoyette             if (out(out_desc, put, (unsigned)left)) { \
    184  1.1.1.1.2.2  pgoyette                 ret = Z_BUF_ERROR; \
    185  1.1.1.1.2.2  pgoyette                 goto inf_leave; \
    186  1.1.1.1.2.2  pgoyette             } \
    187  1.1.1.1.2.2  pgoyette         } \
    188  1.1.1.1.2.2  pgoyette     } while (0)
    189  1.1.1.1.2.2  pgoyette 
    190  1.1.1.1.2.2  pgoyette /*
    191  1.1.1.1.2.2  pgoyette    strm provides the memory allocation functions and window buffer on input,
    192  1.1.1.1.2.2  pgoyette    and provides information on the unused input on return.  For Z_DATA_ERROR
    193  1.1.1.1.2.2  pgoyette    returns, strm will also provide an error message.
    194  1.1.1.1.2.2  pgoyette 
    195  1.1.1.1.2.2  pgoyette    in() and out() are the call-back input and output functions.  When
    196  1.1.1.1.2.2  pgoyette    inflateBack() needs more input, it calls in().  When inflateBack() has
    197  1.1.1.1.2.2  pgoyette    filled the window with output, or when it completes with data in the
    198  1.1.1.1.2.2  pgoyette    window, it calls out() to write out the data.  The application must not
    199  1.1.1.1.2.2  pgoyette    change the provided input until in() is called again or inflateBack()
    200  1.1.1.1.2.2  pgoyette    returns.  The application must not change the window/output buffer until
    201  1.1.1.1.2.2  pgoyette    inflateBack() returns.
    202  1.1.1.1.2.2  pgoyette 
    203  1.1.1.1.2.2  pgoyette    in() and out() are called with a descriptor parameter provided in the
    204  1.1.1.1.2.2  pgoyette    inflateBack() call.  This parameter can be a structure that provides the
    205  1.1.1.1.2.2  pgoyette    information required to do the read or write, as well as accumulated
    206  1.1.1.1.2.2  pgoyette    information on the input and output such as totals and check values.
    207  1.1.1.1.2.2  pgoyette 
    208  1.1.1.1.2.2  pgoyette    in() should return zero on failure.  out() should return non-zero on
    209  1.1.1.1.2.2  pgoyette    failure.  If either in() or out() fails, than inflateBack() returns a
    210  1.1.1.1.2.2  pgoyette    Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it
    211  1.1.1.1.2.2  pgoyette    was in() or out() that caused in the error.  Otherwise,  inflateBack()
    212  1.1.1.1.2.2  pgoyette    returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
    213  1.1.1.1.2.2  pgoyette    error, or Z_MEM_ERROR if it could not allocate memory for the state.
    214  1.1.1.1.2.2  pgoyette    inflateBack() can also return Z_STREAM_ERROR if the input parameters
    215  1.1.1.1.2.2  pgoyette    are not correct, i.e. strm is Z_NULL or the state was not initialized.
    216  1.1.1.1.2.2  pgoyette  */
    217  1.1.1.1.2.2  pgoyette int ZEXPORT inflateBack9(strm, in, in_desc, out, out_desc)
    218  1.1.1.1.2.2  pgoyette z_stream FAR *strm;
    219  1.1.1.1.2.2  pgoyette in_func in;
    220  1.1.1.1.2.2  pgoyette void FAR *in_desc;
    221  1.1.1.1.2.2  pgoyette out_func out;
    222  1.1.1.1.2.2  pgoyette void FAR *out_desc;
    223  1.1.1.1.2.2  pgoyette {
    224  1.1.1.1.2.2  pgoyette     struct inflate_state FAR *state;
    225  1.1.1.1.2.2  pgoyette     unsigned char FAR *next;    /* next input */
    226  1.1.1.1.2.2  pgoyette     unsigned char FAR *put;     /* next output */
    227  1.1.1.1.2.2  pgoyette     unsigned have;              /* available input */
    228  1.1.1.1.2.2  pgoyette     unsigned long left;         /* available output */
    229  1.1.1.1.2.2  pgoyette     inflate_mode mode;          /* current inflate mode */
    230  1.1.1.1.2.2  pgoyette     int lastblock;              /* true if processing last block */
    231  1.1.1.1.2.2  pgoyette     int wrap;                   /* true if the window has wrapped */
    232  1.1.1.1.2.2  pgoyette     unsigned long write;        /* window write index */
    233  1.1.1.1.2.2  pgoyette     unsigned char FAR *window;  /* allocated sliding window, if needed */
    234  1.1.1.1.2.2  pgoyette     unsigned long hold;         /* bit buffer */
    235  1.1.1.1.2.2  pgoyette     unsigned bits;              /* bits in bit buffer */
    236  1.1.1.1.2.2  pgoyette     unsigned extra;             /* extra bits needed */
    237  1.1.1.1.2.2  pgoyette     unsigned long length;       /* literal or length of data to copy */
    238  1.1.1.1.2.2  pgoyette     unsigned long offset;       /* distance back to copy string from */
    239  1.1.1.1.2.2  pgoyette     unsigned long copy;         /* number of stored or match bytes to copy */
    240  1.1.1.1.2.2  pgoyette     unsigned char FAR *from;    /* where to copy match bytes from */
    241  1.1.1.1.2.2  pgoyette     code const FAR *lencode;    /* starting table for length/literal codes */
    242  1.1.1.1.2.2  pgoyette     code const FAR *distcode;   /* starting table for distance codes */
    243  1.1.1.1.2.2  pgoyette     unsigned lenbits;           /* index bits for lencode */
    244  1.1.1.1.2.2  pgoyette     unsigned distbits;          /* index bits for distcode */
    245  1.1.1.1.2.2  pgoyette     code here;                  /* current decoding table entry */
    246  1.1.1.1.2.2  pgoyette     code last;                  /* parent table entry */
    247  1.1.1.1.2.2  pgoyette     unsigned len;               /* length to copy for repeats, bits to drop */
    248  1.1.1.1.2.2  pgoyette     int ret;                    /* return code */
    249  1.1.1.1.2.2  pgoyette     static const unsigned short order[19] = /* permutation of code lengths */
    250  1.1.1.1.2.2  pgoyette         {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
    251  1.1.1.1.2.2  pgoyette #include "inffix9.h"
    252  1.1.1.1.2.2  pgoyette 
    253  1.1.1.1.2.2  pgoyette     /* Check that the strm exists and that the state was initialized */
    254  1.1.1.1.2.2  pgoyette     if (strm == Z_NULL || strm->state == Z_NULL)
    255  1.1.1.1.2.2  pgoyette         return Z_STREAM_ERROR;
    256  1.1.1.1.2.2  pgoyette     state = (struct inflate_state FAR *)strm->state;
    257  1.1.1.1.2.2  pgoyette 
    258  1.1.1.1.2.2  pgoyette     /* Reset the state */
    259  1.1.1.1.2.2  pgoyette     strm->msg = Z_NULL;
    260  1.1.1.1.2.2  pgoyette     mode = TYPE;
    261  1.1.1.1.2.2  pgoyette     lastblock = 0;
    262  1.1.1.1.2.2  pgoyette     write = 0;
    263  1.1.1.1.2.2  pgoyette     wrap = 0;
    264  1.1.1.1.2.2  pgoyette     window = state->window;
    265  1.1.1.1.2.2  pgoyette     next = strm->next_in;
    266  1.1.1.1.2.2  pgoyette     have = next != Z_NULL ? strm->avail_in : 0;
    267  1.1.1.1.2.2  pgoyette     hold = 0;
    268  1.1.1.1.2.2  pgoyette     bits = 0;
    269  1.1.1.1.2.2  pgoyette     put = window;
    270  1.1.1.1.2.2  pgoyette     left = WSIZE;
    271  1.1.1.1.2.2  pgoyette     lencode = Z_NULL;
    272  1.1.1.1.2.2  pgoyette     distcode = Z_NULL;
    273  1.1.1.1.2.2  pgoyette 
    274  1.1.1.1.2.2  pgoyette     /* Inflate until end of block marked as last */
    275  1.1.1.1.2.2  pgoyette     for (;;)
    276  1.1.1.1.2.2  pgoyette         switch (mode) {
    277  1.1.1.1.2.2  pgoyette         case TYPE:
    278  1.1.1.1.2.2  pgoyette             /* determine and dispatch block type */
    279  1.1.1.1.2.2  pgoyette             if (lastblock) {
    280  1.1.1.1.2.2  pgoyette                 BYTEBITS();
    281  1.1.1.1.2.2  pgoyette                 mode = DONE;
    282  1.1.1.1.2.2  pgoyette                 break;
    283  1.1.1.1.2.2  pgoyette             }
    284  1.1.1.1.2.2  pgoyette             NEEDBITS(3);
    285  1.1.1.1.2.2  pgoyette             lastblock = BITS(1);
    286  1.1.1.1.2.2  pgoyette             DROPBITS(1);
    287  1.1.1.1.2.2  pgoyette             switch (BITS(2)) {
    288  1.1.1.1.2.2  pgoyette             case 0:                             /* stored block */
    289  1.1.1.1.2.2  pgoyette                 Tracev((stderr, "inflate:     stored block%s\n",
    290  1.1.1.1.2.2  pgoyette                         lastblock ? " (last)" : ""));
    291  1.1.1.1.2.2  pgoyette                 mode = STORED;
    292  1.1.1.1.2.2  pgoyette                 break;
    293  1.1.1.1.2.2  pgoyette             case 1:                             /* fixed block */
    294  1.1.1.1.2.2  pgoyette                 lencode = lenfix;
    295  1.1.1.1.2.2  pgoyette                 lenbits = 9;
    296  1.1.1.1.2.2  pgoyette                 distcode = distfix;
    297  1.1.1.1.2.2  pgoyette                 distbits = 5;
    298  1.1.1.1.2.2  pgoyette                 Tracev((stderr, "inflate:     fixed codes block%s\n",
    299  1.1.1.1.2.2  pgoyette                         lastblock ? " (last)" : ""));
    300  1.1.1.1.2.2  pgoyette                 mode = LEN;                     /* decode codes */
    301  1.1.1.1.2.2  pgoyette                 break;
    302  1.1.1.1.2.2  pgoyette             case 2:                             /* dynamic block */
    303  1.1.1.1.2.2  pgoyette                 Tracev((stderr, "inflate:     dynamic codes block%s\n",
    304  1.1.1.1.2.2  pgoyette                         lastblock ? " (last)" : ""));
    305  1.1.1.1.2.2  pgoyette                 mode = TABLE;
    306  1.1.1.1.2.2  pgoyette                 break;
    307  1.1.1.1.2.2  pgoyette             case 3:
    308  1.1.1.1.2.2  pgoyette                 strm->msg = (char *)"invalid block type";
    309  1.1.1.1.2.2  pgoyette                 mode = BAD;
    310  1.1.1.1.2.2  pgoyette             }
    311  1.1.1.1.2.2  pgoyette             DROPBITS(2);
    312  1.1.1.1.2.2  pgoyette             break;
    313  1.1.1.1.2.2  pgoyette 
    314  1.1.1.1.2.2  pgoyette         case STORED:
    315  1.1.1.1.2.2  pgoyette             /* get and verify stored block length */
    316  1.1.1.1.2.2  pgoyette             BYTEBITS();                         /* go to byte boundary */
    317  1.1.1.1.2.2  pgoyette             NEEDBITS(32);
    318  1.1.1.1.2.2  pgoyette             if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
    319  1.1.1.1.2.2  pgoyette                 strm->msg = (char *)"invalid stored block lengths";
    320  1.1.1.1.2.2  pgoyette                 mode = BAD;
    321  1.1.1.1.2.2  pgoyette                 break;
    322  1.1.1.1.2.2  pgoyette             }
    323  1.1.1.1.2.2  pgoyette             length = (unsigned)hold & 0xffff;
    324  1.1.1.1.2.2  pgoyette             Tracev((stderr, "inflate:       stored length %lu\n",
    325  1.1.1.1.2.2  pgoyette                     length));
    326  1.1.1.1.2.2  pgoyette             INITBITS();
    327  1.1.1.1.2.2  pgoyette 
    328  1.1.1.1.2.2  pgoyette             /* copy stored block from input to output */
    329  1.1.1.1.2.2  pgoyette             while (length != 0) {
    330  1.1.1.1.2.2  pgoyette                 copy = length;
    331  1.1.1.1.2.2  pgoyette                 PULL();
    332  1.1.1.1.2.2  pgoyette                 ROOM();
    333  1.1.1.1.2.2  pgoyette                 if (copy > have) copy = have;
    334  1.1.1.1.2.2  pgoyette                 if (copy > left) copy = left;
    335  1.1.1.1.2.2  pgoyette                 zmemcpy(put, next, copy);
    336  1.1.1.1.2.2  pgoyette                 have -= copy;
    337  1.1.1.1.2.2  pgoyette                 next += copy;
    338  1.1.1.1.2.2  pgoyette                 left -= copy;
    339  1.1.1.1.2.2  pgoyette                 put += copy;
    340  1.1.1.1.2.2  pgoyette                 length -= copy;
    341  1.1.1.1.2.2  pgoyette             }
    342  1.1.1.1.2.2  pgoyette             Tracev((stderr, "inflate:       stored end\n"));
    343  1.1.1.1.2.2  pgoyette             mode = TYPE;
    344  1.1.1.1.2.2  pgoyette             break;
    345  1.1.1.1.2.2  pgoyette 
    346  1.1.1.1.2.2  pgoyette         case TABLE:
    347  1.1.1.1.2.2  pgoyette             /* get dynamic table entries descriptor */
    348  1.1.1.1.2.2  pgoyette             NEEDBITS(14);
    349  1.1.1.1.2.2  pgoyette             state->nlen = BITS(5) + 257;
    350  1.1.1.1.2.2  pgoyette             DROPBITS(5);
    351  1.1.1.1.2.2  pgoyette             state->ndist = BITS(5) + 1;
    352  1.1.1.1.2.2  pgoyette             DROPBITS(5);
    353  1.1.1.1.2.2  pgoyette             state->ncode = BITS(4) + 4;
    354  1.1.1.1.2.2  pgoyette             DROPBITS(4);
    355  1.1.1.1.2.2  pgoyette             if (state->nlen > 286) {
    356  1.1.1.1.2.2  pgoyette                 strm->msg = (char *)"too many length symbols";
    357  1.1.1.1.2.2  pgoyette                 mode = BAD;
    358  1.1.1.1.2.2  pgoyette                 break;
    359  1.1.1.1.2.2  pgoyette             }
    360  1.1.1.1.2.2  pgoyette             Tracev((stderr, "inflate:       table sizes ok\n"));
    361  1.1.1.1.2.2  pgoyette 
    362  1.1.1.1.2.2  pgoyette             /* get code length code lengths (not a typo) */
    363  1.1.1.1.2.2  pgoyette             state->have = 0;
    364  1.1.1.1.2.2  pgoyette             while (state->have < state->ncode) {
    365  1.1.1.1.2.2  pgoyette                 NEEDBITS(3);
    366  1.1.1.1.2.2  pgoyette                 state->lens[order[state->have++]] = (unsigned short)BITS(3);
    367  1.1.1.1.2.2  pgoyette                 DROPBITS(3);
    368  1.1.1.1.2.2  pgoyette             }
    369  1.1.1.1.2.2  pgoyette             while (state->have < 19)
    370  1.1.1.1.2.2  pgoyette                 state->lens[order[state->have++]] = 0;
    371  1.1.1.1.2.2  pgoyette             state->next = state->codes;
    372  1.1.1.1.2.2  pgoyette             lencode = (code const FAR *)(state->next);
    373  1.1.1.1.2.2  pgoyette             lenbits = 7;
    374  1.1.1.1.2.2  pgoyette             ret = inflate_table9(CODES, state->lens, 19, &(state->next),
    375  1.1.1.1.2.2  pgoyette                                 &(lenbits), state->work);
    376  1.1.1.1.2.2  pgoyette             if (ret) {
    377  1.1.1.1.2.2  pgoyette                 strm->msg = (char *)"invalid code lengths set";
    378  1.1.1.1.2.2  pgoyette                 mode = BAD;
    379  1.1.1.1.2.2  pgoyette                 break;
    380  1.1.1.1.2.2  pgoyette             }
    381  1.1.1.1.2.2  pgoyette             Tracev((stderr, "inflate:       code lengths ok\n"));
    382  1.1.1.1.2.2  pgoyette 
    383  1.1.1.1.2.2  pgoyette             /* get length and distance code code lengths */
    384  1.1.1.1.2.2  pgoyette             state->have = 0;
    385  1.1.1.1.2.2  pgoyette             while (state->have < state->nlen + state->ndist) {
    386  1.1.1.1.2.2  pgoyette                 for (;;) {
    387  1.1.1.1.2.2  pgoyette                     here = lencode[BITS(lenbits)];
    388  1.1.1.1.2.2  pgoyette                     if ((unsigned)(here.bits) <= bits) break;
    389  1.1.1.1.2.2  pgoyette                     PULLBYTE();
    390  1.1.1.1.2.2  pgoyette                 }
    391  1.1.1.1.2.2  pgoyette                 if (here.val < 16) {
    392  1.1.1.1.2.2  pgoyette                     NEEDBITS(here.bits);
    393  1.1.1.1.2.2  pgoyette                     DROPBITS(here.bits);
    394  1.1.1.1.2.2  pgoyette                     state->lens[state->have++] = here.val;
    395  1.1.1.1.2.2  pgoyette                 }
    396  1.1.1.1.2.2  pgoyette                 else {
    397  1.1.1.1.2.2  pgoyette                     if (here.val == 16) {
    398  1.1.1.1.2.2  pgoyette                         NEEDBITS(here.bits + 2);
    399  1.1.1.1.2.2  pgoyette                         DROPBITS(here.bits);
    400  1.1.1.1.2.2  pgoyette                         if (state->have == 0) {
    401  1.1.1.1.2.2  pgoyette                             strm->msg = (char *)"invalid bit length repeat";
    402  1.1.1.1.2.2  pgoyette                             mode = BAD;
    403  1.1.1.1.2.2  pgoyette                             break;
    404  1.1.1.1.2.2  pgoyette                         }
    405  1.1.1.1.2.2  pgoyette                         len = (unsigned)(state->lens[state->have - 1]);
    406  1.1.1.1.2.2  pgoyette                         copy = 3 + BITS(2);
    407  1.1.1.1.2.2  pgoyette                         DROPBITS(2);
    408  1.1.1.1.2.2  pgoyette                     }
    409  1.1.1.1.2.2  pgoyette                     else if (here.val == 17) {
    410  1.1.1.1.2.2  pgoyette                         NEEDBITS(here.bits + 3);
    411  1.1.1.1.2.2  pgoyette                         DROPBITS(here.bits);
    412  1.1.1.1.2.2  pgoyette                         len = 0;
    413  1.1.1.1.2.2  pgoyette                         copy = 3 + BITS(3);
    414  1.1.1.1.2.2  pgoyette                         DROPBITS(3);
    415  1.1.1.1.2.2  pgoyette                     }
    416  1.1.1.1.2.2  pgoyette                     else {
    417  1.1.1.1.2.2  pgoyette                         NEEDBITS(here.bits + 7);
    418  1.1.1.1.2.2  pgoyette                         DROPBITS(here.bits);
    419  1.1.1.1.2.2  pgoyette                         len = 0;
    420  1.1.1.1.2.2  pgoyette                         copy = 11 + BITS(7);
    421  1.1.1.1.2.2  pgoyette                         DROPBITS(7);
    422  1.1.1.1.2.2  pgoyette                     }
    423  1.1.1.1.2.2  pgoyette                     if (state->have + copy > state->nlen + state->ndist) {
    424  1.1.1.1.2.2  pgoyette                         strm->msg = (char *)"invalid bit length repeat";
    425  1.1.1.1.2.2  pgoyette                         mode = BAD;
    426  1.1.1.1.2.2  pgoyette                         break;
    427  1.1.1.1.2.2  pgoyette                     }
    428  1.1.1.1.2.2  pgoyette                     while (copy--)
    429  1.1.1.1.2.2  pgoyette                         state->lens[state->have++] = (unsigned short)len;
    430  1.1.1.1.2.2  pgoyette                 }
    431  1.1.1.1.2.2  pgoyette             }
    432  1.1.1.1.2.2  pgoyette 
    433  1.1.1.1.2.2  pgoyette             /* handle error breaks in while */
    434  1.1.1.1.2.2  pgoyette             if (mode == BAD) break;
    435  1.1.1.1.2.2  pgoyette 
    436  1.1.1.1.2.2  pgoyette             /* check for end-of-block code (better have one) */
    437  1.1.1.1.2.2  pgoyette             if (state->lens[256] == 0) {
    438  1.1.1.1.2.2  pgoyette                 strm->msg = (char *)"invalid code -- missing end-of-block";
    439  1.1.1.1.2.2  pgoyette                 mode = BAD;
    440  1.1.1.1.2.2  pgoyette                 break;
    441  1.1.1.1.2.2  pgoyette             }
    442  1.1.1.1.2.2  pgoyette 
    443  1.1.1.1.2.2  pgoyette             /* build code tables -- note: do not change the lenbits or distbits
    444  1.1.1.1.2.2  pgoyette                values here (9 and 6) without reading the comments in inftree9.h
    445  1.1.1.1.2.2  pgoyette                concerning the ENOUGH constants, which depend on those values */
    446  1.1.1.1.2.2  pgoyette             state->next = state->codes;
    447  1.1.1.1.2.2  pgoyette             lencode = (code const FAR *)(state->next);
    448  1.1.1.1.2.2  pgoyette             lenbits = 9;
    449  1.1.1.1.2.2  pgoyette             ret = inflate_table9(LENS, state->lens, state->nlen,
    450  1.1.1.1.2.2  pgoyette                             &(state->next), &(lenbits), state->work);
    451  1.1.1.1.2.2  pgoyette             if (ret) {
    452  1.1.1.1.2.2  pgoyette                 strm->msg = (char *)"invalid literal/lengths set";
    453  1.1.1.1.2.2  pgoyette                 mode = BAD;
    454  1.1.1.1.2.2  pgoyette                 break;
    455  1.1.1.1.2.2  pgoyette             }
    456  1.1.1.1.2.2  pgoyette             distcode = (code const FAR *)(state->next);
    457  1.1.1.1.2.2  pgoyette             distbits = 6;
    458  1.1.1.1.2.2  pgoyette             ret = inflate_table9(DISTS, state->lens + state->nlen,
    459  1.1.1.1.2.2  pgoyette                             state->ndist, &(state->next), &(distbits),
    460  1.1.1.1.2.2  pgoyette                             state->work);
    461  1.1.1.1.2.2  pgoyette             if (ret) {
    462  1.1.1.1.2.2  pgoyette                 strm->msg = (char *)"invalid distances set";
    463  1.1.1.1.2.2  pgoyette                 mode = BAD;
    464  1.1.1.1.2.2  pgoyette                 break;
    465  1.1.1.1.2.2  pgoyette             }
    466  1.1.1.1.2.2  pgoyette             Tracev((stderr, "inflate:       codes ok\n"));
    467  1.1.1.1.2.2  pgoyette             mode = LEN;
    468  1.1.1.1.2.2  pgoyette 
    469  1.1.1.1.2.2  pgoyette         case LEN:
    470  1.1.1.1.2.2  pgoyette             /* get a literal, length, or end-of-block code */
    471  1.1.1.1.2.2  pgoyette             for (;;) {
    472  1.1.1.1.2.2  pgoyette                 here = lencode[BITS(lenbits)];
    473  1.1.1.1.2.2  pgoyette                 if ((unsigned)(here.bits) <= bits) break;
    474  1.1.1.1.2.2  pgoyette                 PULLBYTE();
    475  1.1.1.1.2.2  pgoyette             }
    476  1.1.1.1.2.2  pgoyette             if (here.op && (here.op & 0xf0) == 0) {
    477  1.1.1.1.2.2  pgoyette                 last = here;
    478  1.1.1.1.2.2  pgoyette                 for (;;) {
    479  1.1.1.1.2.2  pgoyette                     here = lencode[last.val +
    480  1.1.1.1.2.2  pgoyette                             (BITS(last.bits + last.op) >> last.bits)];
    481  1.1.1.1.2.2  pgoyette                     if ((unsigned)(last.bits + here.bits) <= bits) break;
    482  1.1.1.1.2.2  pgoyette                     PULLBYTE();
    483  1.1.1.1.2.2  pgoyette                 }
    484  1.1.1.1.2.2  pgoyette                 DROPBITS(last.bits);
    485  1.1.1.1.2.2  pgoyette             }
    486  1.1.1.1.2.2  pgoyette             DROPBITS(here.bits);
    487  1.1.1.1.2.2  pgoyette             length = (unsigned)here.val;
    488  1.1.1.1.2.2  pgoyette 
    489  1.1.1.1.2.2  pgoyette             /* process literal */
    490  1.1.1.1.2.2  pgoyette             if (here.op == 0) {
    491  1.1.1.1.2.2  pgoyette                 Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
    492  1.1.1.1.2.2  pgoyette                         "inflate:         literal '%c'\n" :
    493  1.1.1.1.2.2  pgoyette                         "inflate:         literal 0x%02x\n", here.val));
    494  1.1.1.1.2.2  pgoyette                 ROOM();
    495  1.1.1.1.2.2  pgoyette                 *put++ = (unsigned char)(length);
    496  1.1.1.1.2.2  pgoyette                 left--;
    497  1.1.1.1.2.2  pgoyette                 mode = LEN;
    498  1.1.1.1.2.2  pgoyette                 break;
    499  1.1.1.1.2.2  pgoyette             }
    500  1.1.1.1.2.2  pgoyette 
    501  1.1.1.1.2.2  pgoyette             /* process end of block */
    502  1.1.1.1.2.2  pgoyette             if (here.op & 32) {
    503  1.1.1.1.2.2  pgoyette                 Tracevv((stderr, "inflate:         end of block\n"));
    504  1.1.1.1.2.2  pgoyette                 mode = TYPE;
    505  1.1.1.1.2.2  pgoyette                 break;
    506  1.1.1.1.2.2  pgoyette             }
    507  1.1.1.1.2.2  pgoyette 
    508  1.1.1.1.2.2  pgoyette             /* invalid code */
    509  1.1.1.1.2.2  pgoyette             if (here.op & 64) {
    510  1.1.1.1.2.2  pgoyette                 strm->msg = (char *)"invalid literal/length code";
    511  1.1.1.1.2.2  pgoyette                 mode = BAD;
    512  1.1.1.1.2.2  pgoyette                 break;
    513  1.1.1.1.2.2  pgoyette             }
    514  1.1.1.1.2.2  pgoyette 
    515  1.1.1.1.2.2  pgoyette             /* length code -- get extra bits, if any */
    516  1.1.1.1.2.2  pgoyette             extra = (unsigned)(here.op) & 31;
    517  1.1.1.1.2.2  pgoyette             if (extra != 0) {
    518  1.1.1.1.2.2  pgoyette                 NEEDBITS(extra);
    519  1.1.1.1.2.2  pgoyette                 length += BITS(extra);
    520  1.1.1.1.2.2  pgoyette                 DROPBITS(extra);
    521  1.1.1.1.2.2  pgoyette             }
    522  1.1.1.1.2.2  pgoyette             Tracevv((stderr, "inflate:         length %lu\n", length));
    523  1.1.1.1.2.2  pgoyette 
    524  1.1.1.1.2.2  pgoyette             /* get distance code */
    525  1.1.1.1.2.2  pgoyette             for (;;) {
    526  1.1.1.1.2.2  pgoyette                 here = distcode[BITS(distbits)];
    527  1.1.1.1.2.2  pgoyette                 if ((unsigned)(here.bits) <= bits) break;
    528  1.1.1.1.2.2  pgoyette                 PULLBYTE();
    529  1.1.1.1.2.2  pgoyette             }
    530  1.1.1.1.2.2  pgoyette             if ((here.op & 0xf0) == 0) {
    531  1.1.1.1.2.2  pgoyette                 last = here;
    532  1.1.1.1.2.2  pgoyette                 for (;;) {
    533  1.1.1.1.2.2  pgoyette                     here = distcode[last.val +
    534  1.1.1.1.2.2  pgoyette                             (BITS(last.bits + last.op) >> last.bits)];
    535  1.1.1.1.2.2  pgoyette                     if ((unsigned)(last.bits + here.bits) <= bits) break;
    536  1.1.1.1.2.2  pgoyette                     PULLBYTE();
    537  1.1.1.1.2.2  pgoyette                 }
    538  1.1.1.1.2.2  pgoyette                 DROPBITS(last.bits);
    539  1.1.1.1.2.2  pgoyette             }
    540  1.1.1.1.2.2  pgoyette             DROPBITS(here.bits);
    541  1.1.1.1.2.2  pgoyette             if (here.op & 64) {
    542  1.1.1.1.2.2  pgoyette                 strm->msg = (char *)"invalid distance code";
    543  1.1.1.1.2.2  pgoyette                 mode = BAD;
    544  1.1.1.1.2.2  pgoyette                 break;
    545  1.1.1.1.2.2  pgoyette             }
    546  1.1.1.1.2.2  pgoyette             offset = (unsigned)here.val;
    547  1.1.1.1.2.2  pgoyette 
    548  1.1.1.1.2.2  pgoyette             /* get distance extra bits, if any */
    549  1.1.1.1.2.2  pgoyette             extra = (unsigned)(here.op) & 15;
    550  1.1.1.1.2.2  pgoyette             if (extra != 0) {
    551  1.1.1.1.2.2  pgoyette                 NEEDBITS(extra);
    552  1.1.1.1.2.2  pgoyette                 offset += BITS(extra);
    553  1.1.1.1.2.2  pgoyette                 DROPBITS(extra);
    554  1.1.1.1.2.2  pgoyette             }
    555  1.1.1.1.2.2  pgoyette             if (offset > WSIZE - (wrap ? 0: left)) {
    556  1.1.1.1.2.2  pgoyette                 strm->msg = (char *)"invalid distance too far back";
    557  1.1.1.1.2.2  pgoyette                 mode = BAD;
    558  1.1.1.1.2.2  pgoyette                 break;
    559  1.1.1.1.2.2  pgoyette             }
    560  1.1.1.1.2.2  pgoyette             Tracevv((stderr, "inflate:         distance %lu\n", offset));
    561  1.1.1.1.2.2  pgoyette 
    562  1.1.1.1.2.2  pgoyette             /* copy match from window to output */
    563  1.1.1.1.2.2  pgoyette             do {
    564  1.1.1.1.2.2  pgoyette                 ROOM();
    565  1.1.1.1.2.2  pgoyette                 copy = WSIZE - offset;
    566  1.1.1.1.2.2  pgoyette                 if (copy < left) {
    567  1.1.1.1.2.2  pgoyette                     from = put + copy;
    568  1.1.1.1.2.2  pgoyette                     copy = left - copy;
    569  1.1.1.1.2.2  pgoyette                 }
    570  1.1.1.1.2.2  pgoyette                 else {
    571  1.1.1.1.2.2  pgoyette                     from = put - offset;
    572  1.1.1.1.2.2  pgoyette                     copy = left;
    573  1.1.1.1.2.2  pgoyette                 }
    574  1.1.1.1.2.2  pgoyette                 if (copy > length) copy = length;
    575  1.1.1.1.2.2  pgoyette                 length -= copy;
    576  1.1.1.1.2.2  pgoyette                 left -= copy;
    577  1.1.1.1.2.2  pgoyette                 do {
    578  1.1.1.1.2.2  pgoyette                     *put++ = *from++;
    579  1.1.1.1.2.2  pgoyette                 } while (--copy);
    580  1.1.1.1.2.2  pgoyette             } while (length != 0);
    581  1.1.1.1.2.2  pgoyette             break;
    582  1.1.1.1.2.2  pgoyette 
    583  1.1.1.1.2.2  pgoyette         case DONE:
    584  1.1.1.1.2.2  pgoyette             /* inflate stream terminated properly -- write leftover output */
    585  1.1.1.1.2.2  pgoyette             ret = Z_STREAM_END;
    586  1.1.1.1.2.2  pgoyette             if (left < WSIZE) {
    587  1.1.1.1.2.2  pgoyette                 if (out(out_desc, window, (unsigned)(WSIZE - left)))
    588  1.1.1.1.2.2  pgoyette                     ret = Z_BUF_ERROR;
    589  1.1.1.1.2.2  pgoyette             }
    590  1.1.1.1.2.2  pgoyette             goto inf_leave;
    591  1.1.1.1.2.2  pgoyette 
    592  1.1.1.1.2.2  pgoyette         case BAD:
    593  1.1.1.1.2.2  pgoyette             ret = Z_DATA_ERROR;
    594  1.1.1.1.2.2  pgoyette             goto inf_leave;
    595  1.1.1.1.2.2  pgoyette 
    596  1.1.1.1.2.2  pgoyette         default:                /* can't happen, but makes compilers happy */
    597  1.1.1.1.2.2  pgoyette             ret = Z_STREAM_ERROR;
    598  1.1.1.1.2.2  pgoyette             goto inf_leave;
    599  1.1.1.1.2.2  pgoyette         }
    600  1.1.1.1.2.2  pgoyette 
    601  1.1.1.1.2.2  pgoyette     /* Return unused input */
    602  1.1.1.1.2.2  pgoyette   inf_leave:
    603  1.1.1.1.2.2  pgoyette     strm->next_in = next;
    604  1.1.1.1.2.2  pgoyette     strm->avail_in = have;
    605  1.1.1.1.2.2  pgoyette     return ret;
    606  1.1.1.1.2.2  pgoyette }
    607  1.1.1.1.2.2  pgoyette 
    608  1.1.1.1.2.2  pgoyette int ZEXPORT inflateBack9End(strm)
    609  1.1.1.1.2.2  pgoyette z_stream FAR *strm;
    610  1.1.1.1.2.2  pgoyette {
    611  1.1.1.1.2.2  pgoyette     if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
    612  1.1.1.1.2.2  pgoyette         return Z_STREAM_ERROR;
    613  1.1.1.1.2.2  pgoyette     ZFREE(strm, strm->state);
    614  1.1.1.1.2.2  pgoyette     strm->state = Z_NULL;
    615  1.1.1.1.2.2  pgoyette     Tracev((stderr, "inflate: end\n"));
    616  1.1.1.1.2.2  pgoyette     return Z_OK;
    617  1.1.1.1.2.2  pgoyette }
    618