]>
git.saurik.com Git - wxWidgets.git/blob - src/zlib/infback.c
   1 /* infback.c -- inflate using a call-back interface 
   2  * Copyright (C) 1995-2005 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) { 
  45         strm
->zalloc 
= zcalloc
; 
  46         strm
->opaque 
= (voidpf
)0; 
  48     if (strm
->zfree 
== (free_func
)0) strm
->zfree 
= zcfree
; 
  49     state 
= (struct inflate_state FAR 
*)ZALLOC(strm
, 1, 
  50                                                sizeof(struct inflate_state
)); 
  51     if (state 
== Z_NULL
) return Z_MEM_ERROR
; 
  52     Tracev((stderr
, "inflate: allocated\n")); 
  53     strm
->state 
= (struct internal_state FAR 
*)state
; 
  55     state
->wbits 
= windowBits
; 
  56     state
->wsize 
= 1U << windowBits
; 
  57     state
->window 
= window
; 
  64    Return state with length and distance decoding tables and index sizes set to 
  65    fixed code decoding.  Normally this returns fixed tables from inffixed.h. 
  66    If BUILDFIXED is defined, then instead this routine builds the tables the 
  67    first time it's called, and returns those tables the first time and 
  68    thereafter.  This reduces the size of the code by about 2K bytes, in 
  69    exchange for a little execution time.  However, BUILDFIXED should not be 
  70    used for threaded applications, since the rewriting of the tables and virgin 
  71    may not be thread-safe. 
  73 local 
void fixedtables(state
) 
  74 struct inflate_state FAR 
*state
; 
  77     static int virgin 
= 1; 
  78     static code 
*lenfix
, *distfix
; 
  79     static code fixed
[544]; 
  81     /* build fixed huffman tables if first call (may not be thread safe) */ 
  86         /* literal/length table */ 
  88         while (sym 
< 144) state
->lens
[sym
++] = 8; 
  89         while (sym 
< 256) state
->lens
[sym
++] = 9; 
  90         while (sym 
< 280) state
->lens
[sym
++] = 7; 
  91         while (sym 
< 288) state
->lens
[sym
++] = 8; 
  95         inflate_table(LENS
, state
->lens
, 288, &(next
), &(bits
), state
->work
); 
  99         while (sym 
< 32) state
->lens
[sym
++] = 5; 
 102         inflate_table(DISTS
, state
->lens
, 32, &(next
), &(bits
), state
->work
); 
 104         /* do this just once */ 
 107 #else /* !BUILDFIXED */ 
 108 #   include "inffixed.h" 
 109 #endif /* BUILDFIXED */ 
 110     state
->lencode 
= lenfix
; 
 112     state
