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