1 /* $NetBSD: infback9.c,v 1.1.1.1 2006/01/14 20:10:50 christos Exp $ */
3 /* infback9.c -- inflate deflate64 data using a call-back interface
4 * Copyright (C) 1995-2003 Mark Adler
5 * For conditions of distribution and use, see copyright notice in zlib.h
16 strm provides memory allocation functions in zalloc and zfree, or
17 Z_NULL to use the library memory allocation functions.
19 window is a user-supplied window and output buffer that is 64K bytes.
21 int ZEXPORT
inflateBack9Init_(strm
, window
, version
, stream_size
)
23 unsigned char FAR
*window
;
27 struct inflate_state FAR
*state
;
29 if (version
== Z_NULL
|| version
[0] != ZLIB_VERSION
[0] ||
30 stream_size
!= (int)(sizeof(z_stream
)))
31 return Z_VERSION_ERROR
;
32 if (strm
== Z_NULL
|| window
== Z_NULL
)
33 return Z_STREAM_ERROR
;
34 strm
->msg
= Z_NULL
; /* in case we return an error */
35 if (strm
->zalloc
== (alloc_func
)0) {
36 strm
->zalloc
= zcalloc
;
37 strm
->opaque
= (voidpf
)0;
39 if (strm
->zfree
== (free_func
)0) strm
->zfree
= zcfree
;
40 state
= (struct inflate_state FAR
*)ZALLOC(strm
, 1,
41 sizeof(struct inflate_state
));
42 if (state
== Z_NULL
) return Z_MEM_ERROR
;
43 Tracev((stderr
, "inflate: allocated\n"));
44 strm
->state
= (voidpf
)state
;
45 state
->window
= window
;
50 Build and output length and distance decoding tables for fixed code
58 unsigned sym
, bits
, low
, size
;
59 code
*next
, *lenfix
, *distfix
;
60 struct inflate_state state
;
63 /* literal/length table */
65 while (sym
< 144) state
.lens
[sym
++] = 8;
66 while (sym
< 256) state
.lens
[sym
++] = 9;
67 while (sym
< 280) state
.lens
[sym
++] = 7;
68 while (sym
< 288) state
.lens
[sym
++] = 8;
72 inflate_table9(LENS
, state
.lens
, 288, &(next
), &(bits
), state
.work
);
76 while (sym
< 32) state
.lens
[sym
++] = 5;
79 inflate_table9(DISTS
, state
.lens
, 32, &(next
), &(bits
), state
.work
);
82 puts(" /* inffix9.h -- table for decoding deflate64 fixed codes");
83 puts(" * Generated automatically by makefixed9().");
86 puts(" /* WARNING: this file should *not* be used by applications.");
87 puts(" It is part of the implementation of this library and is");
88 puts(" subject to change. Applications should only use zlib.h.");
92 printf(" static const code lenfix[%u] = {", size
);
95 if ((low
% 6) == 0) printf("\n ");
96 printf("{%u,%u,%d}", lenfix
[low
].op
, lenfix
[low
].bits
,
98 if (++low
== size
) break;
103 printf("\n static const code distfix[%u] = {", size
);
106 if ((low
% 5) == 0) printf("\n ");
107 printf("{%u,%u,%d}", distfix
[low
].op
, distfix
[low
].bits
,
109 if (++low
== size
) break;
114 #endif /* MAKEFIXED */
116 /* Macros for inflateBack(): */
118 /* Clear the input bit accumulator */
125 /* Assure that some input is available. If input is requested, but denied,
126 then return a Z_BUF_ERROR from inflateBack(). */
130 have = in(in_desc, &next); \
139 /* Get a byte of input into the bit accumulator, or return from inflateBack()
140 with an error if there is no input available. */
145 hold += (unsigned long)(*next++) << bits; \
149 /* Assure that there are at least n bits in the bit accumulator. If there is
150 not enough available input to do that, then return from inflateBack() with
152 #define NEEDBITS(n) \
154 while (bits < (unsigned)(n)) \
158 /* Return the low n bits of the bit accumulator (n <= 16) */
160 ((unsigned)hold & ((1U << (n)) - 1))
162 /* Remove n bits from the bit accumulator */
163 #define DROPBITS(n) \
166 bits -= (unsigned)(n); \
169 /* Remove zero to seven bits as needed to go to a byte boundary */
176 /* Assure that some output space is available, by writing out the window
177 if it's full. If the write fails, return from inflateBack() with a
185 if (out(out_desc, put, (unsigned)left)) { \
193 strm provides the memory allocation functions and window buffer on input,
194 and provides information on the unused input on return. For Z_DATA_ERROR
195 returns, strm will also provide an error message.
197 in() and out() are the call-back input and output functions. When
198 inflateBack() needs more input, it calls in(). When inflateBack() has
199 filled the window with output, or when it completes with data in the
200 window, it calls out() to write out the data. The application must not
201 change the provided input until in() is called again or inflateBack()
202 returns. The application must not change the window/output buffer until
203 inflateBack() returns.
205 in() and out() are called with a descriptor parameter provided in the
206 inflateBack() call. This parameter can be a structure that provides the
207 information required to do the read or write, as well as accumulated
208 information on the input and output such as totals and check values.
210 in() should return zero on failure. out() should return non-zero on
211 failure. If either in() or out() fails, than inflateBack() returns a
212 Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
213 was in() or out() that caused in the error. Otherwise, inflateBack()
214 returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
215 error, or Z_MEM_ERROR if it could not allocate memory for the state.
216 inflateBack() can also return Z_STREAM_ERROR if the input parameters
217 are not correct, i.e. strm is Z_NULL or the state was not initialized.
219 int ZEXPORT
inflateBack9(strm
, in
, in_desc
, out
, out_desc
)
226 struct inflate_state FAR
*state
;
227 unsigned char FAR
*next
; /* next input */
228 unsigned char FAR
*put
; /* next output */
229 unsigned have
; /* available input */
230 unsigned long left
; /* available output */
231 inflate_mode mode
; /* current inflate mode */
232 int lastblock
; /* true if processing last block */
233 int wrap
; /* true if the window has wrapped */
234 unsigned long write
; /* window write index */
235 unsigned char FAR
*window
; /* allocated sliding window, if needed */
236 unsigned long hold
; /* bit buffer */
237 unsigned bits
; /* bits in bit buffer */
238 unsigned extra
; /* extra bits needed */
239 unsigned long length
; /* literal or length of data to copy */
240 unsigned long offset
; /* distance back to copy string from */
241 unsigned long copy
; /* number of stored or match bytes to copy */
242 unsigned char FAR
*from
; /* where to copy match bytes from */
243 code
const FAR
*lencode
; /* starting table for length/literal codes */
244 code
const FAR
*distcode
; /* starting table for distance codes */
245 unsigned lenbits
; /* index bits for lencode */
246 unsigned distbits
; /* index bits for distcode */
247 code
this; /* current decoding table entry */
248 code last
; /* parent table entry */
249 unsigned len
; /* length to copy for repeats, bits to drop */
250 int ret
; /* return code */
251 static const unsigned short order
[19] = /* permutation of code lengths */
252 {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
255 /* Check that the strm exists and that the state was initialized */
256 if (strm
== Z_NULL
|| strm
->state
== Z_NULL
)
257 return Z_STREAM_ERROR
;
258 state
= (struct inflate_state FAR
*)strm
->state
;
260 /* Reset the state */
266 window
= state
->window
;
267 next
= strm
->next_in
;
268 have
= next
!= Z_NULL
? strm
->avail_in
: 0;
276 /* Inflate until end of block marked as last */
280 /* determine and dispatch block type */
290 case 0: /* stored block */
291 Tracev((stderr
, "inflate: stored block%s\n",
292 lastblock
? " (last)" : ""));
295 case 1: /* fixed block */
300 Tracev((stderr
, "inflate: fixed codes block%s\n",
301 lastblock
? " (last)" : ""));
302 mode
= LEN
; /* decode codes */
304 case 2: /* dynamic block */
305 Tracev((stderr
, "inflate: dynamic codes block%s\n",
306 lastblock
? " (last)" : ""));
310 strm
->msg
= (char *)"invalid block type";
317 /* get and verify stored block length */
318 BYTEBITS(); /* go to byte boundary */
320 if ((hold
& 0xffff) != ((hold
>> 16) ^ 0xffff)) {
321 strm
->msg
= (char *)"invalid stored block lengths";
325 length
= (unsigned)hold
& 0xffff;
326 Tracev((stderr
, "inflate: stored length %lu\n",
330 /* copy stored block from input to output */
331 while (length
!= 0) {
335 if (copy
> have
) copy
= have
;
336 if (copy
> left
) copy
= left
;
337 zmemcpy(put
, next
, copy
);
344 Tracev((stderr
, "inflate: stored end\n"));
349 /* get dynamic table entries descriptor */
351 state
->nlen
= BITS(5) + 257;
353 state
->ndist
= BITS(5) + 1;
355 state
->ncode
= BITS(4) + 4;
357 if (state
->nlen
> 286) {
358 strm
->msg
= (char *)"too many length symbols";
362 Tracev((stderr
, "inflate: table sizes ok\n"));
364 /* get code length code lengths (not a typo) */
366 while (state
->have
< state
->ncode
) {
368 state
->lens
[order
[state
->have
++]] = (unsigned short)BITS(3);
371 while (state
->have
< 19)
372 state
->lens
[order
[state
->have
++]] = 0;
373 state
->next
= state
->codes
;
374 lencode
= (code
const FAR
*)(state
->next
);
376 ret
= inflate_table9(CODES
, state
->lens
, 19, &(state
->next
),
377 &(lenbits
), state
->work
);
379 strm
->msg
= (char *)"invalid code lengths set";
383 Tracev((stderr
, "inflate: code lengths ok\n"));
385 /* get length and distance code code lengths */
387 while (state
->have
< state
->nlen
+ state
->ndist
) {
389 this = lencode
[BITS(lenbits
)];
390 if ((unsigned)(this.bits
) <= bits
) break;
396 state
->lens
[state
->have
++] = this.val
;
399 if (this.val
== 16) {
400 NEEDBITS(this.bits
+ 2);
402 if (state
->have
== 0) {
403 strm
->msg
= (char *)"invalid bit length repeat";
407 len
= (unsigned)(state
->lens
[state
->have
- 1]);
411 else if (this.val
== 17) {
412 NEEDBITS(this.bits
+ 3);
419 NEEDBITS(this.bits
+ 7);
425 if (state
->have
+ copy
> state
->nlen
+ state
->ndist
) {
426 strm
->msg
= (char *)"invalid bit length repeat";
431 state
->lens
[state
->have
++] = (unsigned short)len
;
435 /* handle error breaks in while */
436 if (mode
== BAD
) break;
438 /* build code tables */
439 state
->next
= state
->codes
;
440 lencode
= (code
const FAR
*)(state
->next
);
442 ret
= inflate_table9(LENS
, state
->lens
, state
->nlen
,
443 &(state
->next
), &(lenbits
), state
->work
);
445 strm
->msg
= (char *)"invalid literal/lengths set";
449 distcode
= (code
const FAR
*)(state
->next
);
451 ret
= inflate_table9(DISTS
, state
->lens
+ state
->nlen
,
452 state
->ndist
, &(state
->next
), &(distbits
),
455 strm
->msg
= (char *)"invalid distances set";
459 Tracev((stderr
, "inflate: codes ok\n"));
463 /* get a literal, length, or end-of-block code */
465 this = lencode
[BITS(lenbits
)];
466 if ((unsigned)(this.bits
) <= bits
) break;
469 if (this.op
&& (this.op
& 0xf0) == 0) {
472 this = lencode
[last
.val
+
473 (BITS(last
.bits
+ last
.op
) >> last
.bits
)];
474 if ((unsigned)(last
.bits
+ this.bits
) <= bits
) break;
480 length
= (unsigned)this.val
;
482 /* process literal */
484 Tracevv((stderr
, this.val
>= 0x20 && this.val
< 0x7f ?
485 "inflate: literal '%c'\n" :
486 "inflate: literal 0x%02x\n", this.val
));
488 *put
++ = (unsigned char)(length
);
494 /* process end of block */
496 Tracevv((stderr
, "inflate: end of block\n"));
503 strm
->msg
= (char *)"invalid literal/length code";
508 /* length code -- get extra bits, if any */
509 extra
= (unsigned)(this.op
) & 31;
512 length
+= BITS(extra
);
515 Tracevv((stderr
, "inflate: length %lu\n", length
));
517 /* get distance code */
519 this = distcode
[BITS(distbits
)];
520 if ((unsigned)(this.bits
) <= bits
) break;
523 if ((this.op
& 0xf0) == 0) {
526 this = distcode
[last
.val
+
527 (BITS(last
.bits
+ last
.op
) >> last
.bits
)];
528 if ((unsigned)(last
.bits
+ this.bits
) <= bits
) break;
535 strm
->msg
= (char *)"invalid distance code";
539 offset
= (unsigned)this.val
;
541 /* get distance extra bits, if any */
542 extra
= (unsigned)(this.op
) & 15;
545 offset
+= BITS(extra
);
548 if (offset
> WSIZE
- (wrap
? 0: left
)) {
549 strm
->msg
= (char *)"invalid distance too far back";
553 Tracevv((stderr
, "inflate: distance %lu\n", offset
));
555 /* copy match from window to output */
558 copy
= WSIZE
- offset
;
567 if (copy
> length
) copy
= length
;
573 } while (length
!= 0);
577 /* inflate stream terminated properly -- write leftover output */
580 if (out(out_desc
, window
, (unsigned)(WSIZE
- left
)))
589 default: /* can't happen, but makes compilers happy */
590 ret
= Z_STREAM_ERROR
;
594 /* Return unused input */
596 strm
->next_in
= next
;
597 strm
->avail_in
= have
;
601 int ZEXPORT
inflateBack9End(strm
)
604 if (strm
== Z_NULL
|| strm
->state
== Z_NULL
|| strm
->zfree
== (free_func
)0)
605 return Z_STREAM_ERROR
;
606 ZFREE(strm
, strm
->state
);
607 strm
->state
= Z_NULL
;
608 Tracev((stderr
, "inflate: end\n"));