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