The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/lib/libz/inffast.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* $NetBSD: inffast.c,v 1.5 2003/03/18 20:00:48 mycroft Exp $ */
    2 
    3 /* inffast.c -- process literals and length/distance pairs fast
    4  * Copyright (C) 1995-2002 Mark Adler
    5  * For conditions of distribution and use, see copyright notice in zlib.h 
    6  */
    7 
    8 #include "zutil.h"
    9 #include "inftrees.h"
   10 #include "infblock.h"
   11 #include "infcodes.h"
   12 #include "infutil.h"
   13 #include "inffast.h"
   14 
   15 struct inflate_codes_state {int dummy;}; /* for buggy compilers */
   16 
   17 /* simplify the use of the inflate_huft type with some defines */
   18 #define exop word.what.Exop
   19 #define bits word.what.Bits
   20 
   21 /* macros for bit input with no checking and for returning unused bytes */
   22 #define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
   23 #define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
   24 
   25 /* Called with number of bytes left to write in window at least 258
   26    (the maximum string length) and number of input bytes available
   27    at least ten.  The ten bytes are six bytes for the longest length/
   28    distance pair plus four bytes for overloading the bit buffer. */
   29 
   30 int inflate_fast(bl, bd, tl, td, s, z)
   31 uInt bl, bd;
   32 const inflate_huft *tl;
   33 const inflate_huft *td; /* need separate declaration for Borland C++ */
   34 inflate_blocks_statef *s;
   35 z_streamp z;
   36 {
   37   const inflate_huft *t;/* temporary pointer */
   38   uInt e;               /* extra bits or operation */
   39   uLong b;              /* bit buffer */
   40   uInt k;               /* bits in bit buffer */
   41   Bytef *p;             /* input data pointer */
   42   uInt n;               /* bytes available there */
   43   Bytef *q;             /* output window write pointer */
   44   uInt m;               /* bytes to end of window or read pointer */
   45   uInt ml;              /* mask for literal/length tree */
   46   uInt md;              /* mask for distance tree */
   47   uInt c;               /* bytes to copy */
   48   uInt d;               /* distance back to copy from */
   49   Bytef *r;             /* copy source pointer */
   50 
   51   /* load input, output, bit values */
   52   LOAD
   53 
   54   /* initialize masks */
   55   ml = inflate_mask[bl];
   56   md = inflate_mask[bd];
   57 
   58   /* do until not enough input or output space for fast loop */
   59   do {                          /* assume called with m >= 258 && n >= 10 */
   60     /* get literal/length code */
   61     GRABBITS(20)                /* max bits for literal/length code */
   62     if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
   63     {
   64       DUMPBITS(t->bits)
   65       Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
   66                 "inflate:         * literal '%c'\n" :
   67                 "inflate:         * literal 0x%02x\n", t->base));
   68       *q++ = (Byte)t->base;
   69       m--;
   70       continue;
   71     }
   72     do {
   73       DUMPBITS(t->bits)
   74       if (e & 16)
   75       {
   76         /* get extra bits for length */
   77         e &= 15;
   78         c = t->base + ((uInt)b & inflate_mask[e]);
   79         DUMPBITS(e)
   80         Tracevv((stderr, "inflate:         * length %u\n", c));
   81 
   82         /* decode distance base of block to copy */
   83         GRABBITS(15);           /* max bits for distance code */
   84         e = (t = td + ((uInt)b & md))->exop;
   85         do {
   86           DUMPBITS(t->bits)
   87           if (e & 16)
   88           {
   89             /* get extra bits to add to distance base */
   90             e &= 15;
   91             GRABBITS(e)         /* get extra bits (up to 13) */
   92             d = t->base + ((uInt)b & inflate_mask[e]);
   93             DUMPBITS(e)
   94             Tracevv((stderr, "inflate:         * distance %u\n", d));
   95 
   96             /* do the copy */
   97             m -= c;
   98             r = q - d;
   99             if (r < s->window)                  /* wrap if needed */
  100             {
  101               do {
  102                 r += s->end - s->window;        /* force pointer in window */
  103               } while (r < s->window);          /* covers invalid distances */
  104               e = s->end - r;
  105               if (c > e)
  106               {
  107                 c -= e;                         /* wrapped copy */
  108                 do {
  109                     *q++ = *r++;
  110                 } while (--e);
  111                 r = s->window;
  112                 do {
  113                     *q++ = *r++;
  114                 } while (--c);
  115               }
  116               else                              /* normal copy */
  117               {
  118                 *q++ = *r++;  c--;
  119                 *q++ = *r++;  c--;
  120                 do {
  121                     *q++ = *r++;
  122                 } while (--c);
  123               }
  124             }
  125             else                                /* normal copy */
  126             {
  127               *q++ = *r++;  c--;
  128               *q++ = *r++;  c--;
  129               do {
  130                 *q++ = *r++;
  131               } while (--c);
  132             }
  133             break;
  134           }
  135           else if ((e & 64) == 0)
  136           {
  137             t += t->base;
  138             e = (t += ((uInt)b & inflate_mask[e]))->exop;
  139           }
  140           else
  141           {
  142             z->msg = (char*)"invalid distance code";
  143             UNGRAB
  144             UPDATE
  145             return Z_DATA_ERROR;
  146           }
  147         } while (1);
  148         break;
  149       }
  150       if ((e & 64) == 0)
  151       {
  152         t += t->base;
  153         if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
  154         {
  155           DUMPBITS(t->bits)
  156           Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
  157                     "inflate:         * literal '%c'\n" :
  158                     "inflate:         * literal 0x%02x\n", t->base));
  159           *q++ = (Byte)t->base;
  160           m--;
  161           break;
  162         }
  163       }
  164       else if (e & 32)
  165       {
  166         Tracevv((stderr, "inflate:         * end of block\n"));
  167         UNGRAB
  168         UPDATE
  169         return Z_STREAM_END;
  170       }
  171       else
  172       {
  173         z->msg = (char*)"invalid literal/length code";
  174         UNGRAB
  175         UPDATE
  176         return Z_DATA_ERROR;
  177       }
  178     } while (1);
  179   } while (m >= 258 && n >= 10);
  180 
  181   /* not enough input or output--restore pointers and return */
  182   UNGRAB
  183   UPDATE
  184   return Z_OK;
  185 }

Cache object: a2bfb836e96f5d284080bd79d662273d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.