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