/* inffast.c -- fast decoding
* Copyright (C) 1995-2004 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#include "zutil.h"
#include "inftrees.h"
#include "inflate.h"
#include "inffast.h"
#ifndef ASMINF
/* Allow machine dependent optimization for post-increment or pre-increment.
Based on testing to date,
Pre-increment preferred for:
- PowerPC G3 (Adler)
- MIPS R5000 (Randers-Pehrson)
Post-increment preferred for:
- none
No measurable difference:
- Pentium III (Anderson)
- M68060 (Nikl)
*/
#ifdef POSTINC
# define OFF 0
# define PUP(a) *(a)++
#else
# define PUP(a) *++(a)
#endif
/*
Decode literal, length, and distance codes and write out the resulting
literal and match bytes until either not enough input or output is
available, an end-of-block is encountered, or a data error is encountered.
When large enough input and output buffers are supplied to inflate(), for
example, a 16K input buffer and a 64K output buffer, more than 95% of the
inflate execution time is spent in this routine.
Entry assumptions:
state->mode == LEN
strm->avail_in >= 6
strm->avail_out >= 258
start >= strm->avail_out
state->bits < 8
On return, state->mode is one of:
LEN -- ran out of enough output space or enough available input
TYPE -- reached end of block code, inflate() to interpret next block
BAD -- error in block data
Notes:
length code, 5 bits for the length extra, 15 bits for the distance code,
and 13 bits for the distance extra. This totals 48 bits, or six bytes.
Therefore if strm->avail_in >= 6, then there is enough input to avoid
checking for available input while decoding.
bytes, which is the maximum length that can be coded. inflate_fast()
requires strm->avail_out >= 258 for each loop to avoid checking for
output space.
*/
unsigned start; /* inflate()'s starting value for strm->avail_out */
{
#ifdef INFLATE_STRICT
#endif
/* window position, window bytes to copy */
/* copy state to local variables */
#ifdef INFLATE_STRICT
#endif
input data or output space */
do {
if (bits < 15) {
bits += 8;
bits += 8;
}
if (op == 0) { /* literal */
"inflate: literal '%c'\n" :
}
if (op) {
bits += 8;
}
}
if (bits < 15) {
bits += 8;
bits += 8;
}
bits += 8;
bits += 8;
}
}
#ifdef INFLATE_STRICT
break;
}
#endif
break;
}
if (write == 0) { /* very common case */
do {
} while (--op);
}
}
do {
} while (--op);
do {
} while (--op);
}
}
}
else { /* contiguous in window */
do {
} while (--op);
}
}
while (len > 2) {
len -= 3;
}
if (len) {
if (len > 1)
}
}
else {
do { /* minimum length is three */
len -= 3;
} while (len > 2);
if (len) {
if (len > 1)
}
}
}
goto dodist;
}
else {
break;
}
}
goto dolen;
}
break;
}
else {
break;
}
/* return unused bytes (on entry, bits < 8, so in won't go too far back) */
/* update state and return */
return;
}
/*
inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
- Using bit fields for code structure
- Different op definition to avoid & for extra bits (do & for table bits)
- Three separate decoding do-loops for direct, window, and write == 0
- Special case for distance > 1 copies to do overlapped load and store copy
- Explicit branch predictions (based on measured branch probabilities)
- Deferring match copy and interspersed it with decoding subsequent codes
- Larger unrolled copy loops (three is about right)
- Moving len -= 3 statement into middle of loop
*/
#endif /* !ASMINF */