From 6b834a58bdef976383cff6e2a83f353e668a9cf1 Mon Sep 17 00:00:00 2001 From: Mark Adler Date: Fri, 9 Sep 2011 23:08:28 -0700 Subject: zlib 0.93 --- inffast.c | 155 +++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 82 insertions(+), 73 deletions(-) (limited to 'inffast.c') diff --git a/inffast.c b/inffast.c index 2fd707e..49ed1df 100644 --- a/inffast.c +++ b/inffast.c @@ -17,10 +17,6 @@ struct inflate_codes_state {int dummy;}; /* for buggy compilers */ #define bits word.what.Bits /* macros for bit input with no checking and for returning unused bytes */ -#ifdef DEBUG -# undef NEXTBYTE -# define NEXTBYTE (n--?0:fprintf(stderr,"inffast underrun\n"),*p++) -#endif #define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<>3);p-=c;k&=7;} @@ -36,7 +32,7 @@ struct inflate_blocks_state *s; z_stream *z; { inflate_huft *t; /* temporary pointer */ - int e; /* extra bits or operation */ + uInt e; /* extra bits or operation */ uLong b; /* bit buffer */ uInt k; /* bits in bit buffer */ Byte *p; /* input data pointer */ @@ -52,7 +48,7 @@ z_stream *z; /* load input, output, bit values */ LOAD - /* initialize masks in registers */ + /* initialize masks */ ml = inflate_mask[bl]; md = inflate_mask[bd]; @@ -60,93 +56,106 @@ z_stream *z; do { /* assume called with m >= 258 && n >= 10 */ /* get literal/length code */ GRABBITS(20) /* max bits for literal/length code */ - if ((e = (t = tl + ((uInt)b & ml))->exop) < 0) - do { - if (e == -128) - { - z->msg = "invalid literal/length code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - DUMPBITS(t->bits) - e = -e; - if (e & 64) /* end of block */ - { - Tracevv((stderr, "inflate: * end of block\n")); - UNGRAB - UPDATE - return Z_STREAM_END; - } - } while ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) < 0); - DUMPBITS(t->bits) - - /* process literal or length (end of block already trapped) */ - if (e & 16) /* then it's a literal */ + if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) { + DUMPBITS(t->bits) Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? "inflate: * literal '%c'\n" : "inflate: * literal 0x%02x\n", t->base)); *q++ = (Byte)t->base; m--; + continue; } - else /* it's a length */ - { - /* get length of block to copy (already have extra bits) */ - c = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e); - Tracevv((stderr, "inflate: * length %u\n", c)); + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits for length */ + e &= 15; + c = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv((stderr, "inflate: * length %u\n", c)); - /* decode distance base of block to copy */ - GRABBITS(15); /* max bits for distance code */ - if ((e = (t = td + ((uInt)b & md))->exop) < 0) + /* decode distance base of block to copy */ + GRABBITS(15); /* max bits for distance code */ + e = (t = td + ((uInt)b & md))->exop; do { - if (e == -128) + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits to add to distance base */ + e &= 15; + GRABBITS(e) /* get extra bits (up to 13) */ + d = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv((stderr, "inflate: * distance %u\n", d)); + + /* do the copy */ + m -= c; + if ((uInt)(q - s->window) >= d) /* offset before dest */ + { /* just copy */ + r = q - d; + *q++ = *r++; c--; /* minimum count is three, */ + *q++ = *r++; c--; /* so unroll loop a little */ + } + else /* else offset after destination */ + { + e = d - (q - s->window); /* bytes from offset to end */ + r = s->end - e; /* pointer to offset */ + if (c > e) /* if source crosses, */ + { + c -= e; /* copy to end of window */ + do { + *q++ = *r++; + } while (--e); + r = s->window; /* copy rest from start of window */ + } + } + do { /* copy all or what's left */ + *q++ = *r++; + } while (--c); + break; + } + else if ((e & 64) == 0) + e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; + else { z->msg = "invalid distance code"; UNGRAB UPDATE return Z_DATA_ERROR; } - DUMPBITS(t->bits) - e = -e; - } while ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) < 0); - DUMPBITS(t->bits) - - /* get extra bits to add to distance base */ - GRABBITS((uInt)e) /* get extra bits (up to 13) */ - d = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv((stderr, "inflate: * distance %u\n", d)); - - /* do the copy */ - m -= c; - if ((uInt)(q - s->window) >= d) /* if offset before destination, */ - { /* just copy */ - r = q - d; - *q++ = *r++; c--; /* minimum count is three, */ - *q++ = *r++; c--; /* so unroll loop a little */ - do { - *q++ = *r++; - } while (--c); + } while (1); + break; } - else /* else offset after destination */ + if ((e & 64) == 0) { - e = d - (q - s->window); /* bytes from offset to end */ - r = s->end - e; /* pointer to offset */ - if (c > (uInt)e) /* if source crosses, */ + if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0) { - c -= e; /* copy to end of window */ - do { - *q++ = *r++; - } while (--e); - r = s->window; /* copy rest from start of window */ + DUMPBITS(t->bits) + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + break; } - do { /* copy all or what's left */ - *q++ = *r++; - } while (--c); } - } + else if (e & 32) + { + Tracevv((stderr, "inflate: * end of block\n")); + UNGRAB + UPDATE + return Z_STREAM_END; + } + else + { + z->msg = "invalid literal/length code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); } while (m >= 258 && n >= 10); /* not enough input or output--restore pointers and return */ -- cgit v1.2.3-55-g6feb