source: trunk/minix/lib/zlib-1.2.3/contrib/infback9/infback9.c@ 9

Last change on this file since 9 was 9, checked in by Mattia Monga, 13 years ago

Minix 3.1.2a

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