1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/compressionlibs/ziplib/test/oldezlib/Zlib/inffast.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,166 @@
1.4 +/* inffast.c -- process literals and length/distance pairs fast
1.5 + * Copyright (C) 1995-1998 Mark Adler
1.6 + * For conditions of distribution and use, see copyright notice in zlib.h
1.7 + */
1.8 +
1.9 +#include "zutil.h"
1.10 +#include "inftrees.h"
1.11 +#include "infblock.h"
1.12 +#include "infcodes.h"
1.13 +#include "infutil.h"
1.14 +#include "inffast.h"
1.15 +
1.16 +struct inflate_codes_state {int dummy;}; /* for buggy compilers */
1.17 +
1.18 +/* simplify the use of the inflate_huft type with some defines */
1.19 +#define exop word.what.Exop
1.20 +#define bits word.what.Bits
1.21 +
1.22 +/* macros for bit input with no checking and for returning unused bytes */
1.23 +#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
1.24 +#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
1.25 +
1.26 +/* Called with number of bytes left to write in window at least 258
1.27 + (the maximum string length) and number of input bytes available
1.28 + at least ten. The ten bytes are six bytes for the longest length/
1.29 + distance pair plus four bytes for overloading the bit buffer. */
1.30 +
1.31 +int inflate_fast(uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, inflate_blocks_statef *s, z_streamp z)
1.32 +/* inflate_huft *td need separate declaration for Borland C++ */
1.33 +{
1.34 + inflate_huft *t; /* temporary pointer */
1.35 + uInt e; /* extra bits or operation */
1.36 + uLong b; /* bit buffer */
1.37 + uInt k; /* bits in bit buffer */
1.38 + Bytef *p; /* input data pointer */
1.39 + uInt n; /* bytes available there */
1.40 + Bytef *q; /* output window write pointer */
1.41 + uInt m; /* bytes to end of window or read pointer */
1.42 + uInt ml; /* mask for literal/length tree */
1.43 + uInt md; /* mask for distance tree */
1.44 + uInt c; /* bytes to copy */
1.45 + uInt d; /* distance back to copy from */
1.46 + Bytef *r; /* copy source pointer */
1.47 +
1.48 + /* load input, output, bit values */
1.49 + LOAD
1.50 +
1.51 + /* initialize masks */
1.52 + ml = inflate_mask[bl];
1.53 + md = inflate_mask[bd];
1.54 +
1.55 + /* do until not enough input or output space for fast loop */
1.56 + do { /* assume called with m >= 258 && n >= 10 */
1.57 + /* get literal/length code */
1.58 + GRABBITS(20) /* max bits for literal/length code */
1.59 + if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
1.60 + {
1.61 + DUMPBITS(t->bits)
1.62 + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
1.63 + "inflate: * literal '%c'\n" :
1.64 + "inflate: * literal 0x%02x\n", t->base));
1.65 + *q++ = (Byte)t->base;
1.66 + m--;
1.67 + continue;
1.68 + }
1.69 + do {
1.70 + DUMPBITS(t->bits)
1.71 + if (e & 16)
1.72 + {
1.73 + /* get extra bits for length */
1.74 + e &= 15;
1.75 + c = t->base + ((uInt)b & inflate_mask[e]);
1.76 + DUMPBITS(e)
1.77 + Tracevv((stderr, "inflate: * length %u\n", c));
1.78 +
1.79 + /* decode distance base of block to copy */
1.80 + GRABBITS(15); /* max bits for distance code */
1.81 + e = (t = td + ((uInt)b & md))->exop;
1.82 + do {
1.83 + DUMPBITS(t->bits)
1.84 + if (e & 16)
1.85 + {
1.86 + /* get extra bits to add to distance base */
1.87 + e &= 15;
1.88 + GRABBITS(e) /* get extra bits (up to 13) */
1.89 + d = t->base + ((uInt)b & inflate_mask[e]);
1.90 + DUMPBITS(e)
1.91 + Tracevv((stderr, "inflate: * distance %u\n", d));
1.92 +
1.93 + /* do the copy */
1.94 + m -= c;
1.95 + if ((uInt)(q - s->window) >= d) /* offset before dest */
1.96 + { /* just copy */
1.97 + r = q - d;
1.98 + *q++ = *r++; c--; /* minimum count is three, */
1.99 + *q++ = *r++; c--; /* so unroll loop a little */
1.100 + }
1.101 + else /* else offset after destination */
1.102 + {
1.103 + e = d - (uInt)(q - s->window); /* bytes from offset to end */
1.104 + r = s->end - e; /* pointer to offset */
1.105 + if (c > e) /* if source crosses, */
1.106 + {
1.107 + c -= e; /* copy to end of window */
1.108 + do {
1.109 + *q++ = *r++;
1.110 + } while (--e);
1.111 + r = s->window; /* copy rest from start of window */
1.112 + }
1.113 + }
1.114 + do { /* copy all or what's left */
1.115 + *q++ = *r++;
1.116 + } while (--c);
1.117 + break;
1.118 + }
1.119 + else if ((e & 64) == 0)
1.120 + {
1.121 + t += t->base;
1.122 + e = (t += ((uInt)b & inflate_mask[e]))->exop;
1.123 + }
1.124 + else
1.125 + {
1.126 + z->msg = (char*)"invalid distance code";
1.127 + UNGRAB
1.128 + UPDATE
1.129 + return Z_DATA_ERROR;
1.130 + }
1.131 + } while (1);
1.132 + break;
1.133 + }
1.134 + if ((e & 64) == 0)
1.135 + {
1.136 + t += t->base;
1.137 + if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
1.138 + {
1.139 + DUMPBITS(t->bits)
1.140 + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
1.141 + "inflate: * literal '%c'\n" :
1.142 + "inflate: * literal 0x%02x\n", t->base));
1.143 + *q++ = (Byte)t->base;
1.144 + m--;
1.145 + break;
1.146 + }
1.147 + }
1.148 + else if (e & 32)
1.149 + {
1.150 + Tracevv((stderr, "inflate: * end of block\n"));
1.151 + UNGRAB
1.152 + UPDATE
1.153 + return Z_STREAM_END;
1.154 + }
1.155 + else
1.156 + {
1.157 + z->msg = (char*)"invalid literal/length code";
1.158 + UNGRAB
1.159 + UPDATE
1.160 + return Z_DATA_ERROR;
1.161 + }
1.162 + } while (1);
1.163 + } while (m >= 258 && n >= 10);
1.164 +
1.165 + /* not enough input or output--restore pointers and return */
1.166 + UNGRAB
1.167 + UPDATE
1.168 + return Z_OK;
1.169 +}