ZipInflate Class Reference

The inflater for the file compressor and decompressor. Allows the CCDiskFile to offer compression of files. At present just used to compress the native file format. More...

#include <zinflate.h>

List of all members.

Public Member Functions

 ZipInflate ()
 ZipInflate constructor.
 ~ZipInflate ()
 ZipInflate destructor.
INT32 Init (z_stream *strm)
 Initializes the internal stream state for decompression. The fields zalloc and zfree must be initialized before by the caller. If zalloc and zfree are set to Z_NULL, deflateInit updates them to use default allocation functions.
INT32 inflate (z_stream *strm, INT32 flush)
INT32 SetDictionary (z_stream *z, const Bytef *dictionary, uInt dictLength)
 Set the same dictionary on loading that was used on saving. For comments see:-.
INT32 End (z_stream *strm)
 All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output.
INT32 Init (z_stream *strm, INT32 windowBits)
 This is another version of inflate Init with more compression options. The fields next_out, zalloc and zfree must be initialized before by the caller.
INT32 Sync (z_stream *strm)
 Skips invalid compressed data until the special marker (see deflate() above) can be found, or until all available input is skipped. No output is provided.
INT32 Reset (z_stream *strm)
 This function is equivalent to inflateEnd followed by inflateInit, but does not free and reallocate all the internal decompression state. The stream will keep attributes that may have been set by inflateInit2.

Protected Member Functions

INT32 inflate_flush (inflate_blocks_state *, z_stream *, INT32)
 copy as much as possible from the sliding window to the output area
inflate_blocks_stateinflate_blocks_new (z_stream *, check_func, uInt)
INT32 inflate_blocks (inflate_blocks_state *, z_stream *, INT32)
void inflate_blocks_reset (inflate_blocks_state *, z_stream *, uLongf *)
INT32 inflate_blocks_free (inflate_blocks_state *, z_stream *, uLongf *)
void inflate_set_dictionary (inflate_blocks_state *s, const Bytef *d, uInt n)
INT32 inflate_trees_bits (uIntf *, uIntf *, inflate_huft *FAR *, z_stream *)
INT32 inflate_trees_dynamic (uInt, uInt, uIntf *, uIntf *, uIntf *, inflate_huft *FAR *, inflate_huft *FAR *, z_stream *)
 build literal/length tree
INT32 inflate_trees_fixed (uIntf *, uIntf *, inflate_huft *FAR *, inflate_huft *FAR *)
 build fixed tables if not built already--lock out other instances
INT32 inflate_trees_free (inflate_huft *, z_stream *)
 Free the malloc'ed tables built by huft_build(), which makes a linked list of the tables it made, with the links in a dummy first entry of each table.
INT32 huft_build (uIntf *, uInt, uInt, uIntf *, uIntf *, inflate_huft *FAR *, uIntf *, z_stream *)
INT32 inflate_fast (uInt, uInt, inflate_huft *, inflate_huft *, inflate_blocks_state *, z_stream *)
 Called with number of bytes left to write in window at least 258 (the maximum string length) and number of input bytes available at least ten. The ten bytes are six bytes for the longest length/ distance pair plus four bytes for overloading the bit buffer.
inflate_codes_stateinflate_codes_new (uInt, uInt, inflate_huft *, inflate_huft *, z_stream *)
INT32 inflate_codes (inflate_blocks_state *, z_stream *, INT32)
void inflate_codes_free (inflate_codes_state *, z_stream *)

Private Member Functions

 CC_DECLARE_MEMDUMP (ZipInflate)


Detailed Description

The inflater for the file compressor and decompressor. Allows the CCDiskFile to offer compression of files. At present just used to compress the native file format.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> Humprhys
Date:
23/5/95

Definition at line 391 of file zinflate.h.


Constructor & Destructor Documentation

ZipInflate::ZipInflate  ) 
 

ZipInflate constructor.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/05/95

Definition at line 147 of file zinflate.cpp.

00148 {
00149 }   

ZipInflate::~ZipInflate  ) 
 

ZipInflate destructor.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/05/95

Definition at line 161 of file zinflate.cpp.

00162 {
00163     
00164 }   


Member Function Documentation

ZipInflate::CC_DECLARE_MEMDUMP ZipInflate   )  [private]
 

