ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

infcodes.c
Go to the documentation of this file.
00001 /* infcodes.c -- process literals and length/distance pairs
00002  * Copyright (C) 1995-2002 Mark Adler
00003  * For conditions of distribution and use, see copyright notice in zlib.h
00004  */
00005 
00006 #include "zutil.h"
00007 #include "inftrees.h"
00008 #include "infblock.h"
00009 #include "infcodes.h"
00010 #include "infutil.h"
00011 
00012 /* simplify the use of the inflate_huft type with some defines */
00013 #define exop word.what.Exop
00014 #define bits word.what.Bits
00015 
00016 typedef enum {        /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
00017       START,    /* x: set up for LEN */
00018       LEN,      /* i: get length/literal/eob next */
00019       LENEXT,   /* i: getting length extra (have base) */
00020       DIST,     /* i: get distance next */
00021       DISTEXT,  /* i: getting distance extra */
00022       COPY,     /* o: copying bytes in window, waiting for space */
00023       LIT,      /* o: got literal, waiting for output space */
00024       WASH,     /* o: got eob, possibly still output waiting */
00025       END,      /* x: got eob and all data flushed */
00026       BADCODE}  /* x: got error */
00027 inflate_codes_mode;
00028 
00029 /* inflate codes private state */
00030 struct inflate_codes_state {
00031 
00032   /* mode */
00033   inflate_codes_mode mode;      /* current inflate_codes mode */
00034 
00035   /* mode dependent information */
00036   uInt len;
00037   union {
00038     struct {
00039       inflate_huft *tree;       /* pointer into tree */
00040       uInt need;                /* bits needed */
00041     } code;             /* if LEN or DIST, where in tree */
00042     uInt lit;           /* if LIT, literal */
00043     struct {
00044       uInt get;                 /* bits to get for extra */
00045       uInt dist;                /* distance back to copy from */
00046     } copy;             /* if EXT or COPY, where and how much */
00047   } sub;                /* submode */
00048 
00049   /* mode independent information */
00050   Byte lbits;           /* ltree bits decoded per branch */
00051   Byte dbits;           /* dtree bits decoder per branch */
00052   inflate_huft *ltree;          /* literal/length/eob tree */
00053   inflate_huft *dtree;          /* distance tree */
00054 
00055 };
00056 
00057 
00058 local inflate_codes_statef *inflate_codes_new( /* bl, bd, tl, td, z) */
00059 uInt bl, uInt bd,
00060 inflate_huft *tl,
00061 inflate_huft *td, /* need separate declaration for Borland C++ */
00062 z_streamp z )
00063 {
00064   inflate_codes_statef *c;
00065 
00066   if ((c = (inflate_codes_statef *)
00067        ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
00068   {
00069     c->mode = START;
00070     c->lbits = (Byte)bl;
00071     c->dbits = (Byte)bd;
00072     c->ltree = tl;
00073     c->dtree = td;
00074     Tracev((stderr, "inflate:       codes new\n"));
00075   }
00076   return c;
00077 }
00078 
00079 
00080 local int inflate_codes( /* s, z, r) */
00081 inflate_blocks_statef *s,
00082 z_streamp z,
00083 int r )
00084 {
00085   uInt j;               /* temporary storage */
00086   inflate_huft *t;      /* temporary pointer */
00087   uInt e;               /* extra bits or operation */
00088   uLong b;              /* bit buffer */
00089   uInt k;               /* bits in bit buffer */
00090   Bytef *p;             /* input data pointer */
00091   uInt n;               /* bytes available there */
00092   Bytef *q;             /* output window write pointer */
00093   uInt m;               /* bytes to end of window or read pointer */
00094   Bytef *f;             /* pointer to copy strings from */
00095   inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */
00096 
00097   /* copy input/output information to locals (UPDATE macro restores) */
00098   LOAD
00099 
00100   /* process input and output based on current state */
00101   while (1) switch (c->mode)
00102   {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
00103     case START:         /* x: set up for LEN */
00104 #ifndef SLOW
00105       if (m >= 258 && n >= 10)
00106       {
00107         UPDATE
00108         r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
00109         LOAD
00110         if (r != Z_OK)
00111         {
00112           c->mode = r == Z_STREAM_END ? WASH : BADCODE;
00113           break;
00114         }
00115       }
00116 #endif /* !SLOW */
00117       c->sub.code.need = c->lbits;
00118       c->sub.code.tree = c->ltree;
00119       c->mode = LEN;
00120     case LEN:           /* i: get length/literal/eob next */
00121       j = c->sub.code.need;
00122       NEEDBITS(j)
00123       t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
00124       DUMPBITS(t->bits)
00125       e = (uInt)(t->exop);
00126       if (e == 0)               /* literal */
00127       {
00128         c->sub.lit = t->base;
00129         Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
00130                  "inflate:         literal '%c'\n" :
00131                  "inflate:         literal 0x%02x\n", t->base));
00132         c->mode = LIT;
00133         break;
00134       }
00135       if (e & 16)               /* length */
00136       {
00137         c->sub.copy.get = e & 15;
00138         c->len = t->base;
00139         c->mode = LENEXT;
00140         break;
00141       }
00142       if ((e & 64) == 0)        /* next table */
00143       {
00144         c->sub.code.need = e;
00145         c->sub.code.tree = t + t->base;
00146         break;
00147       }
00148       if (e & 32)               /* end of block */
00149       {
00150         Tracevv((stderr, "inflate:         end of block\n"));
00151         c->mode = WASH;
00152         break;
00153       }
00154       c->mode = BADCODE;        /* invalid code */
00155       z->msg = (char*)"invalid literal/length code";
00156       r = Z_DATA_ERROR;
00157       LEAVE
00158     case LENEXT:        /* i: getting length extra (have base) */
00159       j = c->sub.copy.get;
00160       NEEDBITS(j)
00161       c->len += (uInt)b & inflate_mask[j];
00162       DUMPBITS(j)
00163       c->sub.code.need = c->dbits;
00164       c->sub.code.tree = c->dtree;
00165       Tracevv((stderr, "inflate:         length %u\n", c->len));
00166       c->mode = DIST;
00167     case DIST:          /* i: get distance next */
00168       j = c->sub.code.need;
00169       NEEDBITS(j)
00170       t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
00171       DUMPBITS(t->bits)
00172       e = (uInt)(t->exop);
00173       if (e & 16)               /* distance */
00174       {
00175         c->sub.copy.get = e & 15;
00176         c->sub.copy.dist = t->base;
00177         c->mode = DISTEXT;
00178         break;
00179       }
00180       if ((e & 64) == 0)        /* next table */
00181       {
00182         c->sub.code.need = e;
00183         c->sub.code.tree = t + t->base;
00184         break;
00185       }
00186       c->mode = BADCODE;        /* invalid code */
00187       z->msg = (char*)"invalid distance code";
00188       r = Z_DATA_ERROR;
00189       LEAVE
00190     case DISTEXT:       /* i: getting distance extra */
00191       j = c->sub.copy.get;
00192       NEEDBITS(j)
00193       c->sub.copy.dist += (uInt)b & inflate_mask[j];
00194       DUMPBITS(j)
00195       Tracevv((stderr, "inflate:         distance %u\n", c->sub.copy.dist));
00196       c->mode = COPY;
00197     case COPY:          /* o: copying bytes in window, waiting for space */
00198       f = q - c->sub.copy.dist;
00199       while (f < s->window)             /* modulo window size-"while" instead */
00200         f += s->end - s->window;        /* of "if" handles invalid distances */
00201       while (c->len)
00202       {
00203         NEEDOUT
00204         OUTBYTE(*f++)
00205         if (f == s->end)
00206           f = s->window;
00207         c->len--;
00208       }
00209       c->mode = START;
00210       break;
00211     case LIT:           /* o: got literal, waiting for output space */
00212       NEEDOUT
00213       OUTBYTE(c->sub.lit)
00214       c->mode = START;
00215       break;
00216     case WASH:          /* o: got eob, possibly more output */
00217       if (k > 7)        /* return unused byte, if any */
00218       {
00219         Assert(k < 16, "inflate_codes grabbed too many bytes")
00220         k -= 8;
00221         n++;
00222         p--;            /* can always return one */
00223       }
00224       FLUSH
00225       if (s->read != s->write)
00226         LEAVE
00227       c->mode = END;
00228     case END:
00229       r = Z_STREAM_END;
00230       LEAVE
00231     case BADCODE:       /* x: got error */
00232       r = Z_DATA_ERROR;
00233       LEAVE
00234     default:
00235       r = Z_STREAM_ERROR;
00236       LEAVE
00237   }
00238 #ifdef NEED_DUMMY_RETURN
00239   return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
00240 #endif
00241 }
00242 
00243 
00244 local void inflate_codes_free( /* c, z) */
00245 inflate_codes_statef *c,
00246 z_streamp z )
00247 {
00248   ZFREE(z, c);
00249   Tracev((stderr, "inflate:       codes free\n"));
00250 }

Generated on Sun May 27 2012 04:33:51 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.