->distcode 
= distfix
; 
 116 /* Macros for inflateBack(): */ 
 118 /* Load returned state from inflate_fast() */ 
 121         put = strm->next_out; \ 
 122         left = strm->avail_out; \ 
 123         next = strm->next_in; \ 
 124         have = strm->avail_in; \ 
 125         hold = state->hold; \ 
 126         bits = state->bits; \ 
 129 /* Set state from registers for inflate_fast() */ 
 132         strm->next_out = put; \ 
 133         strm->avail_out = left; \ 
 134         strm->next_in = next; \ 
 135         strm->avail_in = have; \ 
 136         state->hold = hold; \ 
 137         state->bits = bits; \ 
 140 /* Clear the input bit accumulator */ 
 147 /* Assure that some input is available.  If input is requested, but denied, 
 148    then return a Z_BUF_ERROR from inflateBack(). */ 
 152             have = in(in_desc, &next); \ 
 161 /* Get a byte of input into the bit accumulator, or return from inflateBack() 
 162    with an error if there is no input available. */ 
 167         hold += (unsigned long)(*next++) << bits; \ 
 171 /* Assure that there are at least n bits in the bit accumulator.  If there is 
 172    not enough available input to do that, then return from inflateBack() with 
 174 #define NEEDBITS(n) \ 
 176         while (bits < (unsigned)(n)) \ 
 180 /* Return the low n bits of the bit accumulator (n < 16) */ 
 182     ((unsigned)hold & ((1U << (n)) - 1)) 
 184 /* Remove n bits from the bit accumulator */ 
 185 #define DROPBITS(n) \ 
 188         bits -= (unsigned)(n); \ 
 191 /* Remove zero to seven bits as needed to go to a byte boundary */ 
 198 /* Assure that some output space is available, by writing out the window 
 199    if it's full.  If the write fails, return from inflateBack() with a 
 204             put = state->window; \ 
 205             left = state->wsize; \ 
 206             state->whave = left; \ 
 207             if (out(out_desc, put, left)) { \ 
 215    strm provides the memory allocation functions and window buffer on input, 
 216    and provides information on the unused input on return.  For Z_DATA_ERROR 
 217    returns, strm will also provide an error message. 
 219    in() and out() are the call-back input and output functions.  When 
 220    inflateBack() needs more input, it calls in().  When inflateBack() has 
 221    filled the window with output, or when it completes with data in the 
 222    window, it calls out() to write out the data.  The application must not 
 223    change the provided input until in() is called again or inflateBack() 
 224    returns.  The application must not change the window/output buffer until 
 225    inflateBack() returns. 
 227    in() and out() are called with a descriptor parameter provided in the 
 228    inflateBack() call.  This parameter can be a structure that provides the 
 229    information required to do the read or write, as well as accumulated 
 230    information on the input and output such as totals and check values. 
 232    in() should return zero on failure.  out() should return non-zero on 
 233    failure.  If either in() or out() fails, than inflateBack() returns a 
 234    Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it 
 235    was in() or out() that caused in the error.  Otherwise,  inflateBack() 
 236    returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format 
 237    error, or Z_MEM_ERROR if it could not allocate memory for the state. 
 238    inflateBack() can also return Z_STREAM_ERROR if the input parameters 
 239    are not correct, i.e. strm is Z_NULL or the state was not initialized. 
 241 int ZEXPORT 
inflateBack(strm
, in
, in_desc
, out
, out_desc
) 
 248     struct inflate_state FAR 
*state
; 
 249     unsigned char FAR 
*next
;    /* next input */ 
 250     unsigned char FAR 
*put
;     /* next output */ 
 251     unsigned have
, left
;        /* available input and output */ 
 252     unsigned long hold
;         /* bit buffer */ 
 253     unsigned bits
;              /* bits in bit buffer */ 
 254     unsigned copy
;              /* number of stored or match bytes to copy */ 
 255     unsigned char FAR 
*from
;    /* where to copy match bytes from */ 
 256     code 
this;                  /* current decoding table entry */ 
 257     code last
;                  /* parent table entry */ 
 258     unsigned len
;               /* length to copy for repeats, bits to drop */ 
 259     int ret
;                    /* return code */ 
 260     static const unsigned short order
