12# pragma message("Assembler code may have bugs -- use at your own risk")
50void ZLIB_INTERNAL inflate_fast(z_streamp strm,
unsigned start) {
52 z_const
unsigned char FAR *in;
53 z_const
unsigned char FAR *last;
54 unsigned char FAR *out;
55 unsigned char FAR *beg;
56 unsigned char FAR *end;
63 unsigned char FAR *window;
66 code const FAR *lcode;
67 code const FAR *dcode;
75 unsigned char FAR *from;
80 last = in + (strm->avail_in - 5);
82 beg = out - (start - strm->avail_out);
83 end = out + (strm->avail_out - 257);
90 window = state->window;
93 lcode = state->lencode;
94 dcode = state->distcode;
95 lmask = (1U << state->lenbits) - 1;
96 dmask = (1U << state->distbits) - 1;
102 hold += (
unsigned long)(*in++) << bits;
104 hold += (
unsigned long)(*in++) << bits;
107 here = lcode + (hold & lmask);
109 op = (unsigned)(here->bits);
112 op = (unsigned)(here->op);
114 Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ?
115 "inflate: literal '%c'\n" :
116 "inflate: literal 0x%02x\n", here->val));
117 *out++ = (
unsigned char)(here->val);
120 len = (unsigned)(here->val);
124 hold += (
unsigned long)(*in++) << bits;
127 len += (unsigned)hold & ((1U << op) - 1);
131 Tracevv((stderr,
"inflate: length %u\n", len));
133 hold += (
unsigned long)(*in++) << bits;
135 hold += (
unsigned long)(*in++) << bits;
138 here = dcode + (hold & dmask);
140 op = (unsigned)(here->bits);
143 op = (unsigned)(here->op);
145 dist = (unsigned)(here->val);
148 hold += (
unsigned long)(*in++) << bits;
151 hold += (
unsigned long)(*in++) << bits;
155 dist += (unsigned)hold & ((1U << op) - 1);
158 strm->msg = (
char *)
"invalid distance too far back";
165 Tracevv((stderr,
"inflate: distance %u\n", dist));
166 op = (unsigned)(out - beg);
172 (
char *)
"invalid distance too far back";
176#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
177 if (len <= op - whave) {
186 }
while (--op > whave);
207 else if (wnext < op) {
208 from += wsize + wnext - op;
263 else if ((op & 64) == 0) {
264 here = dcode + here->val + (hold & ((1U << op) - 1));
268 strm->msg = (
char *)
"invalid distance code";
273 else if ((op & 64) == 0) {
274 here = lcode + here->val + (hold & ((1U << op) - 1));
278 Tracevv((stderr,
"inflate: end of block\n"));
283 strm->msg = (
char *)
"invalid literal/length code";
287 }
while (in < last && out < end);
293 hold &= (1U << bits) - 1;
297 strm->next_out = out;
298 strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
299 strm->avail_out = (unsigned)(out < end ?
300 257 + (end - out) : 257 - (out - end));