INT32 ZipInflate::End z_stream z  ) 
 

All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
24/05/95
Parameters:
s the zip strema to use [INPUTS]
inflate End returns Z_OK if success, Z_STREAM_ERROR if the stream state was inconsistent. In the error case, msg may be set but then points to a static string (which must not be deallocated).

Definition at line 215 of file zinflate.cpp.

00216 {
00217     uLong c;
00218 
00219     if (z == NULL || z->In_state == NULL || z->zfree == Z_NULL) // || z->zfree == NULL)
00220         return Z_STREAM_ERROR;
00221 
00222     if (z->In_state->blocks != NULL)
00223         inflate_blocks_free(z->In_state->blocks, z, &c);
00224 
00225     delete z->In_state;
00226     z->In_state = NULL;
00227     Trace((stderr, "inflate: end\n"));
00228 
00229     return Z_OK;
00230 }

INT32 ZipInflate::huft_build uIntf ,
uInt  ,
uInt  ,
uIntf ,
uIntf ,
inflate_huft *FAR *  ,
uIntf ,
z_stream
[protected]
 

INT32 ZipInflate::inflate z_stream strm,
INT32  flush
 

Definition at line 414 of file zinflate.cpp.

00415 {
00416   INT32 r;
00417   uInt b;
00418 
00419   if (z == Z_NULL || z->In_state == Z_NULL || z->next_in == Z_NULL || f < 0)
00420     return Z_STREAM_ERROR;
00421   r = Z_BUF_ERROR;
00422   while (1) switch (z->In_state->mode)
00423   {
00424     case METHOD:
00425       NEEDBYTE
00426       if (((z->In_state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
00427       {
00428         z->In_state->mode = BAD;
00429         z->msg = (char*)"unknown compression method";
00430         z->In_state->sub.marker = 5;       /* can't try inflateSync */
00431         break;
00432       }
00433       if ((z->In_state->sub.method >> 4) + 8 > z->In_state->wbits)
00434       {
00435         z->In_state->mode = BAD;
00436         z->msg = (char*)"invalid window size";
00437         z->In_state->sub.marker = 5;       /* can't try inflateSync */
00438         break;
00439       }
00440       z->In_state->mode = FLAG;
00441     case FLAG:
00442       NEEDBYTE
00443       b = NEXTBYTE;
00444       if (((z->In_state->sub.method << 8) + b) % 31)
00445       {
00446         z->In_state->mode = BAD;
00447         z->msg = (char*)"incorrect header check";
00448         z->In_state->sub.marker = 5;       /* can't try inflateSync */
00449         break;
00450       }
00451       Trace((stderr, "inflate: zlib header ok\n"));
00452       if (!(b & PRESET_DICT))
00453       {
00454         z->In_state->mode = BLOCKS;
00455     break;
00456       }
00457       z->In_state->mode = DICT4;
00458     case DICT4:
00459       NEEDBYTE
00460       z->In_state->sub.check.need = (uLong)NEXTBYTE << 24;
00461       z->In_state->mode = DICT3;
00462     case DICT3:
00463       NEEDBYTE
00464       z->In_state->sub.check.need += (uLong)NEXTBYTE << 16;
00465       z->In_state->mode = DICT2;
00466     case DICT2:
00467       NEEDBYTE
00468       z->In_state->sub.check.need += (uLong)NEXTBYTE << 8;
00469       z->In_state->mode = DICT1;
00470     case DICT1:
00471       NEEDBYTE
00472       z->In_state->sub.check.need += (uLong)NEXTBYTE;
00473       z->adler = z->In_state->sub.check.need;
00474       z->In_state->mode = DICT0;
00475       return Z_NEED_DICT;
00476     case DICT0:
00477       z->In_state->mode = BAD;
00478       z->msg = (char*)"need dictionary";
00479       z->In_state->sub.marker = 0;       /* can try inflateSync */
00480       return Z_STREAM_ERROR;
00481     case BLOCKS:
00482       r = inflate_blocks(z->In_state->blocks, z, r);
00483       if (r == Z_DATA_ERROR)
00484       {
00485         z->In_state->mode = BAD;
00486         z->In_state->sub.marker = 0;       /* can try inflateSync */
00487         break;
00488       }
00489       if (r != Z_STREAM_END)
00490         return r;
00491       r = Z_OK;
00492       inflate_blocks_reset(z->In_state->blocks, z, &z->In_state->sub.check.was);
00493       if (z->In_state->nowrap)
00494       {
00495         z->In_state->mode = DONE;
00496         break;
00497       }
00498       z->In_state->mode = CHECK4;
00499     case CHECK4:
00500       NEEDBYTE
00501       z->In_state->sub.check.need = (uLong)NEXTBYTE << 24;
00502       z->In_state->mode = CHECK3;
00503     case CHECK3:
00504       NEEDBYTE
00505       z->In_state->sub.check.need += (uLong)NEXTBYTE << 16;
00506       z->In_state->mode = CHECK2;
00507     case CHECK2:
00508       NEEDBYTE
00509       z->In_state->sub.check.need += (uLong)NEXTBYTE << 8;
00510       z->In_state->mode = CHECK1;
00511     case CHECK1:
00512       NEEDBYTE
00513       z->In_state->sub.check.need += (uLong)NEXTBYTE;
00514 
00515       if (z->In_state->sub.check.was != z->In_state->sub.check.need)
00516       {
00517         z->In_state->mode = BAD;
00518         z->msg = (char*)"incorrect data check";
00519         z->In_state->sub.marker = 5;       /* can't try inflateSync */
00520         break;
00521       }
00522       Trace((stderr, "inflate: zlib check ok\n"));
00523       z->In_state->mode = DONE;
00524     case DONE:
00525       return Z_STREAM_END;
00526     case BAD:
00527       return Z_DATA_ERROR;
00528     default:
00529       return Z_STREAM_ERROR;
00530   }
00531 }

INT32 ZipInflate::inflate_blocks inflate_blocks_state s,
z_stream z,
INT32  r
[protected]
 

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/05/95
Parameters:
s [INPUTS] z r

Definition at line 807 of file ziftrees.cpp.

00808 {
00809   uInt t;               /* temporary storage */
00810   uLong b;              /* bit buffer */
00811   uInt k;               /* bits in bit buffer */
00812   Bytef *p;             /* input data pointer */
00813   uInt n;               /* bytes available there */
00814   Bytef *q;             /* output window write pointer */
00815   uInt m;               /* bytes to end of window or read pointer */
00816 
00817   /* copy input/output information to locals (UPDATE macro restores) */
00818   LOAD
00819 
00820   /* process input based on current state */
00821   while (1) switch (s->mode)
00822   {
00823     case TYPE:
00824       NEEDBITS(3)
00825       t = (uInt)b & 7;
00826       s->last = t & 1;
00827       switch (t >> 1)
00828       {
00829         case 0:                         /* stored */
00830           Trace((stderr, "inflate:     stored block%s\n",
00831                  s->last ? " (last)" : ""));
00832           DUMPBITS(3)
00833           t = k & 7;                    /* go to byte boundary */
00834           DUMPBITS(t)
00835           s->mode = LENS;               /* get length of stored block */
00836           break;
00837         case 1:                         /* fixed */
00838           Trace((stderr, "inflate:     fixed codes block%s\n",
00839                  s->last ? " (last)" : ""));
00840           {
00841             uInt bl, bd;
00842             inflate_huft *tl, *td;
00843 
00844             inflate_trees_fixed(&bl, &bd, &tl, &td);
00845             s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
00846             if (s->sub.decode.codes == Z_NULL)
00847             {
00848               r = Z_MEM_ERROR;
00849               LEAVE
00850             }
00851             s->sub.decode.tl = Z_NULL;  /* don't try to free these */
00852             s->sub.decode.td = Z_NULL;
00853           }
00854           DUMPBITS(3)
00855           s->mode = CODES;
00856           break;
00857         case 2:                         /* dynamic */
00858           Trace((stderr, "inflate:     dynamic codes block%s\n",
00859                  s->last ? " (last)" : ""));
00860           DUMPBITS(3)
00861           s->mode = TABLE;
00862           break;
00863         case 3:                         /* illegal */
00864           DUMPBITS(3)
00865           s->mode = BLOCKBAD;
00866           z->msg = (char*)"invalid block type";
00867           r = Z_DATA_ERROR;
00868           LEAVE
00869       }
00870       break;
00871     case LENS:
00872       NEEDBITS(32)
00873       if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
00874       {
00875         s->mode = BLOCKBAD;
00876         z->msg = (char*)"invalid stored block lengths";
00877         r = Z_DATA_ERROR;
00878         LEAVE
00879       }
00880       s->sub.left = (uInt)b & 0xffff;
00881       b = k = 0;                      /* dump bits */
00882       Tracev((stderr, "inflate:       stored length %u\n", s->sub.left));
00883       s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
00884       break;
00885     case STORED:
00886       if (n == 0)
00887         LEAVE
00888       NEEDOUT
00889       t = s->sub.left;
00890       if (t > n) t = n;
00891       if (t > m) t = m;
00892       zmemcpy(q, p, t);
00893       p += t;  n -= t;
00894       q += t;  m -= t;
00895       if ((s->sub.left -= t) != 0)
00896         break;
00897       Tracev((stderr, "inflate:       stored end, %lu total out\n",
00898               z->total_out + (q >= s->read ? q - s->read :
00899               (s->end - s->read) + (q - s->window))));
00900       s->mode = s->last ? DRY : TYPE;
00901       break;
00902     case TABLE:
00903       NEEDBITS(14)
00904       s->sub.trees.table = t = (uInt)b & 0x3fff;
00905 #ifndef PKZIP_BUG_WORKAROUND
00906       if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
00907       {
00908         s->mode = BLOCKBAD;
00909         z->msg = (char*)"too many length or distance symbols";
00910         r = Z_DATA_ERROR;
00911         LEAVE
00912       }
00913 #endif
00914       t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
00915       if (t < 19)
00916         t = 19;
00917       if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
00918       {
00919         r = Z_MEM_ERROR;
00920         LEAVE
00921       }
00922       DUMPBITS(14)
00923       s->sub.trees.index = 0;
00924       Tracev((stderr, "inflate:       table sizes ok\n"));
00925       s->mode = BTREE;
00926     case BTREE:
00927       while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
00928       {
00929         NEEDBITS(3)
00930         s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
00931         DUMPBITS(3)
00932       }
00933       while (s->sub.trees.index < 19)
00934         s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
00935       s->sub.trees.bb = 7;
00936       t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
00937                              &s->sub.trees.tb, z);
00938       if (t != Z_OK)
00939       {
00940         r = t;
00941         if (r == Z_DATA_ERROR)
00942           s->mode = BLOCKBAD;
00943         LEAVE
00944       }
00945       s->sub.trees.index = 0;
00946       Tracev((stderr, "inflate:       bits tree ok\n"));
00947       s->mode = DTREE;
00948     case DTREE:
00949       while (t = s->sub.trees.table,
00950              s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
00951       {
00952         inflate_huft *h;
00953         uInt i, j, c;
00954 
00955         t = s->sub.trees.bb;
00956         NEEDBITS(t)
00957         h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
00958         t = h->word.what.Bits;
00959         c = h->more.Base;
00960         if (c < 16)
00961         {
00962           DUMPBITS(t)
00963           s->sub.trees.blens[s->sub.trees.index++] = c;
00964         }
00965         else /* c == 16..18 */
00966         {
00967           i = c == 18 ? 7 : c - 14;
00968           j = c == 18 ? 11 : 3;
00969           NEEDBITS(t + i)
00970           DUMPBITS(t)
00971           j += (uInt)b & inflate_mask[i];
00972           DUMPBITS(i)
00973           i = s->sub.trees.index;
00974           t = s->sub.trees.table;
00975           if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
00976               (c == 16 && i < 1))
00977           {
00978             s->mode = BLOCKBAD;
00979             z->msg = (char*)"invalid bit length repeat";
00980             r = Z_DATA_ERROR;
00981             LEAVE
00982           }
00983           c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
00984           do {
00985             s->sub.trees.blens[i++] = c;
00986           } while (--j);
00987           s->sub.trees.index = i;
00988         }
00989       }
00990       inflate_trees_free(s->sub.trees.tb, z);
00991       s->sub.trees.tb = Z_NULL;
00992       {
00993         uInt bl, bd;
00994         inflate_huft *tl, *td;
00995         inflate_codes_state *c;
00996 
00997         bl = 9;         /* must be <= 9 for lookahead assumptions */
00998         bd = 6;         /* must be <= 9 for lookahead assumptions */
00999         t = s->sub.trees.table;
01000 #ifdef DEBUG
01001       inflate_hufts = 0;
01002 #endif
01003         t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
01004                                   s->sub.trees.blens, &bl, &bd, &tl, &td, z);
01005         if (t != Z_OK)
01006         {
01007           if (t == (uInt)Z_DATA_ERROR)
01008             s->mode = BLOCKBAD;
01009           r = t;
01010           LEAVE
01011         }
01012         Tracev((stderr, "inflate:       trees ok, %d * %d bytes used\n",
01013               inflate_hufts, sizeof(inflate_huft)));
01014         if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
01015         {
01016           inflate_trees_free(td, z);
01017           inflate_trees_free(tl, z);
01018           r = Z_MEM_ERROR;
01019           LEAVE
01020         }
01021         ZFREE(z, s->sub.trees.blens);
01022         s->sub.decode.codes = c;
01023         s->sub.decode.tl = tl;
01024         s->sub.decode.td = td;
01025       }
01026       s->mode = CODES;
01027     case CODES:
01028       UPDATE
01029       if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
01030         return inflate_flush(s, z, r);
01031       r = Z_OK;
01032       inflate_codes_free(s->sub.decode.codes, z);
01033       inflate_trees_free(s->sub.decode.td, z);
01034       inflate_trees_free(s->sub.decode.tl, z);
01035       LOAD
01036       Tracev((stderr, "inflate:       codes end, %lu total out\n",
01037               z->total_out + (q >= s->read ? q - s->read :
01038               (s->end - s->read) + (q - s->window))));
01039       if (!s->last)
01040       {
01041         s->mode = TYPE;
01042         break;
01043       }
01044       if (k > 7)              /* return unused byte, if any */
01045       {
01046         Assert(k < 16, "inflate_codes grabbed too many bytes")
01047         k -= 8;
01048         n++;
01049         p--;                    /* can always return one */
01050       }
01051       s->mode = DRY;
01052     case DRY:
01053       FLUSH
01054       if (s->read != s->write)
01055         LEAVE
01056       s->mode = BLOCKDONE;
01057     case BLOCKDONE:
01058       r = Z_STREAM_END;
01059       LEAVE
01060     case BLOCKBAD:
01061       r = Z_DATA_ERROR;
01062       LEAVE
01063     default:
01064       r = Z_STREAM_ERROR;
01065       LEAVE
01066   }
01067 }

INT32 ZipInflate::inflate_blocks_free inflate_blocks_state s,
z_stream z,
uLongf c
[protected]
 

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/05/95
Parameters:
s [INPUTS] z c

Definition at line 1083 of file ziftrees.cpp.

01084 {
01085     inflate_blocks_reset(s, z, c);
01086     ZFREE(z, s->window);
01087     delete s;
01088     Trace((stderr, "inflate:   blocks freed\n"));
01089     return Z_OK;
01090 }

inflate_blocks_state * ZipInflate::inflate_blocks_new z_stream z,
check_func  c,
uInt  w
[protected]
 

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/05/95
Parameters:
z [INPUTS] c w
Returns:
NULL if problem

Definition at line 768 of file ziftrees.cpp.

00769 {
00770   inflate_blocks_state *s;
00771 
00772   s = new inflate_blocks_state;
00773   if (s == NULL)
00774     return s;
00775 
00776   if ((s->window = (Byte *)ZALLOC(z, 1, w)) == NULL)
00777   {
00778     delete s;
00779     return NULL;
00780   }
00781 
00782   s->end = s->window + w;
00783   s->checkfn = c;
00784   s->mode = TYPE;
00785   Trace((stderr, "inflate:   blocks allocated\n"));
00786   inflate_blocks_reset(s, z, &s->check);
00787   return s;
00788 }

void ZipInflate::inflate_blocks_reset inflate_blocks_state ,
z_stream ,
uLongf
[protected]
 

Definition at line 732 of file ziftrees.cpp.

00733 {
00734   if (s->checkfn != Z_NULL)
00735     *c = s->check;
00736   if (s->mode == BTREE || s->mode == DTREE)
00737     ZFREE(z, s->sub.trees.blens);
00738   if (s->mode == CODES)
00739   {
00740     inflate_codes_free(s->sub.decode.codes, z);
00741     inflate_trees_free(s->sub.decode.td, z);
00742     inflate_trees_free(s->sub.decode.tl, z);
00743   }
00744   s->mode = TYPE;
00745   s->bitk = 0;
00746   s->bitb = 0;
00747   s->read = s->write = s->window;
00748   if (s->checkfn != Z_NULL)
00749     z->adler = s->check = (*s->checkfn)(0L, Z_NULL, 0);
00750   Trace((stderr, "inflate:   blocks reset\n"));
00751 }

INT32 ZipInflate::inflate_codes inflate_blocks_state s,
z_stream z,
INT32  r
[protected]
 

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/05/95
Parameters:
s [INPUTS] z r

Definition at line 1330 of file ziftrees.cpp.

01331 {
01332   uInt j;               /* temporary storage */
01333   inflate_huft *t;      /* temporary pointer */
01334   uInt e;               /* extra bits or operation */
01335   uLong b;              /* bit buffer */
01336   uInt k;               /* bits in bit buffer */
01337   Bytef *p;             /* input data pointer */
01338   uInt n;               /* bytes available there */
01339   Bytef *q;             /* output window write pointer */
01340   uInt m;               /* bytes to end of window or read pointer */
01341   Bytef *f;             /* pointer to copy strings from */
01342   inflate_codes_state *c = s->sub.decode.codes;  /* codes state */
01343 
01344   /* copy input/output information to locals (UPDATE macro restores) */
01345   LOAD
01346 
01347   /* process input and output based on current state */
01348   while (1) switch (c->mode)
01349   {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
01350     case START:         /* x: set up for LEN */
01351 #ifndef SLOW
01352       if (m >= 258 && n >= 10)
01353       {
01354         UPDATE
01355         r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
01356         LOAD
01357         if (r != Z_OK)
01358         {
01359           c->mode = r == Z_STREAM_END ? WASH : BADCODE;
01360           break;
01361         }
01362       }
01363 #endif /* !SLOW */
01364       c->sub.code.need = c->lbits;
01365       c->sub.code.tree = c->ltree;
01366       c->mode = LEN;
01367     case LEN:           /* i: get length/literal/eob next */
01368       j = c->sub.code.need;
01369       NEEDBITS(j)
01370       t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
01371       DUMPBITS(t->bits)
01372       e = (uInt)(t->exop);
01373       if (e == 0)               /* literal */
01374       {
01375         c->sub.lit = t->base;
01376         Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
01377                  "inflate:         literal '%c'\n" :
01378                  "inflate:         literal 0x%02x\n", t->base));
01379         c->mode = LIT;
01380         break;
01381       }
01382       if (e & 16)               /* length */
01383       {
01384         c->sub.copy.get = e & 15;
01385         c->len = t->base;
01386         c->mode = LENEXT;
01387         break;
01388       }
01389       if ((e & 64) == 0)        /* next table */
01390       {
01391         c->sub.code.need = e;
01392         c->sub.code.tree = t->next;
01393         break;
01394       }
01395       if (e & 32)               /* end of block */
01396       {
01397         Tracevv((stderr, "inflate:         end of block\n"));
01398         c->mode = WASH;
01399         break;
01400       }
01401       c->mode = BADCODE;        /* invalid code */
01402       z->msg = (char*)"invalid literal/length code";
01403       r = Z_DATA_ERROR;
01404       LEAVE
01405     case LENEXT:        /* i: getting length extra (have base) */
01406       j = c->sub.copy.get;
01407       NEEDBITS(j)
01408       c->len += (uInt)b & inflate_mask[j];
01409       DUMPBITS(j)
01410       c->sub.code.need = c->dbits;
01411       c->sub.code.tree = c->dtree;
01412       Tracevv((stderr, "inflate:         length %u\n", c->len));
01413       c->mode = DIST;
01414     case DIST:          /* i: get distance next */
01415       j = c->sub.code.need;
01416       NEEDBITS(j)
01417       t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
01418       DUMPBITS(t->bits)
01419       e = (uInt)(t->exop);
01420       if (e & 16)               /* distance */
01421       {
01422         c->sub.copy.get = e & 15;
01423         c->sub.copy.dist = t->base;
01424         c->mode = DISTEXT;
01425         break;
01426       }
01427       if ((e & 64) == 0)        /* next table */
01428       {
01429         c->sub.code.need = e;
01430         c->sub.code.tree = t->next;
01431         break;
01432       }
01433       c->mode = BADCODE;        /* invalid code */
01434       z->msg = (char*)"invalid distance code";
01435       r = Z_DATA_ERROR;
01436       LEAVE
01437     case DISTEXT:       /* i: getting distance extra */
01438       j = c->sub.copy.get;
01439       NEEDBITS(j)
01440       c->sub.copy.dist += (uInt)b & inflate_mask[j];
01441       DUMPBITS(j)
01442       Tracevv((stderr, "inflate:         distance %u\n", c->sub.copy.dist));
01443       c->mode = COPY;
01444     case COPY:          /* o: copying bytes in window, waiting for space */
01445 #ifndef __TURBOC__ /* Turbo C bug for following expression */
01446       f = (uInt)(q - s->window) < c->sub.copy.dist ?
01447           s->end - (c->sub.copy.dist - (q - s->window)) :
01448           q - c->sub.copy.dist;
01449 #else
01450       f = q - c->sub.copy.dist;
01451       if ((uInt)(q - s->window) < c->sub.copy.dist)
01452         f = s->end - (c->sub.copy.dist - (uInt)(q - s->window));
01453 #endif
01454       while (c->len)
01455       {
01456         NEEDOUT
01457         OUTBYTE(*f++)
01458         if (f == s->end)
01459           f = s->window;
01460         c->len--;
01461       }
01462       c->mode = START;
01463       break;
01464     case LIT:           /* o: got literal, waiting for output space */
01465       NEEDOUT
01466       OUTBYTE(c->sub.lit)
01467       c->mode = START;
01468       break;
01469     case WASH:          /* o: got eob, possibly more output */
01470       FLUSH
01471       if (s->read != s->write)
01472         LEAVE
01473       c->mode = END;
01474     case END:
01475       r = Z_STREAM_END;
01476       LEAVE
01477     case BADCODE:       /* x: got error */
01478       r = Z_DATA_ERROR;
01479       LEAVE
01480     default:
01481       r = Z_STREAM_ERROR;
01482       LEAVE
01483   }
01484 }