[19] = /* permutation of code lengths */ 
 261         {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; 
 263     /* Check that the strm exists and that the state was initialized */ 
 264     if (strm 
== Z_NULL 
|| strm
->state 
== Z_NULL
) 
 265         return Z_STREAM_ERROR
; 
 266     state 
= (struct inflate_state FAR 
*)strm
->state
; 
 268     /* Reset the state */ 
 273     next 
= strm
->next_in
; 
 274     have 
= next 
!= Z_NULL 
? strm
->avail_in 
: 0; 
 280     /* Inflate until end of block marked as last */ 
 282         switch (state
->mode
) { 
 284             /* determine and dispatch block type */ 
 291             state
->last 
= BITS(1); 
 294             case 0:                             /* stored block */ 
 295                 Tracev((stderr
, "inflate:     stored block%s\n", 
 296                         state
->last 
? " (last)" : "")); 
 297                 state
->mode 
= STORED
; 
 299             case 1:                             /* fixed block */ 
 301                 Tracev((stderr
, "inflate:     fixed codes block%s\n", 
 302                         state
->last 
? " (last)" : "")); 
 303                 state
->mode 
= LEN
;              /* decode codes */ 
 305             case 2:                             /* dynamic block */ 
 306                 Tracev((stderr
, "inflate:     dynamic codes block%s\n", 
 307                         state
->last 
? " (last)" : "")); 
 311                 strm
->msg 
= (char *)"invalid block type"; 
 318             /* get and verify stored block length */ 
 319             BYTEBITS();                         /* go to byte boundary */ 
 321             if ((hold 
& 0xffff) != ((hold 
>> 16) ^ 0xffff)) { 
 322                 strm
->msg 
= (char *)"invalid stored block lengths"; 
 326             state
->length 
= (unsigned)hold 
& 0xffff; 
 327             Tracev((stderr
, "inflate:       stored length %u\n", 
 331             /* copy stored block from input to output */ 
 332             while (state
->length 
!= 0) { 
 333                 copy 
= state
->length
; 
 336                 if (copy 
> have
) copy 
= have
; 
 337                 if (copy 
> left
) copy 
= left
; 
 338                 zmemcpy(put
, next
, copy
); 
 343                 state
->length 
-= copy
; 
 345             Tracev((stderr
, "inflate:       stored end\n")); 
 350             /* get dynamic table entries descriptor */ 
 352             state
->nlen 
= BITS(5) + 257; 
 354             state
->ndist 
= BITS(5) + 1; 
 356             state
->ncode 
= BITS(4) + 4; 
 358 #ifndef PKZIP_BUG_WORKAROUND 
 359             if (state
->nlen 
> 286 || state
->ndist 
> 30) { 
 360                 strm
->msg 
= (char *)"too many length or distance symbols"; 
 365             Tracev((stderr
, "inflate:       table sizes ok\n")); 
 367             /* get code length code lengths (not a typo) */ 
 369             while (state
->have 
< state
->ncode
) { 
 371                 state
->lens
[order
[state
->have
++]] = (unsigned short)BITS(3); 
 374             while (state
->have 
< 19) 
 375                 state
->lens
[order
[state
->have
++]] = 0; 
 376             state
->next 
= state
->codes
; 
 377             state
->lencode 
= (code 
const FAR 
*)(state
->next
); 
 379             ret 
= inflate_table(CODES
, state
->lens
, 19, &(state
->next
), 
 380                                 &(state
->lenbits
), state
->work
); 
 382                 strm
->msg 
= (char *)"invalid code lengths set"; 
 386             Tracev((stderr
, "inflate:       code lengths ok\n")); 
 388             /* get length and distance code code lengths */ 
 390             while (state
->have 
< state
->nlen 
+ state
->ndist
) { 
 392                     this = state
->lencode
[BITS(state
->lenbits
)]; 
 393                     if ((unsigned)(this.bits
) <= bits
) break; 
 399                     state
->lens
[state
->have
++] = this.val
; 
 402                     if (this.val 
== 16) { 
 403                         NEEDBITS(this.bits 
+ 2); 
 405                         if (state
->have 
== 0) { 
 406                             strm
->msg 
= (char *)"invalid bit length repeat"; 
 410                         len 
= (unsigned)(state
->lens
[state
->have 
- 1]); 
 414                     else if (this.val 
== 17) { 
 415                         NEEDBITS(this.bits 
+ 3); 
 422                         NEEDBITS(this.bits 
+ 7); 
 428                     if (state
->have 
+ copy 
> state
->nlen 
+ state
->ndist
) { 
 429                         strm
->msg 
= (char *)"invalid bit length repeat"; 
 434                         state
->lens
[state
->have
++] = (unsigned short)len
; 
 438             /* handle error breaks in while */ 
 439             if (state
->mode 
== BAD
) break; 
 441             /* build code tables */ 
 442             state
->next 
= state
->codes
; 
 443             state
->lencode 
= (code 
const FAR 
*)(state
->next
); 
 445             ret 
= inflate_table(LENS
, state
->lens
, state
->nlen
, &(state
->next
), 
 446                                 &(state
->lenbits
), state
->work
); 
 448                 strm
->msg 
= (char *)"invalid literal/lengths set"; 
 452             state
->distcode 
= (code 
const FAR 
*)(state
->next
); 
 454             ret 
= inflate_table(DISTS
, state
->lens 
+ state
->nlen
, state
->ndist
, 
 455                             &(state
->next
), &(state
->distbits
), state
->work
); 
 457                 strm
->msg 
= (char *)"invalid distances set"; 
 461             Tracev((stderr
, "inflate:       codes ok\n")); 
 465             /* use inflate_fast() if we have enough input and output */ 
 466             if (have 
>= 6 && left 
>= 258) { 
 468                 if (state
->whave 
< state
->wsize
) 
 469                     state
->whave 
= state
->wsize 
- left
; 
 470                 inflate_fast(strm
, state
->wsize
); 
 475             /* get a literal, length, or end-of-block code */ 
 477                 this = state
->lencode
[BITS(state
->lenbits
)]; 
 478                 if ((unsigned)(this.bits
) <= bits
) break; 
 481             if (this.op 
&& (this.op 
& 0xf0) == 0) { 
 484                     this = state
->lencode
[last
.val 
+ 
 485                             (BITS(last
.bits 
+ last
.op
) >> last
.bits
)]; 
 486                     if ((unsigned)(last
.bits 
+ this.bits
) <= bits
) break; 
 492             state
->length 
= (unsigned)this.val
; 
 494             /* process literal */ 
 496                 Tracevv((stderr
, this.val 
>= 0x20 && this.val 
< 0x7f ? 
 497                         "inflate:         literal '%c'\n" : 
 498                         "inflate:         literal 0x%02x\n", this.val
)); 
 500                 *put
++ = (unsigned char)(state
->length
); 
 506             /* process end of block */ 
 508                 Tracevv((stderr
, "inflate:         end of block\n")); 
 515                 strm
->msg 
= (char *)"invalid literal/length code"; 
 520             /* length code -- get extra bits, if any */ 
 521             state
->extra 
= (unsigned)(this.op
) & 15; 
 522             if (state
->extra 
!= 0) { 
 523                 NEEDBITS(state
->extra
); 
 524                 state
->length 
+= BITS(state
->extra
); 
 525                 DROPBITS(state
->extra
); 
 527             Tracevv((stderr
, "inflate:         length %u\n", state
->length
)); 
 529             /* get distance code */ 
 531                 this = state
->distcode
[BITS(state
->distbits
)]; 
 532                 if ((unsigned)(this.bits
) <= bits
) break; 
 535             if ((this.op 
& 0xf0) == 0) { 
 538                     this = state
->distcode
[last
.val 
+ 
 539                             (BITS(last
.bits 
+ last
.op
) >> last
.bits
)]; 
 540                     if ((unsigned)(last
.bits 
+ this.bits
) <= bits
) break; 
 547                 strm
->msg 
= (char *)"invalid distance code"; 
 551             state
->offset 
= (unsigned)this.val
; 
 553             /* get distance extra bits, if any */ 
 554             state
->extra 
= (unsigned)(this.op
) & 15; 
 555             if (state
->extra 
!= 0) { 
 556                 NEEDBITS(state
->extra
); 
 557                 state
->offset 
+= BITS(state
->extra
); 
 558                 DROPBITS(state
->extra
); 
 560             if (state
->offset 
> state
->wsize 
- (state
->whave 
< state
->wsize 
? 
 562                 strm
->msg 
= (char *)"invalid distance too far back"; 
 566             Tracevv((stderr
, "inflate:         distance %u\n", state
->offset
)); 
 568             /* copy match from window to output */ 
 571                 copy 
= state
->wsize 
- state
->offset
; 
 577                     from 
= put 
- state
->offset
; 
 580                 if (copy 
> state
->length
) copy 
= state
->length
; 
 581                 state
->length 
-= copy
; 
 586             } while (state
->length 
!= 0); 
 590             /* inflate stream terminated properly -- write leftover output */ 
 592             if (left 
< state
->wsize
) { 
 593                 if (out(out_desc
, state
->window
, state
->wsize 
- left
)) 
 602         default:                /* can't happen, but makes compilers happy */ 
 603             ret 
= Z_STREAM_ERROR
; 
 607     /* Return unused input */ 
 609     strm
->next_in 
= next
; 
 610     strm
->avail_in 
= have
; 
 614 int ZEXPORT 
inflateBackEnd(strm
) 
 617     if (strm 
== Z_NULL 
|| strm
->state 
== Z_NULL 
|| strm
->zfree 
== (free_func
)0) 
 618         return Z_STREAM_ERROR
; 
 619     ZFREE(strm
, strm
->state
); 
 620     strm
->state 
= Z_NULL
; 
 621     Tracev((stderr
, "inflate: end\n"));