1 /* inffast.c -- fast decoding 2 * Copyright (C) 1995-2017 Mark Adler 3 * For conditions of distribution and use, see copyright notice in zlib.h 4 */ 5 6 #include "zutil.h" 7 #include "inftrees.h" 8 #include "inflate.h" 9 #include "inffast.h" 10 11 #ifdef ASMINF 12 # pragma message("Assembler code may have bugs -- use at your own risk") 13 #else 14 15 /* 16 Decode literal, length, and distance codes and write out the resulting 17 literal and match bytes until either not enough input or output is 18 available, an end-of-block is encountered, or a data error is encountered. 19 When large enough input and output buffers are supplied to inflate(), for 20 example, a 16K input buffer and a 64K output buffer, more than 95% of the 21 inflate execution time is spent in this routine. 22 23 Entry assumptions: 24 25 state->mode == LEN 26 strm->avail_in >= 6 27 strm->avail_out >= 258 28 start >= strm->avail_out 29 state->bits < 8 30 31 On return, state->mode is one of: 32 33 LEN -- ran out of enough output space or enough available input 34 TYPE -- reached end of block code, inflate() to interpret next block 35 BAD -- error in block data 36 37 Notes: 38 39 - The maximum input bits used by a length/distance pair is 15 bits for the 40 length code, 5 bits for the length extra, 15 bits for the distance code, 41 and 13 bits for the distance extra. This totals 48 bits, or six bytes. 42 Therefore if strm->avail_in >= 6, then there is enough input to avoid 43 checking for available input while decoding. 44 45 - The maximum bytes that a single length/distance pair can output is 258 46 bytes, which is the maximum length that can be coded. inflate_fast() 47 requires strm->avail_out >= 258 for each loop to avoid checking for 48 output space. 49 */ 50 void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start) { 51 struct inflate_state FAR *state; 52 z_const unsigned char FAR *in; /* local strm->next_in */ 53 z_const unsigned char FAR *last; /* have enough input while in < last */ 54 unsigned char FAR *out; /* local strm->next_out */ 55 unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ 56 unsigned char FAR *end; /* while out < end, enough space available */ 57 #ifdef INFLATE_STRICT 58 unsigned dmax; /* maximum distance from zlib header */ 59 #endif 60 unsigned wsize; /* window size or zero if not using window */ 61 unsigned whave; /* valid bytes in the window */ 62 unsigned wnext; /* window write index */ 63 unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ 64 unsigned long hold; /* local strm->hold */ 65 unsigned bits; /* local strm->bits */ 66 code const FAR *lcode; /* local strm->lencode */ 67 code const FAR *dcode; /* local strm->distcode */ 68 unsigned lmask; /* mask for first level of length codes */ 69 unsigned dmask; /* mask for first level of distance codes */ 70 code const *here; /* retrieved table entry */ 71 unsigned op; /* code bits, operation, extra bits, or */ 72 /* window position, window bytes to copy */ 73 unsigned len; /* match length, unused bytes */ 74 unsigned dist; /* match distance */ 75 unsigned char FAR *from; /* where to copy match from */ 76 77 /* copy state to local variables */ 78 state = (struct inflate_state FAR *)strm->state; 79 in = strm->next_in; 80 last = in + (strm->avail_in - 5); 81 out = strm->next_out; 82 beg = out - (start - strm->avail_out); 83 end = out + (strm->avail_out - 257); 84 #ifdef INFLATE_STRICT 85 dmax = state->dmax; 86 #endif 87 wsize = state->wsize; 88 whave = state->whave; 89 wnext = state->wnext; 90 window = state->window; 91 hold = state->hold; 92 bits = state->bits; 93 lcode = state->lencode; 94 dcode = state->distcode; 95 lmask = (1U << state->lenbits) - 1; 96 dmask = (1U << state->distbits) - 1; 97 98 /* decode literals and length/distances until end-of-block or not enough 99 input data or output space */ 100 do { 101 if (bits < 15) { 102 hold += (unsigned long)(*in++) << bits; 103 bits += 8; 104 hold += (unsigned long)(*in++) << bits; 105 bits += 8; 106 } 107 here = lcode + (hold & lmask); 108 dolen: 109 op = (unsigned)(here->bits); 110 hold >>= op; 111 bits -= op; 112 op = (unsigned)(here->op); 113 if (op == 0) { /* literal */ 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); 118 } 119 else if (op & 16) { /* length base */ 120 len = (unsigned)(here->val); 121 op &= 15; /* number of extra bits */ 122 if (op) { 123 if (bits < op) { 124 hold += (unsigned long)(*in++) << bits; 125 bits += 8; 126 } 127 len += (unsigned)hold & ((1U << op) - 1); 128 hold >>= op; 129 bits -= op; 130 } 131 Tracevv((stderr, "inflate: length %u\n", len)); 132 if (bits < 15) { 133 hold += (unsigned long)(*in++) << bits; 134 bits += 8; 135 hold += (unsigned long)(*in++) << bits; 136 bits += 8; 137 } 138 here = dcode + (hold & dmask); 139 dodist: 140 op = (unsigned)(here->bits); 141 hold >>= op; 142 bits -= op; 143 op = (unsigned)(here->op); 144 if (op & 16) { /* distance base */ 145 dist = (unsigned)(here->val); 146 op &= 15; /* number of extra bits */ 147 if (bits < op) { 148 hold += (unsigned long)(*in++) << bits; 149 bits += 8; 150 if (bits < op) { 151 hold += (unsigned long)(*in++) << bits; 152 bits += 8; 153 } 154 } 155 dist += (unsigned)hold & ((1U << op) - 1); 156 #ifdef INFLATE_STRICT 157 if (dist > dmax) { 158 strm->msg = (char *)"invalid distance too far back"; 159 state->mode = BAD; 160 break; 161 } 162 #endif 163 hold >>= op; 164 bits -= op; 165 Tracevv((stderr, "inflate: distance %u\n", dist)); 166 op = (unsigned)(out - beg); /* max distance in output */ 167 if (dist > op) { /* see if copy from window */ 168 op = dist - op; /* distance back in window */ 169 if (op > whave) { 170 if (state->sane) { 171 strm->msg = 172 (char *)"invalid distance too far back"; 173 state->mode = BAD; 174 break; 175 } 176 #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR 177 if (len <= op - whave) { 178 do { 179 *out++ = 0; 180 } while (--len); 181 continue; 182 } 183 len -= op - whave; 184 do { 185 *out++ = 0; 186 } while (--op > whave); 187 if (op == 0) { 188 from = out - dist; 189 do { 190 *out++ = *from++; 191 } while (--len); 192 continue; 193 } 194 #endif 195 } 196 from = window; 197 if (wnext == 0) { /* very common case */ 198 from += wsize - op; 199 if (op < len) { /* some from window */ 200 len -= op; 201 do { 202 *out++ = *from++; 203 } while (--op); 204 from = out - dist; /* rest from output */ 205 } 206 } 207 else if (wnext < op) { /* wrap around window */ 208 from += wsize + wnext - op; 209 op -= wnext; 210 if (op < len) { /* some from end of window */ 211 len -= op; 212 do { 213 *out++ = *from++; 214 } while (--op); 215 from = window; 216 if (wnext < len) { /* some from start of window */ 217 op = wnext; 218 len -= op; 219 do { 220 *out++ = *from++; 221 } while (--op); 222 from = out - dist; /* rest from output */ 223 } 224 } 225 } 226 else { /* contiguous in window */ 227 from += wnext - op; 228 if (op < len) { /* some from window */ 229 len -= op; 230 do { 231 *out++ = *from++; 232 } while (--op); 233 from = out - dist; /* rest from output */ 234 } 235 } 236 while (len > 2) { 237 *out++ = *from++; 238 *out++ = *from++; 239 *out++ = *from++; 240 len -= 3; 241 } 242 if (len) { 243 *out++ = *from++; 244 if (len > 1) 245 *out++ = *from++; 246 } 247 } 248 else { 249 from = out - dist; /* copy direct from output */ 250 do { /* minimum length is three */ 251 *out++ = *from++; 252 *out++ = *from++; 253 *out++ = *from++; 254 len -= 3; 255 } while (len > 2); 256 if (len) { 257 *out++ = *from++; 258 if (len > 1) 259 *out++ = *from++; 260 } 261 } 262 } 263 else if ((op & 64) == 0) { /* 2nd level distance code */ 264 here = dcode + here->val + (hold & ((1U << op) - 1)); 265 goto dodist; 266 } 267 else { 268 strm->msg = (char *)"invalid distance code"; 269 state->mode = BAD; 270 break; 271 } 272 } 273 else if ((op & 64) == 0) { /* 2nd level length code */ 274 here = lcode + here->val + (hold & ((1U << op) - 1)); 275 goto dolen; 276 } 277 else if (op & 32) { /* end-of-block */ 278 Tracevv((stderr, "inflate: end of block\n")); 279 state->mode = TYPE; 280 break; 281 } 282 else { 283 strm->msg = (char *)"invalid literal/length code"; 284 state->mode = BAD; 285 break; 286 } 287 } while (in < last && out < end); 288 289 /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ 290 len = bits >> 3; 291 in -= len; 292 bits -= len << 3; 293 hold &= (1U << bits) - 1; 294 295 /* update state and return */ 296 strm->next_in = in; 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)); 301 state->hold = hold; 302 state->bits = bits; 303 return; 304 } 305 306 /* 307 inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): 308 - Using bit fields for code structure 309 - Different op definition to avoid & for extra bits (do & for table bits) 310 - Three separate decoding do-loops for direct, window, and wnext == 0 311 - Special case for distance > 1 copies to do overlapped load and store copy 312 - Explicit branch predictions (based on measured branch probabilities) 313 - Deferring match copy and interspersed it with decoding subsequent codes 314 - Swapping literal/length else 315 - Swapping window/direct else 316 - Larger unrolled copy loops (three is about right) 317 - Moving len -= 3 statement into middle of loop 318 */ 319 320 #endif /* !ASMINF */ 321