ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitCommon/OptIO/src/lzo1x_d.ch
Revision: 1.1
Committed: Tue Feb 24 11:56:43 2009 UTC (16 years, 2 months ago) by loizides
Branch: MAIN
CVS Tags: Mit_032, Mit_031, Mit_025c_branch2, Mit_025c_branch1, Mit_030, Mit_029c, Mit_030_pre1, Mit_029a, Mit_029, Mit_029_pre1, Mit_028a, Mit_025c_branch0, Mit_028, Mit_027a, Mit_027, Mit_026, Mit_025e, Mit_025d, Mit_025c, Mit_025b, Mit_025a, Mit_025, Mit_025pre2, Mit_024b, Mit_025pre1, Mit_024a, Mit_024, Mit_023, Mit_022a, Mit_022, Mit_020d, TMit_020d, Mit_020c, Mit_021, Mit_021pre2, Mit_021pre1, Mit_020b, Mit_020a, Mit_020, Mit_020pre1, Mit_018, Mit_017, Mit_017pre3, Mit_017pre2, Mit_017pre1, V07-05-00, Mit_016, Mit_015b, Mit_015a, Mit_015, Mit_014e, Mit_014d, Mit_014c, Mit_014b, ConvRejection-10-06-09, Mit_014a, Mit_014, Mit_014pre3, Mit_014pre2, Mit_014pre1, Mit_013d, Mit_013c, Mit_013b, Mit_013a, Mit_013, Mit_013pre1, Mit_012i, Mit_012g, Mit_012f, Mit_012e, Mit_012d, Mit_012c, Mit_012b, Mit_012a, Mit_012, Mit_011a, Mit_011, Mit_010a, Mit_010, Mit_009c, Mit_009b, Mit_009a, Mit_009, Mit_008, Mit_008pre2, Mit_008pre1, HEAD
Branch point for: Mit_025c_branch
Log Message:
Preload lib for compression improvements.

File Contents

