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