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