void ZipInflate::inflate_codes_free inflate_codes_state c,
z_stream z
[protected]
 

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/05/95
Parameters:
c [INPUTS] z

Definition at line 1498 of file ziftrees.cpp.

01499 {
01500     //ZFREE(z, c);
01501     if (c)
01502         delete c;
01503     Tracev((stderr, "inflate:       codes free\n"));
01504 }

inflate_codes_state * ZipInflate::inflate_codes_new uInt  bl,
uInt  bd,
inflate_huft tl,
inflate_huft td,
z_stream z
[protected]
 

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/05/95
Parameters:
bl [INPUTS] bd tl td z

Definition at line 1298 of file ziftrees.cpp.

01300 {
01301   inflate_codes_state *c;
01302 
01303   c = new inflate_codes_state;
01304   if (c != NULL)
01305   {
01306     c->mode = START;
01307     c->lbits = (Byte)bl;
01308     c->dbits = (Byte)bd;
01309     c->ltree = tl;
01310     c->dtree = td;
01311     Tracev((stderr, "inflate:       codes new\n"));
01312   }
01313   return c;
01314 }

INT32 ZipInflate::inflate_fast uInt  bl,
uInt  bd,
inflate_huft tl,
inflate_huft td,
inflate_blocks_state s,
z_stream z
[protected]
 

