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