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