src/utilfuns/zlib/inffast.c File Reference

#include "zutil.h"
#include "inftrees.h"
#include "infblock.h"
#include "infcodes.h"
#include "infutil.h"
#include "inffast.h"
Include dependency graph for inffast.c:

Go to the source code of this file.

Classes

struct  inflate_codes_state

Defines

#define bits   word.what.Bits
#define exop   word.what.Exop
#define GRABBITS(j)   {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
#define UNGRAB   {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}

Functions

int inflate_fast (uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, inflate_blocks_statef *s, z_streamp z)

Define Documentation

#define bits   word.what.Bits

Definition at line 17 of file inffast.c.

#define exop   word.what.Exop

Definition at line 16 of file inffast.c.

#define GRABBITS (  )     {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}

Definition at line 20 of file inffast.c.

#define UNGRAB   {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}

Definition at line 21 of file inffast.c.


Function Documentation

int inflate_fast ( uInt  bl,
uInt  bd,
inflate_huft tl,
inflate_huft td,
inflate_blocks_statef s,
z_streamp  z 
)

Definition at line 28 of file inffast.c.

00034 {
00035   inflate_huft *t;      /* temporary pointer */
00036   uInt e;               /* extra bits or operation */
00037   uLong b;              /* bit buffer */
00038   uInt k;               /* bits in bit buffer */
00039   Bytef *p;             /* input data pointer */
00040   uInt n;               /* bytes available there */
00041   Bytef *q;             /* output window write pointer */
00042   uInt m;               /* bytes to end of window or read pointer */
00043   uInt ml;              /* mask for literal/length tree */
00044   uInt md;              /* mask for distance tree */
00045   uInt c;               /* bytes to copy */
00046   uInt d;               /* distance back to copy from */
00047   unsigned long csp;             /* copy source pointer */
00048 
00049   /* load input, output, bit values */
00050   LOAD
00051 
00052   /* initialize masks */
00053   ml = inflate_mask[bl];
00054   md = inflate_mask[bd];
00055 
00056   /* do until not enough input or output space for fast loop */
00057   do {                          /* assume called with m >= 258 && n >= 10 */
00058     /* get literal/length code */
00059     GRABBITS(20)                /* max bits for literal/length code */
00060     if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
00061     {
00062      DUMPBITS(t->bits)
00063      Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
00064              "inflate:         * literal '%c'\n" :
00065              "inflate:         * literal 0x%02x\n", t->base));
00066      *q++ = (Byte)t->base;
00067      m--;
00068      continue;
00069     }
00070     do {
00071      DUMPBITS(t->bits)
00072      if (e & 16)
00073      {
00074        /* get extra bits for length */
00075        e &= 15;
00076        c = t->base + ((uInt)b & inflate_mask[e]);
00077        DUMPBITS(e)
00078        Tracevv((stderr, "inflate:         * length %u\n", c));
00079 
00080        /* decode distance base of block to copy */
00081        GRABBITS(15);           /* max bits for distance code */
00082        e = (t = td + ((uInt)b & md))->exop;
00083        do {
00084         DUMPBITS(t->bits)
00085         if (e & 16)
00086         {
00087           /* get extra bits to add to distance base */
00088           e &= 15;
00089           GRABBITS(e)         /* get extra bits (up to 13) */
00090           d = t->base + ((uInt)b & inflate_mask[e]);
00091           DUMPBITS(e)
00092           Tracevv((stderr, "inflate:         * distance %u\n", d));
00093 
00094           /* do the copy */
00095           m -= c;
00096           csp = (unsigned long)q - d;
00097           if (csp < (unsigned long)s->window)                  /* wrap if needed */
00098           {
00099             do {
00100              csp += (unsigned long)(s->end - s->window);        /* force pointer in window */
00101             } while (csp < (unsigned long)s->window);          /* covers invalid distances */
00102             e = (unsigned long)s->end - csp;
00103             if (c > e)
00104             {
00105              c -= e;                         /* wrapped copy */
00106              do {
00107                 *q++ = *(Bytef *)csp++;
00108              } while (--e);
00109              csp = s->window;
00110              do {
00111                 *q++ = *(Bytef *)csp++;
00112              } while (--c);
00113             }
00114             else                              /* normal copy */
00115             {
00116              *q++ = *(Bytef *)csp++;  c--;
00117              *q++ = *(Bytef *)csp++;  c--;
00118              do {
00119                 *q++ = *(Bytef *)csp++;
00120              } while (--c);
00121             }
00122           }
00123           else                                /* normal copy */
00124           {
00125             *q++ = *(Bytef *)csp++;  c--;
00126             *q++ = *(Bytef *)csp++;  c--;
00127             do {
00128              *q++ = *(Bytef *)csp++;
00129             } while (--c);
00130           }
00131           break;
00132         }
00133         else if ((e & 64) == 0)
00134         {
00135           t += t->base;
00136           e = (t += ((uInt)b & inflate_mask[e]))->exop;
00137         }
00138         else
00139         {
00140           z->msg = (char*)"invalid distance code";
00141           UNGRAB
00142           UPDATE
00143           return Z_DATA_ERROR;
00144         }
00145        } while (1);
00146        break;
00147      }
00148      if ((e & 64) == 0)
00149      {
00150        t += t->base;
00151        if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
00152        {
00153         DUMPBITS(t->bits)
00154         Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
00155                 "inflate:         * literal '%c'\n" :
00156                 "inflate:         * literal 0x%02x\n", t->base));
00157         *q++ = (Byte)t->base;
00158         m--;
00159         break;
00160        }
00161      }
00162      else if (e & 32)
00163       {
00164         Tracevv((stderr, "inflate:         * end of block\n"));
00165         UNGRAB
00166         UPDATE
00167         return Z_STREAM_END;
00168       }
00169       else
00170       {
00171         z->msg = (char*)"invalid literal/length code";
00172         UNGRAB
00173         UPDATE
00174         return Z_DATA_ERROR;
00175       }
00176     } while (1);
00177   } while (m >= 258 && n >= 10);
00178 
00179   /* not enough input or output--restore pointers and return */
00180   UNGRAB
00181   UPDATE
00182   return Z_OK;
00183 }


Generated on 18 Mar 2013 for The SWORD Project by  doxygen 1.6.1