Called with number of bytes left to write in window at least 258 (the maximum string length) and number of input bytes available at least ten. The ten bytes are six bytes for the longest length/ distance pair plus four bytes for overloading the bit buffer.

Author:
Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
Date:
25/05/95
Parameters:
bl [INPUTS] bd tl td s z

Definition at line 1142 of file ziftrees.cpp.

01145 {
01146   inflate_huft *t;      /* temporary pointer */
01147   uInt e;               /* extra bits or operation */
01148   uLong b;              /* bit buffer */
01149   uInt k;               /* bits in bit buffer */
01150   Bytef *p;             /* input data pointer */
01151   uInt n;               /* bytes available there */
01152   Bytef *q;             /* output window write pointer */
01153   uInt m;               /* bytes to end of window or read pointer */
01154   uInt ml;              /* mask for literal/length tree */
01155   uInt md;              /* mask for distance tree */
01156   uInt c;               /* bytes to copy */
01157   uInt d;               /* distance back to copy from */
01158   Bytef *r;             /* copy source pointer */
01159 
01160   /* load input, output, bit values */
01161   LOAD
01162 
01163   /* initialize masks */
01164   ml = inflate_mask[bl];
01165   md = inflate_mask[bd];
01166 
01167   /* do until not enough input or output space for fast loop */
01168   do {                          /* assume called with m >= 258 && n >= 10 */
01169     /* get literal/length code */
01170     GRABBITS(20)                /* max bits for literal/length code */
01171     if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
01172     {
01173       DUMPBITS(t->bits)
01174       Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
01175                 "inflate:         * literal '%c'\n" :
01176                 "inflate:         * literal 0x%02x\n", t->base));
01177       *q++ = (Byte)t->base;
01178       m--;
01179       continue;
01180     }
01181     do {
01182       DUMPBITS(t->bits)
01183       if (e & 16)
01184       {
01185         /* get extra bits for length */
01186         e &= 15;
01187         c = t->base + ((uInt)b & inflate_mask[e]);
01188         DUMPBITS(e)
01189         Tracevv((stderr, "inflate:         * length %u\n", c));
01190 
01191         /* decode distance base of block to copy */
01192         GRABBITS(15);           /* max bits for distance code */
01193         e = (t = td + ((uInt)b & md))->exop;
01194         do {
01195           DUMPBITS(t->bits)
01196           if (e & 16)
01197           {
01198             /* get extra bits to add to distance base */
01199             e &= 15;
01200             GRABBITS(e)         /* get extra bits (up to 13) */
01201             d = t->base + ((uInt)b & inflate_mask[e]);
01202             DUMPBITS(e)
01203             Tracevv((stderr, "inflate:         * distance %u\n", d));
01204 
01205             /* do the copy */
01206             m -= c;
01207             if ((uInt)(q - s->window) >= d)     /* offset before dest */
01208             {                                   /*  just copy */
01209               r = q - d;
01210               *q++ = *r++;  c--;        /* minimum count is three, */
01211               *q++ = *r++;  c--;        /*  so unroll loop a little */
01212             }
01213             else                        /* else offset after destination */
01214             {
01215               e = d - (uInt)(q - s->window); /* bytes from offset to end */
01216               r = s->end - e;           /* pointer to offset */
01217               if (c > e)                /* if source crosses, */
01218               {
01219                 c -= e;                 /* copy to end of window */
01220                 do {
01221                   *q++ = *r++;
01222                 } while (--e);
01223                 r = s->window;          /* copy rest from start of window */
01224               }
01225             }
01226             do {                        /* copy all or what's left */
01227               *q++ = *r++;
01228             } while (--c);
01229             break;
01230           }
01231           else if ((e & 64) == 0)
01232             e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop;
01233           else
01234           {
01235             z->msg = (char*)"invalid distance code";
01236             UNGRAB
01237             UPDATE
01238             return Z_DATA_ERROR;
01239           }
01240         } while (1);
01241         break;
01242       }
01243       if ((e & 64) == 0)
01244       {
01245         if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0)
01246         {
01247           DUMPBITS(t->bits)
01248           Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
01249                     "inflate:         * literal '%c'\n" :
01250                     "inflate:         * literal 0x%02x\n", t->base));
01251           *q++ = (Byte)t->base;
01252           m--;
01253           break;
01254         }
01255       }
01256       else if (e & 32)
01257       {
01258         Tracevv((stderr, "inflate:         * end of block\n"));
01259         UNGRAB
01260         UPDATE
01261         return Z_STREAM_END;
01262       }
01263       else
01264       {
01265         z->msg = (char*)"invalid literal/length code";
01266         UNGRAB
01267         UPDATE
01268         return Z_DATA_ERROR;
01269       }
01270     } while (1);
01271   } while (m >= 258 && n >= 10);
01272 
01273   /* not enough input or output--restore pointers and return */
01274   UNGRAB
01275   UPDATE
01276   return Z_OK;
01277 }

INT32 ZipInflate::inflate_flush inflate_blocks_state s,
z_stream z,
INT32  r
[protected]
 

copy as much as possible from th