]>
git.saurik.com Git - wxWidgets.git/blob - src/zlib/infcodes.c
   1 /* infcodes.c -- process literals and length/distance pairs 
   2  * Copyright (C) 1995-2002 Mark Adler 
   3  * For conditions of distribution and use, see copyright notice in zlib.h 
  13 /* simplify the use of the inflate_huft type with some defines */ 
  14 #define exop word.what.Exop 
  15 #define bits word.what.Bits 
  17 typedef enum {        /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ 
  18       START
,    /* x: set up for LEN */ 
  19       LEN
,      /* i: get length/literal/eob next */ 
  20       LENEXT
,   /* i: getting length extra (have base) */ 
  21       DIST
,     /* i: get distance next */ 
  22       DISTEXT
,  /* i: getting distance extra */ 
  23       COPY
,     /* o: copying bytes in window, waiting for space */ 
  24       LIT
,      /* o: got literal, waiting for output space */ 
  25       WASH
,     /* o: got eob, possibly still output waiting */ 
  26       END
,      /* x: got eob and all data flushed */ 
  27       BADCODE
}  /* x: got error */ 
  30 /* inflate codes private state */ 
  31 struct inflate_codes_state 
{ 
  34   inflate_codes_mode mode
;      /* current inflate_codes mode */ 
  36   /* mode dependent information */ 
  40       inflate_huft 
*tree
;       /* pointer into tree */ 
  41       uInt need
;                /* bits needed */ 
  42     } code
;             /* if LEN or DIST, where in tree */ 
  43     uInt lit
;           /* if LIT, literal */ 
  45       uInt get
;                 /* bits to get for extra */ 
  46       uInt dist
;                /* distance back to copy from */ 
  47     } copy
;             /* if EXT or COPY, where and how much */ 
  50   /* mode independent information */ 
  51   Byte lbits
;           /* ltree bits decoded per branch */ 
  52   Byte dbits
;           /* dtree bits decoder per branch */ 
  53   inflate_huft 
*ltree
;          /* literal/length/eob tree */ 
  54   inflate_huft 
*dtree
;          /* distance tree */ 
  58 #if defined(__VISAGECPP__) /* Visualage can't handle this antiquated interface */ 
  59 inflate_codes_statef
* inflate_codes_new(uInt bl
, uInt bd
, inflate_huft
* tl
, inflate_huft
* td
, z_streamp z
) 
  61 inflate_codes_statef 
*inflate_codes_new(bl
, bd
, tl
, td
, z
) 
  64 inflate_huft 
*td
; /* need separate declaration for Borland C++ */ 
  68   inflate_codes_statef 
*c
; 
  70   if ((c 
= (inflate_codes_statef 
*) 
  71        ZALLOC(z
,1,sizeof(struct inflate_codes_state
))) != Z_NULL
) 
  78     Tracev((stderr
, "inflate:       codes new\n")); 
  83 #if defined(__VISAGECPP__) /* Visualage can't handle this antiquated interface */ 
  84 int inflate_codes(inflate_blocks_statef
* s
, z_streamp z
, int r
) 
  86 int inflate_codes(s
, z
, r
) 
  87 inflate_blocks_statef 
*s
; 
  92   uInt j
;               /* temporary storage */ 
  93   inflate_huft 
*t
;      /* temporary pointer */ 
  94   uInt e
;               /* extra bits or operation */ 
  95   uLong b
;              /* bit buffer */ 
  96   uInt k
;               /* bits in bit buffer */ 
  97   Bytef 
*p
;             /* input data pointer */ 
  98   uInt n
;               /* bytes available there */ 
  99   Bytef 
*q
;             /* output window write pointer */ 
 100   uInt m
;               /* bytes to end of window or read pointer */ 
 101   Bytef 
*f
;             /* pointer to copy strings from */ 
 102   inflate_codes_statef 
