--- /dev/null
+/* inffast.c -- process literals and length/distance pairs fast\r
+ * Copyright (C) 1995-2002 Mark Adler\r
+ * For conditions of distribution and use, see copyright notice in zlib.h \r
+ */\r
+\r
+#include "zutil.h"\r
+#include "inftrees.h"\r
+#include "infblock.h"\r
+#include "infcodes.h"\r
+#include "infutil.h"\r
+#include "inffast.h"\r
+\r
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */\r
+\r
+/* simplify the use of the inflate_huft type with some defines */\r
+#define exop word.what.Exop\r
+#define bits word.what.Bits\r
+\r
+/* macros for bit input with no checking and for returning unused bytes */\r
+#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}\r
+#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}\r
+\r
+/* Called with number of bytes left to write in window at least 258\r
+ (the maximum string length) and number of input bytes available\r
+ at least ten. The ten bytes are six bytes for the longest length/\r
+ distance pair plus four bytes for overloading the bit buffer. */\r
+\r
+int inflate_fast(bl, bd, tl, td, s, z)\r
+uInt bl, bd;\r
+inflate_huft *tl;\r
+inflate_huft *td; /* need separate declaration for Borland C++ */\r
+inflate_blocks_statef *s;\r
+z_streamp z;\r
+{\r
+ inflate_huft *t; /* temporary pointer */\r
+ uInt e; /* extra bits or operation */\r
+ uLong b; /* bit buffer */\r
+ uInt k; /* bits in bit buffer */\r
+ Bytef *p; /* input data pointer */\r
+ uInt n; /* bytes available there */\r
+ Bytef *q; /* output window write pointer */\r
+ uInt m; /* bytes to end of window or read pointer */\r
+ uInt ml; /* mask for literal/length tree */\r
+ uInt md; /* mask for distance tree */\r
+ uInt c; /* bytes to copy */\r
+ uInt d; /* distance back to copy from */\r
+ Bytef *r; /* copy source pointer */\r
+\r
+ /* load input, output, bit values */\r
+ LOAD\r
+\r
+ /* initialize masks */\r
+ ml = inflate_mask[bl];\r
+ md = inflate_mask[bd];\r
+\r
+ /* do until not enough input or output space for fast loop */\r
+ do { /* assume called with m >= 258 && n >= 10 */\r
+ /* get literal/length code */\r
+ GRABBITS(20) /* max bits for literal/length code */\r
+ if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)\r
+ {\r
+ DUMPBITS(t->bits)\r
+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?\r
+ "inflate: * literal '%c'\n" :\r
+ "inflate: * literal 0x%02x\n", t->base));\r
+ *q++ = (Byte)t->base;\r
+ m--;\r
+ continue;\r
+ }\r
+ do {\r
+ DUMPBITS(t->bits)\r
+ if (e & 16)\r
+ {\r
+ /* get extra bits for length */\r
+ e &= 15;\r
+ c = t->base + ((uInt)b & inflate_mask[e]);\r
+ DUMPBITS(e)\r
+ Tracevv((stderr, "inflate: * length %u\n", c));\r
+\r
+ /* decode distance base of block to copy */\r
+ GRABBITS(15); /* max bits for distance code */\r
+ e = (t = td + ((uInt)b & md))->exop;\r
+ do {\r
+ DUMPBITS(t->bits)\r
+ if (e & 16)\r
+ {\r
+ /* get extra bits to add to distance base */\r
+ e &= 15;\r
+ GRABBITS(e) /* get extra bits (up to 13) */\r
+ d = t->base + ((uInt)b & inflate_mask[e]);\r
+ DUMPBITS(e)\r
+ Tracevv((stderr, "inflate: * distance %u\n", d));\r
+\r
+ /* do the copy */\r
+ m -= c;\r
+ r = q - d;\r
+ if (r < s->window) /* wrap if needed */\r
+ {\r
+ do {\r
+ r += s->end - s->window; /* force pointer in window */\r
+ } while (r < s->window); /* covers invalid distances */\r
+ e = s->end - r;\r
+ if (c > e)\r
+ {\r
+ c -= e; /* wrapped copy */\r
+ do {\r
+ *q++ = *r++;\r
+ } while (--e);\r
+ r = s->window;\r
+ do {\r
+ *q++ = *r++;\r
+ } while (--c);\r
+ }\r
+ else /* normal copy */\r
+ {\r
+ *q++ = *r++; c--;\r
+ *q++ = *r++; c--;\r
+ do {\r
+ *q++ = *r++;\r
+ } while (--c);\r
+ }\r
+ }\r
+ else /* normal copy */\r
+ {\r
+ *q++ = *r++; c--;\r
+ *q++ = *r++; c--;\r
+ do {\r
+ *q++ = *r++;\r
+ } while (--c);\r
+ }\r
+ break;\r
+ }\r
+ else if ((e & 64) == 0)\r
+ {\r
+ t += t->base;\r
+ e = (t += ((uInt)b & inflate_mask[e]))->exop;\r
+ }\r
+ else\r
+ {\r
+ z->msg = (char*)"invalid distance code";\r
+ UNGRAB\r
+ UPDATE\r
+ return Z_DATA_ERROR;\r
+ }\r
+ } while (1);\r
+ break;\r
+ }\r
+ if ((e & 64) == 0)\r
+ {\r
+ t += t->base;\r
+ if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)\r
+ {\r
+ DUMPBITS(t->bits)\r
+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?\r
+ "inflate: * literal '%c'\n" :\r
+ "inflate: * literal 0x%02x\n", t->base));\r
+ *q++ = (Byte)t->base;\r
+ m--;\r
+ break;\r
+ }\r
+ }\r
+ else if (e & 32)\r
+ {\r
+ Tracevv((stderr, "inflate: * end of block\n"));\r
+ UNGRAB\r
+ UPDATE\r
+ return Z_STREAM_END;\r
+ }\r
+ else\r
+ {\r
+ z->msg = (char*)"invalid literal/length code";\r
+ UNGRAB\r
+ UPDATE\r
+ return Z_DATA_ERROR;\r
+ }\r
+ } while (1);\r
+ } while (m >= 258 && n >= 10);\r
+\r
+ /* not enough input or output--restore pointers and return */\r
+ UNGRAB\r
+ UPDATE\r
+ return Z_OK;\r
+}\r