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 = (z_const 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 #ifdef SMALL 172 strm->msg = (z_const char *)"error"; 173 #else 174 strm->msg = 175 (z_const char *)"invalid distance too far back"; 176 #endif 177 state->mode = BAD; 178 break; 179 } 180 #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR 181 if (len <= op - whave) { 182 do { 183 *out++ = 0; 184 } while (--len); 185 continue; 186 } 187 len -= op - whave; 188 do { 189 *out++ = 0; 190 } while (--op > whave); 191 if (op == 0) { 192 from = out - dist; 193 do { 194 *out++ = *from++; 195 } while (--len); 196 continue; 197 } 198 #endif 199 } 200 from = window; 201 if (wnext == 0) { /* very common case */ 202 from += wsize - op; 203 if (op < len) { /* some from window */ 204 len -= op; 205 do { 206 *out++ = *from++; 207 } while (--op); 208 from = out - dist; /* rest from output */ 209 } 210 } 211 else if (wnext < op) { /* wrap around window */ 212 from += wsize + wnext - op; 213 op -= wnext; 214 if (op < len) { /* some from end of window */ 215 len -= op; 216 do { 217 *out++ = *from++; 218 } while (--op); 219 from = window; 220 if (wnext < len) { /* some from start of window */ 221 op = wnext; 222 len -= op; 223 do { 224 *out++ = *from++; 225 } while (--op); 226 from = out - dist; /* rest from output */ 227 } 228 } 229 } 230 else { /* contiguous in window */ 231 from += wnext - op; 232 if (op < len) { /* some from window */ 233 len -= op; 234 do { 235 *out++ = *from++; 236 } while (--op); 237 from = out - dist; /* rest from output */ 238 } 239 } 240 while (len > 2) { 241 *out++ = *from++; 242 *out++ = *from++; 243 *out++ = *from++; 244 len -= 3; 245 } 246 if (len) { 247 *out++ = *from++; 248 if (len > 1) 249 *out++ = *from++; 250 } 251 } 252 else { 253 from = out - dist; /* copy direct from output */ 254 do { /* minimum length is three */ 255 *out++ = *from++; 256 *out++ = *from++; 257 *out++ = *from++; 258 len -= 3; 259 } while (len > 2); 260 if (len) { 261 *out++ = *from++; 262 if (len > 1) 263 *out++ = *from++; 264 } 265 } 266 } 267 else if ((op & 64) == 0) { /* 2nd level distance code */ 268 here = dcode + here->val + (hold & ((1U << op) - 1)); 269 goto dodist; 270 } 271 else { 272 #ifdef SMALL 273 strm->msg = (z_const char *)"error"; 274 #else 275 strm->msg = (z_const char *)"invalid distance code"; 276 #endif 277 state->mode = BAD; 278 break; 279 } 280 } 281 else if ((op & 64) == 0) { /* 2nd level length code */ 282 here = lcode + here->val + (hold & ((1U << op) - 1)); 283 goto dolen; 284 } 285 else if (op & 32) { /* end-of-block */ 286 Tracevv((stderr, "inflate: end of block\n")); 287 state->mode = TYPE; 288 break; 289 } 290 else { 291 #ifdef SMALL 292 strm->msg = (z_const char *)"error"; 293 #else 294 strm->msg = (z_const char *)"invalid literal/length code"; 295 #endif 296 state->mode = BAD; 297 break; 298 } 299 } while (in < last && out < end); 300 301 /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ 302 len = bits >> 3; 303 in -= len; 304 bits -= len << 3; 305 hold &= (1U << bits) - 1; 306 307 /* update state and return */ 308 strm->next_in = in; 309 strm->next_out = out; 310 strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); 311 strm->avail_out = (unsigned)(out < end ? 312 257 + (end - out) : 257 - (out - end)); 313 state->hold = hold; 314 state->bits = bits; 315 return; 316 } 317 318 /* 319 inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): 320 - Using bit fields for code structure 321 - Different op definition to avoid & for extra bits (do & for table bits) 322 - Three separate decoding do-loops for direct, window, and wnext == 0 323 - Special case for distance > 1 copies to do overlapped load and store copy 324 - Explicit branch predictions (based on measured branch probabilities) 325 - Deferring match copy and interspersed it with decoding subsequent codes 326 - Swapping literal/length else 327 - Swapping window/direct else 328 - Larger unrolled copy loops (three is about right) 329 - Moving len -= 3 statement into middle of loop 330 */ 331 332 #endif /* !ASMINF */ 333