/src/lzo-2.10/src/lzo1x_d.ch
Line | Count | Source |
1 | | /* lzo1x_d.ch -- implementation of the LZO1X decompression algorithm |
2 | | |
3 | | This file is part of the LZO real-time data compression library. |
4 | | |
5 | | Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer |
6 | | All Rights Reserved. |
7 | | |
8 | | The LZO library is free software; you can redistribute it and/or |
9 | | modify it under the terms of the GNU General Public License as |
10 | | published by the Free Software Foundation; either version 2 of |
11 | | the License, or (at your option) any later version. |
12 | | |
13 | | The LZO library is distributed in the hope that it will be useful, |
14 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | | GNU General Public License for more details. |
17 | | |
18 | | You should have received a copy of the GNU General Public License |
19 | | along with the LZO library; see the file COPYING. |
20 | | If not, write to the Free Software Foundation, Inc., |
21 | | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
22 | | |
23 | | Markus F.X.J. Oberhumer |
24 | | <markus@oberhumer.com> |
25 | | http://www.oberhumer.com/opensource/lzo/ |
26 | | */ |
27 | | |
28 | | |
29 | | #include "lzo1_d.ch" |
30 | | |
31 | | |
32 | | /*********************************************************************** |
33 | | // decompress a block of data. |
34 | | ************************************************************************/ |
35 | | |
36 | | #if defined(DO_DECOMPRESS) |
37 | | LZO_PUBLIC(int) |
38 | | DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, |
39 | | lzo_bytep out, lzo_uintp out_len, |
40 | | lzo_voidp wrkmem ) |
41 | | #endif |
42 | 9.25k | { |
43 | 9.25k | lzo_bytep op; |
44 | 9.25k | const lzo_bytep ip; |
45 | 9.25k | lzo_uint t; |
46 | | #if defined(COPY_DICT) |
47 | | lzo_uint m_off; |
48 | | const lzo_bytep dict_end; |
49 | | #else |
50 | 9.25k | const lzo_bytep m_pos; |
51 | 9.25k | #endif |
52 | | |
53 | 9.25k | const lzo_bytep const ip_end = in + in_len; |
54 | | #if defined(HAVE_ANY_OP) |
55 | 1.84k | lzo_bytep const op_end = out + *out_len; |
56 | | #endif |
57 | | #if defined(LZO1Z) |
58 | | lzo_uint last_m_off = 0; |
59 | | #endif |
60 | | |
61 | 9.25k | LZO_UNUSED(wrkmem); |
62 | | |
63 | | #if defined(COPY_DICT) |
64 | | if (dict) |
65 | | { |
66 | | if (dict_len > M4_MAX_OFFSET) |
67 | | { |
68 | | dict += dict_len - M4_MAX_OFFSET; |
69 | | dict_len = M4_MAX_OFFSET; |
70 | | } |
71 | | dict_end = dict + dict_len; |
72 | | } |
73 | | else |
74 | | { |
75 | | dict_len = 0; |
76 | | dict_end = NULL; |
77 | | } |
78 | | #endif /* COPY_DICT */ |
79 | | |
80 | 9.25k | *out_len = 0; |
81 | | |
82 | 9.25k | op = out; |
83 | 9.25k | ip = in; |
84 | | |
85 | 9.25k | NEED_IP(1); |
86 | 9.25k | if (*ip > 17) |
87 | 5.65k | { |
88 | 5.65k | t = *ip++ - 17; |
89 | 5.65k | if (t < 4) |
90 | 2.72k | goto match_next; |
91 | 5.65k | assert(t > 0); NEED_OP(t); NEED_IP(t+3); |
92 | 60.4k | do *op++ = *ip++; while (--t > 0); |
93 | 294 | goto first_literal_run; |
94 | 334 | } |
95 | | |
96 | 3.60k | for (;;) |
97 | 1.67M | { |
98 | 1.67M | NEED_IP(3); |
99 | 171k | t = *ip++; |
100 | 1.67M | if (t >= 16) |
101 | 1.27M | goto match; |
102 | | /* a literal run */ |
103 | 401k | if (t == 0) |
104 | 141k | { |
105 | 26.7M | while (*ip == 0) |
106 | 26.5M | { |
107 | 26.5M | t += 255; |
108 | 26.5M | ip++; |
109 | 26.5M | TEST_IV(t); |
110 | 26.5M | NEED_IP(1); |
111 | 25.8M | } |
112 | 28.6k | t += 15 + *ip++; |
113 | 28.6k | } |
114 | | /* copy literals */ |
115 | 401k | assert(t > 0); NEED_OP(t+3); NEED_IP(t+6); |
116 | 52.7k | #if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) |
117 | 52.7k | t += 3; |
118 | 400k | if (t >= 8) do |
119 | 23.8M | { |
120 | 23.8M | UA_COPY8(op,ip); |
121 | 23.8M | op += 8; ip += 8; t -= 8; |
122 | 23.8M | } while (t >= 8); |
123 | 400k | if (t >= 4) |
124 | 251k | { |
125 | 251k | UA_COPY4(op,ip); |
126 | 251k | op += 4; ip += 4; t -= 4; |
127 | 251k | } |
128 | 400k | if (t > 0) |
129 | 268k | { |
130 | 268k | *op++ = *ip++; |
131 | 268k | if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } |
132 | 268k | } |
133 | | #elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) |
134 | | #if !(LZO_OPT_UNALIGNED32) |
135 | | if (PTR_ALIGNED2_4(op,ip)) |
136 | | { |
137 | | #endif |
138 | | UA_COPY4(op,ip); |
139 | | op += 4; ip += 4; |
140 | | if (--t > 0) |
141 | | { |
142 | | if (t >= 4) |
143 | | { |
144 | | do { |
145 | | UA_COPY4(op,ip); |
146 | | op += 4; ip += 4; t -= 4; |
147 | | } while (t >= 4); |
148 | | if (t > 0) do *op++ = *ip++; while (--t > 0); |
149 | | } |
150 | | else |
151 | | do *op++ = *ip++; while (--t > 0); |
152 | | } |
153 | | #if !(LZO_OPT_UNALIGNED32) |
154 | | } |
155 | | else |
156 | | #endif |
157 | | #endif |
158 | | #if !(LZO_OPT_UNALIGNED32) |
159 | | { |
160 | | *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; |
161 | | do *op++ = *ip++; while (--t > 0); |
162 | | } |
163 | | #endif |
164 | | |
165 | | |
166 | 403k | first_literal_run: |
167 | | |
168 | | |
169 | 403k | t = *ip++; |
170 | 403k | if (t >= 16) |
171 | 360k | goto match; |
172 | | #if defined(COPY_DICT) |
173 | | #if defined(LZO1Z) |
174 | | m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); |
175 | | last_m_off = m_off; |
176 | | #else |
177 | | m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); |
178 | | #endif |
179 | | NEED_OP(3); |
180 | | t = 3; COPY_DICT(t,m_off) |
181 | | #else /* !COPY_DICT */ |
182 | | #if defined(LZO1Z) |
183 | 13.7k | t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); |
184 | 5.29k | m_pos = op - t; |
185 | 5.29k | last_m_off = t; |
186 | | #else |
187 | 29.0k | m_pos = op - (1 + M2_MAX_OFFSET); |
188 | | m_pos -= t >> 2; |
189 | | m_pos -= *ip++ << 2; |
190 | | #endif |
191 | 42.8k | TEST_LB(m_pos); NEED_OP(3); |
192 | 29.6k | *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; |
193 | 29.6k | #endif /* COPY_DICT */ |
194 | 29.6k | goto match_done; |
195 | | |
196 | | |
197 | | /* handle matches */ |
198 | 2.27M | for (;;) { |
199 | 3.90M | match: |
200 | 3.90M | if (t >= 64) /* a M2 match */ |
201 | 1.59M | { |
202 | | #if defined(COPY_DICT) |
203 | | #if defined(LZO1X) |
204 | | m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); |
205 | | t = (t >> 5) - 1; |
206 | | #elif defined(LZO1Y) |
207 | | m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); |
208 | | t = (t >> 4) - 3; |
209 | | #elif defined(LZO1Z) |
210 | | m_off = t & 0x1f; |
211 | | if (m_off >= 0x1c) |
212 | | m_off = last_m_off; |
213 | | else |
214 | | { |
215 | | m_off = 1 + (m_off << 6) + (*ip++ >> 2); |
216 | | last_m_off = m_off; |
217 | | } |
218 | | t = (t >> 5) - 1; |
219 | | #endif |
220 | | #else /* !COPY_DICT */ |
221 | | #if defined(LZO1X) |
222 | | m_pos = op - 1; |
223 | | m_pos -= (t >> 2) & 7; |
224 | | m_pos -= *ip++ << 3; |
225 | | t = (t >> 5) - 1; |
226 | | #elif defined(LZO1Y) |
227 | | m_pos = op - 1; |
228 | | m_pos -= (t >> 2) & 3; |
229 | | m_pos -= *ip++ << 2; |
230 | | t = (t >> 4) - 3; |
231 | | #elif defined(LZO1Z) |
232 | | { |
233 | | lzo_uint off = t & 0x1f; |
234 | | m_pos = op; |
235 | 396k | if (off >= 0x1c) |
236 | 30.6k | { |
237 | 30.6k | assert(last_m_off > 0); |
238 | 30.6k | m_pos -= last_m_off; |
239 | 30.6k | } |
240 | 366k | else |
241 | 366k | { |
242 | 366k | off = 1 + (off << 6) + (*ip++ >> 2); |
243 | 366k | m_pos -= off; |
244 | 366k | last_m_off = off; |
245 | 366k | } |
246 | | } |
247 | | t = (t >> 5) - 1; |
248 | | #endif |
249 | 1.59M | TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); |
250 | 203k | goto copy_match; |
251 | 203k | #endif /* COPY_DICT */ |
252 | 203k | } |
253 | 2.30M | else if (t >= 32) /* a M3 match */ |
254 | 1.03M | { |
255 | 1.03M | t &= 31; |
256 | 1.03M | if (t == 0) |
257 | 208k | { |
258 | 21.3M | while (*ip == 0) |
259 | 21.1M | { |
260 | 21.1M | t += 255; |
261 | 21.1M | ip++; |
262 | 21.1M | TEST_OV(t); |
263 | 21.1M | NEED_IP(1); |
264 | 20.9M | } |
265 | 8.57k | t += 31 + *ip++; |
266 | 208k | NEED_IP(2); |
267 | 8.57k | } |
268 | | #if defined(COPY_DICT) |
269 | | #if defined(LZO1Z) |
270 | | m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); |
271 | | last_m_off = m_off; |
272 | | #else |
273 | | m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); |
274 | | #endif |
275 | | #else /* !COPY_DICT */ |
276 | | #if defined(LZO1Z) |
277 | 19.2k | { |
278 | 19.2k | lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); |
279 | 19.2k | m_pos = op - off; |
280 | 19.2k | last_m_off = off; |
281 | 19.2k | } |
282 | | #elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) |
283 | 60.1k | m_pos = op - 1; |
284 | 778k | m_pos -= UA_GET_LE16(ip) >> 2; |
285 | | #else |
286 | | m_pos = op - 1; |
287 | | m_pos -= (ip[0] >> 2) + (ip[1] << 6); |
288 | | #endif |
289 | 60.1k | #endif /* COPY_DICT */ |
290 | 60.1k | ip += 2; |
291 | 60.1k | } |
292 | 1.26M | else if (t >= 16) /* a M4 match */ |
293 | 197k | { |
294 | | #if defined(COPY_DICT) |
295 | | m_off = (t & 8) << 11; |
296 | | #else /* !COPY_DICT */ |
297 | 197k | m_pos = op; |
298 | 197k | m_pos -= (t & 8) << 11; |
299 | 197k | #endif /* COPY_DICT */ |
300 | 197k | t &= 7; |
301 | 197k | if (t == 0) |
302 | 73.6k | { |
303 | 7.98M | while (*ip == 0) |
304 | 7.91M | { |
305 | 7.91M | t += 255; |
306 | 7.91M | ip++; |
307 | 7.91M | TEST_OV(t); |
308 | 7.91M | NEED_IP(1); |
309 | 7.87M | } |
310 | 7.55k | t += 7 + *ip++; |
311 | 73.5k | NEED_IP(2); |
312 | 7.55k | } |
313 | | #if defined(COPY_DICT) |
314 | | #if defined(LZO1Z) |
315 | | m_off += (ip[0] << 6) + (ip[1] >> 2); |
316 | | #else |
317 | | m_off += (ip[0] >> 2) + (ip[1] << 6); |
318 | | #endif |
319 | | ip += 2; |
320 | | if (m_off == 0) |
321 | | goto eof_found; |
322 | | m_off += 0x4000; |
323 | | #if defined(LZO1Z) |
324 | | last_m_off = m_off; |
325 | | #endif |
326 | | #else /* !COPY_DICT */ |
327 | | #if defined(LZO1Z) |
328 | 6.75k | m_pos -= (ip[0] << 6) + (ip[1] >> 2); |
329 | | #elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) |
330 | 138k | m_pos -= UA_GET_LE16(ip) >> 2; |
331 | | #else |
332 | | m_pos -= (ip[0] >> 2) + (ip[1] << 6); |
333 | | #endif |
334 | 17.6k | ip += 2; |
335 | 197k | if (m_pos == op) |
336 | 7.44k | goto eof_found; |
337 | 190k | m_pos -= 0x4000; |
338 | | #if defined(LZO1Z) |
339 | 57.4k | last_m_off = pd((const lzo_bytep)op, m_pos); |
340 | | #endif |
341 | 190k | #endif /* COPY_DICT */ |
342 | 190k | } |
343 | 1.07M | else /* a M1 match */ |
344 | 1.07M | { |
345 | | #if defined(COPY_DICT) |
346 | | #if defined(LZO1Z) |
347 | | m_off = 1 + (t << 6) + (*ip++ >> 2); |
348 | | last_m_off = m_off; |
349 | | #else |
350 | | m_off = 1 + (t >> 2) + (*ip++ << 2); |
351 | | #endif |
352 | | NEED_OP(2); |
353 | | t = 2; COPY_DICT(t,m_off) |
354 | | #else /* !COPY_DICT */ |
355 | | #if defined(LZO1Z) |
356 | | t = 1 + (t << 6) + (*ip++ >> 2); |
357 | | m_pos = op - t; |
358 | | last_m_off = t; |
359 | | #else |
360 | | m_pos = op - 1; |
361 | | m_pos -= t >> 2; |
362 | | m_pos -= *ip++ << 2; |
363 | | #endif |
364 | 1.07M | TEST_LB(m_pos); NEED_OP(2); |
365 | 118k | *op++ = *m_pos++; *op++ = *m_pos; |
366 | 118k | #endif /* COPY_DICT */ |
367 | 118k | goto match_done; |
368 | 118k | } |
369 | | |
370 | | /* copy match */ |
371 | | #if defined(COPY_DICT) |
372 | | |
373 | | NEED_OP(t+3-1); |
374 | | t += 3-1; COPY_DICT(t,m_off) |
375 | | |
376 | | #else /* !COPY_DICT */ |
377 | | |
378 | 1.22M | TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); |
379 | 103k | #if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) |
380 | 1.22M | if (op - m_pos >= 8) |
381 | 1.15M | { |
382 | 1.15M | t += (3 - 1); |
383 | 1.15M | if (t >= 8) do |
384 | 9.24M | { |
385 | 9.24M | UA_COPY8(op,m_pos); |
386 | 9.24M | op += 8; m_pos += 8; t -= 8; |
387 | 9.24M | } while (t >= 8); |
388 | 1.15M | if (t >= 4) |
389 | 568k | { |
390 | 568k | UA_COPY4(op,m_pos); |
391 | 568k | op += 4; m_pos += 4; t -= 4; |
392 | 568k | } |
393 | 1.15M | if (t > 0) |
394 | 839k | { |
395 | 839k | *op++ = m_pos[0]; |
396 | 839k | if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } } |
397 | 839k | } |
398 | 1.15M | } |
399 | 77.8k | else |
400 | | #elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) |
401 | | #if !(LZO_OPT_UNALIGNED32) |
402 | | if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) |
403 | | { |
404 | | assert((op - m_pos) >= 4); /* both pointers are aligned */ |
405 | | #else |
406 | | if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) |
407 | | { |
408 | | #endif |
409 | | UA_COPY4(op,m_pos); |
410 | | op += 4; m_pos += 4; t -= 4 - (3 - 1); |
411 | | do { |
412 | | UA_COPY4(op,m_pos); |
413 | | op += 4; m_pos += 4; t -= 4; |
414 | | } while (t >= 4); |
415 | | if (t > 0) do *op++ = *m_pos++; while (--t > 0); |
416 | | } |
417 | | else |
418 | | #endif |
419 | 77.8k | { |
420 | 1.67M | copy_match: |
421 | 1.67M | *op++ = *m_pos++; *op++ = *m_pos++; |
422 | 70.5M | do *op++ = *m_pos++; while (--t > 0); |
423 | 1.67M | } |
424 | | |
425 | 103k | #endif /* COPY_DICT */ |
426 | | |
427 | 3.94M | match_done: |
428 | | #if defined(LZO1Z) |
429 | | t = ip[-1] & 3; |
430 | | #else |
431 | | t = ip[-2] & 3; |
432 | | #endif |
433 | 3.94M | if (t == 0) |
434 | 1.67M | break; |
435 | | |
436 | | /* copy literals */ |
437 | 2.27M | match_next: |
438 | 2.27M | assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3); |
439 | | #if 0 |
440 | | do *op++ = *ip++; while (--t > 0); |
441 | | #else |
442 | 284k | *op++ = *ip++; |
443 | 2.27M | if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } |
444 | 284k | #endif |
445 | 284k | t = *ip++; |
446 | 284k | } |
447 | 0 | } |
448 | | |
449 | 7.44k | eof_found: |
450 | 7.44k | *out_len = pd(op, out); |
451 | 7.44k | return (ip == ip_end ? LZO_E_OK : |
452 | 7.44k | (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); |
453 | | |
454 | | |
455 | | #if defined(HAVE_NEED_IP) |
456 | 1.14k | input_overrun: |
457 | 1.14k | *out_len = pd(op, out); |
458 | 1.14k | return LZO_E_INPUT_OVERRUN; |
459 | 0 | #endif |
460 | | |
461 | | #if defined(HAVE_NEED_OP) |
462 | 179 | output_overrun: |
463 | 179 | *out_len = pd(op, out); |
464 | 179 | return LZO_E_OUTPUT_OVERRUN; |
465 | 0 | #endif |
466 | | |
467 | | #if defined(LZO_TEST_OVERRUN_LOOKBEHIND) |
468 | 486 | lookbehind_overrun: |
469 | 486 | *out_len = pd(op, out); |
470 | 486 | return LZO_E_LOOKBEHIND_OVERRUN; |
471 | | #endif |
472 | 3.60k | } Line | Count | Source | 42 | 3.85k | { | 43 | 3.85k | lzo_bytep op; | 44 | 3.85k | const lzo_bytep ip; | 45 | 3.85k | lzo_uint t; | 46 | | #if defined(COPY_DICT) | 47 | | lzo_uint m_off; | 48 | | const lzo_bytep dict_end; | 49 | | #else | 50 | 3.85k | const lzo_bytep m_pos; | 51 | 3.85k | #endif | 52 | | | 53 | 3.85k | const lzo_bytep const ip_end = in + in_len; | 54 | | #if defined(HAVE_ANY_OP) | 55 | | lzo_bytep const op_end = out + *out_len; | 56 | | #endif | 57 | | #if defined(LZO1Z) | 58 | | lzo_uint last_m_off = 0; | 59 | | #endif | 60 | | | 61 | 3.85k | LZO_UNUSED(wrkmem); | 62 | | | 63 | | #if defined(COPY_DICT) | 64 | | if (dict) | 65 | | { | 66 | | if (dict_len > M4_MAX_OFFSET) | 67 | | { | 68 | | dict += dict_len - M4_MAX_OFFSET; | 69 | | dict_len = M4_MAX_OFFSET; | 70 | | } | 71 | | dict_end = dict + dict_len; | 72 | | } | 73 | | else | 74 | | { | 75 | | dict_len = 0; | 76 | | dict_end = NULL; | 77 | | } | 78 | | #endif /* COPY_DICT */ | 79 | | | 80 | 3.85k | *out_len = 0; | 81 | | | 82 | 3.85k | op = out; | 83 | 3.85k | ip = in; | 84 | | | 85 | 3.85k | NEED_IP(1); | 86 | 3.85k | if (*ip > 17) | 87 | 1.47k | { | 88 | 1.47k | t = *ip++ - 17; | 89 | 1.47k | if (t < 4) | 90 | 611 | goto match_next; | 91 | 1.47k | assert(t > 0); NEED_OP(t); NEED_IP(t+3); | 92 | 22.2k | do *op++ = *ip++; while (--t > 0); | 93 | 859 | goto first_literal_run; | 94 | 1.47k | } | 95 | | | 96 | 2.38k | for (;;) | 97 | 908k | { | 98 | 908k | NEED_IP(3); | 99 | 908k | t = *ip++; | 100 | 908k | if (t >= 16) | 101 | 698k | goto match; | 102 | | /* a literal run */ | 103 | 210k | if (t == 0) | 104 | 62.5k | { | 105 | 559k | while (*ip == 0) | 106 | 496k | { | 107 | 496k | t += 255; | 108 | 496k | ip++; | 109 | 496k | TEST_IV(t); | 110 | 496k | NEED_IP(1); | 111 | 496k | } | 112 | 62.5k | t += 15 + *ip++; | 113 | 62.5k | } | 114 | | /* copy literals */ | 115 | 210k | assert(t > 0); NEED_OP(t+3); NEED_IP(t+6); | 116 | 210k | #if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) | 117 | 210k | t += 3; | 118 | 210k | if (t >= 8) do | 119 | 16.4M | { | 120 | 16.4M | UA_COPY8(op,ip); | 121 | 16.4M | op += 8; ip += 8; t -= 8; | 122 | 16.4M | } while (t >= 8); | 123 | 210k | if (t >= 4) | 124 | 136k | { | 125 | 136k | UA_COPY4(op,ip); | 126 | 136k | op += 4; ip += 4; t -= 4; | 127 | 136k | } | 128 | 210k | if (t > 0) | 129 | 135k | { | 130 | 135k | *op++ = *ip++; | 131 | 135k | if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } | 132 | 135k | } | 133 | | #elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) | 134 | | #if !(LZO_OPT_UNALIGNED32) | 135 | | if (PTR_ALIGNED2_4(op,ip)) | 136 | | { | 137 | | #endif | 138 | | UA_COPY4(op,ip); | 139 | | op += 4; ip += 4; | 140 | | if (--t > 0) | 141 | | { | 142 | | if (t >= 4) | 143 | | { | 144 | | do { | 145 | | UA_COPY4(op,ip); | 146 | | op += 4; ip += 4; t -= 4; | 147 | | } while (t >= 4); | 148 | | if (t > 0) do *op++ = *ip++; while (--t > 0); | 149 | | } | 150 | | else | 151 | | do *op++ = *ip++; while (--t > 0); | 152 | | } | 153 | | #if !(LZO_OPT_UNALIGNED32) | 154 | | } | 155 | | else | 156 | | #endif | 157 | | #endif | 158 | | #if !(LZO_OPT_UNALIGNED32) | 159 | | { | 160 | | *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; | 161 | | do *op++ = *ip++; while (--t > 0); | 162 | | } | 163 | | #endif | 164 | | | 165 | | | 166 | 211k | first_literal_run: | 167 | | | 168 | | | 169 | 211k | t = *ip++; | 170 | 211k | if (t >= 16) | 171 | 208k | goto match; | 172 | | #if defined(COPY_DICT) | 173 | | #if defined(LZO1Z) | 174 | | m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); | 175 | | last_m_off = m_off; | 176 | | #else | 177 | | m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); | 178 | | #endif | 179 | | NEED_OP(3); | 180 | | t = 3; COPY_DICT(t,m_off) | 181 | | #else /* !COPY_DICT */ | 182 | | #if defined(LZO1Z) | 183 | | t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); | 184 | | m_pos = op - t; | 185 | | last_m_off = t; | 186 | | #else | 187 | 3.20k | m_pos = op - (1 + M2_MAX_OFFSET); | 188 | 3.20k | m_pos -= t >> 2; | 189 | 3.20k | m_pos -= *ip++ << 2; | 190 | 3.20k | #endif | 191 | 3.20k | TEST_LB(m_pos); NEED_OP(3); | 192 | 3.20k | *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; | 193 | 3.20k | #endif /* COPY_DICT */ | 194 | 3.20k | goto match_done; | 195 | | | 196 | | | 197 | | /* handle matches */ | 198 | 640k | for (;;) { | 199 | 1.54M | match: | 200 | 1.54M | if (t >= 64) /* a M2 match */ | 201 | 782k | { | 202 | | #if defined(COPY_DICT) | 203 | | #if defined(LZO1X) | 204 | | m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); | 205 | | t = (t >> 5) - 1; | 206 | | #elif defined(LZO1Y) | 207 | | m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); | 208 | | t = (t >> 4) - 3; | 209 | | #elif defined(LZO1Z) | 210 | | m_off = t & 0x1f; | 211 | | if (m_off >= 0x1c) | 212 | | m_off = last_m_off; | 213 | | else | 214 | | { | 215 | | m_off = 1 + (m_off << 6) + (*ip++ >> 2); | 216 | | last_m_off = m_off; | 217 | | } | 218 | | t = (t >> 5) - 1; | 219 | | #endif | 220 | | #else /* !COPY_DICT */ | 221 | 782k | #if defined(LZO1X) | 222 | 782k | m_pos = op - 1; | 223 | 782k | m_pos -= (t >> 2) & 7; | 224 | 782k | m_pos -= *ip++ << 3; | 225 | 782k | t = (t >> 5) - 1; | 226 | | #elif defined(LZO1Y) | 227 | | m_pos = op - 1; | 228 | | m_pos -= (t >> 2) & 3; | 229 | | m_pos -= *ip++ << 2; | 230 | | t = (t >> 4) - 3; | 231 | | #elif defined(LZO1Z) | 232 | | { | 233 | | lzo_uint off = t & 0x1f; | 234 | | m_pos = op; | 235 | | if (off >= 0x1c) | 236 | | { | 237 | | assert(last_m_off > 0); | 238 | | m_pos -= last_m_off; | 239 | | } | 240 | | else | 241 | | { | 242 | | off = 1 + (off << 6) + (*ip++ >> 2); | 243 | | m_pos -= off; | 244 | | last_m_off = off; | 245 | | } | 246 | | } | 247 | | t = (t >> 5) - 1; | 248 | | #endif | 249 | 782k | TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); | 250 | 782k | goto copy_match; | 251 | 782k | #endif /* COPY_DICT */ | 252 | 782k | } | 253 | 764k | else if (t >= 32) /* a M3 match */ | 254 | 492k | { | 255 | 492k | t &= 31; | 256 | 492k | if (t == 0) | 257 | 109k | { | 258 | 240k | while (*ip == 0) | 259 | 130k | { | 260 | 130k | t += 255; | 261 | 130k | ip++; | 262 | 130k | TEST_OV(t); | 263 | 130k | NEED_IP(1); | 264 | 130k | } | 265 | 109k | t += 31 + *ip++; | 266 | 109k | NEED_IP(2); | 267 | 109k | } | 268 | | #if defined(COPY_DICT) | 269 | | #if defined(LZO1Z) | 270 | | m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); | 271 | | last_m_off = m_off; | 272 | | #else | 273 | | m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); | 274 | | #endif | 275 | | #else /* !COPY_DICT */ | 276 | | #if defined(LZO1Z) | 277 | | { | 278 | | lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); | 279 | | m_pos = op - off; | 280 | | last_m_off = off; | 281 | | } | 282 | | #elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) | 283 | | m_pos = op - 1; | 284 | 492k | m_pos -= UA_GET_LE16(ip) >> 2; | 285 | | #else | 286 | | m_pos = op - 1; | 287 | | m_pos -= (ip[0] >> 2) + (ip[1] << 6); | 288 | | #endif | 289 | 492k | #endif /* COPY_DICT */ | 290 | 492k | ip += 2; | 291 | 492k | } | 292 | 272k | else if (t >= 16) /* a M4 match */ | 293 | 79.5k | { | 294 | | #if defined(COPY_DICT) | 295 | | m_off = (t & 8) << 11; | 296 | | #else /* !COPY_DICT */ | 297 | 79.5k | m_pos = op; | 298 | 79.5k | m_pos -= (t & 8) << 11; | 299 | 79.5k | #endif /* COPY_DICT */ | 300 | 79.5k | t &= 7; | 301 | 79.5k | if (t == 0) | 302 | 31.4k | { | 303 | 57.2k | while (*ip == 0) | 304 | 25.7k | { | 305 | 25.7k | t += 255; | 306 | 25.7k | ip++; | 307 | 25.7k | TEST_OV(t); | 308 | 25.7k | NEED_IP(1); | 309 | 25.7k | } | 310 | 31.4k | t += 7 + *ip++; | 311 | 31.4k | NEED_IP(2); | 312 | 31.4k | } | 313 | | #if defined(COPY_DICT) | 314 | | #if defined(LZO1Z) | 315 | | m_off += (ip[0] << 6) + (ip[1] >> 2); | 316 | | #else | 317 | | m_off += (ip[0] >> 2) + (ip[1] << 6); | 318 | | #endif | 319 | | ip += 2; | 320 | | if (m_off == 0) | 321 | | goto eof_found; | 322 | | m_off += 0x4000; | 323 | | #if defined(LZO1Z) | 324 | | last_m_off = m_off; | 325 | | #endif | 326 | | #else /* !COPY_DICT */ | 327 | | #if defined(LZO1Z) | 328 | | m_pos -= (ip[0] << 6) + (ip[1] >> 2); | 329 | | #elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) | 330 | 79.5k | m_pos -= UA_GET_LE16(ip) >> 2; | 331 | | #else | 332 | | m_pos -= (ip[0] >> 2) + (ip[1] << 6); | 333 | | #endif | 334 | 79.5k | ip += 2; | 335 | 79.5k | if (m_pos == op) | 336 | 3.85k | goto eof_found; | 337 | 75.7k | m_pos -= 0x4000; | 338 | | #if defined(LZO1Z) | 339 | | last_m_off = pd((const lzo_bytep)op, m_pos); | 340 | | #endif | 341 | 75.7k | #endif /* COPY_DICT */ | 342 | 75.7k | } | 343 | 192k | else /* a M1 match */ | 344 | 192k | { | 345 | | #if defined(COPY_DICT) | 346 | | #if defined(LZO1Z) | 347 | | m_off = 1 + (t << 6) + (*ip++ >> 2); | 348 | | last_m_off = m_off; | 349 | | #else | 350 | | m_off = 1 + (t >> 2) + (*ip++ << 2); | 351 | | #endif | 352 | | NEED_OP(2); | 353 | | t = 2; COPY_DICT(t,m_off) | 354 | | #else /* !COPY_DICT */ | 355 | | #if defined(LZO1Z) | 356 | | t = 1 + (t << 6) + (*ip++ >> 2); | 357 | | m_pos = op - t; | 358 | | last_m_off = t; | 359 | | #else | 360 | 192k | m_pos = op - 1; | 361 | 192k | m_pos -= t >> 2; | 362 | 192k | m_pos -= *ip++ << 2; | 363 | 192k | #endif | 364 | 192k | TEST_LB(m_pos); NEED_OP(2); | 365 | 192k | *op++ = *m_pos++; *op++ = *m_pos; | 366 | 192k | #endif /* COPY_DICT */ | 367 | 192k | goto match_done; | 368 | 192k | } | 369 | | | 370 | | /* copy match */ | 371 | | #if defined(COPY_DICT) | 372 | | | 373 | | NEED_OP(t+3-1); | 374 | | t += 3-1; COPY_DICT(t,m_off) | 375 | | | 376 | | #else /* !COPY_DICT */ | 377 | | | 378 | 567k | TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); | 379 | 567k | #if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) | 380 | 567k | if (op - m_pos >= 8) | 381 | 528k | { | 382 | 528k | t += (3 - 1); | 383 | 528k | if (t >= 8) do | 384 | 4.15M | { | 385 | 4.15M | UA_COPY8(op,m_pos); | 386 | 4.15M | op += 8; m_pos += 8; t -= 8; | 387 | 4.15M | } while (t >= 8); | 388 | 528k | if (t >= 4) | 389 | 278k | { | 390 | 278k | UA_COPY4(op,m_pos); | 391 | 278k | op += 4; m_pos += 4; t -= 4; | 392 | 278k | } | 393 | 528k | if (t > 0) | 394 | 370k | { | 395 | 370k | *op++ = m_pos[0]; | 396 | 370k | if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } } | 397 | 370k | } | 398 | 528k | } | 399 | 39.6k | else | 400 | | #elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) | 401 | | #if !(LZO_OPT_UNALIGNED32) | 402 | | if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) | 403 | | { | 404 | | assert((op - m_pos) >= 4); /* both pointers are aligned */ | 405 | | #else | 406 | | if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) | 407 | | { | 408 | | #endif | 409 | | UA_COPY4(op,m_pos); | 410 | | op += 4; m_pos += 4; t -= 4 - (3 - 1); | 411 | | do { | 412 | | UA_COPY4(op,m_pos); | 413 | | op += 4; m_pos += 4; t -= 4; | 414 | | } while (t >= 4); | 415 | | if (t > 0) do *op++ = *m_pos++; while (--t > 0); | 416 | | } | 417 | | else | 418 | | #endif | 419 | 39.6k | { | 420 | 821k | copy_match: | 421 | 821k | *op++ = *m_pos++; *op++ = *m_pos++; | 422 | 23.6M | do *op++ = *m_pos++; while (--t > 0); | 423 | 821k | } | 424 | | | 425 | 567k | #endif /* COPY_DICT */ | 426 | | | 427 | 1.54M | match_done: | 428 | | #if defined(LZO1Z) | 429 | | t = ip[-1] & 3; | 430 | | #else | 431 | 1.54M | t = ip[-2] & 3; | 432 | 1.54M | #endif | 433 | 1.54M | if (t == 0) | 434 | 906k | break; | 435 | | | 436 | | /* copy literals */ | 437 | 640k | match_next: | 438 | 640k | assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3); | 439 | | #if 0 | 440 | | do *op++ = *ip++; while (--t > 0); | 441 | | #else | 442 | 640k | *op++ = *ip++; | 443 | 640k | if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } | 444 | 640k | #endif | 445 | 640k | t = *ip++; | 446 | 640k | } | 447 | 0 | } | 448 | | | 449 | 3.85k | eof_found: | 450 | 3.85k | *out_len = pd(op, out); | 451 | 3.85k | return (ip == ip_end ? LZO_E_OK : | 452 | 3.85k | (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); | 453 | | | 454 | | | 455 | | #if defined(HAVE_NEED_IP) | 456 | | input_overrun: | 457 | | *out_len = pd(op, out); | 458 | | return LZO_E_INPUT_OVERRUN; | 459 | | #endif | 460 | | | 461 | | #if defined(HAVE_NEED_OP) | 462 | | output_overrun: | 463 | | *out_len = pd(op, out); | 464 | | return LZO_E_OUTPUT_OVERRUN; | 465 | | #endif | 466 | | | 467 | | #if defined(LZO_TEST_OVERRUN_LOOKBEHIND) | 468 | | lookbehind_overrun: | 469 | | *out_len = pd(op, out); | 470 | | return LZO_E_LOOKBEHIND_OVERRUN; | 471 | | #endif | 472 | 2.38k | } |
Line | Count | Source | 42 | 1.86k | { | 43 | 1.86k | lzo_bytep op; | 44 | 1.86k | const lzo_bytep ip; | 45 | 1.86k | lzo_uint t; | 46 | | #if defined(COPY_DICT) | 47 | | lzo_uint m_off; | 48 | | const lzo_bytep dict_end; | 49 | | #else | 50 | 1.86k | const lzo_bytep m_pos; | 51 | 1.86k | #endif | 52 | | | 53 | 1.86k | const lzo_bytep const ip_end = in + in_len; | 54 | | #if defined(HAVE_ANY_OP) | 55 | | lzo_bytep const op_end = out + *out_len; | 56 | | #endif | 57 | | #if defined(LZO1Z) | 58 | | lzo_uint last_m_off = 0; | 59 | | #endif | 60 | | | 61 | 1.86k | LZO_UNUSED(wrkmem); | 62 | | | 63 | | #if defined(COPY_DICT) | 64 | | if (dict) | 65 | | { | 66 | | if (dict_len > M4_MAX_OFFSET) | 67 | | { | 68 | | dict += dict_len - M4_MAX_OFFSET; | 69 | | dict_len = M4_MAX_OFFSET; | 70 | | } | 71 | | dict_end = dict + dict_len; | 72 | | } | 73 | | else | 74 | | { | 75 | | dict_len = 0; | 76 | | dict_end = NULL; | 77 | | } | 78 | | #endif /* COPY_DICT */ | 79 | | | 80 | 1.86k | *out_len = 0; | 81 | | | 82 | 1.86k | op = out; | 83 | 1.86k | ip = in; | 84 | | | 85 | 1.86k | NEED_IP(1); | 86 | 1.86k | if (*ip > 17) | 87 | 1.38k | { | 88 | 1.38k | t = *ip++ - 17; | 89 | 1.38k | if (t < 4) | 90 | 557 | goto match_next; | 91 | 1.38k | assert(t > 0); NEED_OP(t); NEED_IP(t+3); | 92 | 14.2k | do *op++ = *ip++; while (--t > 0); | 93 | 832 | goto first_literal_run; | 94 | 1.38k | } | 95 | | | 96 | 478 | for (;;) | 97 | 299k | { | 98 | 299k | NEED_IP(3); | 99 | 299k | t = *ip++; | 100 | 299k | if (t >= 16) | 101 | 227k | goto match; | 102 | | /* a literal run */ | 103 | 71.2k | if (t == 0) | 104 | 25.6k | { | 105 | 168k | while (*ip == 0) | 106 | 142k | { | 107 | 142k | t += 255; | 108 | 142k | ip++; | 109 | 142k | TEST_IV(t); | 110 | 142k | NEED_IP(1); | 111 | 142k | } | 112 | 25.6k | t += 15 + *ip++; | 113 | 25.6k | } | 114 | | /* copy literals */ | 115 | 71.2k | assert(t > 0); NEED_OP(t+3); NEED_IP(t+6); | 116 | 71.2k | #if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) | 117 | 71.2k | t += 3; | 118 | 71.2k | if (t >= 8) do | 119 | 4.79M | { | 120 | 4.79M | UA_COPY8(op,ip); | 121 | 4.79M | op += 8; ip += 8; t -= 8; | 122 | 4.79M | } while (t >= 8); | 123 | 71.2k | if (t >= 4) | 124 | 44.5k | { | 125 | 44.5k | UA_COPY4(op,ip); | 126 | 44.5k | op += 4; ip += 4; t -= 4; | 127 | 44.5k | } | 128 | 71.2k | if (t > 0) | 129 | 47.2k | { | 130 | 47.2k | *op++ = *ip++; | 131 | 47.2k | if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } | 132 | 47.2k | } | 133 | | #elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) | 134 | | #if !(LZO_OPT_UNALIGNED32) | 135 | | if (PTR_ALIGNED2_4(op,ip)) | 136 | | { | 137 | | #endif | 138 | | UA_COPY4(op,ip); | 139 | | op += 4; ip += 4; | 140 | | if (--t > 0) | 141 | | { | 142 | | if (t >= 4) | 143 | | { | 144 | | do { | 145 | | UA_COPY4(op,ip); | 146 | | op += 4; ip += 4; t -= 4; | 147 | | } while (t >= 4); | 148 | | if (t > 0) do *op++ = *ip++; while (--t > 0); | 149 | | } | 150 | | else | 151 | | do *op++ = *ip++; while (--t > 0); | 152 | | } | 153 | | #if !(LZO_OPT_UNALIGNED32) | 154 | | } | 155 | | else | 156 | | #endif | 157 | | #endif | 158 | | #if !(LZO_OPT_UNALIGNED32) | 159 | | { | 160 | | *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; | 161 | | do *op++ = *ip++; while (--t > 0); | 162 | | } | 163 | | #endif | 164 | | | 165 | | | 166 | 72.0k | first_literal_run: | 167 | | | 168 | | | 169 | 72.0k | t = *ip++; | 170 | 72.0k | if (t >= 16) | 171 | 67.5k | goto match; | 172 | | #if defined(COPY_DICT) | 173 | | #if defined(LZO1Z) | 174 | | m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); | 175 | | last_m_off = m_off; | 176 | | #else | 177 | | m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); | 178 | | #endif | 179 | | NEED_OP(3); | 180 | | t = 3; COPY_DICT(t,m_off) | 181 | | #else /* !COPY_DICT */ | 182 | | #if defined(LZO1Z) | 183 | | t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); | 184 | | m_pos = op - t; | 185 | | last_m_off = t; | 186 | | #else | 187 | 4.55k | m_pos = op - (1 + M2_MAX_OFFSET); | 188 | 4.55k | m_pos -= t >> 2; | 189 | 4.55k | m_pos -= *ip++ << 2; | 190 | 4.55k | #endif | 191 | 4.55k | TEST_LB(m_pos); NEED_OP(3); | 192 | 4.55k | *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; | 193 | 4.55k | #endif /* COPY_DICT */ | 194 | 4.55k | goto match_done; | 195 | | | 196 | | | 197 | | /* handle matches */ | 198 | 603k | for (;;) { | 199 | 898k | match: | 200 | 898k | if (t >= 64) /* a M2 match */ | 201 | 295k | { | 202 | | #if defined(COPY_DICT) | 203 | | #if defined(LZO1X) | 204 | | m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); | 205 | | t = (t >> 5) - 1; | 206 | | #elif defined(LZO1Y) | 207 | | m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); | 208 | | t = (t >> 4) - 3; | 209 | | #elif defined(LZO1Z) | 210 | | m_off = t & 0x1f; | 211 | | if (m_off >= 0x1c) | 212 | | m_off = last_m_off; | 213 | | else | 214 | | { | 215 | | m_off = 1 + (m_off << 6) + (*ip++ >> 2); | 216 | | last_m_off = m_off; | 217 | | } | 218 | | t = (t >> 5) - 1; | 219 | | #endif | 220 | | #else /* !COPY_DICT */ | 221 | | #if defined(LZO1X) | 222 | | m_pos = op - 1; | 223 | | m_pos -= (t >> 2) & 7; | 224 | | m_pos -= *ip++ << 3; | 225 | | t = (t >> 5) - 1; | 226 | | #elif defined(LZO1Y) | 227 | | m_pos = op - 1; | 228 | 295k | m_pos -= (t >> 2) & 3; | 229 | 295k | m_pos -= *ip++ << 2; | 230 | 295k | t = (t >> 4) - 3; | 231 | | #elif defined(LZO1Z) | 232 | | { | 233 | | lzo_uint off = t & 0x1f; | 234 | | m_pos = op; | 235 | | if (off >= 0x1c) | 236 | | { | 237 | | assert(last_m_off > 0); | 238 | | m_pos -= last_m_off; | 239 | | } | 240 | | else | 241 | | { | 242 | | off = 1 + (off << 6) + (*ip++ >> 2); | 243 | | m_pos -= off; | 244 | | last_m_off = off; | 245 | | } | 246 | | } | 247 | | t = (t >> 5) - 1; | 248 | | #endif | 249 | 295k | TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); | 250 | 295k | goto copy_match; | 251 | 295k | #endif /* COPY_DICT */ | 252 | 295k | } | 253 | 603k | else if (t >= 32) /* a M3 match */ | 254 | 226k | { | 255 | 226k | t &= 31; | 256 | 226k | if (t == 0) | 257 | 49.7k | { | 258 | 95.5k | while (*ip == 0) | 259 | 45.7k | { | 260 | 45.7k | t += 255; | 261 | 45.7k | ip++; | 262 | 45.7k | TEST_OV(t); | 263 | 45.7k | NEED_IP(1); | 264 | 45.7k | } | 265 | 49.7k | t += 31 + *ip++; | 266 | 49.7k | NEED_IP(2); | 267 | 49.7k | } | 268 | | #if defined(COPY_DICT) | 269 | | #if defined(LZO1Z) | 270 | | m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); | 271 | | last_m_off = m_off; | 272 | | #else | 273 | | m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); | 274 | | #endif | 275 | | #else /* !COPY_DICT */ | 276 | | #if defined(LZO1Z) | 277 | | { | 278 | | lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); | 279 | | m_pos = op - off; | 280 | | last_m_off = off; | 281 | | } | 282 | | #elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) | 283 | | m_pos = op - 1; | 284 | 226k | m_pos -= UA_GET_LE16(ip) >> 2; | 285 | | #else | 286 | | m_pos = op - 1; | 287 | | m_pos -= (ip[0] >> 2) + (ip[1] << 6); | 288 | | #endif | 289 | 226k | #endif /* COPY_DICT */ | 290 | 226k | ip += 2; | 291 | 226k | } | 292 | 376k | else if (t >= 16) /* a M4 match */ | 293 | 41.2k | { | 294 | | #if defined(COPY_DICT) | 295 | | m_off = (t & 8) << 11; | 296 | | #else /* !COPY_DICT */ | 297 | 41.2k | m_pos = op; | 298 | 41.2k | m_pos -= (t & 8) << 11; | 299 | 41.2k | #endif /* COPY_DICT */ | 300 | 41.2k | t &= 7; | 301 | 41.2k | if (t == 0) | 302 | 15.8k | { | 303 | 25.7k | while (*ip == 0) | 304 | 9.91k | { | 305 | 9.91k | t += 255; | 306 | 9.91k | ip++; | 307 | 9.91k | TEST_OV(t); | 308 | 9.91k | NEED_IP(1); | 309 | 9.91k | } | 310 | 15.8k | t += 7 + *ip++; | 311 | 15.8k | NEED_IP(2); | 312 | 15.8k | } | 313 | | #if defined(COPY_DICT) | 314 | | #if defined(LZO1Z) | 315 | | m_off += (ip[0] << 6) + (ip[1] >> 2); | 316 | | #else | 317 | | m_off += (ip[0] >> 2) + (ip[1] << 6); | 318 | | #endif | 319 | | ip += 2; | 320 | | if (m_off == 0) | 321 | | goto eof_found; | 322 | | m_off += 0x4000; | 323 | | #if defined(LZO1Z) | 324 | | last_m_off = m_off; | 325 | | #endif | 326 | | #else /* !COPY_DICT */ | 327 | | #if defined(LZO1Z) | 328 | | m_pos -= (ip[0] << 6) + (ip[1] >> 2); | 329 | | #elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) | 330 | 41.2k | m_pos -= UA_GET_LE16(ip) >> 2; | 331 | | #else | 332 | | m_pos -= (ip[0] >> 2) + (ip[1] << 6); | 333 | | #endif | 334 | 41.2k | ip += 2; | 335 | 41.2k | if (m_pos == op) | 336 | 1.86k | goto eof_found; | 337 | 39.3k | m_pos -= 0x4000; | 338 | | #if defined(LZO1Z) | 339 | | last_m_off = pd((const lzo_bytep)op, m_pos); | 340 | | #endif | 341 | 39.3k | #endif /* COPY_DICT */ | 342 | 39.3k | } | 343 | 335k | else /* a M1 match */ | 344 | 335k | { | 345 | | #if defined(COPY_DICT) | 346 | | #if defined(LZO1Z) | 347 | | m_off = 1 + (t << 6) + (*ip++ >> 2); | 348 | | last_m_off = m_off; | 349 | | #else | 350 | | m_off = 1 + (t >> 2) + (*ip++ << 2); | 351 | | #endif | 352 | | NEED_OP(2); | 353 | | t = 2; COPY_DICT(t,m_off) | 354 | | #else /* !COPY_DICT */ | 355 | | #if defined(LZO1Z) | 356 | | t = 1 + (t << 6) + (*ip++ >> 2); | 357 | | m_pos = op - t; | 358 | | last_m_off = t; | 359 | | #else | 360 | 335k | m_pos = op - 1; | 361 | 335k | m_pos -= t >> 2; | 362 | 335k | m_pos -= *ip++ << 2; | 363 | 335k | #endif | 364 | 335k | TEST_LB(m_pos); NEED_OP(2); | 365 | 335k | *op++ = *m_pos++; *op++ = *m_pos; | 366 | 335k | #endif /* COPY_DICT */ | 367 | 335k | goto match_done; | 368 | 335k | } | 369 | | | 370 | | /* copy match */ | 371 | | #if defined(COPY_DICT) | 372 | | | 373 | | NEED_OP(t+3-1); | 374 | | t += 3-1; COPY_DICT(t,m_off) | 375 | | | 376 | | #else /* !COPY_DICT */ | 377 | | | 378 | 265k | TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); | 379 | 265k | #if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) | 380 | 265k | if (op - m_pos >= 8) | 381 | 252k | { | 382 | 252k | t += (3 - 1); | 383 | 252k | if (t >= 8) do | 384 | 1.57M | { | 385 | 1.57M | UA_COPY8(op,m_pos); | 386 | 1.57M | op += 8; m_pos += 8; t -= 8; | 387 | 1.57M | } while (t >= 8); | 388 | 252k | if (t >= 4) | 389 | 129k | { | 390 | 129k | UA_COPY4(op,m_pos); | 391 | 129k | op += 4; m_pos += 4; t -= 4; | 392 | 129k | } | 393 | 252k | if (t > 0) | 394 | 178k | { | 395 | 178k | *op++ = m_pos[0]; | 396 | 178k | if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } } | 397 | 178k | } | 398 | 252k | } | 399 | 12.5k | else | 400 | | #elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) | 401 | | #if !(LZO_OPT_UNALIGNED32) | 402 | | if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) | 403 | | { | 404 | | assert((op - m_pos) >= 4); /* both pointers are aligned */ | 405 | | #else | 406 | | if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) | 407 | | { | 408 | | #endif | 409 | | UA_COPY4(op,m_pos); | 410 | | op += 4; m_pos += 4; t -= 4 - (3 - 1); | 411 | | do { | 412 | | UA_COPY4(op,m_pos); | 413 | | op += 4; m_pos += 4; t -= 4; | 414 | | } while (t >= 4); | 415 | | if (t > 0) do *op++ = *m_pos++; while (--t > 0); | 416 | | } | 417 | | else | 418 | | #endif | 419 | 12.5k | { | 420 | 308k | copy_match: | 421 | 308k | *op++ = *m_pos++; *op++ = *m_pos++; | 422 | 9.22M | do *op++ = *m_pos++; while (--t > 0); | 423 | 308k | } | 424 | | | 425 | 265k | #endif /* COPY_DICT */ | 426 | | | 427 | 901k | match_done: | 428 | | #if defined(LZO1Z) | 429 | | t = ip[-1] & 3; | 430 | | #else | 431 | 901k | t = ip[-2] & 3; | 432 | 901k | #endif | 433 | 901k | if (t == 0) | 434 | 298k | break; | 435 | | | 436 | | /* copy literals */ | 437 | 603k | match_next: | 438 | 603k | assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3); | 439 | | #if 0 | 440 | | do *op++ = *ip++; while (--t > 0); | 441 | | #else | 442 | 603k | *op++ = *ip++; | 443 | 603k | if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } | 444 | 603k | #endif | 445 | 603k | t = *ip++; | 446 | 603k | } | 447 | 0 | } | 448 | | | 449 | 1.86k | eof_found: | 450 | 1.86k | *out_len = pd(op, out); | 451 | 1.86k | return (ip == ip_end ? LZO_E_OK : | 452 | 1.86k | (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); | 453 | | | 454 | | | 455 | | #if defined(HAVE_NEED_IP) | 456 | | input_overrun: | 457 | | *out_len = pd(op, out); | 458 | | return LZO_E_INPUT_OVERRUN; | 459 | | #endif | 460 | | | 461 | | #if defined(HAVE_NEED_OP) | 462 | | output_overrun: | 463 | | *out_len = pd(op, out); | 464 | | return LZO_E_OUTPUT_OVERRUN; | 465 | | #endif | 466 | | | 467 | | #if defined(LZO_TEST_OVERRUN_LOOKBEHIND) | 468 | | lookbehind_overrun: | 469 | | *out_len = pd(op, out); | 470 | | return LZO_E_LOOKBEHIND_OVERRUN; | 471 | | #endif | 472 | 478 | } |
Line | Count | Source | 42 | 1.68k | { | 43 | 1.68k | lzo_bytep op; | 44 | 1.68k | const lzo_bytep ip; | 45 | 1.68k | lzo_uint t; | 46 | | #if defined(COPY_DICT) | 47 | | lzo_uint m_off; | 48 | | const lzo_bytep dict_end; | 49 | | #else | 50 | 1.68k | const lzo_bytep m_pos; | 51 | 1.68k | #endif | 52 | | | 53 | 1.68k | const lzo_bytep const ip_end = in + in_len; | 54 | | #if defined(HAVE_ANY_OP) | 55 | | lzo_bytep const op_end = out + *out_len; | 56 | | #endif | 57 | 1.68k | #if defined(LZO1Z) | 58 | 1.68k | lzo_uint last_m_off = 0; | 59 | 1.68k | #endif | 60 | | | 61 | 1.68k | LZO_UNUSED(wrkmem); | 62 | | | 63 | | #if defined(COPY_DICT) | 64 | | if (dict) | 65 | | { | 66 | | if (dict_len > M4_MAX_OFFSET) | 67 | | { | 68 | | dict += dict_len - M4_MAX_OFFSET; | 69 | | dict_len = M4_MAX_OFFSET; | 70 | | } | 71 | | dict_end = dict + dict_len; | 72 | | } | 73 | | else | 74 | | { | 75 | | dict_len = 0; | 76 | | dict_end = NULL; | 77 | | } | 78 | | #endif /* COPY_DICT */ | 79 | | | 80 | 1.68k | *out_len = 0; | 81 | | | 82 | 1.68k | op = out; | 83 | 1.68k | ip = in; | 84 | | | 85 | 1.68k | NEED_IP(1); | 86 | 1.68k | if (*ip > 17) | 87 | 1.64k | { | 88 | 1.64k | t = *ip++ - 17; | 89 | 1.64k | if (t < 4) | 90 | 732 | goto match_next; | 91 | 1.64k | assert(t > 0); NEED_OP(t); NEED_IP(t+3); | 92 | 18.5k | do *op++ = *ip++; while (--t > 0); | 93 | 910 | goto first_literal_run; | 94 | 1.64k | } | 95 | | | 96 | 45 | for (;;) | 97 | 294k | { | 98 | 294k | NEED_IP(3); | 99 | 294k | t = *ip++; | 100 | 294k | if (t >= 16) | 101 | 227k | goto match; | 102 | | /* a literal run */ | 103 | 66.2k | if (t == 0) | 104 | 24.0k | { | 105 | 53.2k | while (*ip == 0) | 106 | 29.2k | { | 107 | 29.2k | t += 255; | 108 | 29.2k | ip++; | 109 | 29.2k | TEST_IV(t); | 110 | 29.2k | NEED_IP(1); | 111 | 29.2k | } | 112 | 24.0k | t += 15 + *ip++; | 113 | 24.0k | } | 114 | | /* copy literals */ | 115 | 66.2k | assert(t > 0); NEED_OP(t+3); NEED_IP(t+6); | 116 | 66.2k | #if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) | 117 | 66.2k | t += 3; | 118 | 66.2k | if (t >= 8) do | 119 | 1.16M | { | 120 | 1.16M | UA_COPY8(op,ip); | 121 | 1.16M | op += 8; ip += 8; t -= 8; | 122 | 1.16M | } while (t >= 8); | 123 | 66.2k | if (t >= 4) | 124 | 41.5k | { | 125 | 41.5k | UA_COPY4(op,ip); | 126 | 41.5k | op += 4; ip += 4; t -= 4; | 127 | 41.5k | } | 128 | 66.2k | if (t > 0) | 129 | 46.2k | { | 130 | 46.2k | *op++ = *ip++; | 131 | 46.2k | if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } | 132 | 46.2k | } | 133 | | #elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) | 134 | | #if !(LZO_OPT_UNALIGNED32) | 135 | | if (PTR_ALIGNED2_4(op,ip)) | 136 | | { | 137 | | #endif | 138 | | UA_COPY4(op,ip); | 139 | | op += 4; ip += 4; | 140 | | if (--t > 0) | 141 | | { | 142 | | if (t >= 4) | 143 | | { | 144 | | do { | 145 | | UA_COPY4(op,ip); | 146 | | op += 4; ip += 4; t -= 4; | 147 | | } while (t >= 4); | 148 | | if (t > 0) do *op++ = *ip++; while (--t > 0); | 149 | | } | 150 | | else | 151 | | do *op++ = *ip++; while (--t > 0); | 152 | | } | 153 | | #if !(LZO_OPT_UNALIGNED32) | 154 | | } | 155 | | else | 156 | | #endif | 157 | | #endif | 158 | | #if !(LZO_OPT_UNALIGNED32) | 159 | | { | 160 | | *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; | 161 | | do *op++ = *ip++; while (--t > 0); | 162 | | } | 163 | | #endif | 164 | | | 165 | | | 166 | 67.1k | first_literal_run: | 167 | | | 168 | | | 169 | 67.1k | t = *ip++; | 170 | 67.1k | if (t >= 16) | 171 | 61.8k | goto match; | 172 | | #if defined(COPY_DICT) | 173 | | #if defined(LZO1Z) | 174 | | m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); | 175 | | last_m_off = m_off; | 176 | | #else | 177 | | m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); | 178 | | #endif | 179 | | NEED_OP(3); | 180 | | t = 3; COPY_DICT(t,m_off) | 181 | | #else /* !COPY_DICT */ | 182 | 5.29k | #if defined(LZO1Z) | 183 | 5.29k | t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); | 184 | 5.29k | m_pos = op - t; | 185 | 5.29k | last_m_off = t; | 186 | | #else | 187 | | m_pos = op - (1 + M2_MAX_OFFSET); | 188 | | m_pos -= t >> 2; | 189 | | m_pos -= *ip++ << 2; | 190 | | #endif | 191 | 5.29k | TEST_LB(m_pos); NEED_OP(3); | 192 | 5.29k | *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; | 193 | 5.29k | #endif /* COPY_DICT */ | 194 | 5.29k | goto match_done; | 195 | | | 196 | | | 197 | | /* handle matches */ | 198 | 745k | for (;;) { | 199 | 1.03M | match: | 200 | 1.03M | if (t >= 64) /* a M2 match */ | 201 | 317k | { | 202 | | #if defined(COPY_DICT) | 203 | | #if defined(LZO1X) | 204 | | m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); | 205 | | t = (t >> 5) - 1; | 206 | | #elif defined(LZO1Y) | 207 | | m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); | 208 | | t = (t >> 4) - 3; | 209 | | #elif defined(LZO1Z) | 210 | | m_off = t & 0x1f; | 211 | | if (m_off >= 0x1c) | 212 | | m_off = last_m_off; | 213 | | else | 214 | | { | 215 | | m_off = 1 + (m_off << 6) + (*ip++ >> 2); | 216 | | last_m_off = m_off; | 217 | | } | 218 | | t = (t >> 5) - 1; | 219 | | #endif | 220 | | #else /* !COPY_DICT */ | 221 | | #if defined(LZO1X) | 222 | | m_pos = op - 1; | 223 | | m_pos -= (t >> 2) & 7; | 224 | | m_pos -= *ip++ << 3; | 225 | | t = (t >> 5) - 1; | 226 | | #elif defined(LZO1Y) | 227 | | m_pos = op - 1; | 228 | | m_pos -= (t >> 2) & 3; | 229 | | m_pos -= *ip++ << 2; | 230 | | t = (t >> 4) - 3; | 231 | | #elif defined(LZO1Z) | 232 | | { | 233 | 317k | lzo_uint off = t & 0x1f; | 234 | 317k | m_pos = op; | 235 | 317k | if (off >= 0x1c) | 236 | 12.2k | { | 237 | 12.2k | assert(last_m_off > 0); | 238 | 12.2k | m_pos -= last_m_off; | 239 | 12.2k | } | 240 | 305k | else | 241 | 305k | { | 242 | 305k | off = 1 + (off << 6) + (*ip++ >> 2); | 243 | 305k | m_pos -= off; | 244 | 305k | last_m_off = off; | 245 | 305k | } | 246 | 317k | } | 247 | 317k | t = (t >> 5) - 1; | 248 | 317k | #endif | 249 | 317k | TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); | 250 | 317k | goto copy_match; | 251 | 317k | #endif /* COPY_DICT */ | 252 | 317k | } | 253 | 717k | else if (t >= 32) /* a M3 match */ | 254 | 241k | { | 255 | 241k | t &= 31; | 256 | 241k | if (t == 0) | 257 | 39.9k | { | 258 | 83.3k | while (*ip == 0) | 259 | 43.3k | { | 260 | 43.3k | t += 255; | 261 | 43.3k | ip++; | 262 | 43.3k | TEST_OV(t); | 263 | 43.3k | NEED_IP(1); | 264 | 43.3k | } | 265 | 39.9k | t += 31 + *ip++; | 266 | 39.9k | NEED_IP(2); | 267 | 39.9k | } | 268 | | #if defined(COPY_DICT) | 269 | | #if defined(LZO1Z) | 270 | | m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); | 271 | | last_m_off = m_off; | 272 | | #else | 273 | | m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); | 274 | | #endif | 275 | | #else /* !COPY_DICT */ | 276 | 241k | #if defined(LZO1Z) | 277 | 241k | { | 278 | 241k | lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); | 279 | 241k | m_pos = op - off; | 280 | 241k | last_m_off = off; | 281 | 241k | } | 282 | | #elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) | 283 | | m_pos = op - 1; | 284 | | m_pos -= UA_GET_LE16(ip) >> 2; | 285 | | #else | 286 | | m_pos = op - 1; | 287 | | m_pos -= (ip[0] >> 2) + (ip[1] << 6); | 288 | | #endif | 289 | 241k | #endif /* COPY_DICT */ | 290 | 241k | ip += 2; | 291 | 241k | } | 292 | 476k | else if (t >= 16) /* a M4 match */ | 293 | 52.4k | { | 294 | | #if defined(COPY_DICT) | 295 | | m_off = (t & 8) << 11; | 296 | | #else /* !COPY_DICT */ | 297 | 52.4k | m_pos = op; | 298 | 52.4k | m_pos -= (t & 8) << 11; | 299 | 52.4k | #endif /* COPY_DICT */ | 300 | 52.4k | t &= 7; | 301 | 52.4k | if (t == 0) | 302 | 18.6k | { | 303 | 27.0k | while (*ip == 0) | 304 | 8.35k | { | 305 | 8.35k | t += 255; | 306 | 8.35k | ip++; | 307 | 8.35k | TEST_OV(t); | 308 | 8.35k | NEED_IP(1); | 309 | 8.35k | } | 310 | 18.6k | t += 7 + *ip++; | 311 | 18.6k | NEED_IP(2); | 312 | 18.6k | } | 313 | | #if defined(COPY_DICT) | 314 | | #if defined(LZO1Z) | 315 | | m_off += (ip[0] << 6) + (ip[1] >> 2); | 316 | | #else | 317 | | m_off += (ip[0] >> 2) + (ip[1] << 6); | 318 | | #endif | 319 | | ip += 2; | 320 | | if (m_off == 0) | 321 | | goto eof_found; | 322 | | m_off += 0x4000; | 323 | | #if defined(LZO1Z) | 324 | | last_m_off = m_off; | 325 | | #endif | 326 | | #else /* !COPY_DICT */ | 327 | 52.4k | #if defined(LZO1Z) | 328 | 52.4k | m_pos -= (ip[0] << 6) + (ip[1] >> 2); | 329 | | #elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) | 330 | | m_pos -= UA_GET_LE16(ip) >> 2; | 331 | | #else | 332 | | m_pos -= (ip[0] >> 2) + (ip[1] << 6); | 333 | | #endif | 334 | 52.4k | ip += 2; | 335 | 52.4k | if (m_pos == op) | 336 | 1.68k | goto eof_found; | 337 | 50.7k | m_pos -= 0x4000; | 338 | 50.7k | #if defined(LZO1Z) | 339 | 50.7k | last_m_off = pd((const lzo_bytep)op, m_pos); | 340 | 50.7k | #endif | 341 | 50.7k | #endif /* COPY_DICT */ | 342 | 50.7k | } | 343 | 423k | else /* a M1 match */ | 344 | 423k | { | 345 | | #if defined(COPY_DICT) | 346 | | #if defined(LZO1Z) | 347 | | m_off = 1 + (t << 6) + (*ip++ >> 2); | 348 | | last_m_off = m_off; | 349 | | #else | 350 | | m_off = 1 + (t >> 2) + (*ip++ << 2); | 351 | | #endif | 352 | | NEED_OP(2); | 353 | | t = 2; COPY_DICT(t,m_off) | 354 | | #else /* !COPY_DICT */ | 355 | 423k | #if defined(LZO1Z) | 356 | 423k | t = 1 + (t << 6) + (*ip++ >> 2); | 357 | 423k | m_pos = op - t; | 358 | 423k | last_m_off = t; | 359 | | #else | 360 | | m_pos = op - 1; | 361 | | m_pos -= t >> 2; | 362 | | m_pos -= *ip++ << 2; | 363 | | #endif | 364 | 423k | TEST_LB(m_pos); NEED_OP(2); | 365 | 423k | *op++ = *m_pos++; *op++ = *m_pos; | 366 | 423k | #endif /* COPY_DICT */ | 367 | 423k | goto match_done; | 368 | 423k | } | 369 | | | 370 | | /* copy match */ | 371 | | #if defined(COPY_DICT) | 372 | | | 373 | | NEED_OP(t+3-1); | 374 | | t += 3-1; COPY_DICT(t,m_off) | 375 | | | 376 | | #else /* !COPY_DICT */ | 377 | | | 378 | 292k | TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); | 379 | 292k | #if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) | 380 | 292k | if (op - m_pos >= 8) | 381 | 274k | { | 382 | 274k | t += (3 - 1); | 383 | 274k | if (t >= 8) do | 384 | 1.43M | { | 385 | 1.43M | UA_COPY8(op,m_pos); | 386 | 1.43M | op += 8; m_pos += 8; t -= 8; | 387 | 1.43M | } while (t >= 8); | 388 | 274k | if (t >= 4) | 389 | 106k | { | 390 | 106k | UA_COPY4(op,m_pos); | 391 | 106k | op += 4; m_pos += 4; t -= 4; | 392 | 106k | } | 393 | 274k | if (t > 0) | 394 | 217k | { | 395 | 217k | *op++ = m_pos[0]; | 396 | 217k | if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } } | 397 | 217k | } | 398 | 274k | } | 399 | 17.4k | else | 400 | | #elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) | 401 | | #if !(LZO_OPT_UNALIGNED32) | 402 | | if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) | 403 | | { | 404 | | assert((op - m_pos) >= 4); /* both pointers are aligned */ | 405 | | #else | 406 | | if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) | 407 | | { | 408 | | #endif | 409 | | UA_COPY4(op,m_pos); | 410 | | op += 4; m_pos += 4; t -= 4 - (3 - 1); | 411 | | do { | 412 | | UA_COPY4(op,m_pos); | 413 | | op += 4; m_pos += 4; t -= 4; | 414 | | } while (t >= 4); | 415 | | if (t > 0) do *op++ = *m_pos++; while (--t > 0); | 416 | | } | 417 | | else | 418 | | #endif | 419 | 17.4k | { | 420 | 335k | copy_match: | 421 | 335k | *op++ = *m_pos++; *op++ = *m_pos++; | 422 | 9.13M | do *op++ = *m_pos++; while (--t > 0); | 423 | 335k | } | 424 | | | 425 | 292k | #endif /* COPY_DICT */ | 426 | | | 427 | 1.03M | match_done: | 428 | 1.03M | #if defined(LZO1Z) | 429 | 1.03M | t = ip[-1] & 3; | 430 | | #else | 431 | | t = ip[-2] & 3; | 432 | | #endif | 433 | 1.03M | if (t == 0) | 434 | 294k | break; | 435 | | | 436 | | /* copy literals */ | 437 | 745k | match_next: | 438 | 745k | assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3); | 439 | | #if 0 | 440 | | do *op++ = *ip++; while (--t > 0); | 441 | | #else | 442 | 745k | *op++ = *ip++; | 443 | 745k | if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } | 444 | 745k | #endif | 445 | 745k | t = *ip++; | 446 | 745k | } | 447 | 0 | } | 448 | | | 449 | 1.68k | eof_found: | 450 | 1.68k | *out_len = pd(op, out); | 451 | 1.68k | return (ip == ip_end ? LZO_E_OK : | 452 | 1.68k | (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); | 453 | | | 454 | | | 455 | | #if defined(HAVE_NEED_IP) | 456 | | input_overrun: | 457 | | *out_len = pd(op, out); | 458 | | return LZO_E_INPUT_OVERRUN; | 459 | | #endif | 460 | | | 461 | | #if defined(HAVE_NEED_OP) | 462 | | output_overrun: | 463 | | *out_len = pd(op, out); | 464 | | return LZO_E_OUTPUT_OVERRUN; | 465 | | #endif | 466 | | | 467 | | #if defined(LZO_TEST_OVERRUN_LOOKBEHIND) | 468 | | lookbehind_overrun: | 469 | | *out_len = pd(op, out); | 470 | | return LZO_E_LOOKBEHIND_OVERRUN; | 471 | | #endif | 472 | 45 | } |
Line | Count | Source | 42 | 615 | { | 43 | 615 | lzo_bytep op; | 44 | 615 | const lzo_bytep ip; | 45 | 615 | lzo_uint t; | 46 | | #if defined(COPY_DICT) | 47 | | lzo_uint m_off; | 48 | | const lzo_bytep dict_end; | 49 | | #else | 50 | 615 | const lzo_bytep m_pos; | 51 | 615 | #endif | 52 | | | 53 | 615 | const lzo_bytep const ip_end = in + in_len; | 54 | 615 | #if defined(HAVE_ANY_OP) | 55 | 615 | lzo_bytep const op_end = out + *out_len; | 56 | 615 | #endif | 57 | | #if defined(LZO1Z) | 58 | | lzo_uint last_m_off = 0; | 59 | | #endif | 60 | | | 61 | 615 | LZO_UNUSED(wrkmem); | 62 | | | 63 | | #if defined(COPY_DICT) | 64 | | if (dict) | 65 | | { | 66 | | if (dict_len > M4_MAX_OFFSET) | 67 | | { | 68 | | dict += dict_len - M4_MAX_OFFSET; | 69 | | dict_len = M4_MAX_OFFSET; | 70 | | } | 71 | | dict_end = dict + dict_len; | 72 | | } | 73 | | else | 74 | | { | 75 | | dict_len = 0; | 76 | | dict_end = NULL; | 77 | | } | 78 | | #endif /* COPY_DICT */ | 79 | | | 80 | 615 | *out_len = 0; | 81 | | | 82 | 615 | op = out; | 83 | 615 | ip = in; | 84 | | | 85 | 615 | NEED_IP(1); | 86 | 615 | if (*ip > 17) | 87 | 379 | { | 88 | 379 | t = *ip++ - 17; | 89 | 379 | if (t < 4) | 90 | 274 | goto match_next; | 91 | 379 | assert(t > 0); NEED_OP(t); NEED_IP(t+3); | 92 | 1.66k | do *op++ = *ip++; while (--t > 0); | 93 | 90 | goto first_literal_run; | 94 | 105 | } | 95 | | | 96 | 236 | for (;;) | 97 | 43.0k | { | 98 | 43.0k | NEED_IP(3); | 99 | 42.9k | t = *ip++; | 100 | 42.9k | if (t >= 16) | 101 | 26.4k | goto match; | 102 | | /* a literal run */ | 103 | 16.4k | if (t == 0) | 104 | 9.99k | { | 105 | 3.80M | while (*ip == 0) | 106 | 3.79M | { | 107 | 3.79M | t += 255; | 108 | 3.79M | ip++; | 109 | 3.79M | TEST_IV(t); | 110 | 3.79M | NEED_IP(1); | 111 | 3.79M | } | 112 | 9.97k | t += 15 + *ip++; | 113 | 9.97k | } | 114 | | /* copy literals */ | 115 | 16.4k | assert(t > 0); NEED_OP(t+3); NEED_IP(t+6); | 116 | 16.3k | #if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) | 117 | 16.3k | t += 3; | 118 | 16.3k | if (t >= 8) do | 119 | 385k | { | 120 | 385k | UA_COPY8(op,ip); | 121 | 385k | op += 8; ip += 8; t -= 8; | 122 | 385k | } while (t >= 8); | 123 | 16.3k | if (t >= 4) | 124 | 8.19k | { | 125 | 8.19k | UA_COPY4(op,ip); | 126 | 8.19k | op += 4; ip += 4; t -= 4; | 127 | 8.19k | } | 128 | 16.3k | if (t > 0) | 129 | 12.9k | { | 130 | 12.9k | *op++ = *ip++; | 131 | 12.9k | if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } | 132 | 12.9k | } | 133 | | #elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) | 134 | | #if !(LZO_OPT_UNALIGNED32) | 135 | | if (PTR_ALIGNED2_4(op,ip)) | 136 | | { | 137 | | #endif | 138 | | UA_COPY4(op,ip); | 139 | | op += 4; ip += 4; | 140 | | if (--t > 0) | 141 | | { | 142 | | if (t >= 4) | 143 | | { | 144 | | do { | 145 | | UA_COPY4(op,ip); | 146 | | op += 4; ip += 4; t -= 4; | 147 | | } while (t >= 4); | 148 | | if (t > 0) do *op++ = *ip++; while (--t > 0); | 149 | | } | 150 | | else | 151 | | do *op++ = *ip++; while (--t > 0); | 152 | | } | 153 | | #if !(LZO_OPT_UNALIGNED32) | 154 | | } | 155 | | else | 156 | | #endif | 157 | | #endif | 158 | | #if !(LZO_OPT_UNALIGNED32) | 159 | | { | 160 | | *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; | 161 | | do *op++ = *ip++; while (--t > 0); | 162 | | } | 163 | | #endif | 164 | | | 165 | | | 166 | 16.3k | first_literal_run: | 167 | | | 168 | | | 169 | 16.3k | t = *ip++; | 170 | 16.3k | if (t >= 16) | 171 | 6.15k | goto match; | 172 | | #if defined(COPY_DICT) | 173 | | #if defined(LZO1Z) | 174 | | m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); | 175 | | last_m_off = m_off; | 176 | | #else | 177 | | m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); | 178 | | #endif | 179 | | NEED_OP(3); | 180 | | t = 3; COPY_DICT(t,m_off) | 181 | | #else /* !COPY_DICT */ | 182 | | #if defined(LZO1Z) | 183 | | t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); | 184 | | m_pos = op - t; | 185 | | last_m_off = t; | 186 | | #else | 187 | 10.2k | m_pos = op - (1 + M2_MAX_OFFSET); | 188 | 10.2k | m_pos -= t >> 2; | 189 | 10.2k | m_pos -= *ip++ << 2; | 190 | 10.2k | #endif | 191 | 10.2k | TEST_LB(m_pos); NEED_OP(3); | 192 | 10.1k | *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; | 193 | 10.1k | #endif /* COPY_DICT */ | 194 | 10.1k | goto match_done; | 195 | | | 196 | | | 197 | | /* handle matches */ | 198 | 88.9k | for (;;) { | 199 | 121k | match: | 200 | 121k | if (t >= 64) /* a M2 match */ | 201 | 41.4k | { | 202 | | #if defined(COPY_DICT) | 203 | | #if defined(LZO1X) | 204 | | m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); | 205 | | t = (t >> 5) - 1; | 206 | | #elif defined(LZO1Y) | 207 | | m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); | 208 | | t = (t >> 4) - 3; | 209 | | #elif defined(LZO1Z) | 210 | | m_off = t & 0x1f; | 211 | | if (m_off >= 0x1c) | 212 | | m_off = last_m_off; | 213 | | else | 214 | | { | 215 | | m_off = 1 + (m_off << 6) + (*ip++ >> 2); | 216 | | last_m_off = m_off; | 217 | | } | 218 | | t = (t >> 5) - 1; | 219 | | #endif | 220 | | #else /* !COPY_DICT */ | 221 | 41.4k | #if defined(LZO1X) | 222 | 41.4k | m_pos = op - 1; | 223 | 41.4k | m_pos -= (t >> 2) & 7; | 224 | 41.4k | m_pos -= *ip++ << 3; | 225 | 41.4k | t = (t >> 5) - 1; | 226 | | #elif defined(LZO1Y) | 227 | | m_pos = op - 1; | 228 | | m_pos -= (t >> 2) & 3; | 229 | | m_pos -= *ip++ << 2; | 230 | | t = (t >> 4) - 3; | 231 | | #elif defined(LZO1Z) | 232 | | { | 233 | | lzo_uint off = t & 0x1f; | 234 | | m_pos = op; | 235 | | if (off >= 0x1c) | 236 | | { | 237 | | assert(last_m_off > 0); | 238 | | m_pos -= last_m_off; | 239 | | } | 240 | | else | 241 | | { | 242 | | off = 1 + (off << 6) + (*ip++ >> 2); | 243 | | m_pos -= off; | 244 | | last_m_off = off; | 245 | | } | 246 | | } | 247 | | t = (t >> 5) - 1; | 248 | | #endif | 249 | 41.4k | TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); | 250 | 41.4k | goto copy_match; | 251 | 41.4k | #endif /* COPY_DICT */ | 252 | 41.4k | } | 253 | 80.0k | else if (t >= 32) /* a M3 match */ | 254 | 32.2k | { | 255 | 32.2k | t &= 31; | 256 | 32.2k | if (t == 0) | 257 | 2.81k | { | 258 | 1.23M | while (*ip == 0) | 259 | 1.23M | { | 260 | 1.23M | t += 255; | 261 | 1.23M | ip++; | 262 | 1.23M | TEST_OV(t); | 263 | 1.23M | NEED_IP(1); | 264 | 1.23M | } | 265 | 2.79k | t += 31 + *ip++; | 266 | 2.79k | NEED_IP(2); | 267 | 2.79k | } | 268 | | #if defined(COPY_DICT) | 269 | | #if defined(LZO1Z) | 270 | | m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); | 271 | | last_m_off = m_off; | 272 | | #else | 273 | | m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); | 274 | | #endif | 275 | | #else /* !COPY_DICT */ | 276 | | #if defined(LZO1Z) | 277 | | { | 278 | | lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); | 279 | | m_pos = op - off; | 280 | | last_m_off = off; | 281 | | } | 282 | | #elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) | 283 | 32.1k | m_pos = op - 1; | 284 | 32.1k | m_pos -= UA_GET_LE16(ip) >> 2; | 285 | | #else | 286 | | m_pos = op - 1; | 287 | | m_pos -= (ip[0] >> 2) + (ip[1] << 6); | 288 | | #endif | 289 | 32.1k | #endif /* COPY_DICT */ | 290 | 32.1k | ip += 2; | 291 | 32.1k | } | 292 | 47.8k | else if (t >= 16) /* a M4 match */ | 293 | 9.02k | { | 294 | | #if defined(COPY_DICT) | 295 | | m_off = (t & 8) << 11; | 296 | | #else /* !COPY_DICT */ | 297 | 9.02k | m_pos = op; | 298 | 9.02k | m_pos -= (t & 8) << 11; | 299 | 9.02k | #endif /* COPY_DICT */ | 300 | 9.02k | t &= 7; | 301 | 9.02k | if (t == 0) | 302 | 2.85k | { | 303 | 1.84M | while (*ip == 0) | 304 | 1.83M | { | 305 | 1.83M | t += 255; | 306 | 1.83M | ip++; | 307 | 1.83M | TEST_OV(t); | 308 | 1.83M | NEED_IP(1); | 309 | 1.83M | } | 310 | 2.83k | t += 7 + *ip++; | 311 | 2.83k | NEED_IP(2); | 312 | 2.83k | } | 313 | | #if defined(COPY_DICT) | 314 | | #if defined(LZO1Z) | 315 | | m_off += (ip[0] << 6) + (ip[1] >> 2); | 316 | | #else | 317 | | m_off += (ip[0] >> 2) + (ip[1] << 6); | 318 | | #endif | 319 | | ip += 2; | 320 | | if (m_off == 0) | 321 | | goto eof_found; | 322 | | m_off += 0x4000; | 323 | | #if defined(LZO1Z) | 324 | | last_m_off = m_off; | 325 | | #endif | 326 | | #else /* !COPY_DICT */ | 327 | | #if defined(LZO1Z) | 328 | | m_pos -= (ip[0] << 6) + (ip[1] >> 2); | 329 | | #elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) | 330 | 8.99k | m_pos -= UA_GET_LE16(ip) >> 2; | 331 | | #else | 332 | | m_pos -= (ip[0] >> 2) + (ip[1] << 6); | 333 | | #endif | 334 | 8.99k | ip += 2; | 335 | 8.99k | if (m_pos == op) | 336 | 14 | goto eof_found; | 337 | 8.98k | m_pos -= 0x4000; | 338 | | #if defined(LZO1Z) | 339 | | last_m_off = pd((const lzo_bytep)op, m_pos); | 340 | | #endif | 341 | 8.98k | #endif /* COPY_DICT */ | 342 | 8.98k | } | 343 | 38.8k | else /* a M1 match */ | 344 | 38.8k | { | 345 | | #if defined(COPY_DICT) | 346 | | #if defined(LZO1Z) | 347 | | m_off = 1 + (t << 6) + (*ip++ >> 2); | 348 | | last_m_off = m_off; | 349 | | #else | 350 | | m_off = 1 + (t >> 2) + (*ip++ << 2); | 351 | | #endif | 352 | | NEED_OP(2); | 353 | | t = 2; COPY_DICT(t,m_off) | 354 | | #else /* !COPY_DICT */ | 355 | | #if defined(LZO1Z) | 356 | | t = 1 + (t << 6) + (*ip++ >> 2); | 357 | | m_pos = op - t; | 358 | | last_m_off = t; | 359 | | #else | 360 | 38.8k | m_pos = op - 1; | 361 | 38.8k | m_pos -= t >> 2; | 362 | 38.8k | m_pos -= *ip++ << 2; | 363 | 38.8k | #endif | 364 | 38.8k | TEST_LB(m_pos); NEED_OP(2); | 365 | 38.8k | *op++ = *m_pos++; *op++ = *m_pos; | 366 | 38.8k | #endif /* COPY_DICT */ | 367 | 38.8k | goto match_done; | 368 | 38.8k | } | 369 | | | 370 | | /* copy match */ | 371 | | #if defined(COPY_DICT) | 372 | | | 373 | | NEED_OP(t+3-1); | 374 | | t += 3-1; COPY_DICT(t,m_off) | 375 | | | 376 | | #else /* !COPY_DICT */ | 377 | | | 378 | 41.1k | TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); | 379 | 41.0k | #if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) | 380 | 41.0k | if (op - m_pos >= 8) | 381 | 38.1k | { | 382 | 38.1k | t += (3 - 1); | 383 | 38.1k | if (t >= 8) do | 384 | 699k | { | 385 | 699k | UA_COPY8(op,m_pos); | 386 | 699k | op += 8; m_pos += 8; t -= 8; | 387 | 699k | } while (t >= 8); | 388 | 38.1k | if (t >= 4) | 389 | 22.9k | { | 390 | 22.9k | UA_COPY4(op,m_pos); | 391 | 22.9k | op += 4; m_pos += 4; t -= 4; | 392 | 22.9k | } | 393 | 38.1k | if (t > 0) | 394 | 28.5k | { | 395 | 28.5k | *op++ = m_pos[0]; | 396 | 28.5k | if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } } | 397 | 28.5k | } | 398 | 38.1k | } | 399 | 2.89k | else | 400 | | #elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) | 401 | | #if !(LZO_OPT_UNALIGNED32) | 402 | | if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) | 403 | | { | 404 | | assert((op - m_pos) >= 4); /* both pointers are aligned */ | 405 | | #else | 406 | | if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) | 407 | | { | 408 | | #endif | 409 | | UA_COPY4(op,m_pos); | 410 | | op += 4; m_pos += 4; t -= 4 - (3 - 1); | 411 | | do { | 412 | | UA_COPY4(op,m_pos); | 413 | | op += 4; m_pos += 4; t -= 4; | 414 | | } while (t >= 4); | 415 | | if (t > 0) do *op++ = *m_pos++; while (--t > 0); | 416 | | } | 417 | | else | 418 | | #endif | 419 | 2.89k | { | 420 | 44.3k | copy_match: | 421 | 44.3k | *op++ = *m_pos++; *op++ = *m_pos++; | 422 | 10.6M | do *op++ = *m_pos++; while (--t > 0); | 423 | 44.3k | } | 424 | | | 425 | 41.0k | #endif /* COPY_DICT */ | 426 | | | 427 | 131k | match_done: | 428 | | #if defined(LZO1Z) | 429 | | t = ip[-1] & 3; | 430 | | #else | 431 | 131k | t = ip[-2] & 3; | 432 | 131k | #endif | 433 | 131k | if (t == 0) | 434 | 42.7k | break; | 435 | | | 436 | | /* copy literals */ | 437 | 89.0k | match_next: | 438 | 89.0k | assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3); | 439 | | #if 0 | 440 | | do *op++ = *ip++; while (--t > 0); | 441 | | #else | 442 | 88.9k | *op++ = *ip++; | 443 | 88.9k | if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } | 444 | 88.9k | #endif | 445 | 88.9k | t = *ip++; | 446 | 88.9k | } | 447 | 0 | } | 448 | | | 449 | 14 | eof_found: | 450 | 14 | *out_len = pd(op, out); | 451 | 14 | return (ip == ip_end ? LZO_E_OK : | 452 | 14 | (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); | 453 | | | 454 | | | 455 | 0 | #if defined(HAVE_NEED_IP) | 456 | 385 | input_overrun: | 457 | 385 | *out_len = pd(op, out); | 458 | 385 | return LZO_E_INPUT_OVERRUN; | 459 | 0 | #endif | 460 | | | 461 | 0 | #if defined(HAVE_NEED_OP) | 462 | 61 | output_overrun: | 463 | 61 | *out_len = pd(op, out); | 464 | 61 | return LZO_E_OUTPUT_OVERRUN; | 465 | 0 | #endif | 466 | | | 467 | 0 | #if defined(LZO_TEST_OVERRUN_LOOKBEHIND) | 468 | 155 | lookbehind_overrun: | 469 | 155 | *out_len = pd(op, out); | 470 | 155 | return LZO_E_LOOKBEHIND_OVERRUN; | 471 | 236 | #endif | 472 | 236 | } |
Line | Count | Source | 42 | 627 | { | 43 | 627 | lzo_bytep op; | 44 | 627 | const lzo_bytep ip; | 45 | 627 | lzo_uint t; | 46 | | #if defined(COPY_DICT) | 47 | | lzo_uint m_off; | 48 | | const lzo_bytep dict_end; | 49 | | #else | 50 | 627 | const lzo_bytep m_pos; | 51 | 627 | #endif | 52 | | | 53 | 627 | const lzo_bytep const ip_end = in + in_len; | 54 | 627 | #if defined(HAVE_ANY_OP) | 55 | 627 | lzo_bytep const op_end = out + *out_len; | 56 | 627 | #endif | 57 | | #if defined(LZO1Z) | 58 | | lzo_uint last_m_off = 0; | 59 | | #endif | 60 | | | 61 | 627 | LZO_UNUSED(wrkmem); | 62 | | | 63 | | #if defined(COPY_DICT) | 64 | | if (dict) | 65 | | { | 66 | | if (dict_len > M4_MAX_OFFSET) | 67 | | { | 68 | | dict += dict_len - M4_MAX_OFFSET; | 69 | | dict_len = M4_MAX_OFFSET; | 70 | | } | 71 | | dict_end = dict + dict_len; | 72 | | } | 73 | | else | 74 | | { | 75 | | dict_len = 0; | 76 | | dict_end = NULL; | 77 | | } | 78 | | #endif /* COPY_DICT */ | 79 | | | 80 | 627 | *out_len = 0; | 81 | | | 82 | 627 | op = out; | 83 | 627 | ip = in; | 84 | | | 85 | 627 | NEED_IP(1); | 86 | 627 | if (*ip > 17) | 87 | 365 | { | 88 | 365 | t = *ip++ - 17; | 89 | 365 | if (t < 4) | 90 | 249 | goto match_next; | 91 | 365 | assert(t > 0); NEED_OP(t); NEED_IP(t+3); | 92 | 2.18k | do *op++ = *ip++; while (--t > 0); | 93 | 105 | goto first_literal_run; | 94 | 116 | } | 95 | | | 96 | 262 | for (;;) | 97 | 78.5k | { | 98 | 78.5k | NEED_IP(3); | 99 | 78.5k | t = *ip++; | 100 | 78.5k | if (t >= 16) | 101 | 58.6k | goto match; | 102 | | /* a literal run */ | 103 | 19.8k | if (t == 0) | 104 | 11.4k | { | 105 | 19.1M | while (*ip == 0) | 106 | 19.0M | { | 107 | 19.0M | t += 255; | 108 | 19.0M | ip++; | 109 | 19.0M | TEST_IV(t); | 110 | 19.0M | NEED_IP(1); | 111 | 19.0M | } | 112 | 11.4k | t += 15 + *ip++; | 113 | 11.4k | } | 114 | | /* copy literals */ | 115 | 19.8k | assert(t > 0); NEED_OP(t+3); NEED_IP(t+6); | 116 | 19.7k | #if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) | 117 | 19.7k | t += 3; | 118 | 19.7k | if (t >= 8) do | 119 | 633k | { | 120 | 633k | UA_COPY8(op,ip); | 121 | 633k | op += 8; ip += 8; t -= 8; | 122 | 633k | } while (t >= 8); | 123 | 19.7k | if (t >= 4) | 124 | 11.1k | { | 125 | 11.1k | UA_COPY4(op,ip); | 126 | 11.1k | op += 4; ip += 4; t -= 4; | 127 | 11.1k | } | 128 | 19.7k | if (t > 0) | 129 | 15.4k | { | 130 | 15.4k | *op++ = *ip++; | 131 | 15.4k | if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } | 132 | 15.4k | } | 133 | | #elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) | 134 | | #if !(LZO_OPT_UNALIGNED32) | 135 | | if (PTR_ALIGNED2_4(op,ip)) | 136 | | { | 137 | | #endif | 138 | | UA_COPY4(op,ip); | 139 | | op += 4; ip += 4; | 140 | | if (--t > 0) | 141 | | { | 142 | | if (t >= 4) | 143 | | { | 144 | | do { | 145 | | UA_COPY4(op,ip); | 146 | | op += 4; ip += 4; t -= 4; | 147 | | } while (t >= 4); | 148 | | if (t > 0) do *op++ = *ip++; while (--t > 0); | 149 | | } | 150 | | else | 151 | | do *op++ = *ip++; while (--t > 0); | 152 | | } | 153 | | #if !(LZO_OPT_UNALIGNED32) | 154 | | } | 155 | | else | 156 | | #endif | 157 | | #endif | 158 | | #if !(LZO_OPT_UNALIGNED32) | 159 | | { | 160 | | *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; | 161 | | do *op++ = *ip++; while (--t > 0); | 162 | | } | 163 | | #endif | 164 | | | 165 | | | 166 | 19.8k | first_literal_run: | 167 | | | 168 | | | 169 | 19.8k | t = *ip++; | 170 | 19.8k | if (t >= 16) | 171 | 8.72k | goto match; | 172 | | #if defined(COPY_DICT) | 173 | | #if defined(LZO1Z) | 174 | | m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); | 175 | | last_m_off = m_off; | 176 | | #else | 177 | | m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); | 178 | | #endif | 179 | | NEED_OP(3); | 180 | | t = 3; COPY_DICT(t,m_off) | 181 | | #else /* !COPY_DICT */ | 182 | | #if defined(LZO1Z) | 183 | | t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); | 184 | | m_pos = op - t; | 185 | | last_m_off = t; | 186 | | #else | 187 | 11.0k | m_pos = op - (1 + M2_MAX_OFFSET); | 188 | 11.0k | m_pos -= t >> 2; | 189 | 11.0k | m_pos -= *ip++ << 2; | 190 | 11.0k | #endif | 191 | 11.0k | TEST_LB(m_pos); NEED_OP(3); | 192 | 11.0k | *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; | 193 | 11.0k | #endif /* COPY_DICT */ | 194 | 11.0k | goto match_done; | 195 | | | 196 | | | 197 | | /* handle matches */ | 198 | 102k | for (;;) { | 199 | 169k | match: | 200 | 169k | if (t >= 64) /* a M2 match */ | 201 | 83.2k | { | 202 | | #if defined(COPY_DICT) | 203 | | #if defined(LZO1X) | 204 | | m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); | 205 | | t = (t >> 5) - 1; | 206 | | #elif defined(LZO1Y) | 207 | | m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); | 208 | | t = (t >> 4) - 3; | 209 | | #elif defined(LZO1Z) | 210 | | m_off = t & 0x1f; | 211 | | if (m_off >= 0x1c) | 212 | | m_off = last_m_off; | 213 | | else | 214 | | { | 215 | | m_off = 1 + (m_off << 6) + (*ip++ >> 2); | 216 | | last_m_off = m_off; | 217 | | } | 218 | | t = (t >> 5) - 1; | 219 | | #endif | 220 | | #else /* !COPY_DICT */ | 221 | | #if defined(LZO1X) | 222 | | m_pos = op - 1; | 223 | | m_pos -= (t >> 2) & 7; | 224 | | m_pos -= *ip++ << 3; | 225 | | t = (t >> 5) - 1; | 226 | | #elif defined(LZO1Y) | 227 | | m_pos = op - 1; | 228 | 83.2k | m_pos -= (t >> 2) & 3; | 229 | 83.2k | m_pos -= *ip++ << 2; | 230 | 83.2k | t = (t >> 4) - 3; | 231 | | #elif defined(LZO1Z) | 232 | | { | 233 | | lzo_uint off = t & 0x1f; | 234 | | m_pos = op; | 235 | | if (off >= 0x1c) | 236 | | { | 237 | | assert(last_m_off > 0); | 238 | | m_pos -= last_m_off; | 239 | | } | 240 | | else | 241 | | { | 242 | | off = 1 + (off << 6) + (*ip++ >> 2); | 243 | | m_pos -= off; | 244 | | last_m_off = off; | 245 | | } | 246 | | } | 247 | | t = (t >> 5) - 1; | 248 | | #endif | 249 | 83.2k | TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); | 250 | 83.2k | goto copy_match; | 251 | 83.2k | #endif /* COPY_DICT */ | 252 | 83.2k | } | 253 | 86.5k | else if (t >= 32) /* a M3 match */ | 254 | 27.9k | { | 255 | 27.9k | t &= 31; | 256 | 27.9k | if (t == 0) | 257 | 2.98k | { | 258 | 18.0M | while (*ip == 0) | 259 | 18.0M | { | 260 | 18.0M | t += 255; | 261 | 18.0M | ip++; | 262 | 18.0M | TEST_OV(t); | 263 | 18.0M | NEED_IP(1); | 264 | 18.0M | } | 265 | 2.95k | t += 31 + *ip++; | 266 | 2.95k | NEED_IP(2); | 267 | 2.95k | } | 268 | | #if defined(COPY_DICT) | 269 | | #if defined(LZO1Z) | 270 | | m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); | 271 | | last_m_off = m_off; | 272 | | #else | 273 | | m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); | 274 | | #endif | 275 | | #else /* !COPY_DICT */ | 276 | | #if defined(LZO1Z) | 277 | | { | 278 | | lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); | 279 | | m_pos = op - off; | 280 | | last_m_off = off; | 281 | | } | 282 | | #elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) | 283 | 27.9k | m_pos = op - 1; | 284 | 27.9k | m_pos -= UA_GET_LE16(ip) >> 2; | 285 | | #else | 286 | | m_pos = op - 1; | 287 | | m_pos -= (ip[0] >> 2) + (ip[1] << 6); | 288 | | #endif | 289 | 27.9k | #endif /* COPY_DICT */ | 290 | 27.9k | ip += 2; | 291 | 27.9k | } | 292 | 58.6k | else if (t >= 16) /* a M4 match */ | 293 | 8.64k | { | 294 | | #if defined(COPY_DICT) | 295 | | m_off = (t & 8) << 11; | 296 | | #else /* !COPY_DICT */ | 297 | 8.64k | m_pos = op; | 298 | 8.64k | m_pos -= (t & 8) << 11; | 299 | 8.64k | #endif /* COPY_DICT */ | 300 | 8.64k | t &= 7; | 301 | 8.64k | if (t == 0) | 302 | 2.44k | { | 303 | 6.03M | while (*ip == 0) | 304 | 6.03M | { | 305 | 6.03M | t += 255; | 306 | 6.03M | ip++; | 307 | 6.03M | TEST_OV(t); | 308 | 6.03M | NEED_IP(1); | 309 | 6.03M | } | 310 | 2.42k | t += 7 + *ip++; | 311 | 2.42k | NEED_IP(2); | 312 | 2.42k | } | 313 | | #if defined(COPY_DICT) | 314 | | #if defined(LZO1Z) | 315 | | m_off += (ip[0] << 6) + (ip[1] >> 2); | 316 | | #else | 317 | | m_off += (ip[0] >> 2) + (ip[1] << 6); | 318 | | #endif | 319 | | ip += 2; | 320 | | if (m_off == 0) | 321 | | goto eof_found; | 322 | | m_off += 0x4000; | 323 | | #if defined(LZO1Z) | 324 | | last_m_off = m_off; | 325 | | #endif | 326 | | #else /* !COPY_DICT */ | 327 | | #if defined(LZO1Z) | 328 | | m_pos -= (ip[0] << 6) + (ip[1] >> 2); | 329 | | #elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) | 330 | 8.61k | m_pos -= UA_GET_LE16(ip) >> 2; | 331 | | #else | 332 | | m_pos -= (ip[0] >> 2) + (ip[1] << 6); | 333 | | #endif | 334 | 8.61k | ip += 2; | 335 | 8.61k | if (m_pos == op) | 336 | 10 | goto eof_found; | 337 | 8.60k | m_pos -= 0x4000; | 338 | | #if defined(LZO1Z) | 339 | | last_m_off = pd((const lzo_bytep)op, m_pos); | 340 | | #endif | 341 | 8.60k | #endif /* COPY_DICT */ | 342 | 8.60k | } | 343 | 49.9k | else /* a M1 match */ | 344 | 49.9k | { | 345 | | #if defined(COPY_DICT) | 346 | | #if defined(LZO1Z) | 347 | | m_off = 1 + (t << 6) + (*ip++ >> 2); | 348 | | last_m_off = m_off; | 349 | | #else | 350 | | m_off = 1 + (t >> 2) + (*ip++ << 2); | 351 | | #endif | 352 | | NEED_OP(2); | 353 | | t = 2; COPY_DICT(t,m_off) | 354 | | #else /* !COPY_DICT */ | 355 | | #if defined(LZO1Z) | 356 | | t = 1 + (t << 6) + (*ip++ >> 2); | 357 | | m_pos = op - t; | 358 | | last_m_off = t; | 359 | | #else | 360 | 49.9k | m_pos = op - 1; | 361 | 49.9k | m_pos -= t >> 2; | 362 | 49.9k | m_pos -= *ip++ << 2; | 363 | 49.9k | #endif | 364 | 49.9k | TEST_LB(m_pos); NEED_OP(2); | 365 | 49.9k | *op++ = *m_pos++; *op++ = *m_pos; | 366 | 49.9k | #endif /* COPY_DICT */ | 367 | 49.9k | goto match_done; | 368 | 49.9k | } | 369 | | | 370 | | /* copy match */ | 371 | | #if defined(COPY_DICT) | 372 | | | 373 | | NEED_OP(t+3-1); | 374 | | t += 3-1; COPY_DICT(t,m_off) | 375 | | | 376 | | #else /* !COPY_DICT */ | 377 | | | 378 | 36.5k | TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); | 379 | 36.4k | #if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) | 380 | 36.4k | if (op - m_pos >= 8) | 381 | 33.0k | { | 382 | 33.0k | t += (3 - 1); | 383 | 33.0k | if (t >= 8) do | 384 | 425k | { | 385 | 425k | UA_COPY8(op,m_pos); | 386 | 425k | op += 8; m_pos += 8; t -= 8; | 387 | 425k | } while (t >= 8); | 388 | 33.0k | if (t >= 4) | 389 | 18.8k | { | 390 | 18.8k | UA_COPY4(op,m_pos); | 391 | 18.8k | op += 4; m_pos += 4; t -= 4; | 392 | 18.8k | } | 393 | 33.0k | if (t > 0) | 394 | 25.2k | { | 395 | 25.2k | *op++ = m_pos[0]; | 396 | 25.2k | if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } } | 397 | 25.2k | } | 398 | 33.0k | } | 399 | 3.37k | else | 400 | | #elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) | 401 | | #if !(LZO_OPT_UNALIGNED32) | 402 | | if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) | 403 | | { | 404 | | assert((op - m_pos) >= 4); /* both pointers are aligned */ | 405 | | #else | 406 | | if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) | 407 | | { | 408 | | #endif | 409 | | UA_COPY4(op,m_pos); | 410 | | op += 4; m_pos += 4; t -= 4 - (3 - 1); | 411 | | do { | 412 | | UA_COPY4(op,m_pos); | 413 | | op += 4; m_pos += 4; t -= 4; | 414 | | } while (t >= 4); | 415 | | if (t > 0) do *op++ = *m_pos++; while (--t > 0); | 416 | | } | 417 | | else | 418 | | #endif | 419 | 3.37k | { | 420 | 86.5k | copy_match: | 421 | 86.5k | *op++ = *m_pos++; *op++ = *m_pos++; | 422 | 10.9M | do *op++ = *m_pos++; while (--t > 0); | 423 | 86.5k | } | 424 | | | 425 | 36.4k | #endif /* COPY_DICT */ | 426 | | | 427 | 180k | match_done: | 428 | | #if defined(LZO1Z) | 429 | | t = ip[-1] & 3; | 430 | | #else | 431 | 180k | t = ip[-2] & 3; | 432 | 180k | #endif | 433 | 180k | if (t == 0) | 434 | 78.3k | break; | 435 | | | 436 | | /* copy literals */ | 437 | 102k | match_next: | 438 | 102k | assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3); | 439 | | #if 0 | 440 | | do *op++ = *ip++; while (--t > 0); | 441 | | #else | 442 | 102k | *op++ = *ip++; | 443 | 102k | if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } | 444 | 102k | #endif | 445 | 102k | t = *ip++; | 446 | 102k | } | 447 | 0 | } | 448 | | | 449 | 10 | eof_found: | 450 | 10 | *out_len = pd(op, out); | 451 | 10 | return (ip == ip_end ? LZO_E_OK : | 452 | 10 | (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); | 453 | | | 454 | | | 455 | 0 | #if defined(HAVE_NEED_IP) | 456 | 372 | input_overrun: | 457 | 372 | *out_len = pd(op, out); | 458 | 372 | return LZO_E_INPUT_OVERRUN; | 459 | 0 | #endif | 460 | | | 461 | 0 | #if defined(HAVE_NEED_OP) | 462 | 61 | output_overrun: | 463 | 61 | *out_len = pd(op, out); | 464 | 61 | return LZO_E_OUTPUT_OVERRUN; | 465 | 0 | #endif | 466 | | | 467 | 0 | #if defined(LZO_TEST_OVERRUN_LOOKBEHIND) | 468 | 184 | lookbehind_overrun: | 469 | 184 | *out_len = pd(op, out); | 470 | 184 | return LZO_E_LOOKBEHIND_OVERRUN; | 471 | 262 | #endif | 472 | 262 | } |
Line | Count | Source | 42 | 606 | { | 43 | 606 | lzo_bytep op; | 44 | 606 | const lzo_bytep ip; | 45 | 606 | lzo_uint t; | 46 | | #if defined(COPY_DICT) | 47 | | lzo_uint m_off; | 48 | | const lzo_bytep dict_end; | 49 | | #else | 50 | 606 | const lzo_bytep m_pos; | 51 | 606 | #endif | 52 | | | 53 | 606 | const lzo_bytep const ip_end = in + in_len; | 54 | 606 | #if defined(HAVE_ANY_OP) | 55 | 606 | lzo_bytep const op_end = out + *out_len; | 56 | 606 | #endif | 57 | 606 | #if defined(LZO1Z) | 58 | 606 | lzo_uint last_m_off = 0; | 59 | 606 | #endif | 60 | | | 61 | 606 | LZO_UNUSED(wrkmem); | 62 | | | 63 | | #if defined(COPY_DICT) | 64 | | if (dict) | 65 | | { | 66 | | if (dict_len > M4_MAX_OFFSET) | 67 | | { | 68 | | dict += dict_len - M4_MAX_OFFSET; | 69 | | dict_len = M4_MAX_OFFSET; | 70 | | } | 71 | | dict_end = dict + dict_len; | 72 | | } | 73 | | else | 74 | | { | 75 | | dict_len = 0; | 76 | | dict_end = NULL; | 77 | | } | 78 | | #endif /* COPY_DICT */ | 79 | | | 80 | 606 | *out_len = 0; | 81 | | | 82 | 606 | op = out; | 83 | 606 | ip = in; | 84 | | | 85 | 606 | NEED_IP(1); | 86 | 606 | if (*ip > 17) | 87 | 411 | { | 88 | 411 | t = *ip++ - 17; | 89 | 411 | if (t < 4) | 90 | 298 | goto match_next; | 91 | 411 | assert(t > 0); NEED_OP(t); NEED_IP(t+3); | 92 | 1.54k | do *op++ = *ip++; while (--t > 0); | 93 | 99 | goto first_literal_run; | 94 | 113 | } | 95 | | | 96 | 195 | for (;;) | 97 | 50.0k | { | 98 | 50.0k | NEED_IP(3); | 99 | 49.9k | t = *ip++; | 100 | 49.9k | if (t >= 16) | 101 | 33.0k | goto match; | 102 | | /* a literal run */ | 103 | 16.9k | if (t == 0) | 104 | 7.22k | { | 105 | 3.00M | while (*ip == 0) | 106 | 3.00M | { | 107 | 3.00M | t += 255; | 108 | 3.00M | ip++; | 109 | 3.00M | TEST_IV(t); | 110 | 3.00M | NEED_IP(1); | 111 | 3.00M | } | 112 | 7.20k | t += 15 + *ip++; | 113 | 7.20k | } | 114 | | /* copy literals */ | 115 | 16.9k | assert(t > 0); NEED_OP(t+3); NEED_IP(t+6); | 116 | 16.7k | #if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) | 117 | 16.7k | t += 3; | 118 | 16.7k | if (t >= 8) do | 119 | 427k | { | 120 | 427k | UA_COPY8(op,ip); | 121 | 427k | op += 8; ip += 8; t -= 8; | 122 | 427k | } while (t >= 8); | 123 | 16.7k | if (t >= 4) | 124 | 9.01k | { | 125 | 9.01k | UA_COPY4(op,ip); | 126 | 9.01k | op += 4; ip += 4; t -= 4; | 127 | 9.01k | } | 128 | 16.7k | if (t > 0) | 129 | 10.7k | { | 130 | 10.7k | *op++ = *ip++; | 131 | 10.7k | if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } | 132 | 10.7k | } | 133 | | #elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) | 134 | | #if !(LZO_OPT_UNALIGNED32) | 135 | | if (PTR_ALIGNED2_4(op,ip)) | 136 | | { | 137 | | #endif | 138 | | UA_COPY4(op,ip); | 139 | | op += 4; ip += 4; | 140 | | if (--t > 0) | 141 | | { | 142 | | if (t >= 4) | 143 | | { | 144 | | do { | 145 | | UA_COPY4(op,ip); | 146 | | op += 4; ip += 4; t -= 4; | 147 | | } while (t >= 4); | 148 | | if (t > 0) do *op++ = *ip++; while (--t > 0); | 149 | | } | 150 | | else | 151 | | do *op++ = *ip++; while (--t > 0); | 152 | | } | 153 | | #if !(LZO_OPT_UNALIGNED32) | 154 | | } | 155 | | else | 156 | | #endif | 157 | | #endif | 158 | | #if !(LZO_OPT_UNALIGNED32) | 159 | | { | 160 | | *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; | 161 | | do *op++ = *ip++; while (--t > 0); | 162 | | } | 163 | | #endif | 164 | | | 165 | | | 166 | 16.8k | first_literal_run: | 167 | | | 168 | | | 169 | 16.8k | t = *ip++; | 170 | 16.8k | if (t >= 16) | 171 | 8.42k | goto match; | 172 | | #if defined(COPY_DICT) | 173 | | #if defined(LZO1Z) | 174 | | m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); | 175 | | last_m_off = m_off; | 176 | | #else | 177 | | m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); | 178 | | #endif | 179 | | NEED_OP(3); | 180 | | t = 3; COPY_DICT(t,m_off) | 181 | | #else /* !COPY_DICT */ | 182 | 8.43k | #if defined(LZO1Z) | 183 | 8.43k | t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); | 184 | 8.43k | m_pos = op - t; | 185 | 8.43k | last_m_off = t; | 186 | | #else | 187 | | m_pos = op - (1 + M2_MAX_OFFSET); | 188 | | m_pos -= t >> 2; | 189 | | m_pos -= *ip++ << 2; | 190 | | #endif | 191 | 8.43k | TEST_LB(m_pos); NEED_OP(3); | 192 | 8.41k | *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; | 193 | 8.41k | #endif /* COPY_DICT */ | 194 | 8.41k | goto match_done; | 195 | | | 196 | | | 197 | | /* handle matches */ | 198 | 93.1k | for (;;) { | 199 | 134k | match: | 200 | 134k | if (t >= 64) /* a M2 match */ | 201 | 79.1k | { | 202 | | #if defined(COPY_DICT) | 203 | | #if defined(LZO1X) | 204 | | m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); | 205 | | t = (t >> 5) - 1; | 206 | | #elif defined(LZO1Y) | 207 | | m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); | 208 | | t = (t >> 4) - 3; | 209 | | #elif defined(LZO1Z) | 210 | | m_off = t & 0x1f; | 211 | | if (m_off >= 0x1c) | 212 | | m_off = last_m_off; | 213 | | else | 214 | | { | 215 | | m_off = 1 + (m_off << 6) + (*ip++ >> 2); | 216 | | last_m_off = m_off; | 217 | | } | 218 | | t = (t >> 5) - 1; | 219 | | #endif | 220 | | #else /* !COPY_DICT */ | 221 | | #if defined(LZO1X) | 222 | | m_pos = op - 1; | 223 | | m_pos -= (t >> 2) & 7; | 224 | | m_pos -= *ip++ << 3; | 225 | | t = (t >> 5) - 1; | 226 | | #elif defined(LZO1Y) | 227 | | m_pos = op - 1; | 228 | | m_pos -= (t >> 2) & 3; | 229 | | m_pos -= *ip++ << 2; | 230 | | t = (t >> 4) - 3; | 231 | | #elif defined(LZO1Z) | 232 | | { | 233 | 79.1k | lzo_uint off = t & 0x1f; | 234 | 79.1k | m_pos = op; | 235 | 79.1k | if (off >= 0x1c) | 236 | 18.4k | { | 237 | 18.4k | assert(last_m_off > 0); | 238 | 18.4k | m_pos -= last_m_off; | 239 | 18.4k | } | 240 | 60.6k | else | 241 | 60.6k | { | 242 | 60.6k | off = 1 + (off << 6) + (*ip++ >> 2); | 243 | 60.6k | m_pos -= off; | 244 | 60.6k | last_m_off = off; | 245 | 60.6k | } | 246 | 79.1k | } | 247 | 79.1k | t = (t >> 5) - 1; | 248 | 79.1k | #endif | 249 | 79.1k | TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); | 250 | 79.1k | goto copy_match; | 251 | 79.1k | #endif /* COPY_DICT */ | 252 | 79.1k | } | 253 | 55.4k | else if (t >= 32) /* a M3 match */ | 254 | 19.2k | { | 255 | 19.2k | t &= 31; | 256 | 19.2k | if (t == 0) | 257 | 2.84k | { | 258 | 1.63M | while (*ip == 0) | 259 | 1.63M | { | 260 | 1.63M | t += 255; | 261 | 1.63M | ip++; | 262 | 1.63M | TEST_OV(t); | 263 | 1.63M | NEED_IP(1); | 264 | 1.63M | } | 265 | 2.82k | t += 31 + *ip++; | 266 | 2.82k | NEED_IP(2); | 267 | 2.82k | } | 268 | | #if defined(COPY_DICT) | 269 | | #if defined(LZO1Z) | 270 | | m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); | 271 | | last_m_off = m_off; | 272 | | #else | 273 | | m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); | 274 | | #endif | 275 | | #else /* !COPY_DICT */ | 276 | 19.2k | #if defined(LZO1Z) | 277 | 19.2k | { | 278 | 19.2k | lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); | 279 | 19.2k | m_pos = op - off; | 280 | 19.2k | last_m_off = off; | 281 | 19.2k | } | 282 | | #elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) | 283 | | m_pos = op - 1; | 284 | | m_pos -= UA_GET_LE16(ip) >> 2; | 285 | | #else | 286 | | m_pos = op - 1; | 287 | | m_pos -= (ip[0] >> 2) + (ip[1] << 6); | 288 | | #endif | 289 | 19.2k | #endif /* COPY_DICT */ | 290 | 19.2k | ip += 2; | 291 | 19.2k | } | 292 | 36.2k | else if (t >= 16) /* a M4 match */ | 293 | 6.76k | { | 294 | | #if defined(COPY_DICT) | 295 | | m_off = (t & 8) << 11; | 296 | | #else /* !COPY_DICT */ | 297 | 6.76k | m_pos = op; | 298 | 6.76k | m_pos -= (t & 8) << 11; | 299 | 6.76k | #endif /* COPY_DICT */ | 300 | 6.76k | t &= 7; | 301 | 6.76k | if (t == 0) | 302 | 2.29k | { | 303 | 4.58k | while (*ip == 0) | 304 | 2.29k | { | 305 | 2.29k | t += 255; | 306 | 2.29k | ip++; | 307 | 2.29k | TEST_OV(t); | 308 | 2.29k | NEED_IP(1); | 309 | 2.29k | } | 310 | 2.29k | t += 7 + *ip++; | 311 | 2.29k | NEED_IP(2); | 312 | 2.29k | } | 313 | | #if defined(COPY_DICT) | 314 | | #if defined(LZO1Z) | 315 | | m_off += (ip[0] << 6) + (ip[1] >> 2); | 316 | | #else | 317 | | m_off += (ip[0] >> 2) + (ip[1] << 6); | 318 | | #endif | 319 | | ip += 2; | 320 | | if (m_off == 0) | 321 | | goto eof_found; | 322 | | m_off += 0x4000; | 323 | | #if defined(LZO1Z) | 324 | | last_m_off = m_off; | 325 | | #endif | 326 | | #else /* !COPY_DICT */ | 327 | 6.75k | #if defined(LZO1Z) | 328 | 6.75k | m_pos -= (ip[0] << 6) + (ip[1] >> 2); | 329 | | #elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) | 330 | | m_pos -= UA_GET_LE16(ip) >> 2; | 331 | | #else | 332 | | m_pos -= (ip[0] >> 2) + (ip[1] << 6); | 333 | | #endif | 334 | 6.75k | ip += 2; | 335 | 6.75k | if (m_pos == op) | 336 | 15 | goto eof_found; | 337 | 6.73k | m_pos -= 0x4000; | 338 | 6.73k | #if defined(LZO1Z) | 339 | 6.73k | last_m_off = pd((const lzo_bytep)op, m_pos); | 340 | 6.73k | #endif | 341 | 6.73k | #endif /* COPY_DICT */ | 342 | 6.73k | } | 343 | 29.4k | else /* a M1 match */ | 344 | 29.4k | { | 345 | | #if defined(COPY_DICT) | 346 | | #if defined(LZO1Z) | 347 | | m_off = 1 + (t << 6) + (*ip++ >> 2); | 348 | | last_m_off = m_off; | 349 | | #else | 350 | | m_off = 1 + (t >> 2) + (*ip++ << 2); | 351 | | #endif | 352 | | NEED_OP(2); | 353 | | t = 2; COPY_DICT(t,m_off) | 354 | | #else /* !COPY_DICT */ | 355 | 29.4k | #if defined(LZO1Z) | 356 | 29.4k | t = 1 + (t << 6) + (*ip++ >> 2); | 357 | 29.4k | m_pos = op - t; | 358 | 29.4k | last_m_off = t; | 359 | | #else | 360 | | m_pos = op - 1; | 361 | | m_pos -= t >> 2; | 362 | | m_pos -= *ip++ << 2; | 363 | | #endif | 364 | 29.4k | TEST_LB(m_pos); NEED_OP(2); | 365 | 29.4k | *op++ = *m_pos++; *op++ = *m_pos; | 366 | 29.4k | #endif /* COPY_DICT */ | 367 | 29.4k | goto match_done; | 368 | 29.4k | } | 369 | | | 370 | | /* copy match */ | 371 | | #if defined(COPY_DICT) | 372 | | | 373 | | NEED_OP(t+3-1); | 374 | | t += 3-1; COPY_DICT(t,m_off) | 375 | | | 376 | | #else /* !COPY_DICT */ | 377 | | | 378 | 25.9k | TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); | 379 | 25.8k | #if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) | 380 | 25.8k | if (op - m_pos >= 8) | 381 | 23.9k | { | 382 | 23.9k | t += (3 - 1); | 383 | 23.9k | if (t >= 8) do | 384 | 950k | { | 385 | 950k | UA_COPY8(op,m_pos); | 386 | 950k | op += 8; m_pos += 8; t -= 8; | 387 | 950k | } while (t >= 8); | 388 | 23.9k | if (t >= 4) | 389 | 11.3k | { | 390 | 11.3k | UA_COPY4(op,m_pos); | 391 | 11.3k | op += 4; m_pos += 4; t -= 4; | 392 | 11.3k | } | 393 | 23.9k | if (t > 0) | 394 | 19.0k | { | 395 | 19.0k | *op++ = m_pos[0]; | 396 | 19.0k | if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } } | 397 | 19.0k | } | 398 | 23.9k | } | 399 | 1.92k | else | 400 | | #elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) | 401 | | #if !(LZO_OPT_UNALIGNED32) | 402 | | if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) | 403 | | { | 404 | | assert((op - m_pos) >= 4); /* both pointers are aligned */ | 405 | | #else | 406 | | if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) | 407 | | { | 408 | | #endif | 409 | | UA_COPY4(op,m_pos); | 410 | | op += 4; m_pos += 4; t -= 4 - (3 - 1); | 411 | | do { | 412 | | UA_COPY4(op,m_pos); | 413 | | op += 4; m_pos += 4; t -= 4; | 414 | | } while (t >= 4); | 415 | | if (t > 0) do *op++ = *m_pos++; while (--t > 0); | 416 | | } | 417 | | else | 418 | | #endif | 419 | 1.92k | { | 420 | 81.0k | copy_match: | 421 | 81.0k | *op++ = *m_pos++; *op++ = *m_pos++; | 422 | 6.89M | do *op++ = *m_pos++; while (--t > 0); | 423 | 81.0k | } | 424 | | | 425 | 25.8k | #endif /* COPY_DICT */ | 426 | | | 427 | 142k | match_done: | 428 | 142k | #if defined(LZO1Z) | 429 | 142k | t = ip[-1] & 3; | 430 | | #else | 431 | | t = ip[-2] & 3; | 432 | | #endif | 433 | 142k | if (t == 0) | 434 | 49.8k | break; | 435 | | | 436 | | /* copy literals */ | 437 | 93.2k | match_next: | 438 | 93.2k | assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3); | 439 | | #if 0 | 440 | | do *op++ = *ip++; while (--t > 0); | 441 | | #else | 442 | 93.1k | *op++ = *ip++; | 443 | 93.1k | if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } | 444 | 93.1k | #endif | 445 | 93.1k | t = *ip++; | 446 | 93.1k | } | 447 | 0 | } | 448 | | | 449 | 15 | eof_found: | 450 | 15 | *out_len = pd(op, out); | 451 | 15 | return (ip == ip_end ? LZO_E_OK : | 452 | 15 | (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); | 453 | | | 454 | | | 455 | 0 | #if defined(HAVE_NEED_IP) | 456 | 387 | input_overrun: | 457 | 387 | *out_len = pd(op, out); | 458 | 387 | return LZO_E_INPUT_OVERRUN; | 459 | 0 | #endif | 460 | | | 461 | 0 | #if defined(HAVE_NEED_OP) | 462 | 57 | output_overrun: | 463 | 57 | *out_len = pd(op, out); | 464 | 57 | return LZO_E_OUTPUT_OVERRUN; | 465 | 0 | #endif | 466 | | | 467 | 0 | #if defined(LZO_TEST_OVERRUN_LOOKBEHIND) | 468 | 147 | lookbehind_overrun: | 469 | 147 | *out_len = pd(op, out); | 470 | 147 | return LZO_E_LOOKBEHIND_OVERRUN; | 471 | 195 | #endif | 472 | 195 | } |
|
473 | | |
474 | | |
475 | | /* vim:set ts=4 sw=4 et: */ |