# minilzo.cpp

Go to the documentation of this file.

    00001 /* $Id: minilzo.cpp 13552 2008-06-17 19:38:00Z smatz $ */
    00002
    00041 #define LZO_DISABLE_CHECKS
    00042 #define LZO1X
    00043
    00044 #define __LZO_IN_MINILZO
    00045 #define LZO_BUILD
    00046
    00047 #ifdef MINILZO_HAVE_CONFIG_H
    00048 #  include <config.h>
    00049 #endif
    00050
    00051 #undef LZO_HAVE_CONFIG_H
    00052 #include "minilzo.h"
    00053
    00054 #if !defined(MINILZO_VERSION) || (MINILZO_VERSION != 0x1080)
    00055 #  error "version mismatch in miniLZO source files"
    00056 #endif
    00057
    00058 #ifdef MINILZO_HAVE_CONFIG_H
    00059 #  define LZO_HAVE_CONFIG_H
    00060 #endif
    00061
    00062 #if !defined(LZO_NO_SYS_TYPES_H) && !defined(WINCE)
    00063 #  include <sys/types.h>
    00064 #endif
    00065 #include <stdio.h>
    00066
    00067 #ifndef __LZO_CONF_H
    00068 #define __LZO_CONF_H
    00069
    00070 #if defined(__BOUNDS_CHECKING_ON)
    00071 #  include <unchecked.h>
    00072 #else
    00073 #  define BOUNDS_CHECKING_OFF_DURING(stmt)    stmt
    00074 #  define BOUNDS_CHECKING_OFF_IN_EXPR(expr)  (expr)
    00075 #endif
    00076
    00077 #if !defined(LZO_HAVE_CONFIG_H)
    00078 #  include <stddef.h>
    00079 #  include <string.h>
    00080 #  if !defined(NO_STDLIB_H)
    00081 # include <stdlib.h>
    00082 #  endif
    00083 #  define HAVE_MEMCMP
    00084 #  define HAVE_MEMCPY
    00085 #  define HAVE_MEMMOVE
    00086 #  define HAVE_MEMSET
    00087 #else
    00088 #  include <sys/types.h>
    00089 #  if defined(HAVE_STDDEF_H)
    00090 # include <stddef.h>
    00091 #  endif
    00092 #  if defined(STDC_HEADERS)
    00093 # include <string.h>
    00094 # include <stdlib.h>
    00095 #  endif
    00096 #endif
    00097
    00098 #if defined(__LZO_DOS16) || defined(__LZO_WIN16)
    00099 #  define HAVE_MALLOC_H
    00100 #  define HAVE_HALLOC
    00101 #endif
    00102
    00103 #undef NDEBUG
    00104 #if !defined(LZO_DEBUG)
    00105 #  define NDEBUG
    00106 #endif
    00107 #if defined(LZO_DEBUG) || !defined(NDEBUG)
    00108 #  if !defined(NO_STDIO_H)
    00109 # include <stdio.h>
    00110 #  endif
    00111 #endif
    00112 #include <assert.h>
    00113
    00114 #if !defined(LZO_COMPILE_TIME_ASSERT)
    00115 #  define LZO_COMPILE_TIME_ASSERT(expr) \
    00116     { typedef int __lzo_compile_time_assert_fail[1 - 2 * !(expr)]; }
    00117 #endif
    00118
    00119 #if !defined(LZO_UNUSED)
    00120 #  if 1
    00121 # define LZO_UNUSED(var)   ((void)&var)
    00122 #  elif 0
    00123 # define LZO_UNUSED(var)   { typedef int __lzo_unused[sizeof(var) ? 2 : 1]; }
    00124 #  else
    00125 # define LZO_UNUSED(parm) (parm = parm)
    00126 #  endif
    00127 #endif
    00128
    00129 #if !defined(__inline__) && !defined(__GNUC__)
    00130 #  if defined(__cplusplus)
    00131 # define __inline__   inline
    00132 #  else
    00133 # define __inline__
    00134 #  endif
    00135 #endif
    00136
    00137 #if defined(NO_MEMCMP)
    00138 #  undef HAVE_MEMCMP
    00139 #endif
    00140
    00141 #if 0
    00142 #  define LZO_BYTE(x)    ((unsigned char) (x))
    00143 #else
    00144 #  define LZO_BYTE(x)    ((unsigned char) ((x) & 0xff))
    00145 #endif
    00146
    00147 #define LZO_MAX(a,b)    ((a) >= (b) ? (a) : (b))
    00148 #define LZO_MIN(a,b)    ((a) <= (b) ? (a) : (b))
    00149 #define LZO_MAX3(a,b,c)  ((a) >= (b) ? LZO_MAX(a,c) : LZO_MAX(b,c))
    00150 #define LZO_MIN3(a,b,c)  ((a) <= (b) ? LZO_MIN(a,c) : LZO_MIN(b,c))
    00151
    00152 #define lzo_sizeof(type)  ((lzo_uint) (sizeof(type)))
    00153
    00154 #define LZO_HIGH(array)  ((lzo_uint) (sizeof(array)/sizeof(*(array))))
    00155
    00156 #define LZO_SIZE(bits)    (1u << (bits))
    00157 #define LZO_MASK(bits)    (LZO_SIZE(bits) - 1)
    00158
    00159 #define LZO_LSIZE(bits)  (1ul << (bits))
    00160 #define LZO_LMASK(bits)  (LZO_LSIZE(bits) - 1)
    00161
    00162 #define LZO_USIZE(bits)  ((lzo_uint) 1 << (bits))
    00163 #define LZO_UMASK(bits)  (LZO_USIZE(bits) - 1)
    00164
    00165 #define LZO_STYPE_MAX(b)  (((1l  << (8*(b)-2)) - 1l)  + (1l  << (8*(b)-2)))
    00166 #define LZO_UTYPE_MAX(b)  (((1ul << (8*(b)-1)) - 1ul) + (1ul << (8*(b)-1)))
    00167
    00168 #if !defined(SIZEOF_UNSIGNED)
    00169 #  if (UINT_MAX == 0xffff)
    00170 # define SIZEOF_UNSIGNED     2
    00171 #  elif (UINT_MAX == LZO_0xffffffffL)
    00172 # define SIZEOF_UNSIGNED     4
    00173 #  elif (UINT_MAX >= LZO_0xffffffffL)
    00174 # define SIZEOF_UNSIGNED     8
    00175 #  else
    00176 # error "SIZEOF_UNSIGNED"
    00177 #  endif
    00178 #endif
    00179
    00180 #if !defined(SIZEOF_UNSIGNED_LONG)
    00181 #  if (ULONG_MAX == LZO_0xffffffffL)
    00182 # define SIZEOF_UNSIGNED_LONG 4
    00183 #  elif (ULONG_MAX >= LZO_0xffffffffL)
    00184 # define SIZEOF_UNSIGNED_LONG 8
    00185 #  else
    00186 # error "SIZEOF_UNSIGNED_LONG"
    00187 #  endif
    00188 #endif
    00189
    00190 #if !defined(SIZEOF_SIZE_T)
    00191 #  define SIZEOF_SIZE_T      SIZEOF_UNSIGNED
    00192 #endif
    00193 #if !defined(SIZE_T_MAX)
    00194 #  define SIZE_T_MAX        LZO_UTYPE_MAX(SIZEOF_SIZE_T)
    00195 #endif
    00196
    00197 #if 1 && defined(__LZO_i386) && (UINT_MAX == LZO_0xffffffffL)
    00198 #  if !defined(LZO_UNALIGNED_OK_2) && (USHRT_MAX == 0xffff)
    00199 # define LZO_UNALIGNED_OK_2
    00200 #  endif
    00201 #  if !defined(LZO_UNALIGNED_OK_4) && (LZO_UINT32_MAX == LZO_0xffffffffL)
    00202 # define LZO_UNALIGNED_OK_4
    00203 #  endif
    00204 #endif
    00205
    00206 #if defined(LZO_UNALIGNED_OK_2) || defined(LZO_UNALIGNED_OK_4)
    00207 #  if !defined(LZO_UNALIGNED_OK)
    00208 # define LZO_UNALIGNED_OK
    00209 #  endif
    00210 #endif
    00211
    00212 #if defined(__LZO_NO_UNALIGNED)
    00213 #  undef LZO_UNALIGNED_OK
    00214 #  undef LZO_UNALIGNED_OK_2
    00215 #  undef LZO_UNALIGNED_OK_4
    00216 #endif
    00217
    00218 #if defined(LZO_UNALIGNED_OK_2) && (USHRT_MAX != 0xffff)
    00219 #  error "LZO_UNALIGNED_OK_2 must not be defined on this system"
    00220 #endif
    00221 #if defined(LZO_UNALIGNED_OK_4) && (LZO_UINT32_MAX != LZO_0xffffffffL)
    00222 #  error "LZO_UNALIGNED_OK_4 must not be defined on this system"
    00223 #endif
    00224
    00225 #if defined(__LZO_NO_ALIGNED)
    00226 #  undef LZO_ALIGNED_OK_4
    00227 #endif
    00228
    00229 #if defined(LZO_ALIGNED_OK_4) && (LZO_UINT32_MAX != LZO_0xffffffffL)
    00230 #  error "LZO_ALIGNED_OK_4 must not be defined on this system"
    00231 #endif
    00232
    00233 #define LZO_LITTLE_ENDIAN 1234
    00234 #define LZO_BIG_ENDIAN    4321
    00235 #define LZO_PDP_ENDIAN    3412
    00236
    00237 #if !defined(LZO_BYTE_ORDER)
    00238 #  if defined(MFX_BYTE_ORDER)
    00239 # define LZO_BYTE_ORDER   MFX_BYTE_ORDER
    00240 #  elif defined(__LZO_i386)
    00241 # define LZO_BYTE_ORDER   LZO_LITTLE_ENDIAN
    00242 #  elif defined(BYTE_ORDER)
    00243 # define LZO_BYTE_ORDER   BYTE_ORDER
    00244 #  elif defined(__BYTE_ORDER)
    00245 # define LZO_BYTE_ORDER   __BYTE_ORDER
    00246 #  endif
    00247 #endif
    00248
    00249 #if defined(LZO_BYTE_ORDER)
    00250 #  if (LZO_BYTE_ORDER != LZO_LITTLE_ENDIAN) && \
    00251     (LZO_BYTE_ORDER != LZO_BIG_ENDIAN)
    00252 # error "invalid LZO_BYTE_ORDER"
    00253 #  endif
    00254 #endif
    00255
    00256 #if defined(LZO_UNALIGNED_OK) && !defined(LZO_BYTE_ORDER)
    00257 #  error "LZO_BYTE_ORDER is not defined"
    00258 #endif
    00259
    00260 #define LZO_OPTIMIZE_GNUC_i386_IS_BUGGY
    00261
    00262 #if defined(NDEBUG) && !defined(LZO_DEBUG) && !defined(__LZO_CHECKER)
    00263 #  if defined(__GNUC__) && defined(__i386__)
    00264 # if !defined(LZO_OPTIMIZE_GNUC_i386_IS_BUGGY)
    00265 #   define LZO_OPTIMIZE_GNUC_i386
    00266 # endif
    00267 #  endif
    00268 #endif
    00269
    00270 __LZO_EXTERN_C int __lzo_init_done;
    00271 __LZO_EXTERN_C const lzo_byte __lzo_copyright[];
    00272 LZO_EXTERN(const lzo_byte *) lzo_copyright();
    00273 __LZO_EXTERN_C const lzo_uint32 _lzo_crc32_table[256];
    00274
    00275 #define _LZO_STRINGIZE(x)      #x
    00276 #define _LZO_MEXPAND(x)      _LZO_STRINGIZE(x)
    00277
    00278 #define _LZO_CONCAT2(a,b)      a ## b
    00279 #define _LZO_CONCAT3(a,b,c)    a ## b ## c
    00280 #define _LZO_CONCAT4(a,b,c,d)    a ## b ## c ## d
    00281 #define _LZO_CONCAT5(a,b,c,d,e)  a ## b ## c ## d ## e
    00282
    00283 #define _LZO_ECONCAT2(a,b)      _LZO_CONCAT2(a,b)
    00284 #define _LZO_ECONCAT3(a,b,c)    _LZO_CONCAT3(a,b,c)
    00285 #define _LZO_ECONCAT4(a,b,c,d)    _LZO_CONCAT4(a,b,c,d)
    00286 #define _LZO_ECONCAT5(a,b,c,d,e)  _LZO_CONCAT5(a,b,c,d,e)
    00287
    00288 #ifndef __LZO_PTR_H
    00289 #define __LZO_PTR_H
    00290
    00291 #ifdef __cplusplus
    00292 extern "C" {
    00293 #endif
    00294
    00295 #if defined(__LZO_DOS16) || defined(__LZO_WIN16)
    00296 #  include <dos.h>
    00297 #  if 1 && defined(__WATCOMC__)
    00298 # include <i86.h>
    00299    __LZO_EXTERN_C unsigned char _HShift;
    00300 # define __LZO_HShift _HShift
    00301 #  elif 1 && defined(_MSC_VER)
    00302    __LZO_EXTERN_C unsigned short __near _AHSHIFT;
    00303 # define __LZO_HShift ((unsigned) &_AHSHIFT)
    00304 #  elif defined(__LZO_WIN16)
    00305 # define __LZO_HShift 3
    00306 #  else
    00307 # define __LZO_HShift 12
    00308 #  endif
    00309 #  if !defined(_FP_SEG) && defined(FP_SEG)
    00310 # define _FP_SEG     FP_SEG
    00311 #  endif
    00312 #  if !defined(_FP_OFF) && defined(FP_OFF)
    00313 # define _FP_OFF     FP_OFF
    00314 #  endif
    00315 #endif
    00316
    00317 #if !defined(lzo_ptrdiff_t)
    00318 #  if (UINT_MAX >= LZO_0xffffffffL)
    00319    typedef ptrdiff_t      lzo_ptrdiff_t;
    00320 #  else
    00321    typedef long        lzo_ptrdiff_t;
    00322 #  endif
    00323 #endif
    00324
    00325 #if !defined(__LZO_HAVE_PTR_T)
    00326 #  if defined(lzo_ptr_t)
    00327 # define __LZO_HAVE_PTR_T
    00328 #  endif
    00329 #endif
    00330 #if !defined(__LZO_HAVE_PTR_T)
    00331 # if defined(_WIN64)
    00332     typedef unsigned __int64 lzo_ptr_t;
    00333     typedef signed __int64   lzo_sptr_r;
    00334 #   define __LZO_HAVE_PTR_T
    00335 # endif
    00336 #endif
    00337 #if !defined(__LZO_HAVE_PTR_T)
    00338 #  if defined(SIZEOF_CHAR_P) && defined(SIZEOF_UNSIGNED_LONG)
    00339 # if (SIZEOF_CHAR_P == SIZEOF_UNSIGNED_LONG)
    00340      typedef unsigned long  lzo_ptr_t;
    00341      typedef long      lzo_sptr_t;
    00342 #   define __LZO_HAVE_PTR_T
    00343 # endif
    00344 #  endif
    00345 #endif
    00346 #if !defined(__LZO_HAVE_PTR_T)
    00347 #  if defined(SIZEOF_CHAR_P) && defined(SIZEOF_UNSIGNED)
    00348 # if (SIZEOF_CHAR_P == SIZEOF_UNSIGNED)
    00349      typedef unsigned int  lzo_ptr_t;
    00350      typedef int        lzo_sptr_t;
    00351 #   define __LZO_HAVE_PTR_T
    00352 # endif
    00353 #  endif
    00354 #endif
    00355 #if !defined(__LZO_HAVE_PTR_T)
    00356 #  if defined(SIZEOF_CHAR_P) && defined(SIZEOF_UNSIGNED_SHORT)
    00357 # if (SIZEOF_CHAR_P == SIZEOF_UNSIGNED_SHORT)
    00358      typedef unsigned short   lzo_ptr_t;
    00359      typedef short      lzo_sptr_t;
    00360 #   define __LZO_HAVE_PTR_T
    00361 # endif
    00362 #  endif
    00363 #endif
    00364 #if !defined(__LZO_HAVE_PTR_T)
    00365 #  if defined(LZO_HAVE_CONFIG_H) || defined(SIZEOF_CHAR_P)
    00366 # error "no suitable type for lzo_ptr_t"
    00367 #  else
    00368    typedef unsigned long    lzo_ptr_t;
    00369    typedef long        lzo_sptr_t;
    00370 # define __LZO_HAVE_PTR_T
    00371 #  endif
    00372 #endif
    00373
    00374 #if defined(__LZO_DOS16) || defined(__LZO_WIN16)
    00375 #define PTR(a)        ((lzo_bytep) (a))
    00376 #define PTR_ALIGNED_4(a)  ((_FP_OFF(a) & 3) == 0)
    00377 #define PTR_ALIGNED2_4(a,b) (((_FP_OFF(a) | _FP_OFF(b)) & 3) == 0)
    00378 #else
    00379 #define PTR(a)        ((lzo_ptr_t) (a))
    00380 #define PTR_LINEAR(a)    PTR(a)
    00381 #define PTR_ALIGNED_4(a)  ((PTR_LINEAR(a) & 3) == 0)
    00382 #define PTR_ALIGNED_8(a)  ((PTR_LINEAR(a) & 7) == 0)
    00383 #define PTR_ALIGNED2_4(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 3) == 0)
    00384 #define PTR_ALIGNED2_8(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 7) == 0)
    00385 #endif
    00386
    00387 #define PTR_LT(a,b)    (PTR(a) < PTR(b))
    00388 #define PTR_GE(a,b)    (PTR(a) >= PTR(b))
    00389 #define PTR_DIFF(a,b)    ((lzo_ptrdiff_t) (PTR(a) - PTR(b)))
    00390 #define pd(a,b)      ((lzo_uint) ((a)-(b)))
    00391
    00392 LZO_EXTERN(lzo_ptr_t)
    00393 __lzo_ptr_linear(const lzo_voidp ptr);
    00394
    00395 typedef union
    00396 {
    00397   char      a_char;
    00398   unsigned char   a_uchar;
    00399   short      a_short;
    00400   unsigned short  a_ushort;
    00401   int      a_int;
    00402   unsigned int  a_uint;
    00403   long      a_long;
    00404   unsigned long   a_ulong;
    00405   lzo_int    a_lzo_int;
    00406   lzo_uint    a_lzo_uint;
    00407   lzo_int32    a_lzo_int32;
    00408   lzo_uint32    a_lzo_uint32;
    00409   ptrdiff_t    a_ptrdiff_t;
    00410   lzo_ptrdiff_t   a_lzo_ptrdiff_t;
    00411   lzo_ptr_t    a_lzo_ptr_t;
    00412   lzo_voidp    a_lzo_voidp;
    00413   void *      a_void_p;
    00414   lzo_bytep    a_lzo_bytep;
    00415   lzo_bytepp    a_lzo_bytepp;
    00416   lzo_uintp    a_lzo_uintp;
    00417   lzo_uint *    a_lzo_uint_p;
    00418   lzo_uint32p  a_lzo_uint32p;
    00419   lzo_uint32 *  a_lzo_uint32_p;
    00420   unsigned char * a_uchar_p;
    00421   char *      a_char_p;
    00422 }
    00423 lzo_full_align_t;
    00424
    00425 #ifdef __cplusplus
    00426 }
    00427 #endif
    00428
    00429 #endif
    00430
    00431 #define LZO_DETERMINISTIC
    00432
    00433 #define LZO_DICT_USE_PTR
    00434 #if defined(__LZO_DOS16) || defined(__LZO_WIN16) || defined(__LZO_STRICT_16BIT)
    00435 #  undef LZO_DICT_USE_PTR
    00436 #endif
    00437
    00438 #if defined(LZO_DICT_USE_PTR)
    00439 #  define lzo_dict_t  const lzo_bytep
    00440 #  define lzo_dict_p  lzo_dict_t __LZO_MMODEL *
    00441 #else
    00442 #  define lzo_dict_t  lzo_uint
    00443 #  define lzo_dict_p  lzo_dict_t __LZO_MMODEL *
    00444 #endif
    00445
    00446 #if !defined(lzo_moff_t)
    00447 #define lzo_moff_t    lzo_uint
    00448 #endif
    00449
    00450 #endif
    00451
    00452
    00453 #ifndef __LZO_UTIL_H
    00454 #define __LZO_UTIL_H
    00455
    00456 #ifndef __LZO_CONF_H
    00457 #endif
    00458
    00459 #ifdef __cplusplus
    00460 extern "C" {
    00461 #endif
    00462
    00463 #if 1 && defined(HAVE_MEMCPY)
    00464 #if !defined(__LZO_DOS16) && !defined(__LZO_WIN16)
    00465
    00466 #define MEMCPY8_DS(dest,src,len) \
    00467   memcpy(dest,src,len); \
    00468   dest += len; \
    00469   src += len
    00470
    00471 #endif
    00472 #endif
    00473
    00474 #if 0 && !defined(MEMCPY8_DS)
    00475
    00476 #define MEMCPY8_DS(dest,src,len) \
    00477   { do { \
    00478     *dest++ = *src++; \
    00479     *dest++ = *src++; \
    00480     *dest++ = *src++; \
    00481     *dest++ = *src++; \
    00482     *dest++ = *src++; \
    00483     *dest++ = *src++; \
    00484     *dest++ = *src++; \
    00485     *dest++ = *src++; \
    00486     len -= 8; \
    00487   } while (len > 0); }
    00488
    00489 #endif
    00490
    00491 #if !defined(MEMCPY8_DS)
    00492
    00493 #define MEMCPY8_DS(dest,src,len) \
    00494   { register lzo_uint __l = (len) / 8; \
    00495   do { \
    00496     *dest++ = *src++; \
    00497     *dest++ = *src++; \
    00498     *dest++ = *src++; \
    00499     *dest++ = *src++; \
    00500     *dest++ = *src++; \
    00501     *dest++ = *src++; \
    00502     *dest++ = *src++; \
    00503     *dest++ = *src++; \
    00504   } while (--__l > 0); }
    00505
    00506 #endif
    00507
    00508 #define MEMCPY_DS(dest,src,len) \
    00509   do *dest++ = *src++; \
    00510   while (--len > 0)
    00511
    00512 #define MEMMOVE_DS(dest,src,len) \
    00513   do *dest++ = *src++; \
    00514   while (--len > 0)
    00515
    00516 #if 0 && defined(LZO_OPTIMIZE_GNUC_i386)
    00517
    00518 #define BZERO8_PTR(s,l,n) \
    00519 __asm__ __volatile__( \
    00520   "movl  %0,%%eax \n"      \
    00521   "movl  %1,%%edi \n"      \
    00522   "movl  %2,%%ecx \n"      \
    00523   "cld \n"            \
    00524   "rep \n"            \
    00525   "stosl %%eax,(%%edi) \n"    \
    00526   :        \
    00527   :"g" (0),"g" (s),"g" (n)    \
    00528   :"eax","edi","ecx", "memory", "cc" \
    00529 )
    00530
    00531 #elif (LZO_UINT_MAX <= SIZE_T_MAX) && defined(HAVE_MEMSET)
    00532
    00533 #if 1
    00534 #define BZERO8_PTR(s,l,n)   memset((s),0,(lzo_uint)(l)*(n))
    00535 #else
    00536 #define BZERO8_PTR(s,l,n)   memset((lzo_voidp)(s),0,(lzo_uint)(l)*(n))
    00537 #endif
    00538
    00539 #else
    00540
    00541 #define BZERO8_PTR(s,l,n) \
    00542   lzo_memset((lzo_voidp)(s),0,(lzo_uint)(l)*(n))
    00543
    00544 #endif
    00545
    00546 #if 0
    00547 #if defined(__GNUC__) && defined(__i386__)
    00548
    00549 unsigned char lzo_rotr8(unsigned char value, int shift);
    00550 extern __inline__ unsigned char lzo_rotr8(unsigned char value, int shift)
    00551 {
    00552   unsigned char result;
    00553
    00554   __asm__ __volatile__ ("movb %b1, %b0; rorb %b2, %b0"
    00555             : "=a"(result) : "g"(value), "c"(shift));
    00556   return result;
    00557 }
    00558
    00559 unsigned short lzo_rotr16(unsigned short value, int shift);
    00560 extern __inline__ unsigned short lzo_rotr16(unsigned short value, int shift)
    00561 {
    00562   unsigned short result;
    00563
    00564   __asm__ __volatile__ ("movw %b1, %b0; rorw %b2, %b0"
    00565             : "=a"(result) : "g"(value), "c"(shift));
    00566   return result;
    00567 }
    00568
    00569 #endif
    00570 #endif
    00571
    00572 #ifdef __cplusplus
    00573 }
    00574 #endif
    00575
    00576 #endif
    00577
    00578
    00579 /* If you use the LZO library in a product, you *must* keep this
    00580  * copyright string in the executable of your product.
    00581  */
    00582
    00583 const lzo_byte __lzo_copyright[] =
    00584 #if !defined(__LZO_IN_MINLZO)
    00585   LZO_VERSION_STRING;
    00586 #else
    00587   "\n\n\n"
    00588   "LZO real-time data compression library.\n"
    00589   "Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Markus Franz Xaver Johannes Oberhumer\n"
    00590   "<markus.oberhumer@jk.uni-linz.ac.at>\n"
    00591   "http://www.oberhumer.com/opensource/lzo/\n"
    00592   "\n"
    00593   "LZO version: v" LZO_VERSION_STRING ", " LZO_VERSION_DATE "\n"
    00594   "LZO build date: " __DATE__ " " __TIME__ "\n\n"
    00595   "LZO special compilation options:\n"
    00596 #ifdef __cplusplus
    00597   " __cplusplus\n"
    00598 #endif
    00599 #if defined(__PIC__)
    00600   " __PIC__\n"
    00601 #elif defined(__pic__)
    00602   " __pic__\n"
    00603 #endif
    00604 #if (UINT_MAX < LZO_0xffffffffL)
    00605   " 16BIT\n"
    00606 #endif
    00607 #if defined(__LZO_STRICT_16BIT)
    00608   " __LZO_STRICT_16BIT\n"
    00609 #endif
    00610 #if (UINT_MAX > LZO_0xffffffffL)
    00611   " UINT_MAX=" _LZO_MEXPAND(UINT_MAX) "\n"
    00612 #endif
    00613 #if (ULONG_MAX > LZO_0xffffffffL)
    00614   " ULONG_MAX=" _LZO_MEXPAND(ULONG_MAX) "\n"
    00615 #endif
    00616 #if defined(LZO_BYTE_ORDER)
    00617   " LZO_BYTE_ORDER=" _LZO_MEXPAND(LZO_BYTE_ORDER) "\n"
    00618 #endif
    00619 #if defined(LZO_UNALIGNED_OK_2)
    00620   " LZO_UNALIGNED_OK_2\n"
    00621 #endif
    00622 #if defined(LZO_UNALIGNED_OK_4)
    00623   " LZO_UNALIGNED_OK_4\n"
    00624 #endif
    00625 #if defined(LZO_ALIGNED_OK_4)
    00626   " LZO_ALIGNED_OK_4\n"
    00627 #endif
    00628 #if defined(LZO_DICT_USE_PTR)
    00629   " LZO_DICT_USE_PTR\n"
    00630 #endif
    00631 #if defined(__LZO_QUERY_COMPRESS)
    00632   " __LZO_QUERY_COMPRESS\n"
    00633 #endif
    00634 #if defined(__LZO_QUERY_DECOMPRESS)
    00635   " __LZO_QUERY_DECOMPRESS\n"
    00636 #endif
    00637 #if defined(__LZO_IN_MINILZO)
    00638   " __LZO_IN_MINILZO\n"
    00639 #endif
    00640   "\n\n"
    00641   "$Id: LZO " LZO_VERSION_STRING " built " __DATE__ " " __TIME__
    00642 #if defined(__GNUC__) && defined(__VERSION__)
    00643   " by gcc " __VERSION__
    00644 #elif defined(__BORLANDC__)
    00645   " by Borland C " _LZO_MEXPAND(__BORLANDC__)
    00646 #elif defined(_MSC_VER)
    00647   " by Microsoft C " _LZO_MEXPAND(_MSC_VER)
    00648 #elif defined(__PUREC__)
    00649   " by Pure C " _LZO_MEXPAND(__PUREC__)
    00650 #elif defined(__SC__)
    00651   " by Symantec C " _LZO_MEXPAND(__SC__)
    00652 #elif defined(__TURBOC__)
    00653   " by Turbo C " _LZO_MEXPAND(__TURBOC__)
    00654 #elif defined(__WATCOMC__)
    00655   " by Watcom C " _LZO_MEXPAND(__WATCOMC__)
    00656 #endif
    00657   " $\n"
    00658   "$Copyright: LZO (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 Markus Franz Xaver Johannes Oberhumer $\n";
    00659 #endif
    00660
    00661 #define LZO_BASE 65521u
    00662 #define LZO_NMAX 5552
    00663
    00664 #define LZO_DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
    00665 #define LZO_DO2(buf,i)  LZO_DO1(buf,i); LZO_DO1(buf,i+1);
    00666 #define LZO_DO4(buf,i)  LZO_DO2(buf,i); LZO_DO2(buf,i+2);
    00667 #define LZO_DO8(buf,i)  LZO_DO4(buf,i); LZO_DO4(buf,i+4);
    00668 #define LZO_DO16(buf,i) LZO_DO8(buf,i); LZO_DO8(buf,i+8);
    00669
    00670 LZO_PUBLIC(lzo_uint32)
    00671 lzo_adler32(lzo_uint32 adler, const lzo_byte *buf, lzo_uint len)
    00672 {
    00673   lzo_uint32 s1 = adler & 0xffff;
    00674   lzo_uint32 s2 = (adler >> 16) & 0xffff;
    00675   int k;
    00676
    00677   if (buf == NULL)
    00678     return 1;
    00679
    00680   while (len > 0)
    00681   {
    00682     k = len < LZO_NMAX ? (int) len : LZO_NMAX;
    00683     len -= k;
    00684     if (k >= 16) do
    00685     {
    00686       LZO_DO16(buf,0);
    00687       buf += 16;
    00688       k -= 16;
    00689     } while (k >= 16);
    00690     if (k != 0) do
    00691     {
    00692       s1 += *buf++;
    00693       s2 += s1;
    00694     } while (--k > 0);
    00695     s1 %= LZO_BASE;
    00696     s2 %= LZO_BASE;
    00697     }
    00698   return (s2 << 16) | s1;
    00699 }
    00700
    00701 #if 0
    00702 #  define IS_SIGNED(type)    (((type) (1ul << (8 * sizeof(type) - 1))) < 0)
    00703 #  define IS_UNSIGNED(type)  (((type) (1ul << (8 * sizeof(type) - 1))) > 0)
    00704 #else
    00705 #  define IS_SIGNED(type)    (((type) (-1)) < ((type) 0))
    00706 #  define IS_UNSIGNED(type)  (((type) (-1)) > ((type) 0))
    00707 #endif
    00708
    00709 #define IS_POWER_OF_2(x)    (((x) & ((x) - 1)) == 0)
    00710
    00711 // static lzo_bool schedule_insns_bug();
    00712 // static lzo_bool strength_reduce_bug(int *);
    00713
    00714 #if 0 || defined(LZO_DEBUG)
    00715 #include <stdio.h>
    00716 static lzo_bool __lzo_assert_fail(const char *s, unsigned line)
    00717 {
    00718 #if defined(__palmos__)
    00719   printf("LZO assertion failed in line %u: '%s'\n",line,s);
    00720 #else
    00721   fprintf(stderr,"LZO assertion failed in line %u: '%s'\n",line,s);
    00722 #endif
    00723   return 0;
    00724 }
    00725 #  define __lzo_assert(x)   ((x) ? 1 : __lzo_assert_fail(#x,__LINE__))
    00726 #else
    00727 #  define __lzo_assert(x)   ((x) ? 1 : 0)
    00728 #endif
    00729
    00730 #undef COMPILE_TIME_ASSERT
    00731 #if 0
    00732 #  define COMPILE_TIME_ASSERT(expr)  r &= __lzo_assert(expr)
    00733 #else
    00734 #  define COMPILE_TIME_ASSERT(expr)  LZO_COMPILE_TIME_ASSERT(expr)
    00735 #endif
    00736
    00737
    00738 #define do_compress    _lzo1x_1_do_compress
    00739
    00740 #define LZO_NEED_DICT_H
    00741 #define D_BITS      12
    00742 #define D_INDEX1(d,p)    d = DM((0x21*DX3(p,5,5,6)) >> 5)
    00743 #define D_INDEX2(d,p)    d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f)
    00744
    00745 #ifndef __LZO_CONFIG1X_H
    00746 #define __LZO_CONFIG1X_H
    00747
    00748 #define LZO_EOF_CODE
    00749 #undef LZO_DETERMINISTIC
    00750
    00751 #define M1_MAX_OFFSET   0x0400
    00752 #ifndef M2_MAX_OFFSET
    00753 #define M2_MAX_OFFSET   0x0800
    00754 #endif
    00755 #define M3_MAX_OFFSET   0x4000
    00756 #define M4_MAX_OFFSET   0xbfff
    00757
    00758 #define MX_MAX_OFFSET   (M1_MAX_OFFSET + M2_MAX_OFFSET)
    00759
    00760 #define M1_MIN_LEN    2
    00761 #define M1_MAX_LEN    2
    00762 #define M2_MIN_LEN    3
    00763 #ifndef M2_MAX_LEN
    00764 #define M2_MAX_LEN    8
    00765 #endif
    00766 #define M3_MIN_LEN    3
    00767 #define M3_MAX_LEN    33
    00768 #define M4_MIN_LEN    3
    00769 #define M4_MAX_LEN    9
    00770
    00771 #define M1_MARKER    0
    00772 #define M2_MARKER    64
    00773 #define M3_MARKER    32
    00774 #define M4_MARKER    16
    00775
    00776 #ifndef MIN_LOOKAHEAD
    00777 #define MIN_LOOKAHEAD    (M2_MAX_LEN + 1)
    00778 #endif
    00779
    00780 #if defined(LZO_NEED_DICT_H)
    00781
    00782 #ifndef LZO_HASH
    00783 #define LZO_HASH      LZO_HASH_LZO_INCREMENTAL_B
    00784 #endif
    00785 #define DL_MIN_LEN      M2_MIN_LEN
    00786
    00787 #ifndef __LZO_DICT_H
    00788 #define __LZO_DICT_H
    00789
    00790 #ifdef __cplusplus
    00791 extern "C" {
    00792 #endif
    00793
    00794 #if !defined(D_BITS) && defined(DBITS)
    00795 #  define D_BITS    DBITS
    00796 #endif
    00797 #if !defined(D_BITS)
    00798 #  error "D_BITS is not defined"
    00799 #endif
    00800 #if (D_BITS < 16)
    00801 #  define D_SIZE    LZO_SIZE(D_BITS)
    00802 #  define D_MASK    LZO_MASK(D_BITS)
    00803 #else
    00804 #  define D_SIZE    LZO_USIZE(D_BITS)
    00805 #  define D_MASK    LZO_UMASK(D_BITS)
    00806 #endif
    00807 #define D_HIGH      ((D_MASK >> 1) + 1)
    00808
    00809 #if !defined(DD_BITS)
    00810 #  define DD_BITS    0
    00811 #endif
    00812 #define DD_SIZE    LZO_SIZE(DD_BITS)
    00813 #define DD_MASK    LZO_MASK(DD_BITS)
    00814
    00815 #if !defined(DL_BITS)
    00816 #  define DL_BITS    (D_BITS - DD_BITS)
    00817 #endif
    00818 #if (DL_BITS < 16)
    00819 #  define DL_SIZE    LZO_SIZE(DL_BITS)
    00820 #  define DL_MASK    LZO_MASK(DL_BITS)
    00821 #else
    00822 #  define DL_SIZE    LZO_USIZE(DL_BITS)
    00823 #  define DL_MASK    LZO_UMASK(DL_BITS)
    00824 #endif
    00825
    00826 #if (D_BITS != DL_BITS + DD_BITS)
    00827 #  error "D_BITS does not match"
    00828 #endif
    00829 #if (D_BITS < 8 || D_BITS > 18)
    00830 #  error "invalid D_BITS"
    00831 #endif
    00832 #if (DL_BITS < 8 || DL_BITS > 20)
    00833 #  error "invalid DL_BITS"
    00834 #endif
    00835 #if (DD_BITS < 0 || DD_BITS > 6)
    00836 #  error "invalid DD_BITS"
    00837 #endif
    00838
    00839 #if !defined(DL_MIN_LEN)
    00840 #  define DL_MIN_LEN  3
    00841 #endif
    00842 #if !defined(DL_SHIFT)
    00843 #  define DL_SHIFT    ((DL_BITS + (DL_MIN_LEN - 1)) / DL_MIN_LEN)
    00844 #endif
    00845
    00846 #define LZO_HASH_GZIP          1
    00847 #define LZO_HASH_GZIP_INCREMENTAL    2
    00848 #define LZO_HASH_LZO_INCREMENTAL_A    3
    00849 #define LZO_HASH_LZO_INCREMENTAL_B    4
    00850
    00851 #if !defined(LZO_HASH)
    00852 #  error "choose a hashing strategy"
    00853 #endif
    00854
    00855 #if (DL_MIN_LEN == 3)
    00856 #  define _DV2_A(p,shift1,shift2) \
    00857     (((( (lzo_uint32)((p)[0]) << shift1) ^ (p)[1]) << shift2) ^ (p)[2])
    00858 #  define _DV2_B(p,shift1,shift2) \
    00859     (((( (lzo_uint32)((p)[2]) << shift1) ^ (p)[1]) << shift2) ^ (p)[0])
    00860 #  define _DV3_B(p,shift1,shift2,shift3) \
    00861     ((_DV2_B((p)+1,shift1,shift2) << (shift3)) ^ (p)[0])
    00862 #elif (DL_MIN_LEN == 2)
    00863 #  define _DV2_A(p,shift1,shift2) \
    00864     (( (lzo_uint32)(p[0]) << shift1) ^ p[1])
    00865 #  define _DV2_B(p,shift1,shift2) \
    00866     (( (lzo_uint32)(p[1]) << shift1) ^ p[2])
    00867 #else
    00868 #  error "invalid DL_MIN_LEN"
    00869 #endif
    00870 #define _DV_A(p,shift)    _DV2_A(p,shift,shift)
    00871 #define _DV_B(p,shift)    _DV2_B(p,shift,shift)
    00872 #define DA2(p,s1,s2) \
    00873     (((((lzo_uint32)((p)[2]) << (s2)) + (p)[1]) << (s1)) + (p)[0])
    00874 #define DS2(p,s1,s2) \
    00875     (((((lzo_uint32)((p)[2]) << (s2)) - (p)[1]) << (s1)) - (p)[0])
    00876 #define DX2(p,s1,s2) \
    00877     (((((lzo_uint32)((p)[2]) << (s2)) ^ (p)[1]) << (s1)) ^ (p)[0])
    00878 #define DA3(p,s1,s2,s3) ((DA2((p)+1,s2,s3) << (s1)) + (p)[0])
    00879 #define DS3(p,s1,s2,s3) ((DS2((p)+1,s2,s3) << (s1)) - (p)[0])
    00880 #define DX3(p,s1,s2,s3) ((DX2((p)+1,s2,s3) << (s1)) ^ (p)[0])
    00881 #define DMS(v,s)    ((lzo_uint) (((v) & (D_MASK >> (s))) << (s)))
    00882 #define DM(v)      DMS(v,0)
    00883
    00884 #if (LZO_HASH == LZO_HASH_GZIP)
    00885 #  define _DINDEX(dv,p)  (_DV_A((p),DL_SHIFT))
    00886
    00887 #elif (LZO_HASH == LZO_HASH_GZIP_INCREMENTAL)
    00888 #  define __LZO_HASH_INCREMENTAL
    00889 #  define DVAL_FIRST(dv,p)  dv = _DV_A((p),DL_SHIFT)
    00890 #  define DVAL_NEXT(dv,p)   dv = (((dv) << DL_SHIFT) ^ p[2])
    00891 #  define _DINDEX(dv,p)  (dv)
    00892 #  define DVAL_LOOKAHEAD  DL_MIN_LEN
    00893
    00894 #elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_A)
    00895 #  define __LZO_HASH_INCREMENTAL
    00896 #  define DVAL_FIRST(dv,p)  dv = _DV_A((p),5)
    00897 #  define DVAL_NEXT(dv,p) \
    00898         dv ^= (lzo_uint32)(p[-1]) << (2*5); dv = (((dv) << 5) ^ p[2])
    00899 #  define _DINDEX(dv,p)  ((0x9f5f * (dv)) >> 5)
    00900 #  define DVAL_LOOKAHEAD  DL_MIN_LEN
    00901
    00902 #elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_B)
    00903 #  define __LZO_HASH_INCREMENTAL
    00904 #  define DVAL_FIRST(dv,p)  dv = _DV_B((p),5)
    00905 #  define DVAL_NEXT(dv,p) \
    00906         dv ^= p[-1]; dv = (((dv) >> 5) ^ ((lzo_uint32)(p[2]) << (2*5)))
    00907 #  define _DINDEX(dv,p)  ((0x9f5f * (dv)) >> 5)
    00908 #  define DVAL_LOOKAHEAD  DL_MIN_LEN
    00909
    00910 #else
    00911 #  error "choose a hashing strategy"
    00912 #endif
    00913
    00914 #ifndef DINDEX
    00915 #define DINDEX(dv,p)    ((lzo_uint)((_DINDEX(dv,p)) & DL_MASK) << DD_BITS)
    00916 #endif
    00917 #if !defined(DINDEX1) && defined(D_INDEX1)
    00918 #define DINDEX1      D_INDEX1
    00919 #endif
    00920 #if !defined(DINDEX2) && defined(D_INDEX2)
    00921 #define DINDEX2      D_INDEX2
    00922 #endif
    00923
    00924 #if !defined(__LZO_HASH_INCREMENTAL)
    00925 #  define DVAL_FIRST(dv,p)  ((void) 0)
    00926 #  define DVAL_NEXT(dv,p)   ((void) 0)
    00927 #  define DVAL_LOOKAHEAD  0
    00928 #endif
    00929
    00930 #if !defined(DVAL_ASSERT)
    00931 #if defined(__LZO_HASH_INCREMENTAL) && !defined(NDEBUG)
    00932 static void DVAL_ASSERT(lzo_uint32 dv, const lzo_byte *p)
    00933 {
    00934   lzo_uint32 df;
    00935   DVAL_FIRST(df,(p));
    00936   assert(DINDEX(dv,p) == DINDEX(df,p));
    00937 }
    00938 #else
    00939 #  define DVAL_ASSERT(dv,p) ((void) 0)
    00940 #endif
    00941 #endif
    00942
    00943 #if defined(LZO_DICT_USE_PTR)
    00944 #  define DENTRY(p,in)              (p)
    00945 #  define GINDEX(m_pos,m_off,dict,dindex,in)  m_pos = dict[dindex]
    00946 #else
    00947 #  define DENTRY(p,in)              ((lzo_uint) ((p)-(in)))
    00948 #  define GINDEX(m_pos,m_off,dict,dindex,in)  m_off = dict[dindex]
    00949 #endif
    00950
    00951 #if (DD_BITS == 0)
    00952
    00953 #  define UPDATE_D(dict,drun,dv,p,in)    dict[ DINDEX(dv,p) ] = DENTRY(p,in)
    00954 #  define UPDATE_I(dict,drun,index,p,in)  dict[index] = DENTRY(p,in)
    00955 #  define UPDATE_P(ptr,drun,p,in)      (ptr)[0] = DENTRY(p,in)
    00956
    00957 #else
    00958
    00959 #  define UPDATE_D(dict,drun,dv,p,in)   \
    00960     dict[ DINDEX(dv,p) + drun++ ] = DENTRY(p,in); drun &= DD_MASK
    00961 #  define UPDATE_I(dict,drun,index,p,in)  \
    00962     dict[ (index) + drun++ ] = DENTRY(p,in); drun &= DD_MASK
    00963 #  define UPDATE_P(ptr,drun,p,in)   \
    00964     (ptr) [ drun++ ] = DENTRY(p,in); drun &= DD_MASK
    00965
    00966 #endif
    00967
    00968 #if defined(LZO_DICT_USE_PTR)
    00969
    00970 #define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \
    00971     (m_pos == NULL || (m_off = (lzo_moff_t) (ip - m_pos)) > max_offset)
    00972
    00973 #define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \
    00974   (BOUNDS_CHECKING_OFF_IN_EXPR( \
    00975     (PTR_LT(m_pos,in) || \
    00976      (m_off = (lzo_moff_t) PTR_DIFF(ip,m_pos)) <= 0 || \
    00977       m_off > max_offset) ))
    00978
    00979 #else
    00980
    00981 #define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \
    00982     (m_off == 0 || \
    00983      ((m_off = (lzo_moff_t) ((ip)-(in)) - m_off) > max_offset) || \
    00984      (m_pos = (ip) - (m_off), 0) )
    00985
    00986 #define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \
    00987     ((lzo_moff_t) ((ip)-(in)) <= m_off || \
    00988      ((m_off = (lzo_moff_t) ((ip)-(in)) - m_off) > max_offset) || \
    00989      (m_pos = (ip) - (m_off), 0) )
    00990
    00991 #endif
    00992
    00993 #if defined(LZO_DETERMINISTIC)
    00994 #  define LZO_CHECK_MPOS  LZO_CHECK_MPOS_DET
    00995 #else
    00996 #  define LZO_CHECK_MPOS  LZO_CHECK_MPOS_NON_DET
    00997 #endif
    00998
    00999 #ifdef __cplusplus
    01000 }
    01001 #endif
    01002
    01003 #endif
    01004
    01005 #endif
    01006
    01007 #endif
    01008
    01009 #define DO_COMPRESS  lzo1x_1_compress
    01010
    01011 static
    01012 lzo_uint do_compress   ( const lzo_byte *in , lzo_uint  in_len,
    01013                  lzo_byte *out, lzo_uintp out_len,
    01014                  lzo_voidp wrkmem )
    01015 {
    01016     register const lzo_byte *ip;
    01017     lzo_byte *op;
    01018     const lzo_byte * const in_end = in + in_len;
    01019     const lzo_byte * const ip_end = in + in_len - M2_MAX_LEN - 5;
    01020     const lzo_byte *ii;
    01021     lzo_dict_p const dict = (lzo_dict_p) wrkmem;
    01022
    01023     op = out;
    01024     ip = in;
    01025     ii = ip;
    01026
    01027     ip += 4;
    01028     for (;;)
    01029     {
    01030     register const lzo_byte *m_pos;
    01031     lzo_moff_t m_off;
    01032     lzo_ptrdiff_t m_len;
    01033     lzo_uint dindex;
    01034
    01035     DINDEX1(dindex,ip);
    01036     GINDEX(m_pos,m_off,dict,dindex,in);
    01037     if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET))
    01038       goto literal;
    01039     if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
    01040       goto try_match;
    01041     DINDEX2(dindex,ip);
    01042     GINDEX(m_pos,m_off,dict,dindex,in);
    01043     if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET))
    01044       goto literal;
    01045     if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3])
    01046       goto try_match;
    01047     goto literal;
    01048
    01049 try_match:
    01050 #if 1 && defined(LZO_UNALIGNED_OK_2)
    01051     if (* (const lzo_ushortp) m_pos != * (const lzo_ushortp) ip)
    01052 #else
    01053     if (m_pos[0] != ip[0] || m_pos[1] != ip[1])
    01054 #endif
    01055     {
    01056     }
    01057     else
    01058     {
    01059       if (m_pos[2] == ip[2])
    01060       {
    01061           goto match;
    01062       }
    01063     }
    01064
    01065 literal:
    01066     UPDATE_I(dict,0,dindex,ip,in);
    01067     ++ip;
    01068     if (ip >= ip_end)
    01069       break;
    01070     continue;
    01071
    01072 match:
    01073     UPDATE_I(dict,0,dindex,ip,in);
    01074     if (pd(ip,ii) > 0)
    01075     {
    01076       register lzo_uint t = pd(ip,ii);
    01077
    01078       if (t <= 3)
    01079       {
    01080         assert(op - 2 > out);
    01081         op[-2] |= LZO_BYTE(t);
    01082       }
    01083       else if (t <= 18)
    01084         *op++ = LZO_BYTE(t - 3);
    01085       else
    01086       {
    01087         register lzo_uint tt = t - 18;
    01088
    01089         *op++ = 0;
    01090         while (tt > 255)
    01091         {
    01092           tt -= 255;
    01093           *op++ = 0;
    01094         }
    01095         assert(tt > 0);
    01096         *op++ = LZO_BYTE(tt);
    01097       }
    01098       do *op++ = *ii++; while (--t > 0);
    01099     }
    01100
    01101     assert(ii == ip);
    01102     ip += 3;
    01103     if (m_pos[3] != *ip++ || m_pos[4] != *ip++ || m_pos[5] != *ip++ ||
    01104       m_pos[6] != *ip++ || m_pos[7] != *ip++ || m_pos[8] != *ip++) {
    01105
    01106       --ip;
    01107       m_len = ip - ii;
    01108       assert(m_len >= 3); assert(m_len <= M2_MAX_LEN);
    01109
    01110       if (m_off <= M2_MAX_OFFSET)
    01111       {
    01112         m_off -= 1;
    01113         *op++ = LZO_BYTE(((m_len - 1) << 5) | ((m_off & 7) << 2));
    01114         *op++ = LZO_BYTE(m_off >> 3);
    01115       }
    01116       else if (m_off <= M3_MAX_OFFSET)
    01117       {
    01118         m_off -= 1;
    01119         *op++ = LZO_BYTE(M3_MARKER | (m_len - 2));
    01120         goto m3_m4_offset;
    01121       }
    01122       else
    01123       {
    01124         m_off -= 0x4000;
    01125         assert(m_off > 0); assert(m_off <= 0x7fff);
    01126         *op++ = LZO_BYTE(M4_MARKER |
    01127                  ((m_off & 0x4000) >> 11) | (m_len - 2));
    01128         goto m3_m4_offset;
    01129       }
    01130     }
    01131     else
    01132     {
    01133       {
    01134         const lzo_byte *end = in_end;
    01135         const lzo_byte *m = m_pos + M2_MAX_LEN + 1;
    01136         while (ip < end && *m == *ip)
    01137           m++, ip++;
    01138         m_len = (ip - ii);
    01139       }
    01140       assert(m_len > M2_MAX_LEN);
    01141
    01142       if (m_off <= M3_MAX_OFFSET)
    01143       {
    01144         m_off -= 1;
    01145         if (m_len <= 33)
    01146           *op++ = LZO_BYTE(M3_MARKER | (m_len - 2));
    01147         else
    01148         {
    01149           m_len -= 33;
    01150           *op++ = M3_MARKER | 0;
    01151           goto m3_m4_len;
    01152         }
    01153       }
    01154       else
    01155       {
    01156         m_off -= 0x4000;
    01157         assert(m_off > 0); assert(m_off <= 0x7fff);
    01158         if (m_len <= M4_MAX_LEN)
    01159           *op++ = LZO_BYTE(M4_MARKER |
    01160                    ((m_off & 0x4000) >> 11) | (m_len - 2));
    01161         else
    01162         {
    01163           m_len -= M4_MAX_LEN;
    01164           *op++ = LZO_BYTE(M4_MARKER | ((m_off & 0x4000) >> 11));
    01165 m3_m4_len:
    01166           while (m_len > 255)
    01167           {
    01168             m_len -= 255;
    01169             *op++ = 0;
    01170           }
    01171           assert(m_len > 0);
    01172           *op++ = LZO_BYTE(m_len);
    01173         }
    01174       }
    01175
    01176 m3_m4_offset:
    01177       *op++ = LZO_BYTE((m_off & 63) << 2);
    01178       *op++ = LZO_BYTE(m_off >> 6);
    01179     }
    01180
    01181     ii = ip;
    01182     if (ip >= ip_end)
    01183       break;
    01184   }
    01185
    01186   *out_len = (lzo_uint)(op - out);
    01187   return pd(in_end,ii);
    01188 }
    01189
    01190 LZO_PUBLIC(int)
    01191 DO_COMPRESS   ( const lzo_byte *in , lzo_uint  in_len,
    01192              lzo_byte *out, lzo_uintp out_len,
    01193              lzo_voidp wrkmem )
    01194 {
    01195   lzo_byte *op = out;
    01196   lzo_uint t;
    01197
    01198   if (in_len <= M2_MAX_LEN + 5)
    01199     t = in_len;
    01200   else
    01201   {
    01202     t = do_compress(in,in_len,op,out_len,wrkmem);
    01203     op += *out_len;
    01204   }
    01205
    01206   if (t > 0)
    01207   {
    01208     const lzo_byte *ii = in + in_len - t;
    01209
    01210     if (op == out && t <= 238)
    01211       *op++ = LZO_BYTE(17 + t);
    01212     else if (t <= 3)
    01213       op[-2] |= LZO_BYTE(t);
    01214     else if (t <= 18)
    01215       *op++ = LZO_BYTE(t - 3);
    01216     else
    01217     {
    01218       lzo_uint tt = t - 18;
    01219
    01220       *op++ = 0;
    01221       while (tt > 255)
    01222       {
    01223         tt -= 255;
    01224         *op++ = 0;
    01225       }
    01226       assert(tt > 0);
    01227       *op++ = LZO_BYTE(tt);
    01228     }
    01229     do *op++ = *ii++; while (--t > 0);
    01230   }
    01231
    01232   *op++ = M4_MARKER | 1;
    01233   *op++ = 0;
    01234   *op++ = 0;
    01235
    01236   *out_len = (lzo_uint)(op - out);
    01237   return LZO_E_OK;
    01238 }
    01239
    01240 #undef do_compress
    01241 #undef DO_COMPRESS
    01242 #undef LZO_HASH
    01243
    01244 #undef LZO_TEST_DECOMPRESS_OVERRUN
    01245 #undef LZO_TEST_DECOMPRESS_OVERRUN_INPUT
    01246 #undef LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT
    01247 #undef LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND
    01248 #undef DO_DECOMPRESS
    01249 #define DO_DECOMPRESS    lzo1x_decompress
    01250
    01251 #if defined(LZO_TEST_DECOMPRESS_OVERRUN)
    01252 #  if !defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT)
    01253 # define LZO_TEST_DECOMPRESS_OVERRUN_INPUT     2
    01254 #  endif
    01255 #  if !defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT)
    01256 # define LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT   2
    01257 #  endif
    01258 #  if !defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
    01259 # define LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND
    01260 #  endif
    01261 #endif
    01262
    01263 #undef TEST_IP
    01264 #undef TEST_OP
    01265 #undef TEST_LOOKBEHIND
    01266 #undef NEED_IP
    01267 #undef NEED_OP
    01268 #undef HAVE_TEST_IP
    01269 #undef HAVE_TEST_OP
    01270 #undef HAVE_NEED_IP
    01271 #undef HAVE_NEED_OP
    01272 #undef HAVE_ANY_IP
    01273 #undef HAVE_ANY_OP
    01274
    01275 #if defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT)
    01276 #  if (LZO_TEST_DECOMPRESS_OVERRUN_INPUT >= 1)
    01277 # define TEST_IP       (ip < ip_end)
    01278 #  endif
    01279 #  if (LZO_TEST_DECOMPRESS_OVERRUN_INPUT >= 2)
    01280 # define NEED_IP(x) \
    01281       if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x))  goto input_overrun
    01282 #  endif
    01283 #endif
    01284
    01285 #if defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT)
    01286 #  if (LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT >= 1)
    01287 # define TEST_OP       (op <= op_end)
    01288 #  endif
    01289 #  if (LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT >= 2)
    01290 # undef TEST_OP
    01291 # define NEED_OP(x) \
    01292       if ((lzo_uint)(op_end - op) < (lzo_uint)(x))  goto output_overrun
    01293 #  endif
    01294 #endif
    01295
    01296 #if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
    01297 #  define TEST_LOOKBEHIND(m_pos,out)  if (m_pos < out) goto lookbehind_overrun
    01298 #else
    01299 #  define TEST_LOOKBEHIND(m_pos,op)  ((void) 0)
    01300 #endif
    01301
    01302 #if !defined(LZO_EOF_CODE) && !defined(TEST_IP)
    01303 #  define TEST_IP        (ip < ip_end)
    01304 #endif
    01305
    01306 #if defined(TEST_IP)
    01307 #  define HAVE_TEST_IP
    01308 #else
    01309 #  define TEST_IP        1
    01310 #endif
    01311 #if defined(TEST_OP)
    01312 #  define HAVE_TEST_OP
    01313 #else
    01314 #  define TEST_OP        1
    01315 #endif
    01316
    01317 #if defined(NEED_IP)
    01318 #  define HAVE_NEED_IP
    01319 #else
    01320 #  define NEED_IP(x)      ((void) 0)
    01321 #endif
    01322 #if defined(NEED_OP)
    01323 #  define HAVE_NEED_OP
    01324 #else
    01325 #  define NEED_OP(x)      ((void) 0)
    01326 #endif
    01327
    01328 #if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP)
    01329 #  define HAVE_ANY_IP
    01330 #endif
    01331 #if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP)
    01332 #  define HAVE_ANY_OP
    01333 #endif
    01334
    01335 #undef __COPY4
    01336 #define __COPY4(dst,src)  * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src)
    01337
    01338 #undef COPY4
    01339 #if defined(LZO_UNALIGNED_OK_4)
    01340 #  define COPY4(dst,src)  __COPY4(dst,src)
    01341 #elif defined(LZO_ALIGNED_OK_4)
    01342 #  define COPY4(dst,src)  __COPY4((lzo_ptr_t)(dst),(lzo_ptr_t)(src))
    01343 #endif
    01344
    01345 #if defined(DO_DECOMPRESS)
    01346 LZO_PUBLIC(int)
    01347 DO_DECOMPRESS  ( const lzo_byte *in , lzo_uint  in_len,
    01348              lzo_byte *out, lzo_uintp out_len,
    01349              lzo_voidp wrkmem )
    01350 #endif
    01351 {
    01352   register lzo_byte *op;
    01353   register const lzo_byte *ip;
    01354   register lzo_uint t;
    01355   register const lzo_byte *m_pos;
    01356
    01357   const lzo_byte * const ip_end = in + in_len;
    01358 #if defined(HAVE_ANY_OP)
    01359   lzo_byte * const op_end = out + *out_len;
    01360 #endif
    01361
    01362   LZO_UNUSED(wrkmem);
    01363
    01364   *out_len = 0;
    01365
    01366   op = out;
    01367   ip = in;
    01368
    01369   if (*ip > 17)
    01370   {
    01371     t = *ip++ - 17;
    01372     if (t < 4)
    01373       goto match_next;
    01374     assert(t > 0); NEED_OP(t); NEED_IP(t+1);
    01375     do *op++ = *ip++; while (--t > 0);
    01376     goto first_literal_run;
    01377   }
    01378
    01379   while (TEST_IP && TEST_OP)
    01380   {
    01381     t = *ip++;
    01382     if (t >= 16)
    01383       goto match;
    01384     if (t == 0)
    01385     {
    01386       NEED_IP(1);
    01387       while (*ip == 0)
    01388       {
    01389         t += 255;
    01390         ip++;
    01391         NEED_IP(1);
    01392       }
    01393       t += 15 + *ip++;
    01394     }
    01395     assert(t > 0); NEED_OP(t+3); NEED_IP(t+4);
    01396 #if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
    01397 #if !defined(LZO_UNALIGNED_OK_4)
    01398     if (PTR_ALIGNED2_4(op,ip))
    01399     {
    01400 #endif
    01401     COPY4(op,ip);
    01402     op += 4; ip += 4;
    01403     if (--t > 0)
    01404     {
    01405       if (t >= 4)
    01406       {
    01407         do {
    01408           COPY4(op,ip);
    01409           op += 4; ip += 4; t -= 4;
    01410         } while (t >= 4);
    01411         if (t > 0) do *op++ = *ip++; while (--t > 0);
    01412       }
    01413       else
    01414         do *op++ = *ip++; while (--t > 0);
    01415     }
    01416 #if !defined(LZO_UNALIGNED_OK_4)
    01417     }
    01418     else
    01419 #endif
    01420 #endif
    01421 #if !defined(LZO_UNALIGNED_OK_4)
    01422     {
    01423       *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
    01424       do *op++ = *ip++; while (--t > 0);
    01425     }
    01426 #endif
    01427
    01428 first_literal_run:
    01429
    01430     t = *ip++;
    01431     if (t >= 16)
    01432       goto match;
    01433     m_pos = op - (1 + M2_MAX_OFFSET);
    01434     m_pos -= t >> 2;
    01435     m_pos -= *ip++ << 2;
    01436     TEST_LOOKBEHIND(m_pos,out); NEED_OP(3);
    01437     *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
    01438     goto match_done;
    01439
    01440     while (TEST_IP && TEST_OP)
    01441     {
    01442 match:
    01443       if (t >= 64)
    01444       {
    01445 #if defined(LZO1X)
    01446         m_pos = op - 1;
    01447         m_pos -= (t >> 2) & 7;
    01448         m_pos -= *ip++ << 3;
    01449         t = (t >> 5) - 1;
    01450 #endif
    01451         TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1);
    01452         goto copy_match;
    01453       }
    01454       else if (t >= 32)
    01455       {
    01456         t &= 31;
    01457         if (t == 0)
    01458         {
    01459           NEED_IP(1);
    01460           while (*ip == 0)
    01461           {
    01462             t += 255;
    01463             ip++;
    01464             NEED_IP(1);
    01465           }
    01466           t += 31 + *ip++;
    01467         }
    01468 #if defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
    01469         m_pos = op - 1;
    01470         m_pos -= (* (const lzo_ushortp) ip) >> 2;
    01471 #else
    01472         m_pos = op - 1;
    01473         m_pos -= (ip[0] >> 2) + (ip[1] << 6);
    01474 #endif
    01475         ip += 2;
    01476       }
    01477       else if (t >= 16)
    01478       {
    01479         m_pos = op;
    01480         m_pos -= (t & 8) << 11;
    01481         t &= 7;
    01482         if (t == 0)
    01483         {
    01484           NEED_IP(1);
    01485           while (*ip == 0)
    01486           {
    01487             t += 255;
    01488             ip++;
    01489             NEED_IP(1);
    01490           }
    01491           t += 7 + *ip++;
    01492         }
    01493 #if defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
    01494         m_pos -= (* (const lzo_ushortp) ip) >> 2;
    01495 #else
    01496         m_pos -= (ip[0] >> 2) + (ip[1] << 6);
    01497 #endif
    01498         ip += 2;
    01499         if (m_pos == op)
    01500           goto eof_found;
    01501         m_pos -= 0x4000;
    01502       }
    01503       else
    01504       {
    01505         m_pos = op - 1;
    01506         m_pos -= t >> 2;
    01507         m_pos -= *ip++ << 2;
    01508         TEST_LOOKBEHIND(m_pos,out); NEED_OP(2);
    01509         *op++ = *m_pos++; *op++ = *m_pos;
    01510         goto match_done;
    01511       }
    01512
    01513       TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1);
    01514 #if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
    01515 #if !defined(LZO_UNALIGNED_OK_4)
    01516       if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
    01517       {
    01518         assert((op - m_pos) >= 4);
    01519 #else
    01520       if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
    01521       {
    01522 #endif
    01523         COPY4(op,m_pos);
    01524         op += 4; m_pos += 4; t -= 4 - (3 - 1);
    01525         do {
    01526           COPY4(op,m_pos);
    01527           op += 4; m_pos += 4; t -= 4;
    01528         } while (t >= 4);
    01529         if (t > 0) do *op++ = *m_pos++; while (--t > 0);
    01530       }
    01531       else
    01532 #endif
    01533       {
    01534 copy_match:
    01535         *op++ = *m_pos++; *op++ = *m_pos++;
    01536         do *op++ = *m_pos++; while (--t > 0);
    01537       }
    01538
    01539 match_done:
    01540       t = ip[-2] & 3;
    01541       if (t == 0)
    01542         break;
    01543
    01544 match_next:
    01545       assert(t > 0); NEED_OP(t); NEED_IP(t+1);
    01546       do *op++ = *ip++; while (--t > 0);
    01547       t = *ip++;
    01548     }
    01549   }
    01550
    01551 #if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
    01552   *out_len = op - out;
    01553   return LZO_E_EOF_NOT_FOUND;
    01554 #endif
    01555
    01556 eof_found:
    01557   assert(t == 1);
    01558   *out_len = (lzo_uint)(op - out);
    01559   return (ip == ip_end ? LZO_E_OK :
    01560        (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
    01561
    01562 #if defined(HAVE_NEED_IP)
    01563 input_overrun:
    01564   *out_len = op - out;
    01565   return LZO_E_INPUT_OVERRUN;
    01566 #endif
    01567
    01568 #if defined(HAVE_NEED_OP)
    01569 output_overrun:
    01570   *out_len = op - out;
    01571   return LZO_E_OUTPUT_OVERRUN;
    01572 #endif
    01573
    01574 #if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
    01575 lookbehind_overrun:
    01576   *out_len = op - out;
    01577   return LZO_E_LOOKBEHIND_OVERRUN;
    01578 #endif
    01579 }
    01580
    01581 #define LZO_TEST_DECOMPRESS_OVERRUN
    01582 #undef DO_DECOMPRESS
    01583 #define DO_DECOMPRESS    lzo1x_decompress_safe
    01584
    01585 #if defined(LZO_TEST_DECOMPRESS_OVERRUN)
    01586 #  if !defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT)
    01587 # define LZO_TEST_DECOMPRESS_OVERRUN_INPUT     2
    01588 #  endif
    01589 #  if !defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT)
    01590 # define LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT   2
    01591 #  endif
    01592 #  if !defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
    01593 # define LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND
    01594 #  endif
    01595 #endif
    01596
    01597 #undef TEST_IP
    01598 #undef TEST_OP
    01599 #undef TEST_LOOKBEHIND
    01600 #undef NEED_IP
    01601 #undef NEED_OP
    01602 #undef HAVE_TEST_IP
    01603 #undef HAVE_TEST_OP
    01604 #undef HAVE_NEED_IP
    01605 #undef HAVE_NEED_OP
    01606 #undef HAVE_ANY_IP
    01607 #undef HAVE_ANY_OP
    01608
    01609
    01610 #if 0
    01611
    01612 #if defined(LZO_TEST_DECOMPRESS_OVERRUN_INPUT)
    01613 #  if (LZO_TEST_DECOMPRESS_OVERRUN_INPUT >= 1)
    01614 # define TEST_IP       (ip < ip_end)
    01615 #  endif
    01616 #  if (LZO_TEST_DECOMPRESS_OVERRUN_INPUT >= 2)
    01617 # define NEED_IP(x) \
    01618       if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x))  goto input_overrun
    01619 #  endif
    01620 #endif
    01621
    01622 #if defined(LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT)
    01623 #  if (LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT >= 1)
    01624 # define TEST_OP       (op <= op_end)
    01625 #  endif
    01626 #  if (LZO_TEST_DECOMPRESS_OVERRUN_OUTPUT >= 2)
    01627 # undef TEST_OP
    01628 # define NEED_OP(x) \
    01629       if ((lzo_uint)(op_end - op) < (lzo_uint)(x))  goto output_overrun
    01630 #  endif
    01631 #endif
    01632
    01633 #if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
    01634 #  define TEST_LOOKBEHIND(m_pos,out)  if (m_pos < out) goto lookbehind_overrun
    01635 #else
    01636 #  define TEST_LOOKBEHIND(m_pos,op)  ((void) 0)
    01637 #endif
    01638
    01639 #if !defined(LZO_EOF_CODE) && !defined(TEST_IP)
    01640 #  define TEST_IP        (ip < ip_end)
    01641 #endif
    01642
    01643 #if defined(TEST_IP)
    01644 #  define HAVE_TEST_IP
    01645 #else
    01646 #  define TEST_IP        1
    01647 #endif
    01648 #if defined(TEST_OP)
    01649 #  define HAVE_TEST_OP
    01650 #else
    01651 #  define TEST_OP        1
    01652 #endif
    01653
    01654 #if defined(NEED_IP)
    01655 #  define HAVE_NEED_IP
    01656 #else
    01657 #  define NEED_IP(x)      ((void) 0)
    01658 #endif
    01659 #if defined(NEED_OP)
    01660 #  define HAVE_NEED_OP
    01661 #else
    01662 #  define NEED_OP(x)      ((void) 0)
    01663 #endif
    01664
    01665 #if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP)
    01666 #  define HAVE_ANY_IP
    01667 #endif
    01668 #if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP)
    01669 #  define HAVE_ANY_OP
    01670 #endif
    01671
    01672 #undef __COPY4
    01673 #define __COPY4(dst,src)  * (lzo_uint32p)(dst) = * (const lzo_uint32p)(src)
    01674
    01675 #undef COPY4
    01676 #if defined(LZO_UNALIGNED_OK_4)
    01677 #  define COPY4(dst,src)  __COPY4(dst,src)
    01678 #elif defined(LZO_ALIGNED_OK_4)
    01679 #  define COPY4(dst,src)  __COPY4((lzo_ptr_t)(dst),(lzo_ptr_t)(src))
    01680 #endif
    01681
    01682 #if defined(DO_DECOMPRESS)
    01683 LZO_PUBLIC(int)
    01684 DO_DECOMPRESS  ( const lzo_byte *in , lzo_uint  in_len,
    01685              lzo_byte *out, lzo_uintp out_len,
    01686              lzo_voidp wrkmem )
    01687 #endif
    01688 {
    01689   register lzo_byte *op;
    01690   register const lzo_byte *ip;
    01691   register lzo_uint t;
    01692   register const lzo_byte *m_pos;
    01693
    01694   const lzo_byte * const ip_end = in + in_len;
    01695 #if defined(HAVE_ANY_OP)
    01696   lzo_byte * const op_end = out + *out_len;
    01697 #endif
    01698
    01699   LZO_UNUSED(wrkmem);
    01700
    01701   *out_len = 0;
    01702
    01703   op = out;
    01704   ip = in;
    01705
    01706   if (*ip > 17)
    01707   {
    01708     t = *ip++ - 17;
    01709     if (t < 4)
    01710       goto match_next;
    01711     assert(t > 0); NEED_OP(t); NEED_IP(t+1);
    01712     do *op++ = *ip++; while (--t > 0);
    01713     goto first_literal_run;
    01714   }
    01715
    01716   while (TEST_IP && TEST_OP)
    01717   {
    01718     t = *ip++;
    01719     if (t >= 16)
    01720       goto match;
    01721     if (t == 0)
    01722     {
    01723       NEED_IP(1);
    01724       while (*ip == 0)
    01725       {
    01726         t += 255;
    01727         ip++;
    01728         NEED_IP(1);
    01729       }
    01730       t += 15 + *ip++;
    01731     }
    01732     assert(t > 0); NEED_OP(t+3); NEED_IP(t+4);
    01733 #if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
    01734 #if !defined(LZO_UNALIGNED_OK_4)
    01735     if (PTR_ALIGNED2_4(op,ip))
    01736     {
    01737 #endif
    01738     COPY4(op,ip);
    01739     op += 4; ip += 4;
    01740     if (--t > 0)
    01741     {
    01742       if (t >= 4)
    01743       {
    01744         do {
    01745           COPY4(op,ip);
    01746           op += 4; ip += 4; t -= 4;
    01747         } while (t >= 4);
    01748         if (t > 0) do *op++ = *ip++; while (--t > 0);
    01749       }
    01750       else
    01751         do *op++ = *ip++; while (--t > 0);
    01752     }
    01753 #if !defined(LZO_UNALIGNED_OK_4)
    01754     }
    01755     else
    01756 #endif
    01757 #endif
    01758 #if !defined(LZO_UNALIGNED_OK_4)
    01759     {
    01760       *op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
    01761       do *op++ = *ip++; while (--t > 0);
    01762     }
    01763 #endif
    01764
    01765 first_literal_run:
    01766
    01767     t = *ip++;
    01768     if (t >= 16)
    01769       goto match;
    01770 #if defined(LZO1Z)
    01771     t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2);
    01772     m_pos = op - t;
    01773     last_m_off = t;
    01774 #else
    01775     m_pos = op - (1 + M2_MAX_OFFSET);
    01776     m_pos -= t >> 2;
    01777     m_pos -= *ip++ << 2;
    01778 #endif
    01779     TEST_LOOKBEHIND(m_pos,out); NEED_OP(3);
    01780     *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos;
    01781     goto match_done;
    01782
    01783     while (TEST_IP && TEST_OP)
    01784     {
    01785 match:
    01786       if (t >= 64)
    01787       {
    01788 #if defined(LZO1X)
    01789         m_pos = op - 1;
    01790         m_pos -= (t >> 2) & 7;
    01791         m_pos -= *ip++ << 3;
    01792         t = (t >> 5) - 1;
    01793 #elif defined(LZO1Y)
    01794         m_pos = op - 1;
    01795         m_pos -= (t >> 2) & 3;
    01796         m_pos -= *ip++ << 2;
    01797         t = (t >> 4) - 3;
    01798 #elif defined(LZO1Z)
    01799         {
    01800           lzo_uint off = t & 0x1f;
    01801           m_pos = op;
    01802           if (off >= 0x1c)
    01803           {
    01804             assert(last_m_off > 0);
    01805             m_pos -= last_m_off;
    01806           }
    01807           else
    01808           {
    01809             off = 1 + (off << 6) + (*ip++ >> 2);
    01810             m_pos -= off;
    01811             last_m_off = off;
    01812           }
    01813         }
    01814         t = (t >> 5) - 1;
    01815 #endif
    01816         TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1);
    01817         goto copy_match;
    01818       }
    01819       else if (t >= 32)
    01820       {
    01821         t &= 31;
    01822         if (t == 0)
    01823         {
    01824           NEED_IP(1);
    01825           while (*ip == 0)
    01826           {
    01827             t += 255;
    01828             ip++;
    01829             NEED_IP(1);
    01830           }
    01831           t += 31 + *ip++;
    01832         }
    01833 #if defined(LZO1Z)
    01834         {
    01835           lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2);
    01836           m_pos = op - off;
    01837           last_m_off = off;
    01838         }
    01839 #elif defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
    01840         m_pos = op - 1;
    01841         m_pos -= (* (const lzo_ushortp) ip) >> 2;
    01842 #else
    01843         m_pos = op - 1;
    01844         m_pos -= (ip[0] >> 2) + (ip[1] << 6);
    01845 #endif
    01846         ip += 2;
    01847       }
    01848       else if (t >= 16)
    01849       {
    01850         m_pos = op;
    01851         m_pos -= (t & 8) << 11;
    01852         t &= 7;
    01853         if (t == 0)
    01854         {
    01855           NEED_IP(1);
    01856           while (*ip == 0)
    01857           {
    01858             t += 255;
    01859             ip++;
    01860             NEED_IP(1);
    01861           }
    01862           t += 7 + *ip++;
    01863         }
    01864 #if defined(LZO1Z)
    01865         m_pos -= (ip[0] << 6) + (ip[1] >> 2);
    01866 #elif defined(LZO_UNALIGNED_OK_2) && (LZO_BYTE_ORDER == LZO_LITTLE_ENDIAN)
    01867         m_pos -= (* (const lzo_ushortp) ip) >> 2;
    01868 #else
    01869         m_pos -= (ip[0] >> 2) + (ip[1] << 6);
    01870 #endif
    01871         ip += 2;
    01872         if (m_pos == op)
    01873           goto eof_found;
    01874         m_pos -= 0x4000;
    01875 #if defined(LZO1Z)
    01876         last_m_off = op - m_pos;
    01877 #endif
    01878       }
    01879       else
    01880       {
    01881 #if defined(LZO1Z)
    01882         t = 1 + (t << 6) + (*ip++ >> 2);
    01883         m_pos = op - t;
    01884         last_m_off = t;
    01885 #else
    01886         m_pos = op - 1;
    01887         m_pos -= t >> 2;
    01888         m_pos -= *ip++ << 2;
    01889 #endif
    01890         TEST_LOOKBEHIND(m_pos,out); NEED_OP(2);
    01891         *op++ = *m_pos++; *op++ = *m_pos;
    01892         goto match_done;
    01893       }
    01894
    01895       TEST_LOOKBEHIND(m_pos,out); assert(t > 0); NEED_OP(t+3-1);
    01896 #if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
    01897 #if !defined(LZO_UNALIGNED_OK_4)
    01898       if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
    01899       {
    01900         assert((op - m_pos) >= 4);
    01901 #else
    01902       if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
    01903       {
    01904 #endif
    01905         COPY4(op,m_pos);
    01906         op += 4; m_pos += 4; t -= 4 - (3 - 1);
    01907         do {
    01908           COPY4(op,m_pos);
    01909           op += 4; m_pos += 4; t -= 4;
    01910         } while (t >= 4);
    01911         if (t > 0) do *op++ = *m_pos++; while (--t > 0);
    01912       }
    01913       else
    01914 #endif
    01915       {
    01916 copy_match:
    01917         *op++ = *m_pos++; *op++ = *m_pos++;
    01918         do *op++ = *m_pos++; while (--t > 0);
    01919       }
    01920
    01921
    01922 match_done:
    01923 #if defined(LZO1Z)
    01924       t = ip[-1] & 3;
    01925 #else
    01926       t = ip[-2] & 3;
    01927 #endif
    01928       if (t == 0)
    01929         break;
    01930
    01931 match_next:
    01932       assert(t > 0); NEED_OP(t); NEED_IP(t+1);
    01933       do *op++ = *ip++; while (--t > 0);
    01934       t = *ip++;
    01935     }
    01936   }
    01937
    01938 #if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
    01939   *out_len = op - out;
    01940   return LZO_E_EOF_NOT_FOUND;
    01941 #endif
    01942
    01943 eof_found:
    01944   assert(t == 1);
    01945   *out_len = op - out;
    01946   return (ip == ip_end ? LZO_E_OK :
    01947        (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
    01948
    01949 #if defined(HAVE_NEED_IP)
    01950 input_overrun:
    01951   *out_len = op - out;
    01952   return LZO_E_INPUT_OVERRUN;
    01953 #endif
    01954
    01955 #if defined(HAVE_NEED_OP)
    01956 output_overrun:
    01957   *out_len = op - out;
    01958   return LZO_E_OUTPUT_OVERRUN;
    01959 #endif
    01960
    01961 #if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)
    01962 lookbehind_overrun:
    01963   *out_len = op - out;
    01964   return LZO_E_LOOKBEHIND_OVERRUN;
    01965 #endif
    01966 }
    01967
    01968 #endif
    01969
    01970 /***** End of minilzo.c *****/