]>
git.saurik.com Git - apple/xnu.git/blob - libkern/zlib/infback.c
   2  * Copyright (c) 2008 Apple Inc. All rights reserved. 
   4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. The rights granted to you under the License 
  10  * may not be used to create, or enable the creation or redistribution of, 
  11  * unlawful or unlicensed copies of an Apple operating system, or to 
  12  * circumvent, violate, or enable the circumvention or violation of, any 
  13  * terms of an Apple operating system software license agreement. 
  15  * Please obtain a copy of the License at 
  16  * http://www.opensource.apple.com/apsl/ and read it before using this file. 
  18  * The Original Code and all software distributed under the License are 
  19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  23  * Please see the License for the specific language governing rights and 
  24  * limitations under the License. 
  26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 
  28 /* infback.c -- inflate using a call-back interface 
  29  * Copyright (C) 1995-2005 Mark Adler 
  30  * For conditions of distribution and use, see copyright notice in zlib.h 
  34    This code is largely copied from inflate.c.  Normally either infback.o or 
  35    inflate.o would be linked into an application--not both.  The interface 
  36    with inffast.c is retained so that optimized assembler-coded versions of 
  37    inflate_fast() can be used with either inflate.c or infback.c. 
  45 /* function prototypes */ 
  46 local 
void fixedtables 
OF((struct inflate_state FAR 
*state
)); 
  49    strm provides memory allocation functions in zalloc and zfree, or 
  50    Z_NULL to use the library memory allocation functions. 
  52    windowBits is in the range 8..15, and window is a user-supplied 
  53    window and output buffer that is 2**windowBits bytes. 
  55 int ZEXPORT 
inflateBackInit_(strm
, windowBits
, window
, version
, stream_size
) 
  58 unsigned char FAR 
*window
; 
  62     struct inflate_state FAR 
*state
; 
  64     if (version 
== Z_NULL 
|| version
[0] != ZLIB_VERSION
[0] || 
  65         stream_size 
!= (int)(sizeof(z_stream
))) 
  66         return Z_VERSION_ERROR
; 
  67     if (strm 
== Z_NULL 
|| window 
== Z_NULL 
|| 
  68         windowBits 
< 8 || windowBits 
> 15) 
  69         return Z_STREAM_ERROR
; 
  70     strm
