2N/A * Copyright (C) 1995-2008, 2010, 2013 Mark Adler 2N/A * For conditions of distribution and use, see copyright notice in zlib.h 2N/A/* Allow machine dependent optimization for post-increment or pre-increment. 2N/A Based on testing to date, 2N/A Pre-increment preferred for: 2N/A - PowerPC G3 (Adler) 2N/A - MIPS R5000 (Randers-Pehrson) 2N/A Post-increment preferred for: 2N/A No measurable difference: 59N/A - Pentium III (Anderson) 59N/A Decode literal, length, and distance codes and write out the resulting 2N/A literal and match bytes until either not enough input or output is 2N/A available, an end-of-block is encountered, or a data error is encountered. 2N/A When large enough input and output buffers are supplied to inflate(), for 2N/A example, a 16K input buffer and a 64K output buffer, more than 95% of the 26N/A inflate execution time is spent in this routine. 26N/A strm->avail_in >= 6 26N/A strm->avail_out >= 258 26N/A start >= strm->avail_out 26N/A On return, state->mode is one of: 26N/A LEN -- ran out of enough output space or enough available input 26N/A TYPE -- reached end of block code, inflate() to interpret next block 26N/A BAD -- error in block data 26N/A length code, 5 bits for the length extra, 15 bits for the distance code, 26N/A and 13 bits for the distance extra. This totals 48 bits, or six bytes. 26N/A Therefore if strm->avail_in >= 6, then there is enough input to avoid 26N/A checking for available input while decoding. 2N/A bytes, which is the maximum length that can be coded. inflate_fast() 26N/A requires strm->avail_out >= 258 for each loop to avoid checking for 26N/Aunsigned start;
/* inflate()'s starting value for strm->avail_out */ 26N/A unsigned char FAR *
out;
/* local strm->next_out */ 26N/A unsigned char FAR *
beg;
/* inflate()'s initial strm->next_out */ 26N/A unsigned char FAR *
end;
/* while out < end, enough space available */ 26N/A unsigned dmax;
/* maximum distance from zlib header */ 27N/A unsigned wsize;
/* window size or zero if not using window */ 27N/A unsigned whave;
/* valid bytes in the window */ 26N/A unsigned char FAR *
window;
/* allocated sliding window, if wsize != 0 */ 59N/A unsigned long hold;
/* local strm->hold */ 26N/A unsigned lmask;
/* mask for first level of length codes */ 26N/A unsigned dmask;
/* mask for first level of distance codes */ 26N/A unsigned op;
/* code bits, operation, extra bits, or */ 30N/A /* window position, window bytes to copy */ 26N/A unsigned len;
/* match length, unused bytes */ 2N/A unsigned dist;
/* match distance */ 7N/A unsigned char FAR *
from;
/* where to copy match from */ 27N/A /* copy state to local variables */ 46N/A input data or output space */ 53N/A "inflate: literal '%c'\n" :
2N/A else if (
op &
16) {
/* length base */ 38N/A op &=
15;
/* number of extra bits */ 32N/A if (
op &
16) {
/* distance base */ 32N/A op &=
15;
/* number of extra bits */ 32N/A (
char *)
"invalid distance too far back";
if (
wnext == 0) {
/* very common case */ if (
op <
len) {
/* some from window */ else if (
wnext <
op) {
/* wrap around window */ if (
op <
len) {
/* some from end of window */ if (
wnext <
len) {
/* some from start of window */ else {
/* contiguous in window */ if (
op <
len) {
/* some from window */ do {
/* minimum length is three */ else if ((
op &
64) == 0) {
/* 2nd level distance code */ strm->
msg = (
char *)
"invalid distance code";
else if ((
op &
64) == 0) {
/* 2nd level length code */ else if (
op &
32) {
/* end-of-block */ /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ /* update state and 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 wnext == 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