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