# Content
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) 2008 Markus Franz Xaver Johannes Oberhumer
6 Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
7 Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
8 Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
9 Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
10 Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
11 Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
12 Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
13 Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
14 Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
15 Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
16 Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
17 Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
18 All Rights Reserved.
19
20 The LZO library is free software; you can redistribute it and/or
21 modify it under the terms of the GNU General Public License as
22 published by the Free Software Foundation; either version 2 of
23 the License, or (at your option) any later version.
24
25 The LZO library is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 GNU General Public License for more details.
29
30 You should have received a copy of the GNU General Public License
31 along with the LZO library; see the file COPYING.
32 If not, write to the Free Software Foundation, Inc.,
33 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
34
35 Markus F.X.J. Oberhumer
36 <markus@oberhumer.com>
37 http://www.oberhumer.com/opensource/lzo/
38 */
39
40
41 #include "lzo1_d.ch"
42
43
44 #undef __COPY4
45 #define __COPY4(dst,src) * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src)
46
47 #undef COPY4
48 #if defined(LZO_UNALIGNED_OK_4)
49 # define COPY4(dst,src) __COPY4(dst,src)
50 #elif defined(LZO_ALIGNED_OK_4)
51 # define COPY4(dst,src) __COPY4((lzo_uintptr_t)(dst),(lzo_uintptr_t)(src))
52 #endif
53
54
55 /***********************************************************************
56 // decompress a block of data.
57 ************************************************************************/
58
59 #if defined(DO_DECOMPRESS)
60 LZO_PUBLIC(int)
61 DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len,
62 lzo_bytep out, lzo_uintp out_len,
63 lzo_voidp wrkmem )
64 #endif
65 {
66 register lzo_bytep op;
67 register const lzo_bytep ip;
68 register lzo_uint t;
69 #if defined(COPY_DICT)
70 lzo_uint m_off;
71 const lzo_bytep dict_end;
72 #else
73 register const lzo_bytep m_pos;
74 #endif
75
76 const lzo_bytep const ip_end = in + in_len;
77 #if defined(HAVE_ANY_OP)
78 lzo_bytep const op_end = out + *out_len;
79 #endif
80 #if defined(LZO1Z)
81 lzo_uint last_m_off = 0;
82 #endif
83
84 LZO_UNUSED(wrkmem);
85
86 #if defined(COPY_DICT)
87 if (dict)
88 {
89 if (dict_len > M4_MAX_OFFSET)
90 {
91 dict += dict_len - M4_MAX_OFFSET;
92 dict_len = M4_MAX_OFFSET;
93 }
94 dict_end = dict + dict_len;
95 }
96 else
97 {
98 dict_len = 0;
99 dict_end = NULL;
100 }
101 #endif /* COPY_DICT */
102
103 *out_len = 0;
104
105 op = out;
106 ip = in;
107
108 if (*ip > 17)
109 {
110 t = *ip++ - 17;
111 if (t < 4)
112 goto match_next;
113 assert(t > 0); NEED_OP(t); NEED_IP(t+1);
114 do *op++ = *ip++; while (--t > 0);
115 goto first_literal_run;
116 }
117
118 while (TEST_IP && TEST_OP)
119 {
120 t = *ip++;
121 if (t >= 16)
122 goto match;
123 /* a literal run */
124 if (t == 0)
125 {
126 NEED_IP(1);
127 while (*ip == 0)
128 {
129 t += 255;
130 ip++;
131 NEED_IP(1);
132 }
133 t += 15 + *ip++;
134 }
135 /* copy literals */
136 assert(t > 0); NEED_OP(t+3); NEED_IP(t+4);
137 #if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
138 #if !defined(LZO_UNALIGNED_OK_4)
139 if (PTR_ALIGNED2_4(op,ip))
140 {
141 #endif
142 COPY4(op,ip);
143 op += 4; ip += 4;
144 if (--t > 0)
145 {
146 if (t >= 4)
147 {
148 do {
149 COPY4(op,ip);
150 op += 4; ip += 4; t -= 4;
151 } while (t >= 4);
152 if (t > 0) do *op++ = *ip++; while (--t > 0);
153 }
154 else
155 do *op++ = *ip++; while (--t > 0);
156 }
157 #if !defined(LZO_UNALIGNED_OK_4)
158 }
159 else
160 #endif
161 #endif
162 #if !defined(LZO_UNALIGNED_OK_4)
163 {
164 *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
165 do *op++ = *ip++; while (--t > 0);
166 }
167 #endif
168
169
170 first_literal_run:
171
172
173 t = *ip++;
174 if (t >= 16)
175 goto match;
176 #if defined(COPY_DICT)
177 #if defined(LZO1Z)
178 m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
179 last_m_off = m_off;
180 #else
181 m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
182 #endif
183 NEED_OP(3);
184 t = 3; COPY_DICT(t,m_off)
185 #else /* !COPY_DICT */
186 #if defined(LZO1Z)
187 t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
188 m_pos = op - t;
189 last_m_off = t;
190 #else
191 m_pos = op - (1 + M2_MAX_OFFSET);
192 m_pos -= t >> 2;
193 m_pos -= *ip++ << 2;
194 #endif
195 TEST_LB(m_pos); NEED_OP(3);
196 *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
197 #endif /* COPY_DICT */
198 goto match_done;
199
200
201 /* handle matches */
202 do {
203 match:
204 if (t >= 64) /* a M2 match */
205 {
206 #if defined(COPY_DICT)
207 #if defined(LZO1X)
208 m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3);
209 t = (t >> 5) - 1;
210 #elif defined(LZO1Y)
211 m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2);
212 t = (t >> 4) - 3;
213 #elif defined(LZO1Z)
214 m_off = t & 0x1f;
215 if (m_off >= 0x1c)
216 m_off = last_m_off;
217 else
218 {
219 m_off = 1 + (m_off << 6) + (*ip++ >> 2);
220 last_m_off = m_off;
221 }
222 t = (t >> 5) - 1;
223 #endif
224 #else /* !COPY_DICT */
225 #if defined(LZO1X)
226 m_pos = op - 1;
227 m_pos -= (t >> 2) & 7;
228 m_pos -= *ip++ << 3;
229 t = (t >> 5) - 1;
230 #elif defined(LZO1Y)
231 m_pos = op - 1;
232 m_pos -= (t >> 2) & 3;
233 m_pos -= *ip++ << 2;
234 t = (t >> 4) - 3;
235 #elif defined(LZO1Z)
236 {
237 lzo_uint off = t & 0x1f;
238 m_pos = op;
239 if (off >= 0x1c)
240 {
241 assert(last_m_off > 0);
242 m_pos -= last_m_off;
243 }
244 else
245 {
246 off = 1 + (off << 6) + (*ip++ >> 2);
247 m_pos -= off;
248 last_m_off = off;
249 }
250 }
251 t = (t >> 5) - 1;
252 #endif
253 TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
254 goto copy_match;
255 #endif /* COPY_DICT */
256 }
257 else if (t >= 32) /* a M3 match */
258 {
259 t &= 31;
260 if (t == 0)
261 {
262 NEED_IP(1);
263 while (*ip == 0)
264 {
265 t += 255;
266 ip++;
267 NEED_IP(1);
268 }
269 t += 31 + *ip++;
270 }
271 #if defined(COPY_DICT)
272 #if defined(LZO1Z)
273 m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
274 last_m_off = m_off;
275 #else
276 m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
277 #endif
278 #else /* !COPY_DICT */
279 #if defined(LZO1Z)
280 {
281 lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
282 m_pos = op - off;
283 last_m_off = off;
284 }
285 #elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN)
286 m_pos = op - 1;
287 m_pos -= (* (const lzo_ushortp) ip) >> 2;
288 #else
289 m_pos = op - 1;
290 m_pos -= (ip[0] >> 2) + (ip[1] << 6);
291 #endif
292 #endif /* COPY_DICT */
293 ip += 2;
294 }
295 else if (t >= 16) /* a M4 match */
296 {
297 #if defined(COPY_DICT)
298 m_off = (t & 8) << 11;
299 #else /* !COPY_DICT */
300 m_pos = op;
301 m_pos -= (t & 8) << 11;
302 #endif /* COPY_DICT */
303 t &= 7;
304 if (t == 0)
305 {
306 NEED_IP(1);
307 while (*ip == 0)
308 {
309 t += 255;
310 ip++;
311 NEED_IP(1);
312 }
313 t += 7 + *ip++;
314 }
315 #if defined(COPY_DICT)
316 #if defined(LZO1Z)
317 m_off += (ip[0] << 6) + (ip[1] >> 2);
318 #else
319 m_off += (ip[0] >> 2) + (ip[1] << 6);
320 #endif
321 ip += 2;
322 if (m_off == 0)
323 goto eof_found;
324 m_off += 0x4000;
325 #if defined(LZO1Z)
326 last_m_off = m_off;
327 #endif
328 #else /* !COPY_DICT */
329 #if defined(LZO1Z)
330 m_pos -= (ip[0] << 6) + (ip[1] >> 2);
331 #elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN)
332 m_pos -= (* (const lzo_ushortp) ip) >> 2;
333 #else
334 m_pos -= (ip[0] >> 2) + (ip[1] << 6);
335 #endif
336 ip += 2;
337 if (m_pos == op)
338 goto eof_found;
339 m_pos -= 0x4000;
340 #if defined(LZO1Z)
341 last_m_off = pd((const lzo_bytep)op, m_pos);
342 #endif
343 #endif /* COPY_DICT */
344 }
345 else /* a M1 match */
346 {
347 #if defined(COPY_DICT)
348 #if defined(LZO1Z)
349 m_off = 1 + (t << 6) + (*ip++ >> 2);
350 last_m_off = m_off;
351 #else
352 m_off = 1 + (t >> 2) + (*ip++ << 2);
353 #endif
354 NEED_OP(2);
355 t = 2; COPY_DICT(t,m_off)
356 #else /* !COPY_DICT */
357 #if defined(LZO1Z)
358 t = 1 + (t << 6) + (*ip++ >> 2);
359 m_pos = op - t;
360 last_m_off = t;
361 #else
362 m_pos = op - 1;
363 m_pos -= t >> 2;
364 m_pos -= *ip++ << 2;
365 #endif
366 TEST_LB(m_pos); NEED_OP(2);
367 *op++ = *m_pos++; *op++ = *m_pos;
368 #endif /* COPY_DICT */
369 goto match_done;
370 }
371
372 /* copy match */
373 #if defined(COPY_DICT)
374
375 NEED_OP(t+3-1);
376 t += 3-1; COPY_DICT(t,m_off)
377
378 #else /* !COPY_DICT */
379
380 TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
381 #if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
382 #if !defined(LZO_UNALIGNED_OK_4)
383 if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
384 {
385 assert((op - m_pos) >= 4); /* both pointers are aligned */
386 #else
387 if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
388 {
389 #endif
390 COPY4(op,m_pos);
391 op += 4; m_pos += 4; t -= 4 - (3 - 1);
392 do {
393 COPY4(op,m_pos);
394 op += 4; m_pos += 4; t -= 4;
395 } while (t >= 4);
396 if (t > 0) do *op++ = *m_pos++; while (--t > 0);
397 }
398 else
399 #endif
400 {
401 copy_match:
402 *op++ = *m_pos++; *op++ = *m_pos++;
403 do *op++ = *m_pos++; while (--t > 0);
404 }
405
406 #endif /* COPY_DICT */
407
408 match_done:
409 #if defined(LZO1Z)
410 t = ip[-1] & 3;
411 #else
412 t = ip[-2] & 3;
413 #endif
414 if (t == 0)
415 break;
416
417 /* copy literals */
418 match_next:
419 assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+1);
420 #if 0
421 do *op++ = *ip++; while (--t > 0);
422 #else
423 *op++ = *ip++;
424 if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
425 #endif
426 t = *ip++;
427 } while (TEST_IP && TEST_OP);
428 }
429
430 #if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
431 /* no EOF code was found */
432 *out_len = pd(op, out);
433 return LZO_E_EOF_NOT_FOUND;
434 #endif
435
436 eof_found:
437 assert(t == 1);
438 *out_len = pd(op, out);
439 return (ip == ip_end ? LZO_E_OK :
440 (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
441
442
443 #if defined(HAVE_NEED_IP)
444 input_overrun:
445 *out_len = pd(op, out);
446 return LZO_E_INPUT_OVERRUN;
447 #endif
448
449 #if defined(HAVE_NEED_OP)
450 output_overrun:
451 *out_len = pd(op, out);
452 return LZO_E_OUTPUT_OVERRUN;
453 #endif
454
455 #if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
456 lookbehind_overrun:
457 *out_len = pd(op, out);
458 return LZO_E_LOOKBEHIND_OVERRUN;
459 #endif
460 }
461
462
463 /*
464 vi:ts=4:et
465 */
466