]>
git.saurik.com Git - wxWidgets.git/blob - src/zlib/infback.c
1 /* infback.c -- inflate using a call-back interface
2 * Copyright (C) 1995-2011 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
7 This code is largely copied from inflate.c. Normally either infback.o or
8 inflate.o would be linked into an application--not both. The interface
9 with inffast.c is retained so that optimized assembler-coded versions of
10 inflate_fast() can be used with either inflate.c or infback.c.
18 /* function prototypes */
19 local
void fixedtables
OF((struct inflate_state FAR
*state
));
22 strm provides memory allocation functions in zalloc and zfree, or
23 Z_NULL to use the library memory allocation functions.
25 windowBits is in the range 8..15, and window is a user-supplied
26 window and output buffer that is 2**windowBits bytes.
28 int ZEXPORT
inflateBackInit_(strm
, windowBits
, window
, version
, stream_size
)
31 unsigned char FAR
*window
;
35 struct inflate_state FAR
*state
;
37 if (version
== Z_NULL
|| version
[0] != ZLIB_VERSION
[0] ||
38 stream_size
!= (int)(sizeof(z_stream
)))
39 return Z_VERSION_ERROR
;
40 if (strm
== Z_NULL
|| window
== Z_NULL
||
41 windowBits
< 8 || windowBits
> 15)
42 return Z_STREAM_ERROR
;
43 strm
->msg
= Z_NULL
; /* in case we return an error */
44 if (strm
->zalloc
== (alloc_func
)0) {
46 return Z_STREAM_ERROR
;
48 strm
->zalloc
= zcalloc
;
49 strm
->opaque
= (voidpf
)0;
52 if (strm
->zfree
== (free_func
)0)
54 return Z_STREAM_ERROR
;
58 state
= (struct inflate_state FAR
*)ZALLOC(strm
, 1,
59 sizeof(struct inflate_state
));
60 if (state
== Z_NULL
) return Z_MEM_ERROR
;
61 Tracev((stderr
, "inflate: allocated\n"));
62 strm
->state
= (struct internal_state FAR
*)state
;
64 state
->wbits
= windowBits
;
65 state
->wsize
= 1U << windowBits
;
66 state
->window
= window
;
73 Return state with length and distance decoding tables and index sizes set to
74 fixed code decoding. Normally this returns fixed tables from inffixed.h.
75 If BUILDFIXED is defined, then instead this routine builds the tables the
76 first time it's called, and returns those tables the first time and
77 thereafter. This reduces the size of the code by about 2K bytes, in
78 exchange for a little execution time. However, BUILDFIXED should not be
79 used for threaded applications, since the rewriting of the tables and virgin
80 may not be thread-safe.
82 local
void fixedtables(state
)
83 struct inflate_state FAR
*state
;
86 static int virgin
= 1;
87 static code
*lenfix
, *distfix
;
88 static code fixed
[544];
90 /* build fixed huffman tables if first call (may not be thread safe) */
95 /* literal/length table */
97 while (sym
< 144) state
->lens
[sym
++] = 8;
98 while (sym
< 256) state
->lens
[sym
++] = 9;
99 while (sym
< 280) state
->lens
[sym
++] = 7;
100 while (sym
< 288) state
->lens
[sym
++] = 8;
104 inflate_table(LENS
, state
->lens
, 288, &(next
), &(bits
), state
->work
);
108 while (sym
< 32) state
->lens
[sym
++] = 5;
111 inflate_table(DISTS
, state
->lens
, 32, &(next
), &(bits
), state
->work
);
113 /* do this just once */
116 #else /* !BUILDFIXED */
117 # include "inffixed.h"
118 #endif /* BUILDFIXED */
119 state
->lencode
= lenfix
;
121 state
->distcode
= distfix
;
125 /* Macros for inflateBack(): */
127 /* Load returned state from inflate_fast() */
130 put = strm->next_out; \
131 left = strm->avail_out; \
132 next = strm->next_in; \
133 have = strm->avail_in; \
134 hold = state->hold; \
135 bits = state->bits; \
138 /* Set state from registers for inflate_fast() */
141 strm->next_out = put; \
142 strm->avail_out = left; \
143 strm->next_in = next; \
144 strm->avail_in = have; \
145 state->hold = hold; \
146 state->bits = bits; \
149 /* Clear the input bit accumulator */
156 /* Assure that some input is available. If input is requested, but denied,
157 then return a Z_BUF_ERROR from inflateBack(). */
161 have = in(in_desc, &next); \
170 /* Get a byte of input into the bit accumulator, or return from inflateBack()
171 with an error if there is no input available. */
176 hold += (unsigned long)(*next++) << bits; \
180 /* Assure that there are at least n bits in the bit accumulator. If there is
181 not enough available input to do that, then return from inflateBack() with
183 #define NEEDBITS(n) \
185 while (bits < (unsigned)(n)) \
189 /* Return the low n bits of the bit accumulator (n < 16) */
191 ((unsigned)hold & ((1U << (n)) - 1))
193 /* Remove n bits from the bit accumulator */
194 #define DROPBITS(n) \
197 bits -= (unsigned)(n); \
200 /* Remove zero to seven bits as needed to go to a byte boundary */
207 /* Assure that some output space is available, by writing out the window
208 if it's full. If the write fails, return from inflateBack() with a
213 put = state->window; \
214 left = state->wsize; \
215 state->whave = left; \
216 if (out(out_desc, put, left)) { \
224 strm provides the memory allocation functions and window buffer on input,
225 and provides information on the unused input on return. For Z_DATA_ERROR
226 returns, strm will also provide an error message.
228 in() and out() are the call-back input and output functions. When
229 inflateBack() needs more input, it calls in(). When inflateBack() has
230 filled the window with output, or when it completes with data in the
231 window, it calls out() to write out the data. The application must not
232 change the provided input until in() is called again or inflateBack()
233 returns. The application must not change the window/output buffer until
234 inflateBack() returns.
236 in() and out() are called with a descriptor parameter provided in the
237 inflateBack() call. This parameter can be a structure that provides the
238 information required to do the read or write, as well as accumulated
239 information on the input and output such as totals and check values.
241 in() should return zero on failure. out() should return non-zero on
242 failure. If either in() or out() fails, than inflateBack() returns a
243 Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
244 was in() or out() that caused in the error. Otherwise, inflateBack()
245 returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
246 error, or Z_MEM_ERROR if it could not allocate memory for the state.
247 inflateBack() can also return Z_STREAM_ERROR if the input parameters
248 are not correct, i.e. strm is Z_NULL or the state was not initialized.
250 int ZEXPORT
inflateBack(strm
, in
, in_desc
, out
, out_desc
)
257 struct inflate_state FAR
*state
;
258 z_const
unsigned char FAR
*next
; /* next input */
259 unsigned char FAR
*put
; /* next output */
260 unsigned have
, left
; /* available input and output */
261 unsigned long hold
; /* bit buffer */
262 unsigned bits
; /* bits in bit buffer */
263 unsigned copy
; /* number of stored or match bytes to copy */
264 unsigned char FAR
*from
; /* where to copy match bytes from */
265 code here
; /* current decoding table entry */
266 code last
; /* parent table entry */
267 unsigned len
; /* length to copy for repeats, bits to drop */
268 int ret
; /* return code */
269 static const unsigned short order
[19] = /* permutation of code lengths */
270 {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
272 /* Check that the strm exists and that the state was initialized */
273 if (strm
== Z_NULL
|| strm
->state
== Z_NULL
)
274 return Z_STREAM_ERROR
;
275 state
= (struct inflate_state FAR
*)strm
->state
;
277 /* Reset the state */
282 next
= strm
->next_in
;
283 have
= next
!= Z_NULL
? strm
->avail_in
: 0;
289 /* Inflate until end of block marked as last */
291 switch (state
->mode
) {
293 /* determine and dispatch block type */
300 state
->last
= BITS(1);
303 case 0: /* stored block */
304 Tracev((stderr
, "inflate: stored block%s\n",
305 state
->last
? " (last)" : ""));
306 state
->mode
= STORED
;
308 case 1: /* fixed block */
310 Tracev((stderr
, "inflate: fixed codes block%s\n",
311 state
->last
? " (last)" : ""));
312 state
->mode
= LEN
; /* decode codes */
314 case 2: /* dynamic block */
315 Tracev((stderr
, "inflate: dynamic codes block%s\n",
316 state
->last
? " (last)" : ""));
320 strm
->msg
= (char *)"invalid block type";
327 /* get and verify stored block length */
328 BYTEBITS(); /* go to byte boundary */
330 if ((hold
& 0xffff) != ((hold
>> 16) ^ 0xffff)) {
331 strm
->msg
= (char *)"invalid stored block lengths";
335 state
->length
= (unsigned)hold
& 0xffff;
336 Tracev((stderr
, "inflate: stored length %u\n",
340 /* copy stored block from input to output */
341 while (state
->length
!= 0) {
342 copy
= state
->length
;
345 if (copy
> have
) copy
= have
;
346 if (copy
> left
) copy
= left
;
347 zmemcpy(put
, next
, copy
);
352 state
->length
-= copy
;
354 Tracev((stderr
, "inflate: stored end\n"));
359 /* get dynamic table entries descriptor */
361 state
->nlen
= BITS(5) + 257;
363 state
->ndist
= BITS(5) + 1;
365 state
->ncode
= BITS(4) + 4;
367 #ifndef PKZIP_BUG_WORKAROUND
368 if (state
->nlen
> 286 || state
->ndist
> 30) {
369 strm
->msg
= (char *)"too many length or distance symbols";
374 Tracev((stderr
, "inflate: table sizes ok\n"));
376 /* get code length code lengths (not a typo) */
378 while (state
->have
< state
->ncode
) {
380 state
->lens
[order
[state
->have
++]] = (unsigned short)BITS(3);
383 while (state
->have
< 19)
384 state
->lens
[order
[state
->have
++]] = 0;
385 state
->next
= state
->codes
;
386 state
->lencode
= (code
const FAR
*)(state
->next
);
388 ret
= inflate_table(CODES
, state
->lens
, 19, &(state
->next
),
389 &(state
->lenbits
), state
->work
);
391 strm
->msg
= (char *)"invalid code lengths set";
395 Tracev((stderr
, "inflate: code lengths ok\n"));
397 /* get length and distance code code lengths */
399 while (state
->have
< state
->nlen
+ state
->ndist
) {
401 here
= state
->lencode
[BITS(state
->lenbits
)];
402 if ((unsigned)(here
.bits
) <= bits
) break;
407 state
->lens
[state
->have
++] = here
.val
;
410 if (here
.val
== 16) {
411 NEEDBITS(here
.bits
+ 2);
413 if (state
->have
== 0) {
414 strm
->msg
= (char *)"invalid bit length repeat";
418 len
= (unsigned)(state
->lens
[state
->have
- 1]);
422 else if (here
.val
== 17) {
423 NEEDBITS(here
.bits
+ 3);
430 NEEDBITS(here
.bits
+ 7);
436 if (state
->have
+ copy
> state
->nlen
+ state
->ndist
) {
437 strm
->msg
= (char *)"invalid bit length repeat";
442 state
->lens
[state
->have
++] = (unsigned short)len
;
446 /* handle error breaks in while */
447 if (state
->mode
== BAD
) break;
449 /* check for end-of-block code (better have one) */
450 if (state
->lens
[256] == 0) {
451 strm
->msg
= (char *)"invalid code -- missing end-of-block";
456 /* build code tables -- note: do not change the lenbits or distbits
457 values here (9 and 6) without reading the comments in inftrees.h
458 concerning the ENOUGH constants, which depend on those values */
459 state
->next
= state
->codes
;
460 state
->lencode
= (code
const FAR
*)(state
->next
);
462 ret
= inflate_table(LENS
, state
->lens
, state
->nlen
, &(state
->next
),
463 &(state
->lenbits
), state
->work
);
465 strm
->msg
= (char *)"invalid literal/lengths set";
469 state
->distcode
= (code
const FAR
*)(state
->next
);
471 ret
= inflate_table(DISTS
, state
->lens
+ state
->nlen
, state
->ndist
,
472 &(state
->next
), &(state
->distbits
), state
->work
);
474 strm
->msg
= (char *)"invalid distances set";
478 Tracev((stderr
, "inflate: codes ok\n"));
482 /* use inflate_fast() if we have enough input and output */
483 if (have
>= 6 && left
>= 258) {
485 if (state
->whave
< state
->wsize
)
486 state
->whave
= state
->wsize
- left
;
487 inflate_fast(strm
, state
->wsize
);
492 /* get a literal, length, or end-of-block code */
494 here
= state
->lencode
[BITS(state
->lenbits
)];
495 if ((unsigned)(here
.bits
) <= bits
) break;
498 if (here
.op
&& (here
.op
& 0xf0) == 0) {
501 here
= state
->lencode
[last
.val
+
502 (BITS(last
.bits
+ last
.op
) >> last
.bits
)];
503 if ((unsigned)(last
.bits
+ here
.bits
) <= bits
) break;
509 state
->length
= (unsigned)here
.val
;
511 /* process literal */
513 Tracevv((stderr
, here
.val
>= 0x20 && here
.val
< 0x7f ?
514 "inflate: literal '%c'\n" :
515 "inflate: literal 0x%02x\n", here
.val
));
517 *put
++ = (unsigned char)(state
->length
);
523 /* process end of block */
525 Tracevv((stderr
, "inflate: end of block\n"));
532 strm
->msg
= (char *)"invalid literal/length code";
537 /* length code -- get extra bits, if any */
538 state
->extra
= (unsigned)(here
.op
) & 15;
539 if (state
->extra
!= 0) {
540 NEEDBITS(state
->extra
);
541 state
->length
+= BITS(state
->extra
);
542 DROPBITS(state
->extra
);
544 Tracevv((stderr
, "inflate: length %u\n", state
->length
));
546 /* get distance code */
548 here
= state
->distcode
[BITS(state
->distbits
)];
549 if ((unsigned)(here
.bits
) <= bits
) break;
552 if ((here
.op
& 0xf0) == 0) {
555 here
= state
->distcode
[last
.val
+
556 (BITS(last
.bits
+ last
.op
) >> last
.bits
)];
557 if ((unsigned)(last
.bits
+ here
.bits
) <= bits
) break;
564 strm
->msg
= (char *)"invalid distance code";
568 state
->offset
= (unsigned)here
.val
;
570 /* get distance extra bits, if any */
571 state
->extra
= (unsigned)(here
.op
) & 15;
572 if (state
->extra
!= 0) {
573 NEEDBITS(state
->extra
);
574 state
->offset
+= BITS(state
->extra
);
575 DROPBITS(state
->extra
);
577 if (state
->offset
> state
->wsize
- (state
->whave
< state
->wsize
?
579 strm
->msg
= (char *)"invalid distance too far back";
583 Tracevv((stderr
, "inflate: distance %u\n", state
->offset
));
585 /* copy match from window to output */
588 copy
= state
->wsize
- state
->offset
;
594 from
= put
- state
->offset
;
597 if (copy
> state
->length
) copy
= state
->length
;
598 state
->length
-= copy
;
603 } while (state
->length
!= 0);
607 /* inflate stream terminated properly -- write leftover output */
609 if (left
< state
->wsize
) {
610 if (out(out_desc
, state
->window
, state
->wsize
- left
))
619 default: /* can't happen, but makes compilers happy */
620 ret
= Z_STREAM_ERROR
;
624 /* Return unused input */
626 strm
->next_in
= next
;
627 strm
->avail_in
= have
;
631 int ZEXPORT
inflateBackEnd(strm
)
634 if (strm
== Z_NULL
|| strm
->state
== Z_NULL
|| strm
->zfree
== (free_func
)0)
635 return Z_STREAM_ERROR
;
636 ZFREE(strm
, strm
->state
);
637 strm
->state
= Z_NULL
;
638 Tracev((stderr
, "inflate: end\n"));