*c 
= s
->sub
.decode
.codes
;  /* codes state */ 
 104   /* copy input/output information to locals (UPDATE macro restores) */ 
 107   /* process input and output based on current state */ 
 108   while (1) switch (c
->mode
) 
 109   {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ 
 110     case START
:         /* x: set up for LEN */ 
 112       if (m 
>= 258 && n 
>= 10) 
 115         r 
= inflate_fast(c
->lbits
, c
->dbits
, c
->ltree
, c
->dtree
, s
, z
); 
 119           c
->mode 
= r 
== Z_STREAM_END 
? WASH 
: BADCODE
; 
 124       c
->sub
.code
.need 
= c
->lbits
; 
 125       c
->sub
.code
.tree 
= c
->ltree
; 
 127     case LEN
:           /* i: get length/literal/eob next */ 
 128       j 
= c
->sub
.code
.need
; 
 130       t 
= c
->sub
.code
.tree 
+ ((uInt
)b 
& inflate_mask
[j
]); 
 133       if (e 
== 0)               /* literal */ 
 135         c
->sub
.lit 
= t
->base
; 
 136         Tracevv((stderr
, t
->base 
>= 0x20 && t
->base 
< 0x7f ? 
 137                  "inflate:         literal '%c'\n" : 
 138                  "inflate:         literal 0x%02x\n", t
->base
)); 
 142       if (e 
& 16)               /* length */ 
 144         c
->sub
.copy
.get 
= e 
& 15; 
 149       if ((e 
& 64) == 0)        /* next table */ 
 151         c
->sub
.code
.need 
= e
; 
 152         c
->sub
.code
.tree 
= t 
+ t
->base
; 
 155       if (e 
& 32)               /* end of block */ 
 157         Tracevv((stderr
, "inflate:         end of block\n")); 
 161       c
->mode 
= BADCODE
;        /* invalid code */ 
 162       z
->msg 
= (char*)"invalid literal/length code"; 
 165     case LENEXT
:        /* i: getting length extra (have base) */ 
 168       c
->len 
+= (uInt
)b 
& inflate_mask
[j
]; 
 170       c
->sub
.code
.need 
= c
->dbits
; 
 171       c
->sub
.code
.tree 
= c
->dtree
; 
 172       Tracevv((stderr
, "inflate:         length %u\n", c
->len
)); 
 174     case DIST
:          /* i: get distance next */ 
 175       j 
= c
->sub
.code
.need
; 
 177       t 
= c
->sub
.code
.tree 
+ ((uInt
)b 
& inflate_mask
[j
]); 
 180       if (e 
& 16)               /* distance */ 
 182         c
->sub
.copy
.get 
= e 
& 15; 
 183         c
->sub
.copy
.dist 
= t
->base
; 
 187       if ((e 
& 64) == 0)        /* next table */ 
 189         c
->sub
.code
.need 
= e
; 
 190         c
->sub
.code
.tree 
= t 
+ t
->base
; 
 193       c
->mode 
= BADCODE
;        /* invalid code */ 
 194       z
->msg 
= (char*)"invalid distance code"; 
 197     case DISTEXT
:       /* i: getting distance extra */ 
 200       c
->sub
.copy
.dist 
+= (uInt
)b 
& inflate_mask
[j
]; 
 202       Tracevv((stderr
, "inflate:         distance %u\n", c
->sub
.copy
.dist
)); 
 204     case COPY
:          /* o: copying bytes in window, waiting for space */ 
 205       f 
= q 
- c
->sub
.copy
.dist
; 
 206       while (f 
< s
->window
)             /* modulo window size-"while" instead */ 
 207         f 
+= s
->end 
- s
->window
;        /* of "if" handles invalid distances */ 
 218     case LIT
:           /* o: got literal, waiting for output space */ 
 223     case WASH
:          /* o: got eob, possibly more output */ 
 224       if (k 
> 7)        /* return unused byte, if any */ 
 226         Assert(k 
< 16, "inflate_codes grabbed too many bytes") 
 229         p
--;            /* can always return one */ 
 232       if (s
->read 
!= s
->write
) 
 238     case BADCODE
:       /* x: got error */ 
 245 #ifdef NEED_DUMMY_RETURN 
 246   return Z_STREAM_ERROR
;  /* Some dumb compilers complain without this */ 
 250 #if defined(__VISAGECPP__) /* Visualage can't handle this antiquated interface */ 
 251 void inflate_codes_free(inflate_codes_statef
* c
, z_streamp z
) 
 253 void inflate_codes_free(c
, z
) 
 254 inflate_codes_statef 
*c
; 
 259   Tracev((stderr
, "inflate:       codes free\n"));