This source file includes following definitions.
- inflate_fast
1
2
3
4
5
6
7 #include "zutil.h"
8 #include "inftrees.h"
9 #include "inflate.h"
10 #include "inffast.h"
11
12 #ifndef ASMINF
13
14
15
16
17
18
19
20
21
22
23
24
25 #ifdef POSTINC
26 # define OFF 0
27 # define PUP(a) *(a)++
28 #else
29 # define OFF 1
30 # define PUP(a) *++(a)
31 #endif
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 void inflate_fast(strm, start)
69 z_streamp strm;
70 unsigned start;
71 {
72 struct inflate_state FAR *state;
73 unsigned char FAR *in;
74 unsigned char FAR *last;
75 unsigned char FAR *out;
76 unsigned char FAR *beg;
77 unsigned char FAR *end;
78 #ifdef INFLATE_STRICT
79 unsigned dmax;
80 #endif
81 unsigned wsize;
82 unsigned whave;
83 unsigned write;
84 unsigned char FAR *window;
85 unsigned long hold;
86 unsigned bits;
87 code const FAR *lcode;
88 code const FAR *dcode;
89 unsigned lmask;
90 unsigned dmask;
91 code this;
92 unsigned op;
93
94 unsigned len;
95 unsigned dist;
96 unsigned char FAR *from;
97
98
99 state = (struct inflate_state FAR *)strm->state;
100 in = strm->next_in - OFF;
101 last = in + (strm->avail_in - 5);
102 out = strm->next_out - OFF;
103 beg = out - (start - strm->avail_out);
104 end = out + (strm->avail_out - 257);
105 #ifdef INFLATE_STRICT
106 dmax = state->dmax;
107 #endif
108 wsize = state->wsize;
109 whave = state->whave;
110 write = state->write;
111 window = state->window;
112 hold = state->hold;
113 bits = state->bits;
114 lcode = state->lencode;
115 dcode = state->distcode;
116 lmask = (1U << state->lenbits) - 1;
117 dmask = (1U << state->distbits) - 1;
118
119
120
121 do {
122 if (bits < 15) {
123 hold += (unsigned long)(PUP(in)) << bits;
124 bits += 8;
125 hold += (unsigned long)(PUP(in)) << bits;
126 bits += 8;
127 }
128 this = lcode[hold & lmask];
129 dolen:
130 op = (unsigned)(this.bits);
131 hold >>= op;
132 bits -= op;
133 op = (unsigned)(this.op);
134 if (op == 0) {
135 Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
136 "inflate: literal '%c'\n" :
137 "inflate: literal 0x%02x\n", this.val));
138 PUP(out) = (unsigned char)(this.val);
139 }
140 else if (op & 16) {
141 len = (unsigned)(this.val);
142 op &= 15;
143 if (op) {
144 if (bits < op) {
145 hold += (unsigned long)(PUP(in)) << bits;
146 bits += 8;
147 }
148 len += (unsigned)hold & ((1U << op) - 1);
149 hold >>= op;
150 bits -= op;
151 }
152 Tracevv((stderr, "inflate: length %u\n", len));
153 if (bits < 15) {
154 hold += (unsigned long)(PUP(in)) << bits;
155 bits += 8;
156 hold += (unsigned long)(PUP(in)) << bits;
157 bits += 8;
158 }
159 this = dcode[hold & dmask];
160 dodist:
161 op = (unsigned)(this.bits);
162 hold >>= op;
163 bits -= op;
164 op = (unsigned)(this.op);
165 if (op & 16) {
166 dist = (unsigned)(this.val);
167 op &= 15;
168 if (bits < op) {
169 hold += (unsigned long)(PUP(in)) << bits;
170 bits += 8;
171 if (bits < op) {
172 hold += (unsigned long)(PUP(in)) << bits;
173 bits += 8;
174 }
175 }
176 dist += (unsigned)hold & ((1U << op) - 1);
177 #ifdef INFLATE_STRICT
178 if (dist > dmax) {
179 strm->msg = (char *)"invalid distance too far back";
180 state->mode = BAD;
181 break;
182 }
183 #endif
184 hold >>= op;
185 bits -= op;
186 Tracevv((stderr, "inflate: distance %u\n", dist));
187 op = (unsigned)(out - beg);
188 if (dist > op) {
189 op = dist - op;
190 if (op > whave) {
191 #ifdef SMALL
192 strm->msg = "error";
193 #else
194 strm->msg = (char *)"invalid distance too far back";
195 #endif
196 state->mode = BAD;
197 break;
198 }
199 from = window - OFF;
200 if (write == 0) {
201 from += wsize - op;
202 if (op < len) {
203 len -= op;
204 do {
205 PUP(out) = PUP(from);
206 } while (--op);
207 from = out - dist;
208 }
209 }
210 else if (write < op) {
211 from += wsize + write - op;
212 op -= write;
213 if (op < len) {
214 len -= op;
215 do {
216 PUP(out) = PUP(from);
217 } while (--op);
218 from = window - OFF;
219 if (write < len) {
220 op = write;
221 len -= op;
222 do {
223 PUP(out) = PUP(from);
224 } while (--op);
225 from = out - dist;
226 }
227 }
228 }
229 else {
230 from += write - op;
231 if (op < len) {
232 len -= op;
233 do {
234 PUP(out) = PUP(from);
235 } while (--op);
236 from = out - dist;
237 }
238 }
239 while (len > 2) {
240 PUP(out) = PUP(from);
241 PUP(out) = PUP(from);
242 PUP(out) = PUP(from);
243 len -= 3;
244 }
245 if (len) {
246 PUP(out) = PUP(from);
247 if (len > 1)
248 PUP(out) = PUP(from);
249 }
250 }
251 else {
252 from = out - dist;
253 do {
254 PUP(out) = PUP(from);
255 PUP(out) = PUP(from);
256 PUP(out) = PUP(from);
257 len -= 3;
258 } while (len > 2);
259 if (len) {
260 PUP(out) = PUP(from);
261 if (len > 1)
262 PUP(out) = PUP(from);
263 }
264 }
265 }
266 else if ((op & 64) == 0) {
267 this = dcode[this.val + (hold & ((1U << op) - 1))];
268 goto dodist;
269 }
270 else {
271 #ifdef SMALL
272 strm->msg = "error";
273 #else
274 strm->msg = (char *)"invalid distance code";
275 #endif
276 state->mode = BAD;
277 break;
278 }
279 }
280 else if ((op & 64) == 0) {
281 this = lcode[this.val + (hold & ((1U << op) - 1))];
282 goto dolen;
283 }
284 else if (op & 32) {
285 Tracevv((stderr, "inflate: end of block\n"));
286 state->mode = TYPE;
287 break;
288 }
289 else {
290 #ifdef SMALL
291 strm->msg = "error";
292 #else
293 strm->msg = (char *)"invalid literal/length code";
294 #endif
295 state->mode = BAD;
296 break;
297 }
298 } while (in < last && out < end);
299
300
301 len = bits >> 3;
302 in -= len;
303 bits -= len << 3;
304 hold &= (1U << bits) - 1;
305
306
307 strm->next_in = in + OFF;
308 strm->next_out = out + OFF;
309 strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
310 strm->avail_out = (unsigned)(out < end ?
311 257 + (end - out) : 257 - (out - end));
312 state->hold = hold;
313 state->bits = bits;
314 return;
315 }
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331 #endif