# minilzo.cpp

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