->msg 
= Z_NULL
;                 /* in case we return an error */ 
  72     if (strm
->zalloc 
== (alloc_func
)0) { 
  73         strm
->zalloc 
= zcalloc
; 
  74         strm
->opaque 
= (voidpf
)0; 
  76     if (strm
->zfree 
== (free_func
)0) strm
->zfree 
= zcfree
; 
  77 #endif /* NO_ZCFUNCS */ 
  78     state 
= (struct inflate_state FAR 
*)ZALLOC(strm
, 1, 
  79                                                sizeof(struct inflate_state
)); 
  80     if (state 
== Z_NULL
) return Z_MEM_ERROR
; 
  81     Tracev((stderr
, "inflate: allocated\n")); 
  82     strm
->state 
= (struct internal_state FAR 
*)state
; 
  84     state
->wbits 
= windowBits
; 
  85     state
->wsize 
= 1U << windowBits
; 
  86     state
->window 
= window
; 
  93    Return state with length and distance decoding tables and index sizes set to 
  94    fixed code decoding.  Normally this returns fixed tables from inffixed.h. 
  95    If BUILDFIXED is defined, then instead this routine builds the tables the 
  96    first time it's called, and returns those tables the first time and 
  97    thereafter.  This reduces the size of the code by about 2K bytes, in 
  98    exchange for a little execution time.  However, BUILDFIXED should not be 
  99    used for threaded applications, since the rewriting of the tables and virgin 
 100    may not be thread-safe. 
 102 local 
void fixedtables(state
) 
 103 struct inflate_state FAR 
*state
; 
 106     static int virgin 
= 1; 
 107     static code 
*lenfix
, *distfix
; 
 108     static code fixed
[544]; 
 110     /* build fixed huffman tables if first call (may not be thread safe) */ 
 115         /* literal/length table */ 
 117         while (sym 
< 144) state
->lens
[sym
++] = 8; 
 118         while (sym 
< 256) state
->lens
[sym
++] = 9; 
 119         while (sym 
< 280) state
->lens
[sym
++] = 7; 
 120         while (sym 
< 288) state
->lens
[sym
++] = 8; 
 124         inflate_table(LENS
, state
->lens
, 288, &(next
), &(bits
), state
->work
); 
 128         while (sym 
< 32) state
->lens
[sym
++] = 5; 
 131         inflate_table(DISTS
, state
->lens
, 32, &(next
), &(bits
), state
->work
); 
 133         /* do this just once */ 
 136 #else /* !BUILDFIXED */ 
 137 #   include "inffixed.h" 
 138 #endif /* BUILDFIXED */ 
 139     state
->lencode 
= lenfix
; 
 141     state
->distcode 
= distfix
; 
 145 /* Macros for inflateBack(): */ 
 147 /* Load returned state from inflate_fast() */ 
 150         put = strm->next_out; \ 
 151         left = strm->avail_out; \ 
 152         next = strm->next_in; \ 
 153         have = strm->avail_in; \ 
 154         hold = state->hold; \ 
 155         bits = state->bits; \ 
 158 /* Set state from registers for inflate_fast() */ 
 161         strm->next_out = put; \ 
 162         strm->avail_out = left; \ 
 163         strm->next_in = next; \ 
 164         strm->avail_in = have; \ 
 165         state->hold = hold; \ 
 166         state->bits = bits; \ 
 169 /* Clear the input bit accumulator */ 
 176 /* Assure that some input is available.  If input is requested, but denied, 
 177    then return a Z_BUF_ERROR from inflateBack(). */ 
 181             have = in(in_desc, &next); \ 
 190 /* Get a byte of input into the bit accumulator, or return from inflateBack() 
 191    with an error if there is no input available. */ 
 196         hold += (unsigned long)(*next++) << bits; \ 
 200 /* Assure that there are at least n bits in the bit accumulator.  If there is 
 201    not enough available input to do that, then return from inflateBack() with 
 203 #define NEEDBITS(n) \ 
 205         while (bits < (unsigned)(n)) \ 
 209 /* Return the low n bits of the bit accumulator (n < 16) */ 
 211     ((unsigned)hold & ((1U << (n)) - 1)) 
 213 /* Remove n bits from the bit accumulator */ 
 214 #define DROPBITS(n) \ 
 217         bits -= (unsigned)(n); \ 
 220 /* Remove zero to seven bits as needed to go to a byte boundary */ 
 227 /* Assure that some output space is available, by writing out the window 
 228    if it's full.  If the write fails, return from inflateBack() with a 
 233             put = state->window; \ 
 234             left = state->wsize; \ 
 235             state->whave = left; \ 
 236             if (out(out_desc, put, left)) { \ 
 244    strm provides the memory allocation functions and window buffer on input, 
 245    and provides information on the unused input on return.  For Z_DATA_ERROR 
 246    returns, strm will also provide an error message. 
 248    in() and out() are the call-back input and output functions.  When 
 249    inflateBack() needs more input, it calls in().  When inflateBack() has 
 250    filled the window with output, or when it completes with data in the 
 251    window, it calls out() to write out the data.  The application must not 
 252    change the provided input until in() is called again or inflateBack() 
 253    returns.  The application must not change the window/output buffer until 
 254    inflateBack() returns. 
 256    in() and out() are called with a descriptor parameter provided in the 
 257    inflateBack() call.  This parameter can be a structure that provides the 
 258    information required to do the read or write, as well as accumulated 
 259    information on the input and output such as totals and check values. 
 261    in() should return zero on failure.  out() should return non-zero on 
 262    failure.  If either in() or out() fails, than inflateBack() returns a 
 263    Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it 
 264    was in() or out() that caused in the error.  Otherwise,  inflateBack() 
 265    returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format 
 266    error, or Z_MEM_ERROR if it could not allocate memory for the state. 
 267    inflateBack() can also return Z_STREAM_ERROR if the input parameters 
 268    are not correct, i.e. strm is Z_NULL or the state was not initialized. 
 270 int ZEXPORT 
inflateBack(strm
, in
, in_desc
, out
, out_desc
) 
 277     struct inflate_state FAR 
*state
; 
 278     unsigned char FAR 
*next
;    /* next input */ 
 279     unsigned char FAR 
*put
;     /* next output */ 
 280     unsigned have
, left
;        /* available input and output */ 
 281     unsigned long hold
;         /* bit buffer */ 
 282     unsigned bits
;              /* bits in bit buffer */ 
 283     unsigned copy
;              /* number of stored or match bytes to copy */ 
 284     unsigned char FAR 
*from
;    /* where to copy match bytes from */ 
 285     code 
this;                  /* current decoding table entry */ 
 286     code last
;                  /* parent table entry */ 
 287     unsigned len
;               /* length to copy for repeats, bits to drop */ 
 288     int ret
;                    /* return code */ 
 289     static const unsigned short order
[19] = /* permutation of code lengths */ 
 290         {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; 
 292     /* Check that the strm exists and that the state was initialized */ 
 293     if (strm 
== Z_NULL 
|| strm
->state 
== Z_NULL
) 
 294         return Z_STREAM_ERROR
; 
 295     state 
= (struct inflate_state FAR 
*)strm
->state
; 
 297     /* Reset the state */ 
 302     next 
= strm
->next_in
; 
 303     have 
= next 
!= Z_NULL 
? strm
->avail_in 
: 0; 
 309     /* Inflate until end of block marked as last */ 
 311         switch (state
->mode
) { 
 313             /* determine and dispatch block type */ 
 320             state
->last 
= BITS(1); 
 323             case 0:                             /* stored block */ 
 324                 Tracev((stderr
, "inflate:     stored block%s\n", 
 325                         state
->last 
? " (last)" : "")); 
 326                 state
->mode 
= STORED
; 
 328             case 1:                             /* fixed block */ 
 330                 Tracev((stderr
, "inflate:     fixed codes block%s\n", 
 331                         state
->last 
? " (last)" : "")); 
 332                 state
->mode 
= LEN
;              /* decode codes */ 
 334             case 2:                             /* dynamic block */ 
 335                 Tracev((stderr
, "inflate:     dynamic codes block%s\n", 
 336                         state
->last 
? " (last)" : "")); 
 340                 strm
->msg 
= (char *)"invalid block type"; 
 347             /* get and verify stored block length */ 
 348             BYTEBITS();                         /* go to byte boundary */ 
 350             if ((hold 
& 0xffff) != ((hold 
>> 16) ^ 0xffff)) { 
 351                 strm
->msg 
= (char *)"invalid stored block lengths"; 
 355             state
->length 
= (unsigned)hold 
& 0xffff; 
 356             Tracev((stderr
, "inflate:       stored length %u\n", 
 360             /* copy stored block from input to output */ 
 361             while (state
->length 
!= 0) { 
 362                 copy 
= state
->length
; 
 365                 if (copy 
> have
) copy 
= have
; 
 366                 if (copy 
> left
) copy 
= left
; 
 367                 zmemcpy(put
, next
, copy
); 
 372                 state
->length 
-= copy
; 
 374             Tracev((stderr
, "inflate:       stored end\n")); 
 379             /* get dynamic table entries descriptor */ 
 381             state
->nlen 
= BITS(5) + 257; 
 383             state
->ndist 
= BITS(5) + 1; 
 385             state
->ncode 
= BITS(4) + 4; 
 387 #ifndef PKZIP_BUG_WORKAROUND 
 388             if (state
->nlen 
> 286 || state
->ndist 
> 30) { 
 389                 strm
->msg 
= (char *)"too many length or distance symbols"; 
 394             Tracev((stderr
, "inflate:       table sizes ok\n")); 
 396             /* get code length code lengths (not a typo) */ 
 398             while (state
->have 
< state
->ncode
) { 
 400                 state
->lens
[order
[state
->have
++]] = (unsigned short)BITS(3); 
 403             while (state
->have 
< 19) 
 404                 state
->lens
[order
[state
->have
++]] = 0; 
 405             state
->next 
= state
->codes
; 
 406             state
->lencode 
= (code 
const FAR 
*)(state
->next
); 
 408             ret 
= inflate_table(CODES
, state
->lens
, 19, &(state
->next
), 
 409                                 &(state
->lenbits
), state
->work
); 
 411                 strm
->msg 
= (char *)"invalid code lengths set"; 
 415             Tracev((stderr
, "inflate:       code lengths ok\n")); 
 417             /* get length and distance code code lengths */ 
 419             while (state
->have 
< state
->nlen 
+ state
->ndist
) { 
 421                     this = state
->lencode
[BITS(state
->lenbits
)]; 
 422                     if ((unsigned)(this.bits
) <= bits
) break; 
 428                     state
->lens
[state
->have
++] = this.val
; 
 431                     if (this.val 
== 16) { 
 432                         NEEDBITS(this.bits 
+ 2); 
 434                         if (state
->have 
== 0) { 
 435                             strm
->msg 
= (char *)"invalid bit length repeat"; 
 439                         len 
= (unsigned)(state
->lens
[state
->have 
- 1]); 
 443                     else if (this.val 
== 17) { 
 444                         NEEDBITS(this.bits 
+ 3); 
 451                         NEEDBITS(this.bits 
+ 7); 
 457                     if (state
->have 
+ copy 
> state
->nlen 
+ state
->ndist
) { 
 458                         strm
->msg 
= (char *)"invalid bit length repeat"; 
 463                         state
->lens
[state
->have
++] = (unsigned short)len
; 
 467             /* handle error breaks in while */ 
 468             if (state
->mode 
== BAD
) break; 
 470             /* build code tables */ 
 471             state
->next 
= state
->codes
; 
 472             state
->lencode 
= (code 
const FAR 
*)(state
->next
); 
 474             ret 
= inflate_table(LENS
, state
->lens
, state
->nlen
, &(state
->next
), 
 475                                 &(state
->lenbits
), state
->work
); 
 477                 strm
->msg 
= (char *)"invalid literal/lengths set"; 
 481             state
->distcode 
= (code 
const FAR 
*)(state
->next
); 
 483             ret 
= inflate_table(DISTS
, state
->lens 
+ state
->nlen
, state
->ndist
, 
 484                             &(state
->next
), &(state
->distbits
), state
->work
); 
 486                 strm
->msg 
= (char *)"invalid distances set"; 
 490             Tracev((stderr
, "inflate:       codes ok\n")); 
 494             /* use inflate_fast() if we have enough input and output */ 
 495             if (have 
>= 6 && left 
>= 258) { 
 497                 if (state
->whave 
< state
->wsize
) 
 498                     state
->whave 
= state
->wsize 
- left
; 
 499                 inflate_fast(strm
, state
->wsize
); 
 504             /* get a literal, length, or end-of-block code */ 
 506                 this = state
->lencode
[BITS(state
->lenbits
)]; 
 507                 if ((unsigned)(this.bits
) <= bits
) break; 
 510             if (this.op 
&& (this.op 
& 0xf0) == 0) { 
 513                     this = state
->lencode
[last
.val 
+ 
 514                             (BITS(last
.bits 
+ last
.op
) >> last
.bits
)]; 
 515                     if ((unsigned)(last
.bits 
+ this.bits
) <= bits
) break; 
 521             state
->length 
= (unsigned)this.val
; 
 523             /* process literal */ 
 525                 Tracevv((stderr
, this.val 
>= 0x20 && this.val 
< 0x7f ? 
 526                         "inflate:         literal '%c'\n" : 
 527                         "inflate:         literal 0x%02x\n", this.val
)); 
 529                 *put
++ = (unsigned char)(state
->length
); 
 535             /* process end of block */ 
 537                 Tracevv((stderr
, "inflate:         end of block\n")); 
 544                 strm
->msg 
= (char *)"invalid literal/length code"; 
 549             /* length code -- get extra bits, if any */ 
 550             state
->extra 
= (unsigned)(this.op
) & 15; 
 551             if (state
->extra 
!= 0) { 
 552                 NEEDBITS(state
->extra
); 
 553                 state
->length 
+= BITS(state
->extra
); 
 554                 DROPBITS(state
->extra
); 
 556             Tracevv((stderr
, "inflate:         length %u\n", state
->length
)); 
 558             /* get distance code */ 
 560                 this = state
->distcode
[BITS(state
->distbits
)]; 
 561                 if ((unsigned)(this.bits
) <= bits
) break; 
 564             if ((this.op 
& 0xf0) == 0) { 
 567                     this = state
->distcode
[last
.val 
+ 
 568                             (BITS(last
.bits 
+ last
.op
) >> last
.bits
)]; 
 569                     if ((unsigned)(last
.bits 
+ this.bits
) <= bits
) break; 
 576                 strm
->msg 
= (char *)"invalid distance code"; 
 580             state
->offset 
= (unsigned)this.val
; 
 582             /* get distance extra bits, if any */ 
 583             state
->extra 
= (unsigned)(this.op
) & 15; 
 584             if (state
->extra 
!= 0) { 
 585                 NEEDBITS(state
->extra
); 
 586                 state
->offset 
+= BITS(state
->extra
); 
 587                 DROPBITS(state
->extra
); 
 589             if (state
->offset 
> state
->wsize 
- (state
->whave 
< state
->wsize 
? 
 591                 strm
->msg 
= (char *)"invalid distance too far back"; 
 595             Tracevv((stderr
, "inflate:         distance %u\n", state
->offset
)); 
 597             /* copy match from window to output */ 
 600                 copy 
= state
->wsize 
- state
->offset
; 
 606                     from 
= put 
- state
->offset
; 
 609                 if (copy 
> state
->length
) copy 
= state
->length
; 
 610                 state
->length 
-= copy
; 
 615             } while (state
->length 
!= 0); 
 619             /* inflate stream terminated properly -- write leftover output */ 
 621             if (left 
< state
->wsize
) { 
 622                 if (out(out_desc
, state
->window
, state
->wsize 
- left
)) 
 631         default:                /* can't happen, but makes compilers happy */ 
 632             ret 
= Z_STREAM_ERROR
; 
 636     /* Return unused input */ 
 638     strm
->next_in 
= next
; 
 639     strm
->avail_in 
= have
; 
 643 int ZEXPORT 
inflateBackEnd(strm
) 
 646     if (strm 
== Z_NULL 
|| strm
->state 
== Z_NULL 
|| strm
->zfree 
== (free_func
)0) 
 647         return Z_STREAM_ERROR
; 
 648     ZFREE(strm
, strm
->state
); 
 649     strm
->state 
= Z_NULL
; 
 650     Tracev((stderr
, "inflate: end\n"));