update about dialog
[presencevnc] / libvnc / libvncclient / minilzo.c
1 /* minilzo.c -- mini subset of the LZO real-time data compression library
2
3    This file is part of the LZO real-time data compression library.
4
5    Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
6    Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
7    Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
8    Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
9    Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
10    Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
11    Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
12    All Rights Reserved.
13
14    The LZO library is free software; you can redistribute it and/or
15    modify it under the terms of the GNU General Public License as
16    published by the Free Software Foundation; either version 2 of
17    the License, or (at your option) any later version.
18
19    The LZO library is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22    GNU General Public License for more details.
23
24    You should have received a copy of the GNU General Public License
25    along with the LZO library; see the file COPYING.
26    If not, write to the Free Software Foundation, Inc.,
27    59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28
29    Markus F.X.J. Oberhumer
30    <markus@oberhumer.com>
31    http://www.oberhumer.com/opensource/lzo/
32  */
33
34 /*
35  * NOTE:
36  *   the full LZO package can be found at
37  *   http://www.oberhumer.com/opensource/lzo/
38  */
39
40 #define __LZO_IN_MINILZO
41 #define LZO_BUILD
42
43 #ifdef MINILZO_HAVE_CONFIG_H
44 #  include <config.h>
45 #endif
46
47 #undef LZO_HAVE_CONFIG_H
48 #include "minilzo.h"
49
50 #if !defined(MINILZO_VERSION) || (MINILZO_VERSION != 0x1080)
51 #  error "version mismatch in miniLZO source files"
52 #endif
53
54 #ifdef MINILZO_HAVE_CONFIG_H
55 #  define LZO_HAVE_CONFIG_H
56 #endif
57
58 #if !defined(LZO_NO_SYS_TYPES_H)
59 #  include <sys/types.h>
60 #endif
61 #include <stdio.h>
62
63 #ifndef __LZO_CONF_H
64 #define __LZO_CONF_H
65
66 #if !defined(__LZO_IN_MINILZO)
67 #  ifndef __LZOCONF_H
68 #    include <lzoconf.h>
69 #  endif
70 #endif
71
72 #if defined(__BOUNDS_CHECKING_ON)
73 #  include <unchecked.h>
74 #else
75 #  define BOUNDS_CHECKING_OFF_DURING(stmt)      stmt
76 #  define BOUNDS_CHECKING_OFF_IN_EXPR(expr)     (expr)
77 #endif
78
79 #if !defined(LZO_HAVE_CONFIG_H)
80 #  include <stddef.h>
81 #  include <string.h>
82 #  if !defined(NO_STDLIB_H)
83 #    include <stdlib.h>
84 #  endif
85 #  define HAVE_MEMCMP
86 #  define HAVE_MEMCPY
87 #  define HAVE_MEMMOVE
88 #  define HAVE_MEMSET
89 #else
90 #  include <sys/types.h>
91 #  if defined(HAVE_STDDEF_H)
92 #    include <stddef.h>
93 #  endif
94 #  if defined(STDC_HEADERS)
95 #    include <string.h>
96 #    include <stdlib.h>
97 #  endif
98 #endif
99
100 #if defined(__LZO_DOS16) || defined(__LZO_WIN16)
101 #  define HAVE_MALLOC_H
102 #  define HAVE_HALLOC
103 #endif
104
105 #undef NDEBUG
106 #if !defined(LZO_DEBUG)
107 #  define NDEBUG
108 #endif
109 #if defined(LZO_DEBUG) || !defined(NDEBUG)
110 #  if !defined(NO_STDIO_H)
111 #    include <stdio.h>
112 #  endif
113 #endif
114 #include <assert.h>
115
116 #if !defined(LZO_COMPILE_TIME_ASSERT)
117 #  define LZO_COMPILE_TIME_ASSERT(expr) \
118         { typedef int __lzo_compile_time_assert_fail[1 - 2 * !(expr)]; }
119 #endif
120
121 #if !defined(LZO_UNUSED)
122 #  if 1
123 #    define LZO_UNUSED(var)     ((void)&var)
124 #  elif 0
125 #    define LZO_UNUSED(var)     { typedef int __lzo_unused[sizeof(var) ? 2 : 1]; }
126 #  else
127 #    define LZO_UNUSED(parm)    (parm = parm)
128 #  endif
129 #endif
130
131 #if !defined(__inline__) && !defined(__GNUC__)
132 #  if defined(__cplusplus)
133 #    define __inline__      inline
134 #  else
135 #    define __inline__
136 #  endif
137 #endif
138
139 #if defined(NO_MEMCMP)
140 #  undef HAVE_MEMCMP
141 #endif
142
143 #if !defined(HAVE_MEMCMP)
144 #  undef memcmp
145 #  define memcmp    lzo_memcmp
146 #endif
147 #if !defined(HAVE_MEMCPY)
148 #  undef memcpy
149 #  define memcpy    lzo_memcpy
150 #endif
151 #if !defined(HAVE_MEMMOVE)
152 #  undef memmove
153 #  define memmove   lzo_memmove
154 #endif
155 #if !defined(HAVE_MEMSET)
156 #  undef memset
157 #  define memset    lzo_memset
158 #endif
159
160 #if 0
161 #  define LZO_BYTE(x)       ((unsigned char) (x))
162 #else
163 #  define LZO_BYTE(x)       ((unsigned char) ((x) & 0xff))
164 #endif
165
166 #define LZO_MAX(a,b)        ((a) >= (b) ? (a) : (b))
167 #define LZO_MIN(a,b)        ((a) <= (b) ? (a) : (b))
168 #define LZO_MAX3(a,b,c)     ((a) >= (b) ? LZO_MAX(a,c) : LZO_MAX(b,c))
169 #define LZO_MIN3(a,b,c)     ((a) <= (b) ? LZO_MIN(a,c) : LZO_MIN(b,c))
170
171 #define lzo_sizeof(type)    ((lzo_uint) (sizeof(type)))
172
173 #define LZO_HIGH(array)     ((lzo_uint) (sizeof(array)/sizeof(*(array))))
174
175 #define LZO_SIZE(bits)      (1u << (bits))
176 #define LZO_MASK(bits)      (LZO_SIZE(bits) - 1)
177
178 #define LZO_LSIZE(bits)     (1ul << (bits))
179 #define LZO_LMASK(bits)     (LZO_LSIZE(bits) - 1)
180
181 #define LZO_USIZE(bits)     ((lzo_uint) 1 << (bits))
182 #define LZO_UMASK(bits)     (LZO_USIZE(bits) - 1)
183
184 #define LZO_STYPE_MAX(b)    (((1l  << (8*(b)-2)) - 1l)  + (1l  << (8*(b)-2)))
185 #define LZO_UTYPE_MAX(b)    (((1ul << (8*(b)-1)) - 1ul) + (1ul << (8*(b)-1)))
186
187 #if !defined(SIZEOF_UNSIGNED)
188 #  if (UINT_MAX == 0xffff)
189 #    define SIZEOF_UNSIGNED         2
190 #  elif (UINT_MAX == LZO_0xffffffffL)
191 #    define SIZEOF_UNSIGNED         4
192 #  elif (UINT_MAX >= LZO_0xffffffffL)
193 #    define SIZEOF_UNSIGNED         8
194 #  else
195 #    error "SIZEOF_UNSIGNED"
196 #  endif
197 #endif
198
199 #if !defined(SIZEOF_UNSIGNED_LONG)
200 #  if (ULONG_MAX == LZO_0xffffffffL)
201 #    define SIZEOF_UNSIGNED_LONG    4
202 #  elif (ULONG_MAX >= LZO_0xffffffffL)
203 #    define SIZEOF_UNSIGNED_LONG    8
204 #  else
205 #    error "SIZEOF_UNSIGNED_LONG"
206 #  endif
207 #endif
208
209 #if !defined(SIZEOF_SIZE_T)
210 #  define SIZEOF_SIZE_T             SIZEOF_UNSIGNED
211 #endif
212 #if !defined(SIZE_T_MAX)
213 #  define SIZE_T_MAX                LZO_UTYPE_MAX(SIZEOF_SIZE_T)
214 #endif
215
216 #if 1 && defined(__LZO_i386) && (UINT_MAX == LZO_0xffffffffL)
217 #  if !defined(LZO_UNALIGNED_OK_2) && (USHRT_MAX == 0xffff)
218 #    define LZO_UNALIGNED_OK_2
219 #  endif
220 #  if !defined(LZO_UNALIGNED_OK_4) && (LZO_UINT32_MAX == LZO_0xffffffffL)
221 #    define LZO_UNALIGNED_OK_4
222 #  endif
223 #endif
224
225 #if defined(LZO_UNALIGNED_OK_2) || defined(LZO_UNALIGNED_OK_4)
226 #  if !defined(LZO_UNALIGNED_OK)
227 #    define LZO_UNALIGNED_OK
228 #  endif
229 #endif
230
231 #if defined(__LZO_NO_UNALIGNED)
232 #  undef LZO_UNALIGNED_OK
233 #  undef LZO_UNALIGNED_OK_2
234 #  undef LZO_UNALIGNED_OK_4
235 #endif
236
237 #if defined(LZO_UNALIGNED_OK_2) && (USHRT_MAX != 0xffff)
238 #  error "LZO_UNALIGNED_OK_2 must not be defined on this system"
239 #endif
240 #if defined(LZO_UNALIGNED_OK_4) && (LZO_UINT32_MAX != LZO_0xffffffffL)
241 #  error "LZO_UNALIGNED_OK_4 must not be defined on this system"
242 #endif
243
244 #if defined(__LZO_NO_ALIGNED)
245 #  undef LZO_ALIGNED_OK_4
246 #endif
247
248 #if defined(LZO_ALIGNED_OK_4) && (LZO_UINT32_MAX != LZO_0xffffffffL)
249 #  error "LZO_ALIGNED_OK_4 must not be defined on this system"
250 #endif
251
252 #define LZO_LITTLE_ENDIAN       1234
253 #define LZO_BIG_ENDIAN          4321
254 #define LZO_PDP_ENDIAN          3412
255
256 #if !defined(LZO_BYTE_ORDER)
257 #  if defined(MFX_BYTE_ORDER)
258 #    define LZO_BYTE_ORDER      MFX_BYTE_ORDER
259 #  elif defined(__LZO_i386)
260 #    define LZO_BYTE_ORDER      LZO_LITTLE_ENDIAN
261 #  elif defined(BYTE_ORDER)
262 #    define LZO_BYTE_ORDER      BYTE_ORDER
263 #  elif defined(__BYTE_ORDER)
264 #    define LZO_BYTE_ORDER      __BYTE_ORDER
265 #  endif
266 #endif
267
268 #if defined(LZO_BYTE_ORDER)
269 #  if (LZO_BYTE_ORDER != LZO_LITTLE_ENDIAN) && \
270       (LZO_BYTE_ORDER != LZO_BIG_ENDIAN)
271 #    error "invalid LZO_BYTE_ORDER"
272 #  endif
273 #endif
274
275 #if defined(LZO_UNALIGNED_OK) && !defined(LZO_BYTE_ORDER)
276 #  error "LZO_BYTE_ORDER is not defined"
277 #endif
278
279 #define LZO_OPTIMIZE_GNUC_i386_IS_BUGGY
280
281 #if defined(NDEBUG) && !defined(LZO_DEBUG) && !defined(__LZO_CHECKER)
282 #  if defined(__GNUC__) && defined(__i386__)
283 #    if !defined(LZO_OPTIMIZE_GNUC_i386_IS_BUGGY)
284 #      define LZO_OPTIMIZE_GNUC_i386
285 #    endif
286 #  endif
287 #endif
288
289 __LZO_EXTERN_C int __lzo_init_done;
290 __LZO_EXTERN_C const lzo_byte __lzo_copyright[];
291 LZO_EXTERN(const lzo_byte *) lzo_copyright(void);
292 __LZO_EXTERN_C const lzo_uint32 _lzo_crc32_table[256];
293
294 #define _LZO_STRINGIZE(x)           #x
295 #define _LZO_MEXPAND(x)             _LZO_STRINGIZE(x)
296
297 #define _LZO_CONCAT2(a,b)           a ## b
298 #define _LZO_CONCAT3(a,b,c)         a ## b ## c
299 #define _LZO_CONCAT4(a,b,c,d)       a ## b ## c ## d
300 #define _LZO_CONCAT5(a,b,c,d,e)     a ## b ## c ## d ## e
301
302 #define _LZO_ECONCAT2(a,b)          _LZO_CONCAT2(a,b)
303 #define _LZO_ECONCAT3(a,b,c)        _LZO_CONCAT3(a,b,c)
304 #define _LZO_ECONCAT4(a,b,c,d)      _LZO_CONCAT4(a,b,c,d)
305 #define _LZO_ECONCAT5(a,b,c,d,e)    _LZO_CONCAT5(a,b,c,d,e)
306
307 #if 0
308
309 #define __LZO_IS_COMPRESS_QUERY(i,il,o,ol,w)    ((lzo_voidp)(o) == (w))
310 #define __LZO_QUERY_COMPRESS(i,il,o,ol,w,n,s) \
311                 (*ol = (n)*(s), LZO_E_OK)
312
313 #define __LZO_IS_DECOMPRESS_QUERY(i,il,o,ol,w)  ((lzo_voidp)(o) == (w))
314 #define __LZO_QUERY_DECOMPRESS(i,il,o,ol,w,n,s) \
315                 (*ol = (n)*(s), LZO_E_OK)
316
317 #define __LZO_IS_OPTIMIZE_QUERY(i,il,o,ol,w)    ((lzo_voidp)(o) == (w))
318 #define __LZO_QUERY_OPTIMIZE(i,il,o,ol,w,n,s) \
319                 (*ol = (n)*(s), LZO_E_OK)
320
321 #endif
322
323 #ifndef __LZO_PTR_H
324 #define __LZO_PTR_H
325
326 #ifdef __cplusplus
327 extern "C" {
328 #endif
329
330 #if defined(__LZO_DOS16) || defined(__LZO_WIN16)
331 #  include <dos.h>
332 #  if 1 && defined(__WATCOMC__)
333 #    include <i86.h>
334      __LZO_EXTERN_C unsigned char _HShift;
335 #    define __LZO_HShift    _HShift
336 #  elif 1 && defined(_MSC_VER)
337      __LZO_EXTERN_C unsigned short __near _AHSHIFT;
338 #    define __LZO_HShift    ((unsigned) &_AHSHIFT)
339 #  elif defined(__LZO_WIN16)
340 #    define __LZO_HShift    3
341 #  else
342 #    define __LZO_HShift    12
343 #  endif
344 #  if !defined(_FP_SEG) && defined(FP_SEG)
345 #    define _FP_SEG         FP_SEG
346 #  endif
347 #  if !defined(_FP_OFF) && defined(FP_OFF)
348 #    define _FP_OFF         FP_OFF
349 #  endif
350 #endif
351
352 #if !defined(lzo_ptrdiff_t)
353 #  if (UINT_MAX >= LZO_0xffffffffL)
354      typedef ptrdiff_t          lzo_ptrdiff_t;
355 #  else
356      typedef long               lzo_ptrdiff_t;
357 #  endif
358 #endif
359
360 #if !defined(__LZO_HAVE_PTR_T)
361 #  if defined(lzo_ptr_t)
362 #    define __LZO_HAVE_PTR_T
363 #  endif
364 #endif
365 #if !defined(__LZO_HAVE_PTR_T)
366 #  if defined(SIZEOF_CHAR_P) && defined(SIZEOF_UNSIGNED_LONG)
367 #    if (SIZEOF_CHAR_P == SIZEOF_UNSIGNED_LONG)
368        typedef unsigned long    lzo_ptr_t;
369        typedef long             lzo_sptr_t;
370 #      define __LZO_HAVE_PTR_T
371 #    endif
372 #  endif
373 #endif
374 #if !defined(__LZO_HAVE_PTR_T)
375 #  if defined(SIZEOF_CHAR_P) && defined(SIZEOF_UNSIGNED)
376 #    if (SIZEOF_CHAR_P == SIZEOF_UNSIGNED)
377        typedef unsigned int     lzo_ptr_t;
378        typedef int              lzo_sptr_t;
379 #      define __LZO_HAVE_PTR_T
380 #    endif
381 #  endif
382 #endif
383 #if !defined(__LZO_HAVE_PTR_T)
384 #  if defined(SIZEOF_CHAR_P) && defined(SIZEOF_UNSIGNED_SHORT)
385 #    if (SIZEOF_CHAR_P == SIZEOF_UNSIGNED_SHORT)
386        typedef unsigned short   lzo_ptr_t;
387        typedef short            lzo_sptr_t;
388 #      define __LZO_HAVE_PTR_T
389 #    endif
390 #  endif
391 #endif
392 #if !defined(__LZO_HAVE_PTR_T)
393 #  if defined(LZO_HAVE_CONFIG_H) || defined(SIZEOF_CHAR_P)
394 #    error "no suitable type for lzo_ptr_t"
395 #  else
396      typedef unsigned long      lzo_ptr_t;
397      typedef long               lzo_sptr_t;
398 #    define __LZO_HAVE_PTR_T
399 #  endif
400 #endif
401
402 #if defined(__LZO_DOS16) || defined(__LZO_WIN16)
403 #define PTR(a)              ((lzo_bytep) (a))
404 #define PTR_ALIGNED_4(a)    ((_FP_OFF(a) & 3) == 0)
405 #define PTR_ALIGNED2_4(a,b) (((_FP_OFF(a) | _FP_OFF(b)) & 3) == 0)
406 #else
407 #define PTR(a)              ((lzo_ptr_t) (a))
408 #define PTR_LINEAR(a)       PTR(a)
409 #define PTR_ALIGNED_4(a)    ((PTR_LINEAR(a) & 3) == 0)
410 #define PTR_ALIGNED_8(a)    ((PTR_LINEAR(a) & 7) == 0)
411 #define PTR_ALIGNED2_4(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 3) == 0)
412 #define PTR_ALIGNED2_8(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 7) == 0)
413 #endif
414
415 #define PTR_LT(a,b)         (PTR(a) < PTR(b))
416 #define PTR_GE(a,b)         (PTR(a) >= PTR(b))
417 #define PTR_DIFF(a,b)       ((lzo_ptrdiff_t) (PTR(a) - PTR(b)))
418 #define pd(a,b)             ((lzo_uint) ((a)-(b)))
419
420 LZO_EXTERN(lzo_ptr_t)
421 __lzo_ptr_linear(const lzo_voidp ptr);
422
423 typedef union
424 {
425     char            a_char;
426     unsigned char   a_uchar;
427     short           a_short;
428     unsigned short  a_ushort;
429     int             a_int;
430     unsigned int    a_uint;
431     long            a_long;
432     unsigned long   a_ulong;
433     lzo_int         a_lzo_int;
434     lzo_uint        a_lzo_uint;
435     lzo_int32       a_lzo_int32;
436     lzo_uint32      a_lzo_uint32;
437     ptrdiff_t       a_ptrdiff_t;
438     lzo_ptrdiff_t   a_lzo_ptrdiff_t;
439     lzo_ptr_t       a_lzo_ptr_t;
440     lzo_voidp       a_lzo_voidp;
441     void *          a_void_p;
442     lzo_bytep       a_lzo_bytep;
443     lzo_bytepp      a_lzo_bytepp;
444     lzo_uintp       a_lzo_uintp;
445     lzo_uint *      a_lzo_uint_p;
446     lzo_uint32p     a_lzo_uint32p;
447     lzo_uint32 *    a_lzo_uint32_p;
448     unsigned char * a_uchar_p;
449     char *          a_char_p;
450 }
451 lzo_full_align_t;
452
453 #ifdef __cplusplus
454 }
455 #endif
456
457 #endif
458
459 #define LZO_DETERMINISTIC
460
461 #define LZO_DICT_USE_PTR
462 #if defined(__LZO_DOS16) || defined(__LZO_WIN16) || defined(__LZO_STRICT_16BIT)
463 #  undef LZO_DICT_USE_PTR
464 #endif
465
466 #if defined(LZO_DICT_USE_PTR)
467 #  define lzo_dict_t    const lzo_bytep
468 #  define lzo_dict_p    lzo_dict_t __LZO_MMODEL *
469 #else
470 #  define lzo_dict_t    lzo_uint
471 #  define lzo_dict_p    lzo_dict_t __LZO_MMODEL *
472 #endif
473
474 #if !defined(lzo_moff_t)
475 #define lzo_moff_t      lzo_uint
476 #endif
477
478 #endif
479
480 LZO_PUBLIC(lzo_ptr_t)
481 __lzo_ptr_linear(const lzo_voidp ptr)
482 {
483     lzo_ptr_t p;
484
485 #if defined(__LZO_DOS16) || defined(__LZO_WIN16)
486     p = (((lzo_ptr_t)(_FP_SEG(ptr))) << (16 - __LZO_HShift)) + (_FP_OFF(ptr));
487 #else
488     p = PTR_LINEAR(ptr);
489 #endif
490
491     return p;
492 }
493
494 LZO_PUBLIC(unsigned)
495 __lzo_align_gap(const lzo_voidp ptr, lzo_uint size)
496 {
497     lzo_ptr_t p, s, n;
498
499     assert(size > 0);
500
501     p = __lzo_ptr_linear(ptr);
502     s = (lzo_ptr_t) (size - 1);
503 #if 0
504     assert((size & (size - 1)) == 0);
505     n = ((p + s) & ~s) - p;
506 #else
507     n = (((p + s) / size) * size) - p;
508 #endif
509
510     assert((long)n >= 0);
511     assert(n <= s);
512
513     return (unsigned)n;
514 }
515
516 #ifndef __LZO_UTIL_H
517 #define __LZO_UTIL_H
518
519 #ifndef __LZO_CONF_H
520 #endif
521
522 #ifdef __cplusplus
523 extern "C" {
524 #endif
525
526 #if 1 && defined(HAVE_MEMCPY)
527 #if !defined(__LZO_DOS16) && !defined(__LZO_WIN16)
528
529 #define MEMCPY8_DS(dest,src,len) \
530     memcpy(dest,src,len); \
531     dest += len; \
532     src += len
533
534 #endif
535 #endif
536
537 #if 0 && !defined(MEMCPY8_DS)
538
539 #define MEMCPY8_DS(dest,src,len) \
540     { do { \
541         *dest++ = *src++; \
542         *dest++ = *src++; \
543         *dest++ = *src++; \
544         *dest++ = *src++; \
545         *dest++ = *src++; \
546         *dest++ = *src++; \
547         *dest++ = *src++; \
548         *dest++ = *src++; \
549         len -= 8; \
550     } while (len > 0); }
551
552 #endif
553
554 #if !defined(MEMCPY8_DS)
555
556 #define MEMCPY8_DS(dest,src,len) \
557     { register lzo_uint __l = (len) / 8; \
558     do { \
559         *dest++ = *src++; \
560         *dest++ = *src++; \
561         *dest++ = *src++; \
562         *dest++ = *src++; \
563         *dest++ = *src++; \
564         *dest++ = *src++; \
565         *dest++ = *src++; \
566         *dest++ = *src++; \
567     } while (--__l > 0); }
568
569 #endif
570
571 #define MEMCPY_DS(dest,src,len) \
572     do *dest++ = *src++; \
573     while (--len > 0)
574
575 #define MEMMOVE_DS(dest,src,len) \
576     do *dest++ = *src++; \
577     while (--len > 0)
578
579 #if 0 && defined(LZO_OPTIMIZE_GNUC_i386)
580
581 #define BZERO8_PTR(s,l,n) \
582 __asm__ __volatile__( \
583     "movl  %0,%%eax \n"             \
584     "movl  %1,%%edi \n"             \
585     "movl  %2,%%ecx \n"             \
586     "cld \n"                        \
587     "rep \n"                        \
588     "stosl %%eax,(%%edi) \n"        \
589     :               \
590     :"g" (0),"g" (s),"g" (n)        \
591     :"eax","edi","ecx", "memory", "cc" \
592 )
593
594 #elif (LZO_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMSET)
595
596 #if 1
597 #define BZERO8_PTR(s,l,n)   memset((s),0,(lzo_uint)(l)*(n))
598 #else
599 #define BZERO8_PTR(s,l,n)   memset((lzo_voidp)(s),0,(lzo_uint)(l)*(n))
600 #endif
601
602 #else
603
604 #define BZERO8_PTR(s,l,n) \
605     lzo_memset((lzo_voidp)(s),0,(lzo_uint)(l)*(n))
606
607 #endif
608
609 #if 0
610 #if defined(__GNUC__) && defined(__i386__)
611
612 unsigned char lzo_rotr8(unsigned char value, int shift);
613 extern __inline__ unsigned char lzo_rotr8(unsigned char value, int shift)
614 {
615     unsigned char result;
616
617     __asm__ __volatile__ ("movb %b1, %b0; rorb %b2, %b0"
618                         : "=a"(result) : "g"(value), "c"(shift));
619     return result;
620 }
621
622 unsigned short lzo_rotr16(unsigned short value, int shift);
623 extern __inline__ unsigned short lzo_rotr16(unsigned short value, int shift)
624 {
625     unsigned short result;
626
627     __asm__ __volatile__ ("movw %b1, %b0; rorw %b2, %b0"
628                         : "=a"(result) : "g"(value), "c"(shift));
629     return result;
630 }
631
632 #endif
633 #endif
634
635 #ifdef __cplusplus
636 }
637 #endif
638
639 #endif
640
641 LZO_PUBLIC(lzo_bool)
642 lzo_assert(int expr)
643 {
644     return (expr) ? 1 : 0;
645 }
646
647 /* If you use the LZO library in a product, you *must* keep this
648  * copyright string in the executable of your product.
649  */
650
651 const lzo_byte __lzo_copyright[] =
652 #if !defined(__LZO_IN_MINLZO)
653     LZO_VERSION_STRING;
654 #else
655     "\n\n\n"
656     "LZO real-time data compression library.\n"
657     "Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Markus Franz Xaver Johannes Oberhumer\n"
658     "<markus.oberhumer@jk.uni-linz.ac.at>\n"
659     "http://www.oberhumer.com/opensource/lzo/\n"
660     "\n"
661     "LZO version: v" LZO_VERSION_STRING ", " LZO_VERSION_DATE "\n"
662     "LZO build date: " __DATE__ " " __TIME__ "\n\n"
663     "LZO special compilation options:\n"
664 #ifdef __cplusplus
665     " __cplusplus\n"
666 #endif
667 #if defined(__PIC__)
668     " __PIC__\n"
669 #elif defined(__pic__)
670     " __pic__\n"
671 #endif
672 #if (UINT_MAX < LZO_0xffffffffL)
673     " 16BIT\n"
674 #endif
675 #if defined(__LZO_STRICT_16BIT)
676     " __LZO_STRICT_16BIT\n"
677 #endif
678 #if (UINT_MAX > LZO_0xffffffffL)
679     " UINT_MAX=" _LZO_MEXPAND(UINT_MAX) "\n"
680 #endif
681 #if (ULONG_MAX > LZO_0xffffffffL)
682     " ULONG_MAX=" _LZO_MEXPAND(ULONG_MAX) "\n"
683 #endif
684 #if defined(LZO_BYTE_ORDER)
685     " LZO_BYTE_ORDER=" _LZO_MEXPAND(LZO_BYTE_ORDER) "\n"
686 #endif
687 #if defined(LZO_UNALIGNED_OK_2)
688     " LZO_UNALIGNED_OK_2\n"
689 #endif
690 #if defined(LZO_UNALIGNED_OK_4)
691     " LZO_UNALIGNED_OK_4\n"
692 #endif
693 #if defined(LZO_ALIGNED_OK_4)
694     " LZO_ALIGNED_OK_4\n"
695 #endif
696 #if defined(LZO_DICT_USE_PTR)
697     " LZO_DICT_USE_PTR\n"
698 #endif
699 #if defined(__LZO_QUERY_COMPRESS)
700     " __LZO_QUERY_COMPRESS\n"
701 #endif
702 #if defined(__LZO_QUERY_DECOMPRESS)
703     " __LZO_QUERY_DECOMPRESS\n"
704 #endif
705 #if defined(__LZO_IN_MINILZO)
706     " __LZO_IN_MINILZO\n"
707 #endif
708     "\n\n"
709     "$Id: LZO " LZO_VERSION_STRING " built " __DATE__ " " __TIME__
710 #if defined(__GNUC__) && defined(__VERSION__)
711     " by gcc " __VERSION__
712 #elif defined(__BORLANDC__)
713     " by Borland C " _LZO_MEXPAND(__BORLANDC__)
714 #elif defined(_MSC_VER)
715     " by Microsoft C " _LZO_MEXPAND(_MSC_VER)
716 #elif defined(__PUREC__)
717     " by Pure C " _LZO_MEXPAND(__PUREC__)
718 #elif defined(__SC__)
719     " by Symantec C " _LZO_MEXPAND(__SC__)
720 #elif defined(__TURBOC__)
721     " by Turbo C " _LZO_MEXPAND(__TURBOC__)
722 #elif defined(__WATCOMC__)
723     " by Watcom C " _LZO_MEXPAND(__WATCOMC__)
724 #endif
725     " $\n"
726     "$Copyright: LZO (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Markus Franz Xaver Johannes Oberhumer $\n";
727 #endif
728
729 LZO_PUBLIC(const lzo_byte *)
730 lzo_copyright(void)
731 {
732     return __lzo_copyright;
733 }
734
735 LZO_PUBLIC(unsigned)
736 lzo_version(void)
737 {
738     return LZO_VERSION;
739 }
740
741 LZO_PUBLIC(const char *)
742 lzo_version_string(void)
743 {
744     return LZO_VERSION_STRING;
745 }
746
747 LZO_PUBLIC(const char *)
748 lzo_version_date(void)
749 {
750     return LZO_VERSION_DATE;
751 }
752
753 LZO_PUBLIC(const lzo_charp)
754 _lzo_version_string(void)
755 {
756     return LZO_VERSION_STRING;
757 }
758
759 LZO_PUBLIC(const lzo_charp)
760 _lzo_version_date(void)
761 {
762     return LZO_VERSION_DATE;
763 }
764
765 #define LZO_BASE 65521u
766 #define LZO_NMAX 5552
767
768 #define LZO_DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
769 #define LZO_DO2(buf,i)  LZO_DO1(buf,i); LZO_DO1(buf,i+1);
770 #define LZO_DO4(buf,i)  LZO_DO2(buf,i); LZO_DO2(buf,i+2);
771 #define LZO_DO8(buf,i)  LZO_DO4(buf,i); LZO_DO4(buf,i+4);
772 #define LZO_DO16(buf,i) LZO_DO8(buf,i); LZO_DO8(buf,i+8);
773
774 LZO_PUBLIC(lzo_uint32)
775 lzo_adler32(lzo_uint32 adler, const lzo_byte *buf, lzo_uint len)
776 {
777     lzo_uint32 s1 = adler & 0xffff;
778     lzo_uint32 s2 = (adler >> 16) & 0xffff;
779     int k;
780
781     if (buf == NULL)
782         return 1;
783
784     while (len > 0)
785     {
786         k = len < LZO_NMAX ? (int) len : LZO_NMAX;
787         len -= k;
788         if (k >= 16) do
789         {
790             LZO_DO16(buf,0);
791             buf += 16;
792             k -= 16;
793         } while (k >= 16);
794         if (k != 0) do
795         {
796             s1 += *buf++;
797             s2 += s1;
798         } while (--k > 0);
799         s1 %= LZO_BASE;
800         s2 %= LZO_BASE;
801     }
802     return (s2 << 16) | s1;
803 }
804
805 LZO_PUBLIC(int)
806 lzo_memcmp(const lzo_voidp s1, const lzo_voidp s2, lzo_uint len)
807 {
808 #if (LZO_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMCMP)
809     return memcmp(s1,s2,len);
810 #else
811     const lzo_byte *p1 = (const lzo_byte *) s1;
812     const lzo_byte *p2 = (const lzo_byte *) s2;
813     int d;
814
815     if (len > 0) do
816     {
817         d = *p1 - *p2;
818         if (d != 0)
819             return d;
820         p1++;
821         p2++;
822     }
823     while (--len > 0);
824     return 0;
825 #endif
826 }
827
828 LZO_PUBLIC(lzo_voidp)
829 lzo_memcpy(lzo_voidp dest, const lzo_voidp src, lzo_uint len)
830 {
831 #if (LZO_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMCPY)
832     return memcpy(dest,src,len);
833 #else
834     lzo_byte *p1 = (lzo_byte *) dest;
835     const lzo_byte *p2 = (const lzo_byte *) src;
836
837     if (len <= 0 || p1 == p2)
838         return dest;
839     do
840         *p1++ = *p2++;
841     while (--len > 0);
842     return dest;
843 #endif
844 }
845
846 LZO_PUBLIC(lzo_voidp)
847 lzo_memmove(lzo_voidp dest, const lzo_voidp src, lzo_uint len)
848 {
849 #if (LZO_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMMOVE)
850     return memmove(dest,src,len);
851 #else
852     lzo_byte *p1 = (lzo_byte *) dest;
853     const lzo_byte *p2 = (const lzo_byte *) src;
854
855     if (len <= 0 || p1 == p2)
856         return dest;
857
858     if (p1 < p2)
859     {
860         do
861             *p1++ = *p2++;
862         while (--len > 0);
863     }
864     else
865     {
866         p1 += len;
867         p2 += len;
868         do
869             *--p1 = *--p2;
870         while (--len > 0);
871     }
872     return dest;
873 #endif
874 }
875
876 LZO_PUBLIC(lzo_voidp)
877 lzo_memset(lzo_voidp s, int c, lzo_uint len)
878 {
879 #if (LZO_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMSET)
880     return memset(s,c,len);
881 #else
882     lzo_byte *p = (lzo_byte *) s;
883
884     if (len > 0) do
885         *p++ = LZO_BYTE(c);
886     while (--len > 0);
887     return s;
888 #endif
889 }
890
891 #if 0
892 #  define IS_SIGNED(type)       (((type) (1ul << (8 * sizeof(type) - 1))) < 0)
893 #  define IS_UNSIGNED(type)     (((type) (1ul << (8 * sizeof(type) - 1))) > 0)
894 #else
895 #  define IS_SIGNED(type)       (((type) (-1)) < ((type) 0))
896 #  define IS_UNSIGNED(type)     (((type) (-1)) > ((type) 0))
897 #endif
898
899 #define IS_POWER_OF_2(x)        (((x) & ((x) - 1)) == 0)
900
901 static lzo_bool schedule_insns_bug(void);
902 static lzo_bool strength_reduce_bug(int *);
903
904 #if 0 || defined(LZO_DEBUG)
905 #include <stdio.h>
906 static lzo_bool __lzo_assert_fail(const char *s, unsigned line)
907 {
908 #if defined(__palmos__)
909     printf("LZO assertion failed in line %u: '%s'\n",line,s);
910 #else
911     fprintf(stderr,"LZO assertion failed in line %u: '%s'\n",line,s);
912 #endif
913     return 0;
914 }
915 #  define __lzo_assert(x)   ((x) ? 1 : __lzo_assert_fail(#x,__LINE__))
916 #else
917 #  define __lzo_assert(x)   ((x) ? 1 : 0)
918 #endif
919
920 #undef COMPILE_TIME_ASSERT
921 #if 0
922 #  define COMPILE_TIME_ASSERT(expr)     r &= __lzo_assert(expr)
923 #else
924 #  define COMPILE_TIME_ASSERT(expr)     LZO_COMPILE_TIME_ASSERT(expr)
925 #endif
926
927 static lzo_bool basic_integral_check(void)
928 {
929     lzo_bool r = 1;
930
931     COMPILE_TIME_ASSERT(CHAR_BIT == 8);
932     COMPILE_TIME_ASSERT(sizeof(char) == 1);
933     COMPILE_TIME_ASSERT(sizeof(short) >= 2);
934     COMPILE_TIME_ASSERT(sizeof(long) >= 4);
935     COMPILE_TIME_ASSERT(sizeof(int) >= sizeof(short));
936     COMPILE_TIME_ASSERT(sizeof(long) >= sizeof(int));
937
938     COMPILE_TIME_ASSERT(sizeof(lzo_uint) == sizeof(lzo_int));
939     COMPILE_TIME_ASSERT(sizeof(lzo_uint32) == sizeof(lzo_int32));
940
941     COMPILE_TIME_ASSERT(sizeof(lzo_uint32) >= 4);
942     COMPILE_TIME_ASSERT(sizeof(lzo_uint32) >= sizeof(unsigned));
943 #if defined(__LZO_STRICT_16BIT)
944     COMPILE_TIME_ASSERT(sizeof(lzo_uint) == 2);
945 #else
946     COMPILE_TIME_ASSERT(sizeof(lzo_uint) >= 4);
947     COMPILE_TIME_ASSERT(sizeof(lzo_uint) >= sizeof(unsigned));
948 #endif
949
950 #if (USHRT_MAX == 65535u)
951     COMPILE_TIME_ASSERT(sizeof(short) == 2);
952 #elif (USHRT_MAX == LZO_0xffffffffL)
953     COMPILE_TIME_ASSERT(sizeof(short) == 4);
954 #elif (USHRT_MAX >= LZO_0xffffffffL)
955     COMPILE_TIME_ASSERT(sizeof(short) > 4);
956 #endif
957 #if (UINT_MAX == 65535u)
958     COMPILE_TIME_ASSERT(sizeof(int) == 2);
959 #elif (UINT_MAX == LZO_0xffffffffL)
960     COMPILE_TIME_ASSERT(sizeof(int) == 4);
961 #elif (UINT_MAX >= LZO_0xffffffffL)
962     COMPILE_TIME_ASSERT(sizeof(int) > 4);
963 #endif
964 #if (ULONG_MAX == 65535ul)
965     COMPILE_TIME_ASSERT(sizeof(long) == 2);
966 #elif (ULONG_MAX == LZO_0xffffffffL)
967     COMPILE_TIME_ASSERT(sizeof(long) == 4);
968 #elif (ULONG_MAX >= LZO_0xffffffffL)
969     COMPILE_TIME_ASSERT(sizeof(long) > 4);
970 #endif
971
972 #if defined(SIZEOF_UNSIGNED)
973     COMPILE_TIME_ASSERT(SIZEOF_UNSIGNED == sizeof(unsigned));
974 #endif
975 #if defined(SIZEOF_UNSIGNED_LONG)
976     COMPILE_TIME_ASSERT(SIZEOF_UNSIGNED_LONG == sizeof(unsigned long));
977 #endif
978 #if defined(SIZEOF_UNSIGNED_SHORT)
979     COMPILE_TIME_ASSERT(SIZEOF_UNSIGNED_SHORT == sizeof(unsigned short));
980 #endif
981 #if !defined(__LZO_IN_MINILZO)
982 #if defined(SIZEOF_SIZE_T)
983     COMPILE_TIME_ASSERT(SIZEOF_SIZE_T == sizeof(size_t));
984 #endif
985 #endif
986
987     COMPILE_TIME_ASSERT(IS_UNSIGNED(unsigned char));
988     COMPILE_TIME_ASSERT(IS_UNSIGNED(unsigned short));
989     COMPILE_TIME_ASSERT(IS_UNSIGNED(unsigned));
990     COMPILE_TIME_ASSERT(IS_UNSIGNED(unsigned long));
991     COMPILE_TIME_ASSERT(IS_SIGNED(short));
992     COMPILE_TIME_ASSERT(IS_SIGNED(int));
993     COMPILE_TIME_ASSERT(IS_SIGNED(long));
994
995     COMPILE_TIME_ASSERT(IS_UNSIGNED(lzo_uint32));
996     COMPILE_TIME_ASSERT(IS_UNSIGNED(lzo_uint));
997     COMPILE_TIME_ASSERT(IS_SIGNED(lzo_int32));
998     COMPILE_TIME_ASSERT(IS_SIGNED(lzo_int));
999
1000     COMPILE_TIME_ASSERT(INT_MAX    == LZO_STYPE_MAX(sizeof(int)));
1001     COMPILE_TIME_ASSERT(UINT_MAX   == LZO_UTYPE_MAX(sizeof(unsigned)));
1002     COMPILE_TIME_ASSERT(LONG_MAX   == LZO_STYPE_MAX(sizeof(long)));
1003     COMPILE_TIME_ASSERT(ULONG_MAX  == LZO_UTYPE_MAX(sizeof(unsigned long)));
1004     COMPILE_TIME_ASSERT(SHRT_MAX   == LZO_STYPE_MAX(sizeof(short)));
1005     COMPILE_TIME_ASSERT(USHRT_MAX  == LZO_UTYPE_MAX(sizeof(unsigned short)));
1006     COMPILE_TIME_ASSERT(LZO_UINT32_MAX == LZO_UTYPE_MAX(sizeof(lzo_uint32)));
1007     COMPILE_TIME_ASSERT(LZO_UINT_MAX   == LZO_UTYPE_MAX(sizeof(lzo_uint)));
1008 #if !defined(__LZO_IN_MINILZO)
1009     COMPILE_TIME_ASSERT(SIZE_T_MAX     == LZO_UTYPE_MAX(sizeof(size_t)));
1010 #endif
1011
1012     r &= __lzo_assert(LZO_BYTE(257) == 1);
1013
1014     return r;
1015 }
1016
1017 static lzo_bool basic_ptr_check(void)
1018 {
1019     lzo_bool r = 1;
1020
1021     COMPILE_TIME_ASSERT(sizeof(char *) >= sizeof(int));
1022     COMPILE_TIME_ASSERT(sizeof(lzo_byte *) >= sizeof(char *));
1023
1024     COMPILE_TIME_ASSERT(sizeof(lzo_voidp) == sizeof(lzo_byte *));
1025     COMPILE_TIME_ASSERT(sizeof(lzo_voidp) == sizeof(lzo_voidpp));
1026     COMPILE_TIME_ASSERT(sizeof(lzo_voidp) == sizeof(lzo_bytepp));
1027     COMPILE_TIME_ASSERT(sizeof(lzo_voidp) >= sizeof(lzo_uint));
1028
1029     COMPILE_TIME_ASSERT(sizeof(lzo_ptr_t) == sizeof(lzo_voidp));
1030     COMPILE_TIME_ASSERT(sizeof(lzo_ptr_t) == sizeof(lzo_sptr_t));
1031     COMPILE_TIME_ASSERT(sizeof(lzo_ptr_t) >= sizeof(lzo_uint));
1032
1033     COMPILE_TIME_ASSERT(sizeof(lzo_ptrdiff_t) >= 4);
1034     COMPILE_TIME_ASSERT(sizeof(lzo_ptrdiff_t) >= sizeof(ptrdiff_t));
1035
1036     COMPILE_TIME_ASSERT(sizeof(ptrdiff_t) >= sizeof(size_t));
1037     COMPILE_TIME_ASSERT(sizeof(lzo_ptrdiff_t) >= sizeof(lzo_uint));
1038
1039 #if defined(SIZEOF_CHAR_P)
1040     COMPILE_TIME_ASSERT(SIZEOF_CHAR_P == sizeof(char *));
1041 #endif
1042 #if defined(SIZEOF_PTRDIFF_T)
1043     COMPILE_TIME_ASSERT(SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t));
1044 #endif
1045
1046     COMPILE_TIME_ASSERT(IS_SIGNED(ptrdiff_t));
1047     COMPILE_TIME_ASSERT(IS_UNSIGNED(size_t));
1048     COMPILE_TIME_ASSERT(IS_SIGNED(lzo_ptrdiff_t));
1049     COMPILE_TIME_ASSERT(IS_SIGNED(lzo_sptr_t));
1050     COMPILE_TIME_ASSERT(IS_UNSIGNED(lzo_ptr_t));
1051     COMPILE_TIME_ASSERT(IS_UNSIGNED(lzo_moff_t));
1052
1053     return r;
1054 }
1055
1056 static lzo_bool ptr_check(void)
1057 {
1058     lzo_bool r = 1;
1059     int i;
1060     char _wrkmem[10 * sizeof(lzo_byte *) + sizeof(lzo_full_align_t)];
1061     lzo_bytep wrkmem;
1062     lzo_bytepp dict;
1063     unsigned char x[4 * sizeof(lzo_full_align_t)];
1064     long d;
1065     lzo_full_align_t a;
1066     lzo_full_align_t u;
1067
1068     for (i = 0; i < (int) sizeof(x); i++)
1069         x[i] = LZO_BYTE(i);
1070
1071     wrkmem = LZO_PTR_ALIGN_UP((lzo_byte *)_wrkmem,sizeof(lzo_full_align_t));
1072
1073 #if 0
1074     dict = (lzo_bytepp) wrkmem;
1075 #else
1076
1077     u.a_lzo_bytep = wrkmem; dict = u.a_lzo_bytepp;
1078 #endif
1079
1080     d = (long) ((const lzo_bytep) dict - (const lzo_bytep) _wrkmem);
1081     r &= __lzo_assert(d >= 0);
1082     r &= __lzo_assert(d < (long) sizeof(lzo_full_align_t));
1083
1084     memset(&a,0,sizeof(a));
1085     r &= __lzo_assert(a.a_lzo_voidp == NULL);
1086
1087     memset(&a,0xff,sizeof(a));
1088     r &= __lzo_assert(a.a_ushort == USHRT_MAX);
1089     r &= __lzo_assert(a.a_uint == UINT_MAX);
1090     r &= __lzo_assert(a.a_ulong == ULONG_MAX);
1091     r &= __lzo_assert(a.a_lzo_uint == LZO_UINT_MAX);
1092     r &= __lzo_assert(a.a_lzo_uint32 == LZO_UINT32_MAX);
1093
1094     if (r == 1)
1095     {
1096         for (i = 0; i < 8; i++)
1097             r &= __lzo_assert((const lzo_voidp) (&dict[i]) == (const lzo_voidp) (&wrkmem[i * sizeof(lzo_byte *)]));
1098     }
1099
1100     memset(&a,0,sizeof(a));
1101     r &= __lzo_assert(a.a_char_p == NULL);
1102     r &= __lzo_assert(a.a_lzo_bytep == NULL);
1103     r &= __lzo_assert(NULL == (void *)0);
1104     if (r == 1)
1105     {
1106         for (i = 0; i < 10; i++)
1107             dict[i] = wrkmem;
1108         BZERO8_PTR(dict+1,sizeof(dict[0]),8);
1109         r &= __lzo_assert(dict[0] == wrkmem);
1110         for (i = 1; i < 9; i++)
1111             r &= __lzo_assert(dict[i] == NULL);
1112         r &= __lzo_assert(dict[9] == wrkmem);
1113     }
1114
1115     if (r == 1)
1116     {
1117         unsigned k = 1;
1118         const unsigned n = (unsigned) sizeof(lzo_uint32);
1119         lzo_byte *p0;
1120         lzo_byte *p1;
1121
1122         k += __lzo_align_gap(&x[k],n);
1123         p0 = (lzo_bytep) &x[k];
1124 #if defined(PTR_LINEAR)
1125         r &= __lzo_assert((PTR_LINEAR(p0) & (n-1)) == 0);
1126 #else
1127         r &= __lzo_assert(n == 4);
1128         r &= __lzo_assert(PTR_ALIGNED_4(p0));
1129 #endif
1130
1131         r &= __lzo_assert(k >= 1);
1132         p1 = (lzo_bytep) &x[1];
1133         r &= __lzo_assert(PTR_GE(p0,p1));
1134
1135         r &= __lzo_assert(k < 1+n);
1136         p1 = (lzo_bytep) &x[1+n];
1137         r &= __lzo_assert(PTR_LT(p0,p1));
1138
1139         if (r == 1)
1140         {
1141             lzo_uint32 v0, v1;
1142 #if 0
1143             v0 = * (lzo_uint32 *) &x[k];
1144             v1 = * (lzo_uint32 *) &x[k+n];
1145 #else
1146
1147             u.a_uchar_p = &x[k];
1148             v0 = *u.a_lzo_uint32_p;
1149             u.a_uchar_p = &x[k+n];
1150             v1 = *u.a_lzo_uint32_p;
1151 #endif
1152             r &= __lzo_assert(v0 > 0);
1153             r &= __lzo_assert(v1 > 0);
1154         }
1155     }
1156
1157     return r;
1158 }
1159
1160 LZO_PUBLIC(int)
1161 _lzo_config_check(void)
1162 {
1163     lzo_bool r = 1;
1164     int i;
1165     union {
1166         lzo_uint32 a;
1167         unsigned short b;
1168         lzo_uint32 aa[4];
1169         unsigned char x[4*sizeof(lzo_full_align_t)];
1170     } u;
1171
1172     COMPILE_TIME_ASSERT( (int) ((unsigned char) ((signed char) -1)) == 255);
1173     COMPILE_TIME_ASSERT( (((unsigned char)128) << (int)(8*sizeof(int)-8)) < 0);
1174
1175 #if 0
1176     r &= __lzo_assert((const void *)&u == (const void *)&u.a);
1177     r &= __lzo_assert((const void *)&u == (const void *)&u.b);
1178     r &= __lzo_assert((const void *)&u == (const void *)&u.x[0]);
1179     r &= __lzo_assert((const void *)&u == (const void *)&u.aa[0]);
1180 #endif
1181
1182     r &= basic_integral_check();
1183     r &= basic_ptr_check();
1184     if (r != 1)
1185         return LZO_E_ERROR;
1186
1187     u.a = 0; u.b = 0;
1188     for (i = 0; i < (int) sizeof(u.x); i++)
1189         u.x[i] = LZO_BYTE(i);
1190
1191 #if defined(LZO_BYTE_ORDER)
1192     if (r == 1)
1193     {
1194 #  if (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
1195         lzo_uint32 a = (lzo_uint32) (u.a & LZO_0xffffffffL);
1196         unsigned short b = (unsigned short) (u.b & 0xffff);
1197         r &= __lzo_assert(a == 0x03020100L);
1198         r &= __lzo_assert(b == 0x0100);
1199 #  elif (LZO_BYTE_ORDER == LZO_BIG_ENDIAN)
1200         lzo_uint32 a = u.a >> (8 * sizeof(u.a) - 32);
1201         unsigned short b = u.b >> (8 * sizeof(u.b) - 16);
1202         r &= __lzo_assert(a == 0x00010203L);
1203         r &= __lzo_assert(b == 0x0001);
1204 #  else
1205 #    error "invalid LZO_BYTE_ORDER"
1206 #  endif
1207     }
1208 #endif
1209
1210 #if defined(LZO_UNALIGNED_OK_2)
1211     COMPILE_TIME_ASSERT(sizeof(short) == 2);
1212     if (r == 1)
1213     {
1214         unsigned short b[4];
1215
1216         for (i = 0; i < 4; i++)
1217             b[i] = * (const unsigned short *) &u.x[i];
1218
1219 #  if (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
1220         r &= __lzo_assert(b[0] == 0x0100);
1221         r &= __lzo_assert(b[1] == 0x0201);
1222         r &= __lzo_assert(b[2] == 0x0302);
1223         r &= __lzo_assert(b[3] == 0x0403);
1224 #  elif (LZO_BYTE_ORDER == LZO_BIG_ENDIAN)
1225         r &= __lzo_assert(b[0] == 0x0001);
1226         r &= __lzo_assert(b[1] == 0x0102);
1227         r &= __lzo_assert(b[2] == 0x0203);
1228         r &= __lzo_assert(b[3] == 0x0304);
1229 #  endif
1230     }
1231 #endif
1232
1233 #if defined(LZO_UNALIGNED_OK_4)
1234     COMPILE_TIME_ASSERT(sizeof(lzo_uint32) == 4);
1235     if (r == 1)
1236     {
1237         lzo_uint32 a[4];
1238
1239         for (i = 0; i < 4; i++)
1240             a[i] = * (const lzo_uint32 *) &u.x[i];
1241
1242 #  if (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
1243         r &= __lzo_assert(a[0] == 0x03020100L);
1244         r &= __lzo_assert(a[1] == 0x04030201L);
1245         r &= __lzo_assert(a[2] == 0x05040302L);
1246         r &= __lzo_assert(a[3] == 0x06050403L);
1247 #  elif (LZO_BYTE_ORDER == LZO_BIG_ENDIAN)
1248         r &= __lzo_assert(a[0] == 0x00010203L);
1249         r &= __lzo_assert(a[1] == 0x01020304L);
1250         r &= __lzo_assert(a[2] == 0x02030405L);
1251         r &= __lzo_assert(a[3] == 0x03040506L);
1252 #  endif
1253     }
1254 #endif
1255
1256 #if defined(LZO_ALIGNED_OK_4)
1257     COMPILE_TIME_ASSERT(sizeof(lzo_uint32) == 4);
1258 #endif
1259
1260     COMPILE_TIME_ASSERT(lzo_sizeof_dict_t == sizeof(lzo_dict_t));
1261
1262 #if defined(__LZO_IN_MINLZO)
1263     if (r == 1)
1264     {
1265         lzo_uint32 adler;
1266         adler = lzo_adler32(0, NULL, 0);
1267         adler = lzo_adler32(adler, lzo_copyright(), 200);
1268         r &= __lzo_assert(adler == 0xc76f1751L);
1269     }
1270 #endif
1271
1272     if (r == 1)
1273     {
1274         r &= __lzo_assert(!schedule_insns_bug());
1275     }
1276
1277     if (r == 1)
1278     {
1279         static int x[3];
1280         static unsigned xn = 3;
1281         register unsigned j;
1282
1283         for (j = 0; j < xn; j++)
1284             x[j] = (int)j - 3;
1285         r &= __lzo_assert(!strength_reduce_bug(x));
1286     }
1287
1288     if (r == 1)
1289     {
1290         r &= ptr_check();
1291     }
1292
1293     return r == 1 ? LZO_E_OK : LZO_E_ERROR;
1294 }
1295
1296 static lzo_bool schedule_insns_bug(void)
1297 {
1298 #if defined(__LZO_CHECKER)
1299     return 0;
1300 #else
1301     const int clone[] = {1, 2, 0};
1302     const int *q;
1303     q = clone;
1304     return (*q) ? 0 : 1;
1305 #endif
1306 }
1307
1308 static lzo_bool strength_reduce_bug(int *x)
1309 {
1310     return x[0] != -3 || x[1] != -2 || x[2] != -1;
1311 }
1312
1313 #undef COMPILE_TIME_ASSERT
1314
1315 int __lzo_init_done = 0;
1316
1317 LZO_PUBLIC(int)
1318 __lzo_init2(unsigned v, int s1, int s2, int s3, int s4, int s5,
1319                         int s6, int s7, int s8, int s9)
1320 {
1321     int r;
1322
1323     __lzo_init_done = 1;
1324
1325     if (v == 0)
1326         return LZO_E_ERROR;
1327
1328     r = (s1 == -1 || s1 == (int) sizeof(short)) &&
1329         (s2 == -1 || s2 == (int) sizeof(int)) &&
1330         (s3 == -1 || s3 == (int) sizeof(long)) &&
1331         (s4 == -1 || s4 == (int) sizeof(lzo_uint32)) &&
1332         (s5 == -1 || s5 == (int) sizeof(lzo_uint)) &&
1333         (s6 == -1 || s6 == (int) lzo_sizeof_dict_t) &&
1334         (s7 == -1 || s7 == (int) sizeof(char *)) &&
1335         (s8 == -1 || s8 == (int) sizeof(lzo_voidp)) &&
1336         (s9 == -1 || s9 == (int) sizeof(lzo_compress_t));
1337     if (!r)
1338         return LZO_E_ERROR;
1339
1340     r = _lzo_config_check();
1341     if (r != LZO_E_OK)
1342         return r;
1343
1344     return r;
1345 }
1346
1347 #if !defined(__LZO_IN_MINILZO)
1348
1349 LZO_EXTERN(int)
1350 __lzo_init(unsigned v,int s1,int s2,int s3,int s4,int s5,int s6,int s7);
1351
1352 LZO_PUBLIC(int)
1353 __lzo_init(unsigned v,int s1,int s2,int s3,int s4,int s5,int s6,int s7)
1354 {
1355     if (v == 0 || v > 0x1010)
1356         return LZO_E_ERROR;
1357     return __lzo_init2(v,s1,s2,s3,s4,s5,-1,-1,s6,s7);
1358 }
1359
1360 #endif
1361
1362 #define do_compress         _lzo1x_1_do_compress
1363
1364 #define LZO_NEED_DICT_H
1365 #define D_BITS          14
1366 #define D_INDEX1(d,p)       d = DM((0x21*DX3(p,5,5,6)) >> 5)
1367 #define D_INDEX2(d,p)       d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f)
1368
1369 #ifndef __LZO_CONFIG1X_H
1370 #define __LZO_CONFIG1X_H
1371
1372 #if !defined(LZO1X) && !defined(LZO1Y) && !defined(LZO1Z)
1373 #  define LZO1X
1374 #endif
1375
1376 #if !defined(__LZO_IN_MINILZO)
1377 #include <lzo1x.h>
1378 #endif
1379
1380 #define LZO_EOF_CODE
1381 #undef LZO_DETERMINISTIC
1382
1383 #define M1_MAX_OFFSET   0x0400
1384 #ifndef M2_MAX_OFFSET
1385 #define M2_MAX_OFFSET   0x0800
1386 #endif
1387 #define M3_MAX_OFFSET   0x4000
1388 #define M4_MAX_OFFSET   0xbfff
1389
1390 #define MX_MAX_OFFSET   (M1_MAX_OFFSET + M2_MAX_OFFSET)
1391
1392 #define M1_MIN_LEN      2
1393 #define M1_MAX_LEN      2
1394 #define M2_MIN_LEN      3
1395 #ifndef M2_MAX_LEN
1396 #define M2_MAX_LEN      8
1397 #endif
1398 #define M3_MIN_LEN      3
1399 #define M3_MAX_LEN      33
1400 #define M4_MIN_LEN      3
1401 #define M4_MAX_LEN      9
1402
1403 #define M1_MARKER       0
1404 #define M2_MARKER       64
1405 #define M3_MARKER       32
1406 #define M4_MARKER       16
1407
1408 #ifndef MIN_LOOKAHEAD
1409 #define MIN_LOOKAHEAD       (M2_MAX_LEN + 1)
1410 #endif
1411
1412 #if defined(LZO_NEED_DICT_H)
1413
1414 #ifndef LZO_HASH
1415 #define LZO_HASH            LZO_HASH_LZO_INCREMENTAL_B
1416 #endif
1417 #define DL_MIN_LEN          M2_MIN_LEN
1418
1419 #ifndef __LZO_DICT_H
1420 #define __LZO_DICT_H
1421
1422 #ifdef __cplusplus
1423 extern "C" {
1424 #endif
1425
1426 #if !defined(D_BITS) && defined(DBITS)
1427 #  define D_BITS        DBITS
1428 #endif
1429 #if !defined(D_BITS)
1430 #  error "D_BITS is not defined"
1431 #endif
1432 #if (D_BITS < 16)
1433 #  define D_SIZE        LZO_SIZE(D_BITS)
1434 #  define D_MASK        LZO_MASK(D_BITS)
1435 #else
1436 #  define D_SIZE        LZO_USIZE(D_BITS)
1437 #  define D_MASK        LZO_UMASK(D_BITS)
1438 #endif
1439 #define D_HIGH          ((D_MASK >> 1) + 1)
1440
1441 #if !defined(DD_BITS)
1442 #  define DD_BITS       0
1443 #endif
1444 #define DD_SIZE         LZO_SIZE(DD_BITS)
1445 #define DD_MASK         LZO_MASK(DD_BITS)
1446
1447 #if !defined(DL_BITS)
1448 #  define DL_BITS       (D_BITS - DD_BITS)
1449 #endif
1450 #if (DL_BITS < 16)
1451 #  define DL_SIZE       LZO_SIZE(DL_BITS)
1452 #  define DL_MASK       LZO_MASK(DL_BITS)
1453 #else
1454 #  define DL_SIZE       LZO_USIZE(DL_BITS)
1455 #  define DL_MASK       LZO_UMASK(DL_BITS)
1456 #endif
1457
1458 #if (D_BITS != DL_BITS + DD_BITS)
1459 #  error "D_BITS does not match"
1460 #endif
1461 #if (D_BITS < 8 || D_BITS > 18)
1462 #  error "invalid D_BITS"
1463 #endif
1464 #if (DL_BITS < 8 || DL_BITS > 20)
1465 #  error "invalid DL_BITS"
1466 #endif
1467 #if (DD_BITS < 0 || DD_BITS > 6)
1468 #  error "invalid DD_BITS"
1469 #endif
1470
1471 #if !defined(DL_MIN_LEN)
1472 #  define DL_MIN_LEN    3
1473 #endif
1474 #if !defined(DL_SHIFT)
1475 #  define DL_SHIFT      ((DL_BITS + (DL_MIN_LEN - 1)) / DL_MIN_LEN)
1476 #endif
1477
1478 #define LZO_HASH_GZIP                   1
1479 #define LZO_HASH_GZIP_INCREMENTAL       2
1480 #define LZO_HASH_LZO_INCREMENTAL_A      3
1481 #define LZO_HASH_LZO_INCREMENTAL_B      4
1482
1483 #if !defined(LZO_HASH)
1484 #  error "choose a hashing strategy"
1485 #endif
1486
1487 #if (DL_MIN_LEN == 3)
1488 #  define _DV2_A(p,shift1,shift2) \
1489         (((( (lzo_uint32)((p)[0]) << shift1) ^ (p)[1]) << shift2) ^ (p)[2])
1490 #  define _DV2_B(p,shift1,shift2) \
1491         (((( (lzo_uint32)((p)[2]) << shift1) ^ (p)[1]) << shift2) ^ (p)[0])
1492 #  define _DV3_B(p,shift1,shift2,shift3) \
1493         ((_DV2_B((p)+1,shift1,shift2) << (shift3)) ^ (p)[0])
1494 #elif (DL_MIN_LEN == 2)
1495 #  define _DV2_A(p,shift1,shift2) \
1496         (( (lzo_uint32)(p[0]) << shift1) ^ p[1])
1497 #  define _DV2_B(p,shift1,shift2) \
1498         (( (lzo_uint32)(p[1]) << shift1) ^ p[2])
1499 #else
1500 #  error "invalid DL_MIN_LEN"
1501 #endif
1502 #define _DV_A(p,shift)      _DV2_A(p,shift,shift)
1503 #define _DV_B(p,shift)      _DV2_B(p,shift,shift)
1504 #define DA2(p,s1,s2) \
1505         (((((lzo_uint32)((p)[2]) << (s2)) + (p)[1]) << (s1)) + (p)[0])
1506 #define DS2(p,s1,s2) \
1507         (((((lzo_uint32)((p)[2]) << (s2)) - (p)[1]) << (s1)) - (p)[0])
1508 #define DX2(p,s1,s2) \
1509         (((((lzo_uint32)((p)[2]) << (s2)) ^ (p)[1]) << (s1)) ^ (p)[0])
1510 #define DA3(p,s1,s2,s3) ((DA2((p)+1,s2,s3) << (s1)) + (p)[0])
1511 #define DS3(p,s1,s2,s3) ((DS2((p)+1,s2,s3) << (s1)) - (p)[0])
1512 #define DX3(p,s1,s2,s3) ((DX2((p)+1,s2,s3) << (s1)) ^ (p)[0])
1513 #define DMS(v,s)        ((lzo_uint) (((v) & (D_MASK >> (s))) << (s)))
1514 #define DM(v)           DMS(v,0)
1515
1516 #if (LZO_HASH == LZO_HASH_GZIP)
1517 #  define _DINDEX(dv,p)     (_DV_A((p),DL_SHIFT))
1518
1519 #elif (LZO_HASH == LZO_HASH_GZIP_INCREMENTAL)
1520 #  define __LZO_HASH_INCREMENTAL
1521 #  define DVAL_FIRST(dv,p)  dv = _DV_A((p),DL_SHIFT)
1522 #  define DVAL_NEXT(dv,p)   dv = (((dv) << DL_SHIFT) ^ p[2])
1523 #  define _DINDEX(dv,p)     (dv)
1524 #  define DVAL_LOOKAHEAD    DL_MIN_LEN
1525
1526 #elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_A)
1527 #  define __LZO_HASH_INCREMENTAL
1528 #  define DVAL_FIRST(dv,p)  dv = _DV_A((p),5)
1529 #  define DVAL_NEXT(dv,p) \
1530                 dv ^= (lzo_uint32)(p[-1]) << (2*5); dv = (((dv) << 5) ^ p[2])
1531 #  define _DINDEX(dv,p)     ((0x9f5f * (dv)) >> 5)
1532 #  define DVAL_LOOKAHEAD    DL_MIN_LEN
1533
1534 #elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_B)
1535 #  define __LZO_HASH_INCREMENTAL
1536 #  define DVAL_FIRST(dv,p)  dv = _DV_B((p),5)
1537 #  define DVAL_NEXT(dv,p) \
1538                 dv ^= p[-1]; dv = (((dv) >> 5) ^ ((lzo_uint32)(p[2]) << (2*5)))
1539 #  define _DINDEX(dv,p)     ((0x9f5f * (dv)) >> 5)
1540 #  define DVAL_LOOKAHEAD    DL_MIN_LEN
1541
1542 #else
1543 #  error "choose a hashing strategy"
1544 #endif
1545
1546 #ifndef DINDEX
1547 #define DINDEX(dv,p)        ((lzo_uint)((_DINDEX(dv,p)) & DL_MASK) << DD_BITS)
1548 #endif
1549 #if !defined(DINDEX1) && defined(D_INDEX1)
1550 #define DINDEX1             D_INDEX1
1551 #endif
1552 #if !defined(DINDEX2) && defined(D_INDEX2)
1553 #define DINDEX2             D_INDEX2
1554 #endif
1555
1556 #if !defined(__LZO_HASH_INCREMENTAL)
1557 #  define DVAL_FIRST(dv,p)  ((void) 0)
1558 #  define DVAL_NEXT(dv,p)   ((void) 0)
1559 #  define DVAL_LOOKAHEAD    0
1560 #endif
1561
1562 #if !defined(DVAL_ASSERT)
1563 #if defined(__LZO_HASH_INCREMENTAL) && !defined(NDEBUG)
1564 static void DVAL_ASSERT(lzo_uint32 dv, const lzo_byte *p)
1565 {
1566     lzo_uint32 df;
1567     DVAL_FIRST(df,(p));
1568     assert(DINDEX(dv,p) == DINDEX(df,p));
1569 }
1570 #else
1571 #  define DVAL_ASSERT(dv,p) ((void) 0)
1572 #endif
1573 #endif
1574
1575 #if defined(LZO_DICT_USE_PTR)
1576 #  define DENTRY(p,in)                          (p)
1577 #  define GINDEX(m_pos,m_off,dict,dindex,in)    m_pos = dict[dindex]
1578 #else
1579 #  define DENTRY(p,in)                          ((lzo_uint) ((p)-(in)))
1580 #  define GINDEX(m_pos,m_off,dict,dindex,in)    m_off = dict[dindex]
1581 #endif
1582
1583 #if (DD_BITS == 0)
1584
1585 #  define UPDATE_D(dict,drun,dv,p,in)       dict[ DINDEX(dv,p) ] = DENTRY(p,in)
1586 #  define UPDATE_I(dict,drun,index,p,in)    dict[index] = DENTRY(p,in)
1587 #  define UPDATE_P(ptr,drun,p,in)           (ptr)[0] = DENTRY(p,in)
1588
1589 #else
1590
1591 #  define UPDATE_D(dict,drun,dv,p,in)   \
1592         dict[ DINDEX(dv,p) + drun++ ] = DENTRY(p,in); drun &= DD_MASK
1593 #  define UPDATE_I(dict,drun,index,p,in)    \
1594         dict[ (index) + drun++ ] = DENTRY(p,in); drun &= DD_MASK
1595 #  define UPDATE_P(ptr,drun,p,in)   \
1596         (ptr) [ drun++ ] = DENTRY(p,in); drun &= DD_MASK
1597
1598 #endif
1599
1600 #if defined(LZO_DICT_USE_PTR)
1601
1602 #define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \
1603         (m_pos == NULL || (m_off = (lzo_moff_t) (ip - m_pos)) > max_offset)
1604
1605 #define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \
1606     (BOUNDS_CHECKING_OFF_IN_EXPR( \
1607         (PTR_LT(m_pos,in) || \
1608          (m_off = (lzo_moff_t) PTR_DIFF(ip,m_pos)) <= 0 || \
1609           m_off > max_offset) ))
1610
1611 #else
1612
1613 #define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \
1614         (m_off == 0 || \
1615          ((m_off = (lzo_moff_t) ((ip)-(in)) - m_off) > max_offset) || \
1616          (m_pos = (ip) - (m_off), 0) )
1617
1618 #define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \
1619         ((lzo_moff_t) ((ip)-(in)) <= m_off || \
1620          ((m_off = (lzo_moff_t) ((ip)-(in)) - m_off) > max_offset) || \
1621          (m_pos = (ip) - (m_off), 0) )
1622
1623 #endif
1624
1625 #if defined(LZO_DETERMINISTIC)
1626 #  define LZO_CHECK_MPOS    LZO_CHECK_MPOS_DET
1627 #else
1628 #  define LZO_CHECK_MPOS    LZO_CHECK_MPOS_NON_DET
1629 #endif
1630
1631 #ifdef __cplusplus
1632 }
1633 #endif
1634
1635 #endif
1636
1637 #endif
1638
1639 #endif
1640
1641 #define DO_COMPRESS     lzo1x_1_compress
1642
1643 static
1644 lzo_uint do_compress     ( const lzo_byte *in , lzo_uint  in_len,
1645                                  lzo_byte *out, lzo_uintp out_len,
1646                                  lzo_voidp wrkmem )
1647 {
1648 #if 0 && defined(__GNUC__) && defined(__i386__)
1649     register const lzo_byte *ip __asm__("%esi");
1650 #else
1651     register const lzo_byte *ip;
1652 #endif
1653     lzo_byte *op;
1654     const lzo_byte * const in_end = in + in_len;
1655     const lzo_byte * const ip_end = in + in_len - M2_MAX_LEN - 5;
1656     const lzo_byte *ii;
1657     lzo_dict_p const dict = (lzo_dict_p) wrkmem;
1658
1659     op = out;
1660     ip = in;
1661     ii = ip;
1662
1663     ip += 4;
1664     for (;;)
1665     {
1666 #if 0 && defined(__GNUC__) && defined(__i386__)
1667         register const lzo_byte *m_pos __asm__("%edi");
1668 #else
1669         register const lzo_byte *m_pos;
1670 #endif
1671         lzo_moff_t m_off;
1672         lzo_uint m_len;
1673         lzo_uint dindex;
1674
1675         DINDEX1(dindex,ip);
1676         GINDEX(m_pos,m_off,dict,dindex,in);
1677         if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET))
1678             goto literal;
1679 #if 1
1680         if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
1681             goto try_match;
1682         DINDEX2(dindex,ip);
1683 #endif
1684         GINDEX(m_pos,m_off,dict,dindex,in);
1685         if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET))
1686             goto literal;
1687         if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
1688             goto try_match;
1689         goto literal;
1690
1691 try_match:
1692 #if 1 && defined(LZO_UNALIGNED_OK_2)
1693         if (* (const lzo_ushortp) m_pos != * (const lzo_ushortp) ip)
1694 #else
1695         if (m_pos[0] != ip[0] || m_pos[1] != ip[1])
1696 #endif
1697         {
1698         }
1699         else
1700         {
1701             if (m_pos[2] == ip[2])
1702             {
1703 #if 0
1704                 if (m_off <= M2_MAX_OFFSET)
1705                     goto match;
1706                 if (lit <= 3)
1707                     goto match;
1708                 if (lit == 3)
1709                 {
1710                     assert(op - 2 > out); op[-2] |= LZO_BYTE(3);
1711                     *op++ = *ii++; *op++ = *ii++; *op++ = *ii++;
1712                     goto code_match;
1713                 }
1714                 if (m_pos[3] == ip[3])
1715 #endif
1716                     goto match;
1717             }
1718             else
1719             {
1720 #if 0
1721 #if 0
1722                 if (m_off <= M1_MAX_OFFSET && lit > 0 && lit <= 3)
1723 #else
1724                 if (m_off <= M1_MAX_OFFSET && lit == 3)
1725 #endif
1726                 {
1727                     register lzo_uint t;
1728
1729                     t = lit;
1730                     assert(op - 2 > out); op[-2] |= LZO_BYTE(t);
1731                     do *op++ = *ii++; while (--t > 0);
1732                     assert(ii == ip);
1733                     m_off -= 1;
1734                     *op++ = LZO_BYTE(M1_MARKER | ((m_off & 3) << 2));
1735                     *op++ = LZO_BYTE(m_off >> 2);
1736                     ip += 2;
1737                     goto match_done;
1738                 }
1739 #endif
1740             }
1741         }
1742
1743 literal:
1744         UPDATE_I(dict,0,dindex,ip,in);
1745         ++ip;
1746         if (ip >= ip_end)
1747             break;
1748         continue;
1749
1750 match:
1751         UPDATE_I(dict,0,dindex,ip,in);
1752         if (pd(ip,ii) > 0)
1753         {
1754             register lzo_uint t = pd(ip,ii);
1755
1756             if (t <= 3)
1757             {
1758                 assert(op - 2 > out);
1759                 op[-2] |= LZO_BYTE(t);
1760             }
1761             else if (t <= 18)
1762                 *op++ = LZO_BYTE(t - 3);
1763             else
1764             {
1765                 register lzo_uint tt = t - 18;
1766
1767                 *op++ = 0;
1768                 while (tt > 255)
1769                 {
1770                     tt -= 255;
1771                     *op++ = 0;
1772                 }
1773                 assert(tt > 0);
1774                 *op++ = LZO_BYTE(tt);
1775             }
1776             do *op++ = *ii++; while (--t > 0);
1777         }
1778
1779         assert(ii == ip);
1780         ip += 3;
1781         if (m_pos[3] != *ip++ || m_pos[4] != *ip++ || m_pos[5] != *ip++ ||
1782             m_pos[6] != *ip++ || m_pos[7] != *ip++ || m_pos[8] != *ip++
1783 #ifdef LZO1Y
1784             || m_pos[ 9] != *ip++ || m_pos[10] != *ip++ || m_pos[11] != *ip++
1785             || m_pos[12] != *ip++ || m_pos[13] != *ip++ || m_pos[14] != *ip++
1786 #endif
1787            )
1788         {
1789             --ip;
1790             m_len = ip - ii;
1791             assert(m_len >= 3); assert(m_len <= M2_MAX_LEN);
1792
1793             if (m_off <= M2_MAX_OFFSET)
1794             {
1795                 m_off -= 1;
1796 #if defined(LZO1X)
1797                 *op++ = LZO_BYTE(((m_len - 1) << 5) | ((m_off & 7) << 2));
1798                 *op++ = LZO_BYTE(m_off >> 3);
1799 #elif defined(LZO1Y)
1800                 *op++ = LZO_BYTE(((m_len + 1) << 4) | ((m_off & 3) << 2));
1801                 *op++ = LZO_BYTE(m_off >> 2);
1802 #endif
1803             }
1804             else if (m_off <= M3_MAX_OFFSET)
1805             {
1806                 m_off -= 1;
1807                 *op++ = LZO_BYTE(M3_MARKER | (m_len - 2));
1808                 goto m3_m4_offset;
1809             }
1810             else
1811 #if defined(LZO1X)
1812             {
1813                 m_off -= 0x4000;
1814                 assert(m_off > 0); assert(m_off <= 0x7fff);
1815                 *op++ = LZO_BYTE(M4_MARKER |
1816                                  ((m_off & 0x4000) >> 11) | (m_len - 2));
1817                 goto m3_m4_offset;
1818             }
1819 #elif defined(LZO1Y)
1820                 goto m4_match;
1821 #endif
1822         }
1823         else
1824         {
1825             {
1826                 const lzo_byte *end = in_end;
1827                 const lzo_byte *m = m_pos + M2_MAX_LEN + 1;
1828                 while (ip < end && *m == *ip)
1829                     m++, ip++;
1830                 m_len = (ip - ii);
1831             }
1832             assert(m_len > M2_MAX_LEN);
1833
1834             if (m_off <= M3_MAX_OFFSET)
1835             {
1836                 m_off -= 1;
1837                 if (m_len <= 33)
1838                     *op++ = LZO_BYTE(M3_MARKER | (m_len - 2));
1839                 else
1840                 {
1841                     m_len -= 33;
1842                     *op++ = M3_MARKER | 0;
1843                     goto m3_m4_len;
1844                 }
1845             }
1846             else
1847             {
1848 #if defined(LZO1Y)
1849 m4_match:
1850 #endif
1851                 m_off -= 0x4000;
1852                 assert(m_off > 0); assert(m_off <= 0x7fff);
1853                 if (m_len <= M4_MAX_LEN)
1854                     *op++ = LZO_BYTE(M4_MARKER |
1855                                      ((m_off & 0x4000) >> 11) | (m_len - 2));
1856                 else
1857                 {
1858                     m_len -= M4_MAX_LEN;
1859                     *op++ = LZO_BYTE(M4_MARKER | ((m_off & 0x4000) >> 11));
1860 m3_m4_len:
1861                     while (m_len > 255)
1862                     {
1863                         m_len -= 255;
1864                         *op++ = 0;
1865                     }
1866                     assert(m_len > 0);
1867                     *op++ = LZO_BYTE(m_len);
1868                 }
1869             }
1870
1871 m3_m4_offset:
1872             *op++ = LZO_BYTE((m_off & 63) << 2);
1873             *op++ = LZO_BYTE(m_off >> 6);
1874         }
1875
1876 #if 0
1877 match_done:
1878 #endif
1879         ii = ip;
1880         if (ip >= ip_end)
1881             break;
1882     }
1883
1884     *out_len = op - out;
1885     return pd(in_end,ii);
1886 }
1887
1888 LZO_PUBLIC(int)
1889 DO_COMPRESS      ( const lzo_byte *in , lzo_uint  in_len,
1890                          lzo_byte *out, lzo_uintp out_len,
1891                          lzo_voidp wrkmem )
1892 {
1893     lzo_byte *op = out;
1894     lzo_uint t;
1895
1896 #if defined(__LZO_QUERY_COMPRESS)
1897     if (__LZO_IS_COMPRESS_QUERY(in,in_len,out,out_len,wrkmem))
1898         return __LZO_QUERY_COMPRESS(in,in_len,out,out_len,wrkmem,D_SIZE,lzo_sizeof(lzo_dict_t));
1899 #endif
1900
1901     if (in_len <= M2_MAX_LEN + 5)
1902         t = in_len;
1903     else
1904     {
1905         t = do_compress(in,in_len,op,out_len,wrkmem);
1906         op += *out_len;
1907     }
1908
1909     if (t > 0)
1910     {
1911         const lzo_byte *ii = in + in_len - t;
1912
1913         if (op == out && t <= 238)
1914             *op++ = LZO_BYTE(17 + t);
1915         else if (t <= 3)
1916             op[-2] |= LZO_BYTE(t);
1917         else if (t <= 18)
1918             *op++ = LZO_BYTE(t - 3);
1919         else
1920         {
1921             lzo_uint tt = t - 18;
1922
1923             *op++ = 0;
1924             while (tt > 255)
1925             {
1926                 tt -= 255;
1927                 *op++ = 0;
1928             }
1929             assert(tt > 0);
1930             *op++ = LZO_BYTE(tt);
1931         }
1932         do *op++ = *ii++; while (--t > 0);
1933     }
1934
1935     *op++ = M4_MARKER | 1;
1936     *op++ = 0;
1937     *op++ = 0;
1938
1939     *out_len = op - out;
1940     return LZO_E_OK;
1941 }
1942
1943 #undef do_compress
1944 #undef DO_COMPRESS
1945 #undef LZO_HASH
1946
1947 #undef LZO_TEST_DECOMPRESS_OVERRUN
1948 #undef LZO_TEST_DECOMPRESS_OVERRUN_INPUT
1949 #undef LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT
1950 #undef LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND
1951 #undef DO_DECOMPRESS
1952 #define DO_DECOMPRESS       lzo1x_decompress
1953
1954 #if defined(LZO_TEST_DECOMPRESS_OVERRUN)
1955 #  if !defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT)
1956 #    define LZO_TEST_DECOMPRESS_OVERRUN_INPUT       2
1957 #  endif
1958 #  if !defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT)
1959 #    define LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT      2
1960 #  endif
1961 #  if !defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
1962 #    define LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND
1963 #  endif
1964 #endif
1965
1966 #undef TEST_IP
1967 #undef TEST_OP
1968 #undef TEST_LOOKBEHIND
1969 #undef NEED_IP
1970 #undef NEED_OP
1971 #undef HAVE_TEST_IP
1972 #undef HAVE_TEST_OP
1973 #undef HAVE_NEED_IP
1974 #undef HAVE_NEED_OP
1975 #undef HAVE_ANY_IP
1976 #undef HAVE_ANY_OP
1977
1978 #if defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT)
1979 #  if (LZO_TEST_DECOMPRESS_OVERRUN_INPUT >= 1)
1980 #    define TEST_IP             (ip < ip_end)
1981 #  endif
1982 #  if (LZO_TEST_DECOMPRESS_OVERRUN_INPUT >= 2)
1983 #    define NEED_IP(x) \
1984             if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x))  goto input_overrun
1985 #  endif
1986 #endif
1987
1988 #if defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT)
1989 #  if (LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT >= 1)
1990 #    define TEST_OP             (op <= op_end)
1991 #  endif
1992 #  if (LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT >= 2)
1993 #    undef TEST_OP
1994 #    define NEED_OP(x) \
1995             if ((lzo_uint)(op_end - op) < (lzo_uint)(x))  goto output_overrun
1996 #  endif
1997 #endif
1998
1999 #if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
2000 #  define TEST_LOOKBEHIND(m_pos,out)    if (m_pos < out) goto lookbehind_overrun
2001 #else
2002 #  define TEST_LOOKBEHIND(m_pos,op)     ((void) 0)
2003 #endif
2004
2005 #if !defined(LZO_EOF_CODE) && !defined(TEST_IP)
2006 #  define TEST_IP               (ip < ip_end)
2007 #endif
2008
2009 #if defined(TEST_IP)
2010 #  define HAVE_TEST_IP
2011 #else
2012 #  define TEST_IP               1
2013 #endif
2014 #if defined(TEST_OP)
2015 #  define HAVE_TEST_OP
2016 #else
2017 #  define TEST_OP               1
2018 #endif
2019
2020 #if defined(NEED_IP)
2021 #  define HAVE_NEED_IP
2022 #else
2023 #  define NEED_IP(x)            ((void) 0)
2024 #endif
2025 #if defined(NEED_OP)
2026 #  define HAVE_NEED_OP
2027 #else
2028 #  define NEED_OP(x)            ((void) 0)
2029 #endif
2030
2031 #if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP)
2032 #  define HAVE_ANY_IP
2033 #endif
2034 #if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP)
2035 #  define HAVE_ANY_OP
2036 #endif
2037
2038 #undef __COPY4
2039 #define __COPY4(dst,src)    * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src)
2040
2041 #undef COPY4
2042 #if defined(LZO_UNALIGNED_OK_4)
2043 #  define COPY4(dst,src)    __COPY4(dst,src)
2044 #elif defined(LZO_ALIGNED_OK_4)
2045 #  define COPY4(dst,src)    __COPY4((lzo_ptr_t)(dst),(lzo_ptr_t)(src))
2046 #endif
2047
2048 #if defined(DO_DECOMPRESS)
2049 LZO_PUBLIC(int)
2050 DO_DECOMPRESS  ( const lzo_byte *in , lzo_uint  in_len,
2051                        lzo_byte *out, lzo_uintp out_len,
2052                        lzo_voidp wrkmem )
2053 #endif
2054 {
2055     register lzo_byte *op;
2056     register const lzo_byte *ip;
2057     register lzo_uint t;
2058 #if defined(COPY_DICT)
2059     lzo_uint m_off;
2060     const lzo_byte *dict_end;
2061 #else
2062     register const lzo_byte *m_pos;
2063 #endif
2064
2065     const lzo_byte * const ip_end = in + in_len;
2066 #if defined(HAVE_ANY_OP)
2067     lzo_byte * const op_end = out + *out_len;
2068 #endif
2069 #if defined(LZO1Z)
2070     lzo_uint last_m_off = 0;
2071 #endif
2072
2073     LZO_UNUSED(wrkmem);
2074
2075 #if defined(__LZO_QUERY_DECOMPRESS)
2076     if (__LZO_IS_DECOMPRESS_QUERY(in,in_len,out,out_len,wrkmem))
2077         return __LZO_QUERY_DECOMPRESS(in,in_len,out,out_len,wrkmem,0,0);
2078 #endif
2079
2080 #if defined(COPY_DICT)
2081     if (dict)
2082     {
2083         if (dict_len > M4_MAX_OFFSET)
2084         {
2085             dict += dict_len - M4_MAX_OFFSET;
2086             dict_len = M4_MAX_OFFSET;
2087         }
2088         dict_end = dict + dict_len;
2089     }
2090     else
2091     {
2092         dict_len = 0;
2093         dict_end = NULL;
2094     }
2095 #endif
2096
2097     *out_len = 0;
2098
2099     op = out;
2100     ip = in;
2101
2102     if (*ip > 17)
2103     {
2104         t = *ip++ - 17;
2105         if (t < 4)
2106             goto match_next;
2107         assert(t > 0); NEED_OP(t); NEED_IP(t+1);
2108         do *op++ = *ip++; while (--t > 0);
2109         goto first_literal_run;
2110     }
2111
2112     while (TEST_IP && TEST_OP)
2113     {
2114         t = *ip++;
2115         if (t >= 16)
2116             goto match;
2117         if (t == 0)
2118         {
2119             NEED_IP(1);
2120             while (*ip == 0)
2121             {
2122                 t += 255;
2123                 ip++;
2124                 NEED_IP(1);
2125             }
2126             t += 15 + *ip++;
2127         }
2128         assert(t > 0); NEED_OP(t+3); NEED_IP(t+4);
2129 #if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
2130 #if !defined(LZO_UNALIGNED_OK_4)
2131         if (PTR_ALIGNED2_4(op,ip))
2132         {
2133 #endif
2134         COPY4(op,ip);
2135         op += 4; ip += 4;
2136         if (--t > 0)
2137         {
2138             if (t >= 4)
2139             {
2140                 do {
2141                     COPY4(op,ip);
2142                     op += 4; ip += 4; t -= 4;
2143                 } while (t >= 4);
2144                 if (t > 0) do *op++ = *ip++; while (--t > 0);
2145             }
2146             else
2147                 do *op++ = *ip++; while (--t > 0);
2148         }
2149 #if !defined(LZO_UNALIGNED_OK_4)
2150         }
2151         else
2152 #endif
2153 #endif
2154 #if !defined(LZO_UNALIGNED_OK_4)
2155         {
2156             *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
2157             do *op++ = *ip++; while (--t > 0);
2158         }
2159 #endif
2160
2161 first_literal_run:
2162
2163         t = *ip++;
2164         if (t >= 16)
2165             goto match;
2166 #if defined(COPY_DICT)
2167 #if defined(LZO1Z)
2168         m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
2169         last_m_off = m_off;
2170 #else
2171         m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
2172 #endif
2173         NEED_OP(3);
2174         t = 3; COPY_DICT(t,m_off)
2175 #else
2176 #if defined(LZO1Z)
2177         t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
2178         m_pos = op - t;
2179         last_m_off = t;
2180 #else
2181         m_pos = op - (1 + M2_MAX_OFFSET);
2182         m_pos -= t >> 2;
2183         m_pos -= *ip++ << 2;
2184 #endif
2185         TEST_LOOKBEHIND(m_pos,out); NEED_OP(3);
2186         *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
2187 #endif
2188         goto match_done;
2189
2190         while (TEST_IP && TEST_OP)
2191         {
2192 match:
2193             if (t >= 64)
2194             {
2195 #if defined(COPY_DICT)
2196 #if defined(LZO1X)
2197                 m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3);
2198                 t = (t >> 5) - 1;
2199 #elif defined(LZO1Y)
2200                 m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2);
2201                 t = (t >> 4) - 3;
2202 #elif defined(LZO1Z)
2203                 m_off = t & 0x1f;
2204                 if (m_off >= 0x1c)
2205                     m_off = last_m_off;
2206                 else
2207                 {
2208                     m_off = 1 + (m_off << 6) + (*ip++ >> 2);
2209                     last_m_off = m_off;
2210                 }
2211                 t = (t >> 5) - 1;
2212 #endif
2213 #else
2214 #if defined(LZO1X)
2215                 m_pos = op - 1;
2216                 m_pos -= (t >> 2) & 7;
2217                 m_pos -= *ip++ << 3;
2218                 t = (t >> 5) - 1;
2219 #elif defined(LZO1Y)
2220                 m_pos = op - 1;
2221                 m_pos -= (t >> 2) & 3;
2222                 m_pos -= *ip++ << 2;
2223                 t = (t >> 4) - 3;
2224 #elif defined(LZO1Z)
2225                 {
2226                     lzo_uint off = t & 0x1f;
2227                     m_pos = op;
2228                     if (off >= 0x1c)
2229                     {
2230                         assert(last_m_off > 0);
2231                         m_pos -= last_m_off;
2232                     }
2233                     else
2234                     {
2235                         off = 1 + (off << 6) + (*ip++ >> 2);
2236                         m_pos -= off;
2237                         last_m_off = off;
2238                     }
2239                 }
2240                 t = (t >> 5) - 1;
2241 #endif
2242                 TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1);
2243                 goto copy_match;
2244 #endif
2245             }
2246             else if (t >= 32)
2247             {
2248                 t &= 31;
2249                 if (t == 0)
2250                 {
2251                     NEED_IP(1);
2252                     while (*ip == 0)
2253                     {
2254                         t += 255;
2255                         ip++;
2256                         NEED_IP(1);
2257                     }
2258                     t += 31 + *ip++;
2259                 }
2260 #if defined(COPY_DICT)
2261 #if defined(LZO1Z)
2262                 m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
2263                 last_m_off = m_off;
2264 #else
2265                 m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
2266 #endif
2267 #else
2268 #if defined(LZO1Z)
2269                 {
2270                     lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
2271                     m_pos = op - off;
2272                     last_m_off = off;
2273                 }
2274 #elif defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
2275                 m_pos = op - 1;
2276                 m_pos -= (* (const lzo_ushortp) ip) >> 2;
2277 #else
2278                 m_pos = op - 1;
2279                 m_pos -= (ip[0] >> 2) + (ip[1] << 6);
2280 #endif
2281 #endif
2282                 ip += 2;
2283             }
2284             else if (t >= 16)
2285             {
2286 #if defined(COPY_DICT)
2287                 m_off = (t & 8) << 11;
2288 #else
2289                 m_pos = op;
2290                 m_pos -= (t & 8) << 11;
2291 #endif
2292                 t &= 7;
2293                 if (t == 0)
2294                 {
2295                     NEED_IP(1);
2296                     while (*ip == 0)
2297                     {
2298                         t += 255;
2299                         ip++;
2300                         NEED_IP(1);
2301                     }
2302                     t += 7 + *ip++;
2303                 }
2304 #if defined(COPY_DICT)
2305 #if defined(LZO1Z)
2306                 m_off += (ip[0] << 6) + (ip[1] >> 2);
2307 #else
2308                 m_off += (ip[0] >> 2) + (ip[1] << 6);
2309 #endif
2310                 ip += 2;
2311                 if (m_off == 0)
2312                     goto eof_found;
2313                 m_off += 0x4000;
2314 #if defined(LZO1Z)
2315                 last_m_off = m_off;
2316 #endif
2317 #else
2318 #if defined(LZO1Z)
2319                 m_pos -= (ip[0] << 6) + (ip[1] >> 2);
2320 #elif defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
2321                 m_pos -= (* (const lzo_ushortp) ip) >> 2;
2322 #else
2323                 m_pos -= (ip[0] >> 2) + (ip[1] << 6);
2324 #endif
2325                 ip += 2;
2326                 if (m_pos == op)
2327                     goto eof_found;
2328                 m_pos -= 0x4000;
2329 #if defined(LZO1Z)
2330                 last_m_off = op - m_pos;
2331 #endif
2332 #endif
2333             }
2334             else
2335             {
2336 #if defined(COPY_DICT)
2337 #if defined(LZO1Z)
2338                 m_off = 1 + (t << 6) + (*ip++ >> 2);
2339                 last_m_off = m_off;
2340 #else
2341                 m_off = 1 + (t >> 2) + (*ip++ << 2);
2342 #endif
2343                 NEED_OP(2);
2344                 t = 2; COPY_DICT(t,m_off)
2345 #else
2346 #if defined(LZO1Z)
2347                 t = 1 + (t << 6) + (*ip++ >> 2);
2348                 m_pos = op - t;
2349                 last_m_off = t;
2350 #else
2351                 m_pos = op - 1;
2352                 m_pos -= t >> 2;
2353                 m_pos -= *ip++ << 2;
2354 #endif
2355                 TEST_LOOKBEHIND(m_pos,out); NEED_OP(2);
2356                 *op++ = *m_pos++; *op++ = *m_pos;
2357 #endif
2358                 goto match_done;
2359             }
2360
2361 #if defined(COPY_DICT)
2362
2363             NEED_OP(t+3-1);
2364             t += 3-1; COPY_DICT(t,m_off)
2365
2366 #else
2367
2368             TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1);
2369 #if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
2370 #if !defined(LZO_UNALIGNED_OK_4)
2371             if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
2372             {
2373                 assert((op - m_pos) >= 4);
2374 #else
2375             if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
2376             {
2377 #endif
2378                 COPY4(op,m_pos);
2379                 op += 4; m_pos += 4; t -= 4 - (3 - 1);
2380                 do {
2381                     COPY4(op,m_pos);
2382                     op += 4; m_pos += 4; t -= 4;
2383                 } while (t >= 4);
2384                 if (t > 0) do *op++ = *m_pos++; while (--t > 0);
2385             }
2386             else
2387 #endif
2388             {
2389 copy_match:
2390                 *op++ = *m_pos++; *op++ = *m_pos++;
2391                 do *op++ = *m_pos++; while (--t > 0);
2392             }
2393
2394 #endif
2395
2396 match_done:
2397 #if defined(LZO1Z)
2398             t = ip[-1] & 3;
2399 #else
2400             t = ip[-2] & 3;
2401 #endif
2402             if (t == 0)
2403                 break;
2404
2405 match_next:
2406             assert(t > 0); NEED_OP(t); NEED_IP(t+1);
2407             do *op++ = *ip++; while (--t > 0);
2408             t = *ip++;
2409         }
2410     }
2411
2412 #if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
2413     *out_len = op - out;
2414     return LZO_E_EOF_NOT_FOUND;
2415 #endif
2416
2417 eof_found:
2418     assert(t == 1);
2419     *out_len = op - out;
2420     return (ip == ip_end ? LZO_E_OK :
2421            (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
2422
2423 #if defined(HAVE_NEED_IP)
2424 input_overrun:
2425     *out_len = op - out;
2426     return LZO_E_INPUT_OVERRUN;
2427 #endif
2428
2429 #if defined(HAVE_NEED_OP)
2430 output_overrun:
2431     *out_len = op - out;
2432     return LZO_E_OUTPUT_OVERRUN;
2433 #endif
2434
2435 #if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
2436 lookbehind_overrun:
2437     *out_len = op - out;
2438     return LZO_E_LOOKBEHIND_OVERRUN;
2439 #endif
2440 }
2441
2442 #define LZO_TEST_DECOMPRESS_OVERRUN
2443 #undef DO_DECOMPRESS
2444 #define DO_DECOMPRESS       lzo1x_decompress_safe
2445
2446 #if defined(LZO_TEST_DECOMPRESS_OVERRUN)
2447 #  if !defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT)
2448 #    define LZO_TEST_DECOMPRESS_OVERRUN_INPUT       2
2449 #  endif
2450 #  if !defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT)
2451 #    define LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT      2
2452 #  endif
2453 #  if !defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
2454 #    define LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND
2455 #  endif
2456 #endif
2457
2458 #undef TEST_IP
2459 #undef TEST_OP
2460 #undef TEST_LOOKBEHIND
2461 #undef NEED_IP
2462 #undef NEED_OP
2463 #undef HAVE_TEST_IP
2464 #undef HAVE_TEST_OP
2465 #undef HAVE_NEED_IP
2466 #undef HAVE_NEED_OP
2467 #undef HAVE_ANY_IP
2468 #undef HAVE_ANY_OP
2469
2470 #if defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT)
2471 #  if (LZO_TEST_DECOMPRESS_OVERRUN_INPUT >= 1)
2472 #    define TEST_IP             (ip < ip_end)
2473 #  endif
2474 #  if (LZO_TEST_DECOMPRESS_OVERRUN_INPUT >= 2)
2475 #    define NEED_IP(x) \
2476             if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x))  goto input_overrun
2477 #  endif
2478 #endif
2479
2480 #if defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT)
2481 #  if (LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT >= 1)
2482 #    define TEST_OP             (op <= op_end)
2483 #  endif
2484 #  if (LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT >= 2)
2485 #    undef TEST_OP
2486 #    define NEED_OP(x) \
2487             if ((lzo_uint)(op_end - op) < (lzo_uint)(x))  goto output_overrun
2488 #  endif
2489 #endif
2490
2491 #if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
2492 #  define TEST_LOOKBEHIND(m_pos,out)    if (m_pos < out) goto lookbehind_overrun
2493 #else
2494 #  define TEST_LOOKBEHIND(m_pos,op)     ((void) 0)
2495 #endif
2496
2497 #if !defined(LZO_EOF_CODE) && !defined(TEST_IP)
2498 #  define TEST_IP               (ip < ip_end)
2499 #endif
2500
2501 #if defined(TEST_IP)
2502 #  define HAVE_TEST_IP
2503 #else
2504 #  define TEST_IP               1
2505 #endif
2506 #if defined(TEST_OP)
2507 #  define HAVE_TEST_OP
2508 #else
2509 #  define TEST_OP               1
2510 #endif
2511
2512 #if defined(NEED_IP)
2513 #  define HAVE_NEED_IP
2514 #else
2515 #  define NEED_IP(x)            ((void) 0)
2516 #endif
2517 #if defined(NEED_OP)
2518 #  define HAVE_NEED_OP
2519 #else
2520 #  define NEED_OP(x)            ((void) 0)
2521 #endif
2522
2523 #if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP)
2524 #  define HAVE_ANY_IP
2525 #endif
2526 #if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP)
2527 #  define HAVE_ANY_OP
2528 #endif
2529
2530 #undef __COPY4
2531 #define __COPY4(dst,src)    * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src)
2532
2533 #undef COPY4
2534 #if defined(LZO_UNALIGNED_OK_4)
2535 #  define COPY4(dst,src)    __COPY4(dst,src)
2536 #elif defined(LZO_ALIGNED_OK_4)
2537 #  define COPY4(dst,src)    __COPY4((lzo_ptr_t)(dst),(lzo_ptr_t)(src))
2538 #endif
2539
2540 #if defined(DO_DECOMPRESS)
2541 LZO_PUBLIC(int)
2542 DO_DECOMPRESS  ( const lzo_byte *in , lzo_uint  in_len,
2543                        lzo_byte *out, lzo_uintp out_len,
2544                        lzo_voidp wrkmem )
2545 #endif
2546 {
2547     register lzo_byte *op;
2548     register const lzo_byte *ip;
2549     register lzo_uint t;
2550 #if defined(COPY_DICT)
2551     lzo_uint m_off;
2552     const lzo_byte *dict_end;
2553 #else
2554     register const lzo_byte *m_pos;
2555 #endif
2556
2557     const lzo_byte * const ip_end = in + in_len;
2558 #if defined(HAVE_ANY_OP)
2559     lzo_byte * const op_end = out + *out_len;
2560 #endif
2561 #if defined(LZO1Z)
2562     lzo_uint last_m_off = 0;
2563 #endif
2564
2565     LZO_UNUSED(wrkmem);
2566
2567 #if defined(__LZO_QUERY_DECOMPRESS)
2568     if (__LZO_IS_DECOMPRESS_QUERY(in,in_len,out,out_len,wrkmem))
2569         return __LZO_QUERY_DECOMPRESS(in,in_len,out,out_len,wrkmem,0,0);
2570 #endif
2571
2572 #if defined(COPY_DICT)
2573     if (dict)
2574     {
2575         if (dict_len > M4_MAX_OFFSET)
2576         {
2577             dict += dict_len - M4_MAX_OFFSET;
2578             dict_len = M4_MAX_OFFSET;
2579         }
2580         dict_end = dict + dict_len;
2581     }
2582     else
2583     {
2584         dict_len = 0;
2585         dict_end = NULL;
2586     }
2587 #endif
2588
2589     *out_len = 0;
2590
2591     op = out;
2592     ip = in;
2593
2594     if (*ip > 17)
2595     {
2596         t = *ip++ - 17;
2597         if (t < 4)
2598             goto match_next;
2599         assert(t > 0); NEED_OP(t); NEED_IP(t+1);
2600         do *op++ = *ip++; while (--t > 0);
2601         goto first_literal_run;
2602     }
2603
2604     while (TEST_IP && TEST_OP)
2605     {
2606         t = *ip++;
2607         if (t >= 16)
2608             goto match;
2609         if (t == 0)
2610         {
2611             NEED_IP(1);
2612             while (*ip == 0)
2613             {
2614                 t += 255;
2615                 ip++;
2616                 NEED_IP(1);
2617             }
2618             t += 15 + *ip++;
2619         }
2620         assert(t > 0); NEED_OP(t+3); NEED_IP(t+4);
2621 #if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
2622 #if !defined(LZO_UNALIGNED_OK_4)
2623         if (PTR_ALIGNED2_4(op,ip))
2624         {
2625 #endif
2626         COPY4(op,ip);
2627         op += 4; ip += 4;
2628         if (--t > 0)
2629         {
2630             if (t >= 4)
2631             {
2632                 do {
2633                     COPY4(op,ip);
2634                     op += 4; ip += 4; t -= 4;
2635                 } while (t >= 4);
2636                 if (t > 0) do *op++ = *ip++; while (--t > 0);
2637             }
2638             else
2639                 do *op++ = *ip++; while (--t > 0);
2640         }
2641 #if !defined(LZO_UNALIGNED_OK_4)
2642         }
2643         else
2644 #endif
2645 #endif
2646 #if !defined(LZO_UNALIGNED_OK_4)
2647         {
2648             *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
2649             do *op++ = *ip++; while (--t > 0);
2650         }
2651 #endif
2652
2653 first_literal_run:
2654
2655         t = *ip++;
2656         if (t >= 16)
2657             goto match;
2658 #if defined(COPY_DICT)
2659 #if defined(LZO1Z)
2660         m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
2661         last_m_off = m_off;
2662 #else
2663         m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2);
2664 #endif
2665         NEED_OP(3);
2666         t = 3; COPY_DICT(t,m_off)
2667 #else
2668 #if defined(LZO1Z)
2669         t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
2670         m_pos = op - t;
2671         last_m_off = t;
2672 #else
2673         m_pos = op - (1 + M2_MAX_OFFSET);
2674         m_pos -= t >> 2;
2675         m_pos -= *ip++ << 2;
2676 #endif
2677         TEST_LOOKBEHIND(m_pos,out); NEED_OP(3);
2678         *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
2679 #endif
2680         goto match_done;
2681
2682         while (TEST_IP && TEST_OP)
2683         {
2684 match:
2685             if (t >= 64)
2686             {
2687 #if defined(COPY_DICT)
2688 #if defined(LZO1X)
2689                 m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3);
2690                 t = (t >> 5) - 1;
2691 #elif defined(LZO1Y)
2692                 m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2);
2693                 t = (t >> 4) - 3;
2694 #elif defined(LZO1Z)
2695                 m_off = t & 0x1f;
2696                 if (m_off >= 0x1c)
2697                     m_off = last_m_off;
2698                 else
2699                 {
2700                     m_off = 1 + (m_off << 6) + (*ip++ >> 2);
2701                     last_m_off = m_off;
2702                 }
2703                 t = (t >> 5) - 1;
2704 #endif
2705 #else
2706 #if defined(LZO1X)
2707                 m_pos = op - 1;
2708                 m_pos -= (t >> 2) & 7;
2709                 m_pos -= *ip++ << 3;
2710                 t = (t >> 5) - 1;
2711 #elif defined(LZO1Y)
2712                 m_pos = op - 1;
2713                 m_pos -= (t >> 2) & 3;
2714                 m_pos -= *ip++ << 2;
2715                 t = (t >> 4) - 3;
2716 #elif defined(LZO1Z)
2717                 {
2718                     lzo_uint off = t & 0x1f;
2719                     m_pos = op;
2720                     if (off >= 0x1c)
2721                     {
2722                         assert(last_m_off > 0);
2723                         m_pos -= last_m_off;
2724                     }
2725                     else
2726                     {
2727                         off = 1 + (off << 6) + (*ip++ >> 2);
2728                         m_pos -= off;
2729                         last_m_off = off;
2730                     }
2731                 }
2732                 t = (t >> 5) - 1;
2733 #endif
2734                 TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1);
2735                 goto copy_match;
2736 #endif
2737             }
2738             else if (t >= 32)
2739             {
2740                 t &= 31;
2741                 if (t == 0)
2742                 {
2743                     NEED_IP(1);
2744                     while (*ip == 0)
2745                     {
2746                         t += 255;
2747                         ip++;
2748                         NEED_IP(1);
2749                     }
2750                     t += 31 + *ip++;
2751                 }
2752 #if defined(COPY_DICT)
2753 #if defined(LZO1Z)
2754                 m_off = 1 + (ip[0] << 6) + (ip[1] >> 2);
2755                 last_m_off = m_off;
2756 #else
2757                 m_off = 1 + (ip[0] >> 2) + (ip[1] << 6);
2758 #endif
2759 #else
2760 #if defined(LZO1Z)
2761                 {
2762                     lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
2763                     m_pos = op - off;
2764                     last_m_off = off;
2765                 }
2766 #elif defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
2767                 m_pos = op - 1;
2768                 m_pos -= (* (const lzo_ushortp) ip) >> 2;
2769 #else
2770                 m_pos = op - 1;
2771                 m_pos -= (ip[0] >> 2) + (ip[1] << 6);
2772 #endif
2773 #endif
2774                 ip += 2;
2775             }
2776             else if (t >= 16)
2777             {
2778 #if defined(COPY_DICT)
2779                 m_off = (t & 8) << 11;
2780 #else
2781                 m_pos = op;
2782                 m_pos -= (t & 8) << 11;
2783 #endif
2784                 t &= 7;
2785                 if (t == 0)
2786                 {
2787                     NEED_IP(1);
2788                     while (*ip == 0)
2789                     {
2790                         t += 255;
2791                         ip++;
2792                         NEED_IP(1);
2793                     }
2794                     t += 7 + *ip++;
2795                 }
2796 #if defined(COPY_DICT)
2797 #if defined(LZO1Z)
2798                 m_off += (ip[0] << 6) + (ip[1] >> 2);
2799 #else
2800                 m_off += (ip[0] >> 2) + (ip[1] << 6);
2801 #endif
2802                 ip += 2;
2803                 if (m_off == 0)
2804                     goto eof_found;
2805                 m_off += 0x4000;
2806 #if defined(LZO1Z)
2807                 last_m_off = m_off;
2808 #endif
2809 #else
2810 #if defined(LZO1Z)
2811                 m_pos -= (ip[0] << 6) + (ip[1] >> 2);
2812 #elif defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
2813                 m_pos -= (* (const lzo_ushortp) ip) >> 2;
2814 #else
2815                 m_pos -= (ip[0] >> 2) + (ip[1] << 6);
2816 #endif
2817                 ip += 2;
2818                 if (m_pos == op)
2819                     goto eof_found;
2820                 m_pos -= 0x4000;
2821 #if defined(LZO1Z)
2822                 last_m_off = op - m_pos;
2823 #endif
2824 #endif
2825             }
2826             else
2827             {
2828 #if defined(COPY_DICT)
2829 #if defined(LZO1Z)
2830                 m_off = 1 + (t << 6) + (*ip++ >> 2);
2831                 last_m_off = m_off;
2832 #else
2833                 m_off = 1 + (t >> 2) + (*ip++ << 2);
2834 #endif
2835                 NEED_OP(2);
2836                 t = 2; COPY_DICT(t,m_off)
2837 #else
2838 #if defined(LZO1Z)
2839                 t = 1 + (t << 6) + (*ip++ >> 2);
2840                 m_pos = op - t;
2841                 last_m_off = t;
2842 #else
2843                 m_pos = op - 1;
2844                 m_pos -= t >> 2;
2845                 m_pos -= *ip++ << 2;
2846 #endif
2847                 TEST_LOOKBEHIND(m_pos,out); NEED_OP(2);
2848                 *op++ = *m_pos++; *op++ = *m_pos;
2849 #endif
2850                 goto match_done;
2851             }
2852
2853 #if defined(COPY_DICT)
2854
2855             NEED_OP(t+3-1);
2856             t += 3-1; COPY_DICT(t,m_off)
2857
2858 #else
2859
2860             TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1);
2861 #if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
2862 #if !defined(LZO_UNALIGNED_OK_4)
2863             if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
2864             {
2865                 assert((op - m_pos) >= 4);
2866 #else
2867             if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
2868             {
2869 #endif
2870                 COPY4(op,m_pos);
2871                 op += 4; m_pos += 4; t -= 4 - (3 - 1);
2872                 do {
2873                     COPY4(op,m_pos);
2874                     op += 4; m_pos += 4; t -= 4;
2875                 } while (t >= 4);
2876                 if (t > 0) do *op++ = *m_pos++; while (--t > 0);
2877             }
2878             else
2879 #endif
2880             {
2881 copy_match:
2882                 *op++ = *m_pos++; *op++ = *m_pos++;
2883                 do *op++ = *m_pos++; while (--t > 0);
2884             }
2885
2886 #endif
2887
2888 match_done:
2889 #if defined(LZO1Z)
2890             t = ip[-1] & 3;
2891 #else
2892             t = ip[-2] & 3;
2893 #endif
2894             if (t == 0)
2895                 break;
2896
2897 match_next:
2898             assert(t > 0); NEED_OP(t); NEED_IP(t+1);
2899             do *op++ = *ip++; while (--t > 0);
2900             t = *ip++;
2901         }
2902     }
2903
2904 #if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
2905     *out_len = op - out;
2906     return LZO_E_EOF_NOT_FOUND;
2907 #endif
2908
2909 eof_found:
2910     assert(t == 1);
2911     *out_len = op - out;
2912     return (ip == ip_end ? LZO_E_OK :
2913            (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
2914
2915 #if defined(HAVE_NEED_IP)
2916 input_overrun:
2917     *out_len = op - out;
2918     return LZO_E_INPUT_OVERRUN;
2919 #endif
2920
2921 #if defined(HAVE_NEED_OP)
2922 output_overrun:
2923     *out_len = op - out;
2924     return LZO_E_OUTPUT_OVERRUN;
2925 #endif
2926
2927 #if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
2928 lookbehind_overrun:
2929     *out_len = op - out;
2930     return LZO_E_LOOKBEHIND_OVERRUN;
2931 #endif
2932 }
2933
2934 /***** End of minilzo.c *****/
2935