lz4

Log

Files

Refs

LICENSE

lz4.c (62206B)

     1 /*
     2    LZ4 - Fast LZ compression algorithm
     3    Copyright (C) 2011-2017, Yann Collet.
     4 
     5    BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
     6 
     7    Redistribution and use in source and binary forms, with or without
     8    modification, are permitted provided that the following conditions are
     9    met:
    10 
    11        * Redistributions of source code must retain the above copyright
    12    notice, this list of conditions and the following disclaimer.
    13        * Redistributions in binary form must reproduce the above
    14    copyright notice, this list of conditions and the following disclaimer
    15    in the documentation and/or other materials provided with the
    16    distribution.
    17 
    18    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    19    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    20    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    21    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    22    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    23    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    24    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    25    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    26    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    27    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    28    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    29 
    30    You can contact the author at :
    31     - LZ4 homepage : http://www.lz4.org
    32     - LZ4 source repository : https://github.com/lz4/lz4
    33 */
    34 
    35 
    36 /*-************************************
    37 *  Tuning parameters
    38 **************************************/
    39 /*
    40  * LZ4_HEAPMODE :
    41  * Select how default compression functions will allocate memory for their hash table,
    42  * in memory stack (0:default, fastest), or in memory heap (1:requires malloc()).
    43  */
    44 #ifndef LZ4_HEAPMODE
    45 #  define LZ4_HEAPMODE 0
    46 #endif
    47 
    48 /*
    49  * ACCELERATION_DEFAULT :
    50  * Select "acceleration" for LZ4_compress_fast() when parameter value <= 0
    51  */
    52 #define ACCELERATION_DEFAULT 1
    53 
    54 
    55 /*-************************************
    56 *  CPU Feature Detection
    57 **************************************/
    58 /* LZ4_FORCE_MEMORY_ACCESS
    59  * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.
    60  * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.
    61  * The below switch allow to select different access method for improved performance.
    62  * Method 0 (default) : use `memcpy()`. Safe and portable.
    63  * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable).
    64  *            This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.
    65  * Method 2 : direct access. This method is portable but violate C standard.
    66  *            It can generate buggy code on targets which assembly generation depends on alignment.
    67  *            But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6)
    68  * See https://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details.
    69  * Prefer these methods in priority order (0 > 1 > 2)
    70  */
    71 #ifndef LZ4_FORCE_MEMORY_ACCESS   /* can be defined externally */
    72 #  if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )
    73 #    define LZ4_FORCE_MEMORY_ACCESS 2
    74 #  elif (defined(__INTEL_COMPILER) && !defined(_WIN32)) || defined(__GNUC__)
    75 #    define LZ4_FORCE_MEMORY_ACCESS 1
    76 #  endif
    77 #endif
    78 
    79 /*
    80  * LZ4_FORCE_SW_BITCOUNT
    81  * Define this parameter if your target system or compiler does not support hardware bit count
    82  */
    83 #if defined(_MSC_VER) && defined(_WIN32_WCE)   /* Visual Studio for Windows CE does not support Hardware bit count */
    84 #  define LZ4_FORCE_SW_BITCOUNT
    85 #endif
    86 
    87 
    88 
    89 /*-************************************
    90 *  Dependency
    91 **************************************/
    92 #include "lz4.h"
    93 /* see also "memory routines" below */
    94 
    95 
    96 /*-************************************
    97 *  Compiler Options
    98 **************************************/
    99 #ifdef _MSC_VER    /* Visual Studio */
   100 #  include <intrin.h>
   101 #  pragma warning(disable : 4127)        /* disable: C4127: conditional expression is constant */
   102 #  pragma warning(disable : 4293)        /* disable: C4293: too large shift (32-bits) */
   103 #endif  /* _MSC_VER */
   104 
   105 #ifndef LZ4_FORCE_INLINE
   106 #  ifdef _MSC_VER    /* Visual Studio */
   107 #    define LZ4_FORCE_INLINE static __forceinline
   108 #  else
   109 #    if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L   /* C99 */
   110 #      ifdef __GNUC__
   111 #        define LZ4_FORCE_INLINE static inline __attribute__((always_inline))
   112 #      else
   113 #        define LZ4_FORCE_INLINE static inline
   114 #      endif
   115 #    else
   116 #      define LZ4_FORCE_INLINE static
   117 #    endif /* __STDC_VERSION__ */
   118 #  endif  /* _MSC_VER */
   119 #endif /* LZ4_FORCE_INLINE */
   120 
   121 /* LZ4_FORCE_O2_GCC_PPC64LE and LZ4_FORCE_O2_INLINE_GCC_PPC64LE
   122  * Gcc on ppc64le generates an unrolled SIMDized loop for LZ4_wildCopy,
   123  * together with a simple 8-byte copy loop as a fall-back path.
   124  * However, this optimization hurts the decompression speed by >30%,
   125  * because the execution does not go to the optimized loop
   126  * for typical compressible data, and all of the preamble checks
   127  * before going to the fall-back path become useless overhead.
   128  * This optimization happens only with the -O3 flag, and -O2 generates
   129  * a simple 8-byte copy loop.
   130  * With gcc on ppc64le, all of the LZ4_decompress_* and LZ4_wildCopy
   131  * functions are annotated with __attribute__((optimize("O2"))),
   132  * and also LZ4_wildCopy is forcibly inlined, so that the O2 attribute
   133  * of LZ4_wildCopy does not affect the compression speed.
   134  */
   135 #if defined(__PPC64__) && defined(__LITTLE_ENDIAN__) && defined(__GNUC__)
   136 #  define LZ4_FORCE_O2_GCC_PPC64LE __attribute__((optimize("O2")))
   137 #  define LZ4_FORCE_O2_INLINE_GCC_PPC64LE __attribute__((optimize("O2"))) LZ4_FORCE_INLINE
   138 #else
   139 #  define LZ4_FORCE_O2_GCC_PPC64LE
   140 #  define LZ4_FORCE_O2_INLINE_GCC_PPC64LE static
   141 #endif
   142 
   143 #if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__)
   144 #  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
   145 #else
   146 #  define expect(expr,value)    (expr)
   147 #endif
   148 
   149 #define likely(expr)     expect((expr) != 0, 1)
   150 #define unlikely(expr)   expect((expr) != 0, 0)
   151 
   152 
   153 /*-************************************
   154 *  Memory routines
   155 **************************************/
   156 #include <stdlib.h>   /* malloc, calloc, free */
   157 #define ALLOCATOR(n,s) calloc(n,s)
   158 #define FREEMEM        free
   159 #include <string.h>   /* memset, memcpy */
   160 #define MEM_INIT       memset
   161 
   162 
   163 /*-************************************
   164 *  Basic Types
   165 **************************************/
   166 #if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
   167 # include <stdint.h>
   168   typedef  uint8_t BYTE;
   169   typedef uint16_t U16;
   170   typedef uint32_t U32;
   171   typedef  int32_t S32;
   172   typedef uint64_t U64;
   173   typedef uintptr_t uptrval;
   174 #else
   175   typedef unsigned char       BYTE;
   176   typedef unsigned short      U16;
   177   typedef unsigned int        U32;
   178   typedef   signed int        S32;
   179   typedef unsigned long long  U64;
   180   typedef size_t              uptrval;   /* generally true, except OpenVMS-64 */
   181 #endif
   182 
   183 #if defined(__x86_64__)
   184   typedef U64    reg_t;   /* 64-bits in x32 mode */
   185 #else
   186   typedef size_t reg_t;   /* 32-bits in x32 mode */
   187 #endif
   188 
   189 /*-************************************
   190 *  Reading and writing into memory
   191 **************************************/
   192 static unsigned LZ4_isLittleEndian(void)
   193 {
   194     const union { U32 u; BYTE c[4]; } one = { 1 };   /* don't use static : performance detrimental */
   195     return one.c[0];
   196 }
   197 
   198 
   199 #if defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS==2)
   200 /* lie to the compiler about data alignment; use with caution */
   201 
   202 static U16 LZ4_read16(const void* memPtr) { return *(const U16*) memPtr; }
   203 static U32 LZ4_read32(const void* memPtr) { return *(const U32*) memPtr; }
   204 static reg_t LZ4_read_ARCH(const void* memPtr) { return *(const reg_t*) memPtr; }
   205 
   206 static void LZ4_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; }
   207 static void LZ4_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; }
   208 
   209 #elif defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS==1)
   210 
   211 /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
   212 /* currently only defined for gcc and icc */
   213 typedef union { U16 u16; U32 u32; reg_t uArch; } __attribute__((packed)) unalign;
   214 
   215 static U16 LZ4_read16(const void* ptr) { return ((const unalign*)ptr)->u16; }
   216 static U32 LZ4_read32(const void* ptr) { return ((const unalign*)ptr)->u32; }
   217 static reg_t LZ4_read_ARCH(const void* ptr) { return ((const unalign*)ptr)->uArch; }
   218 
   219 static void LZ4_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u16 = value; }
   220 static void LZ4_write32(void* memPtr, U32 value) { ((unalign*)memPtr)->u32 = value; }
   221 
   222 #else  /* safe and portable access through memcpy() */
   223 
   224 static U16 LZ4_read16(const void* memPtr)
   225 {
   226     U16 val; memcpy(&val, memPtr, sizeof(val)); return val;
   227 }
   228 
   229 static U32 LZ4_read32(const void* memPtr)
   230 {
   231     U32 val; memcpy(&val, memPtr, sizeof(val)); return val;
   232 }
   233 
   234 static reg_t LZ4_read_ARCH(const void* memPtr)
   235 {
   236     reg_t val; memcpy(&val, memPtr, sizeof(val)); return val;
   237 }
   238 
   239 static void LZ4_write16(void* memPtr, U16 value)
   240 {
   241     memcpy(memPtr, &value, sizeof(value));
   242 }
   243 
   244 static void LZ4_write32(void* memPtr, U32 value)
   245 {
   246     memcpy(memPtr, &value, sizeof(value));
   247 }
   248 
   249 #endif /* LZ4_FORCE_MEMORY_ACCESS */
   250 
   251 
   252 static U16 LZ4_readLE16(const void* memPtr)
   253 {
   254     if (LZ4_isLittleEndian()) {
   255         return LZ4_read16(memPtr);
   256     } else {
   257         const BYTE* p = (const BYTE*)memPtr;
   258         return (U16)((U16)p[0] + (p[1]<<8));
   259     }
   260 }
   261 
   262 static void LZ4_writeLE16(void* memPtr, U16 value)
   263 {
   264     if (LZ4_isLittleEndian()) {
   265         LZ4_write16(memPtr, value);
   266     } else {
   267         BYTE* p = (BYTE*)memPtr;
   268         p[0] = (BYTE) value;
   269         p[1] = (BYTE)(value>>8);
   270     }
   271 }
   272 
   273 /* customized variant of memcpy, which can overwrite up to 8 bytes beyond dstEnd */
   274 LZ4_FORCE_O2_INLINE_GCC_PPC64LE
   275 void LZ4_wildCopy(void* dstPtr, const void* srcPtr, void* dstEnd)
   276 {
   277     BYTE* d = (BYTE*)dstPtr;
   278     const BYTE* s = (const BYTE*)srcPtr;
   279     BYTE* const e = (BYTE*)dstEnd;
   280 
   281     do { memcpy(d,s,8); d+=8; s+=8; } while (d<e);
   282 }
   283 
   284 
   285 /*-************************************
   286 *  Common Constants
   287 **************************************/
   288 #define MINMATCH 4
   289 
   290 #define WILDCOPYLENGTH 8
   291 #define LASTLITERALS 5
   292 #define MFLIMIT (WILDCOPYLENGTH+MINMATCH)
   293 static const int LZ4_minLength = (MFLIMIT+1);
   294 
   295 #define KB *(1 <<10)
   296 #define MB *(1 <<20)
   297 #define GB *(1U<<30)
   298 
   299 #define MAXD_LOG 16
   300 #define MAX_DISTANCE ((1 << MAXD_LOG) - 1)
   301 
   302 #define ML_BITS  4
   303 #define ML_MASK  ((1U<<ML_BITS)-1)
   304 #define RUN_BITS (8-ML_BITS)
   305 #define RUN_MASK ((1U<<RUN_BITS)-1)
   306 
   307 
   308 /*-************************************
   309 *  Error detection
   310 **************************************/
   311 #if defined(LZ4_DEBUG) && (LZ4_DEBUG>=1)
   312 #  include <assert.h>
   313 #else
   314 #  ifndef assert
   315 #    define assert(condition) ((void)0)
   316 #  endif
   317 #endif
   318 
   319 #define LZ4_STATIC_ASSERT(c)   { enum { LZ4_static_assert = 1/(int)(!!(c)) }; }   /* use only *after* variable declarations */
   320 
   321 #if defined(LZ4_DEBUG) && (LZ4_DEBUG>=2)
   322 #  include <stdio.h>
   323 static int g_debuglog_enable = 1;
   324 #  define DEBUGLOG(l, ...) {                                  \
   325                 if ((g_debuglog_enable) && (l<=LZ4_DEBUG)) {  \
   326                     fprintf(stderr, __FILE__ ": ");           \
   327                     fprintf(stderr, __VA_ARGS__);             \
   328                     fprintf(stderr, " \n");                   \
   329             }   }
   330 #else
   331 #  define DEBUGLOG(l, ...)      {}    /* disabled */
   332 #endif
   333 
   334 
   335 /*-************************************
   336 *  Common functions
   337 **************************************/
   338 static unsigned LZ4_NbCommonBytes (reg_t val)
   339 {
   340     if (LZ4_isLittleEndian()) {
   341         if (sizeof(val)==8) {
   342 #       if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT)
   343             unsigned long r = 0;
   344             _BitScanForward64( &r, (U64)val );
   345             return (int)(r>>3);
   346 #       elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT)
   347             return (__builtin_ctzll((U64)val) >> 3);
   348 #       else
   349             static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2,
   350                                                      0, 3, 1, 3, 1, 4, 2, 7,
   351                                                      0, 2, 3, 6, 1, 5, 3, 5,
   352                                                      1, 3, 4, 4, 2, 5, 6, 7,
   353                                                      7, 0, 1, 2, 3, 3, 4, 6,
   354                                                      2, 6, 5, 5, 3, 4, 5, 6,
   355                                                      7, 1, 2, 4, 6, 4, 4, 5,
   356                                                      7, 2, 6, 5, 7, 6, 7, 7 };
   357             return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];
   358 #       endif
   359         } else /* 32 bits */ {
   360 #       if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
   361             unsigned long r;
   362             _BitScanForward( &r, (U32)val );
   363             return (int)(r>>3);
   364 #       elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT)
   365             return (__builtin_ctz((U32)val) >> 3);
   366 #       else
   367             static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0,
   368                                                      3, 2, 2, 1, 3, 2, 0, 1,
   369                                                      3, 3, 1, 2, 2, 2, 2, 0,
   370                                                      3, 1, 2, 0, 1, 0, 1, 1 };
   371             return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
   372 #       endif
   373         }
   374     } else   /* Big Endian CPU */ {
   375         if (sizeof(val)==8) {   /* 64-bits */
   376 #       if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT)
   377             unsigned long r = 0;
   378             _BitScanReverse64( &r, val );
   379             return (unsigned)(r>>3);
   380 #       elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT)
   381             return (__builtin_clzll((U64)val) >> 3);
   382 #       else
   383             static const U32 by32 = sizeof(val)*4;  /* 32 on 64 bits (goal), 16 on 32 bits.
   384                 Just to avoid some static analyzer complaining about shift by 32 on 32-bits target.
   385                 Note that this code path is never triggered in 32-bits mode. */
   386             unsigned r;
   387             if (!(val>>by32)) { r=4; } else { r=0; val>>=by32; }
   388             if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
   389             r += (!val);
   390             return r;
   391 #       endif
   392         } else /* 32 bits */ {
   393 #       if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
   394             unsigned long r = 0;
   395             _BitScanReverse( &r, (unsigned long)val );
   396             return (unsigned)(r>>3);
   397 #       elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT)
   398             return (__builtin_clz((U32)val) >> 3);
   399 #       else
   400             unsigned r;
   401             if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
   402             r += (!val);
   403             return r;
   404 #       endif
   405         }
   406     }
   407 }
   408 
   409 #define STEPSIZE sizeof(reg_t)
   410 LZ4_FORCE_INLINE
   411 unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLimit)
   412 {
   413     const BYTE* const pStart = pIn;
   414 
   415     if (likely(pIn < pInLimit-(STEPSIZE-1))) {
   416         reg_t const diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn);
   417         if (!diff) {
   418             pIn+=STEPSIZE; pMatch+=STEPSIZE;
   419         } else {
   420             return LZ4_NbCommonBytes(diff);
   421     }   }
   422 
   423     while (likely(pIn < pInLimit-(STEPSIZE-1))) {
   424         reg_t const diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn);
   425         if (!diff) { pIn+=STEPSIZE; pMatch+=STEPSIZE; continue; }
   426         pIn += LZ4_NbCommonBytes(diff);
   427         return (unsigned)(pIn - pStart);
   428     }
   429 
   430     if ((STEPSIZE==8) && (pIn<(pInLimit-3)) && (LZ4_read32(pMatch) == LZ4_read32(pIn))) { pIn+=4; pMatch+=4; }
   431     if ((pIn<(pInLimit-1)) && (LZ4_read16(pMatch) == LZ4_read16(pIn))) { pIn+=2; pMatch+=2; }
   432     if ((pIn<pInLimit) && (*pMatch == *pIn)) pIn++;
   433     return (unsigned)(pIn - pStart);
   434 }
   435 
   436 
   437 #ifndef LZ4_COMMONDEFS_ONLY
   438 /*-************************************
   439 *  Local Constants
   440 **************************************/
   441 static const int LZ4_64Klimit = ((64 KB) + (MFLIMIT-1));
   442 static const U32 LZ4_skipTrigger = 6;  /* Increase this value ==> compression run slower on incompressible data */
   443 
   444 
   445 /*-************************************
   446 *  Local Structures and types
   447 **************************************/
   448 typedef enum { notLimited = 0, limitedOutput = 1 } limitedOutput_directive;
   449 typedef enum { byPtr, byU32, byU16 } tableType_t;
   450 
   451 typedef enum { noDict = 0, withPrefix64k, usingExtDict } dict_directive;
   452 typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive;
   453 
   454 typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive;
   455 typedef enum { full = 0, partial = 1 } earlyEnd_directive;
   456 
   457 
   458 /*-************************************
   459 *  Local Utils
   460 **************************************/
   461 int LZ4_versionNumber (void) { return LZ4_VERSION_NUMBER; }
   462 const char* LZ4_versionString(void) { return LZ4_VERSION_STRING; }
   463 int LZ4_compressBound(int isize)  { return LZ4_COMPRESSBOUND(isize); }
   464 int LZ4_sizeofState() { return LZ4_STREAMSIZE; }
   465 
   466 
   467 /*-******************************
   468 *  Compression functions
   469 ********************************/
   470 static U32 LZ4_hash4(U32 sequence, tableType_t const tableType)
   471 {
   472     if (tableType == byU16)
   473         return ((sequence * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1)));
   474     else
   475         return ((sequence * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG));
   476 }
   477 
   478 static U32 LZ4_hash5(U64 sequence, tableType_t const tableType)
   479 {
   480     static const U64 prime5bytes = 889523592379ULL;
   481     static const U64 prime8bytes = 11400714785074694791ULL;
   482     const U32 hashLog = (tableType == byU16) ? LZ4_HASHLOG+1 : LZ4_HASHLOG;
   483     if (LZ4_isLittleEndian())
   484         return (U32)(((sequence << 24) * prime5bytes) >> (64 - hashLog));
   485     else
   486         return (U32)(((sequence >> 24) * prime8bytes) >> (64 - hashLog));
   487 }
   488 
   489 LZ4_FORCE_INLINE U32 LZ4_hashPosition(const void* const p, tableType_t const tableType)
   490 {
   491     if ((sizeof(reg_t)==8) && (tableType != byU16)) return LZ4_hash5(LZ4_read_ARCH(p), tableType);
   492     return LZ4_hash4(LZ4_read32(p), tableType);
   493 }
   494 
   495 static void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableType_t const tableType, const BYTE* srcBase)
   496 {
   497     switch (tableType)
   498     {
   499     case byPtr: { const BYTE** hashTable = (const BYTE**)tableBase; hashTable[h] = p; return; }
   500     case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = (U32)(p-srcBase); return; }
   501     case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = (U16)(p-srcBase); return; }
   502     }
   503 }
   504 
   505 LZ4_FORCE_INLINE void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase)
   506 {
   507     U32 const h = LZ4_hashPosition(p, tableType);
   508     LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase);
   509 }
   510 
   511 static const BYTE* LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase)
   512 {
   513     if (tableType == byPtr) { const BYTE** hashTable = (const BYTE**) tableBase; return hashTable[h]; }
   514     if (tableType == byU32) { const U32* const hashTable = (U32*) tableBase; return hashTable[h] + srcBase; }
   515     { const U16* const hashTable = (U16*) tableBase; return hashTable[h] + srcBase; }   /* default, to ensure a return */
   516 }
   517 
   518 LZ4_FORCE_INLINE const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase)
   519 {
   520     U32 const h = LZ4_hashPosition(p, tableType);
   521     return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase);
   522 }
   523 
   524 
   525 /** LZ4_compress_generic() :
   526     inlined, to ensure branches are decided at compilation time */
   527 LZ4_FORCE_INLINE int LZ4_compress_generic(
   528                  LZ4_stream_t_internal* const cctx,
   529                  const char* const source,
   530                  char* const dest,
   531                  const int inputSize,
   532                  const int maxOutputSize,
   533                  const limitedOutput_directive outputLimited,
   534                  const tableType_t tableType,
   535                  const dict_directive dict,
   536                  const dictIssue_directive dictIssue,
   537                  const U32 acceleration)
   538 {
   539     const BYTE* ip = (const BYTE*) source;
   540     const BYTE* base;
   541     const BYTE* lowLimit;
   542     const BYTE* const lowRefLimit = ip - cctx->dictSize;
   543     const BYTE* const dictionary = cctx->dictionary;
   544     const BYTE* const dictEnd = dictionary + cctx->dictSize;
   545     const ptrdiff_t dictDelta = dictEnd - (const BYTE*)source;
   546     const BYTE* anchor = (const BYTE*) source;
   547     const BYTE* const iend = ip + inputSize;
   548     const BYTE* const mflimitPlusOne = iend - MFLIMIT + 1;
   549     const BYTE* const matchlimit = iend - LASTLITERALS;
   550 
   551     BYTE* op = (BYTE*) dest;
   552     BYTE* const olimit = op + maxOutputSize;
   553 
   554     U32 forwardH;
   555 
   556     /* Init conditions */
   557     if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0;   /* Unsupported inputSize, too large (or negative) */
   558     switch(dict)
   559     {
   560     case noDict:
   561     default:
   562         base = (const BYTE*)source;
   563         lowLimit = (const BYTE*)source;
   564         break;
   565     case withPrefix64k:
   566         base = (const BYTE*)source - cctx->currentOffset;
   567         lowLimit = (const BYTE*)source - cctx->dictSize;
   568         break;
   569     case usingExtDict:
   570         base = (const BYTE*)source - cctx->currentOffset;
   571         lowLimit = (const BYTE*)source;
   572         break;
   573     }
   574     if ((tableType == byU16) && (inputSize>=LZ4_64Klimit)) return 0;   /* Size too large (not within 64K limit) */
   575     if (inputSize<LZ4_minLength) goto _last_literals;                  /* Input too small, no compression (all literals) */
   576 
   577     /* First Byte */
   578     LZ4_putPosition(ip, cctx->hashTable, tableType, base);
   579     ip++; forwardH = LZ4_hashPosition(ip, tableType);
   580 
   581     /* Main Loop */
   582     for ( ; ; ) {
   583         ptrdiff_t refDelta = 0;
   584         const BYTE* match;
   585         BYTE* token;
   586 
   587         /* Find a match */
   588         {   const BYTE* forwardIp = ip;
   589             unsigned step = 1;
   590             unsigned searchMatchNb = acceleration << LZ4_skipTrigger;
   591             do {
   592                 U32 const h = forwardH;
   593                 ip = forwardIp;
   594                 forwardIp += step;
   595                 step = (searchMatchNb++ >> LZ4_skipTrigger);
   596 
   597                 if (unlikely(forwardIp > mflimitPlusOne)) goto _last_literals;
   598                 assert(ip < mflimitPlusOne);
   599 
   600                 match = LZ4_getPositionOnHash(h, cctx->hashTable, tableType, base);
   601                 if (dict==usingExtDict) {
   602                     if (match < (const BYTE*)source) {
   603                         refDelta = dictDelta;
   604                         lowLimit = dictionary;
   605                     } else {
   606                         refDelta = 0;
   607                         lowLimit = (const BYTE*)source;
   608                 }   }
   609                 forwardH = LZ4_hashPosition(forwardIp, tableType);
   610                 LZ4_putPositionOnHash(ip, h, cctx->hashTable, tableType, base);
   611 
   612             } while ( ((dictIssue==dictSmall) ? (match < lowRefLimit) : 0)
   613                 || ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip))
   614                 || (LZ4_read32(match+refDelta) != LZ4_read32(ip)) );
   615         }
   616 
   617         /* Catch up */
   618         while (((ip>anchor) & (match+refDelta > lowLimit)) && (unlikely(ip[-1]==match[refDelta-1]))) { ip--; match--; }
   619 
   620         /* Encode Literals */
   621         {   unsigned const litLength = (unsigned)(ip - anchor);
   622             token = op++;
   623             if ((outputLimited) &&  /* Check output buffer overflow */
   624                 (unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit)))
   625                 return 0;
   626             if (litLength >= RUN_MASK) {
   627                 int len = (int)litLength-RUN_MASK;
   628                 *token = (RUN_MASK<<ML_BITS);
   629                 for(; len >= 255 ; len-=255) *op++ = 255;
   630                 *op++ = (BYTE)len;
   631             }
   632             else *token = (BYTE)(litLength<<ML_BITS);
   633 
   634             /* Copy Literals */
   635             LZ4_wildCopy(op, anchor, op+litLength);
   636             op+=litLength;
   637         }
   638 
   639 _next_match:
   640         /* Encode Offset */
   641         LZ4_writeLE16(op, (U16)(ip-match)); op+=2;
   642 
   643         /* Encode MatchLength */
   644         {   unsigned matchCode;
   645 
   646             if ((dict==usingExtDict) && (lowLimit==dictionary)) {
   647                 const BYTE* limit;
   648                 match += refDelta;
   649                 limit = ip + (dictEnd-match);
   650                 if (limit > matchlimit) limit = matchlimit;
   651                 matchCode = LZ4_count(ip+MINMATCH, match+MINMATCH, limit);
   652                 ip += MINMATCH + matchCode;
   653                 if (ip==limit) {
   654                     unsigned const more = LZ4_count(ip, (const BYTE*)source, matchlimit);
   655                     matchCode += more;
   656                     ip += more;
   657                 }
   658             } else {
   659                 matchCode = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit);
   660                 ip += MINMATCH + matchCode;
   661             }
   662 
   663             if ( outputLimited &&    /* Check output buffer overflow */
   664                 (unlikely(op + (1 + LASTLITERALS) + (matchCode>>8) > olimit)) )
   665                 return 0;
   666             if (matchCode >= ML_MASK) {
   667                 *token += ML_MASK;
   668                 matchCode -= ML_MASK;
   669                 LZ4_write32(op, 0xFFFFFFFF);
   670                 while (matchCode >= 4*255) {
   671                     op+=4;
   672                     LZ4_write32(op, 0xFFFFFFFF);
   673                     matchCode -= 4*255;
   674                 }
   675                 op += matchCode / 255;
   676                 *op++ = (BYTE)(matchCode % 255);
   677             } else
   678                 *token += (BYTE)(matchCode);
   679         }
   680 
   681         anchor = ip;
   682 
   683         /* Test end of chunk */
   684         if (ip >= mflimitPlusOne) break;
   685 
   686         /* Fill table */
   687         LZ4_putPosition(ip-2, cctx->hashTable, tableType, base);
   688 
   689         /* Test next position */
   690         match = LZ4_getPosition(ip, cctx->hashTable, tableType, base);
   691         if (dict==usingExtDict) {
   692             if (match < (const BYTE*)source) {
   693                 refDelta = dictDelta;
   694                 lowLimit = dictionary;
   695             } else {
   696                 refDelta = 0;
   697                 lowLimit = (const BYTE*)source;
   698         }   }
   699         LZ4_putPosition(ip, cctx->hashTable, tableType, base);
   700         if ( ((dictIssue==dictSmall) ? (match>=lowRefLimit) : 1)
   701             && (match+MAX_DISTANCE>=ip)
   702             && (LZ4_read32(match+refDelta)==LZ4_read32(ip)) )
   703         { token=op++; *token=0; goto _next_match; }
   704 
   705         /* Prepare next loop */
   706         forwardH = LZ4_hashPosition(++ip, tableType);
   707     }
   708 
   709 _last_literals:
   710     /* Encode Last Literals */
   711     {   size_t const lastRun = (size_t)(iend - anchor);
   712         if ( (outputLimited) &&  /* Check output buffer overflow */
   713             ((op - (BYTE*)dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize) )
   714             return 0;
   715         if (lastRun >= RUN_MASK) {
   716             size_t accumulator = lastRun - RUN_MASK;
   717             *op++ = RUN_MASK << ML_BITS;
   718             for(; accumulator >= 255 ; accumulator-=255) *op++ = 255;
   719             *op++ = (BYTE) accumulator;
   720         } else {
   721             *op++ = (BYTE)(lastRun<<ML_BITS);
   722         }
   723         memcpy(op, anchor, lastRun);
   724         op += lastRun;
   725     }
   726 
   727     /* End */
   728     return (int) (((char*)op)-dest);
   729 }
   730 
   731 
   732 int LZ4_compress_fast_extState(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
   733 {
   734     LZ4_stream_t_internal* ctx = &((LZ4_stream_t*)state)->internal_donotuse;
   735     LZ4_resetStream((LZ4_stream_t*)state);
   736     if (acceleration < 1) acceleration = ACCELERATION_DEFAULT;
   737 
   738     if (maxOutputSize >= LZ4_compressBound(inputSize)) {
   739         if (inputSize < LZ4_64Klimit)
   740             return LZ4_compress_generic(ctx, source, dest, inputSize,             0,    notLimited,                        byU16, noDict, noDictIssue, acceleration);
   741         else
   742             return LZ4_compress_generic(ctx, source, dest, inputSize,             0,    notLimited, (sizeof(void*)==8) ? byU32 : byPtr, noDict, noDictIssue, acceleration);
   743     } else {
   744         if (inputSize < LZ4_64Klimit)
   745             return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput,                        byU16, noDict, noDictIssue, acceleration);
   746         else
   747             return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, (sizeof(void*)==8) ? byU32 : byPtr, noDict, noDictIssue, acceleration);
   748     }
   749 }
   750 
   751 
   752 int LZ4_compress_fast(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
   753 {
   754 #if (LZ4_HEAPMODE)
   755     void* ctxPtr = ALLOCATOR(1, sizeof(LZ4_stream_t));   /* malloc-calloc always properly aligned */
   756 #else
   757     LZ4_stream_t ctx;
   758     void* const ctxPtr = &ctx;
   759 #endif
   760 
   761     int const result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, maxOutputSize, acceleration);
   762 
   763 #if (LZ4_HEAPMODE)
   764     FREEMEM(ctxPtr);
   765 #endif
   766     return result;
   767 }
   768 
   769 
   770 int LZ4_compress_default(const char* source, char* dest, int inputSize, int maxOutputSize)
   771 {
   772     return LZ4_compress_fast(source, dest, inputSize, maxOutputSize, 1);
   773 }
   774 
   775 
   776 /* hidden debug function */
   777 /* strangely enough, gcc generates faster code when this function is uncommented, even if unused */
   778 int LZ4_compress_fast_force(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
   779 {
   780     LZ4_stream_t ctx;
   781     LZ4_resetStream(&ctx);
   782 
   783     if (inputSize < LZ4_64Klimit)
   784         return LZ4_compress_generic(&ctx.internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, byU16,                        noDict, noDictIssue, acceleration);
   785     else
   786         return LZ4_compress_generic(&ctx.internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, sizeof(void*)==8 ? byU32 : byPtr, noDict, noDictIssue, acceleration);
   787 }
   788 
   789 
   790 /*-******************************
   791 *  *_destSize() variant
   792 ********************************/
   793 
   794 static int LZ4_compress_destSize_generic(
   795                        LZ4_stream_t_internal* const ctx,
   796                  const char* const src,
   797                        char* const dst,
   798                        int*  const srcSizePtr,
   799                  const int targetDstSize,
   800                  const tableType_t tableType)
   801 {
   802     const BYTE* ip = (const BYTE*) src;
   803     const BYTE* base = (const BYTE*) src;
   804     const BYTE* lowLimit = (const BYTE*) src;
   805     const BYTE* anchor = ip;
   806     const BYTE* const iend = ip + *srcSizePtr;
   807     const BYTE* const mflimit = iend - MFLIMIT;
   808     const BYTE* const matchlimit = iend - LASTLITERALS;
   809 
   810     BYTE* op = (BYTE*) dst;
   811     BYTE* const oend = op + targetDstSize;
   812     BYTE* const oMaxLit = op + targetDstSize - 2 /* offset */ - 8 /* because 8+MINMATCH==MFLIMIT */ - 1 /* token */;
   813     BYTE* const oMaxMatch = op + targetDstSize - (LASTLITERALS + 1 /* token */);
   814     BYTE* const oMaxSeq = oMaxLit - 1 /* token */;
   815 
   816     U32 forwardH;
   817 
   818 
   819     /* Init conditions */
   820     if (targetDstSize < 1) return 0;                                     /* Impossible to store anything */
   821     if ((U32)*srcSizePtr > (U32)LZ4_MAX_INPUT_SIZE) return 0;            /* Unsupported input size, too large (or negative) */
   822     if ((tableType == byU16) && (*srcSizePtr>=LZ4_64Klimit)) return 0;   /* Size too large (not within 64K limit) */
   823     if (*srcSizePtr<LZ4_minLength) goto _last_literals;                  /* Input too small, no compression (all literals) */
   824 
   825     /* First Byte */
   826     *srcSizePtr = 0;
   827     LZ4_putPosition(ip, ctx->hashTable, tableType, base);
   828     ip++; forwardH = LZ4_hashPosition(ip, tableType);
   829 
   830     /* Main Loop */
   831     for ( ; ; ) {
   832         const BYTE* match;
   833         BYTE* token;
   834 
   835         /* Find a match */
   836         {   const BYTE* forwardIp = ip;
   837             unsigned step = 1;
   838             unsigned searchMatchNb = 1 << LZ4_skipTrigger;
   839 
   840             do {
   841                 U32 h = forwardH;
   842                 ip = forwardIp;
   843                 forwardIp += step;
   844                 step = (searchMatchNb++ >> LZ4_skipTrigger);
   845 
   846                 if (unlikely(forwardIp > mflimit)) goto _last_literals;
   847 
   848                 match = LZ4_getPositionOnHash(h, ctx->hashTable, tableType, base);
   849                 forwardH = LZ4_hashPosition(forwardIp, tableType);
   850                 LZ4_putPositionOnHash(ip, h, ctx->hashTable, tableType, base);
   851 
   852             } while ( ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip))
   853                 || (LZ4_read32(match) != LZ4_read32(ip)) );
   854         }
   855 
   856         /* Catch up */
   857         while ((ip>anchor) && (match > lowLimit) && (unlikely(ip[-1]==match[-1]))) { ip--; match--; }
   858 
   859         /* Encode Literal length */
   860         {   unsigned litLength = (unsigned)(ip - anchor);
   861             token = op++;
   862             if (op + ((litLength+240)/255) + litLength > oMaxLit) {
   863                 /* Not enough space for a last match */
   864                 op--;
   865                 goto _last_literals;
   866             }
   867             if (litLength>=RUN_MASK) {
   868                 unsigned len = litLength - RUN_MASK;
   869                 *token=(RUN_MASK<<ML_BITS);
   870                 for(; len >= 255 ; len-=255) *op++ = 255;
   871                 *op++ = (BYTE)len;
   872             }
   873             else *token = (BYTE)(litLength<<ML_BITS);
   874 
   875             /* Copy Literals */
   876             LZ4_wildCopy(op, anchor, op+litLength);
   877             op += litLength;
   878         }
   879 
   880 _next_match:
   881         /* Encode Offset */
   882         LZ4_writeLE16(op, (U16)(ip-match)); op+=2;
   883 
   884         /* Encode MatchLength */
   885         {   size_t matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit);
   886 
   887             if (op + ((matchLength+240)/255) > oMaxMatch) {
   888                 /* Match description too long : reduce it */
   889                 matchLength = (15-1) + (oMaxMatch-op) * 255;
   890             }
   891             ip += MINMATCH + matchLength;
   892 
   893             if (matchLength>=ML_MASK) {
   894                 *token += ML_MASK;
   895                 matchLength -= ML_MASK;
   896                 while (matchLength >= 255) { matchLength-=255; *op++ = 255; }
   897                 *op++ = (BYTE)matchLength;
   898             }
   899             else *token += (BYTE)(matchLength);
   900         }
   901 
   902         anchor = ip;
   903 
   904         /* Test end of block */
   905         if (ip > mflimit) break;
   906         if (op > oMaxSeq) break;
   907 
   908         /* Fill table */
   909         LZ4_putPosition(ip-2, ctx->hashTable, tableType, base);
   910 
   911         /* Test next position */
   912         match = LZ4_getPosition(ip, ctx->hashTable, tableType, base);
   913         LZ4_putPosition(ip, ctx->hashTable, tableType, base);
   914         if ( (match+MAX_DISTANCE>=ip)
   915             && (LZ4_read32(match)==LZ4_read32(ip)) )
   916         { token=op++; *token=0; goto _next_match; }
   917 
   918         /* Prepare next loop */
   919         forwardH = LZ4_hashPosition(++ip, tableType);
   920     }
   921 
   922 _last_literals:
   923     /* Encode Last Literals */
   924     {   size_t lastRunSize = (size_t)(iend - anchor);
   925         if (op + 1 /* token */ + ((lastRunSize+240)/255) /* litLength */ + lastRunSize /* literals */ > oend) {
   926             /* adapt lastRunSize to fill 'dst' */
   927             lastRunSize  = (oend-op) - 1;
   928             lastRunSize -= (lastRunSize+240)/255;
   929         }
   930         ip = anchor + lastRunSize;
   931 
   932         if (lastRunSize >= RUN_MASK) {
   933             size_t accumulator = lastRunSize - RUN_MASK;
   934             *op++ = RUN_MASK << ML_BITS;
   935             for(; accumulator >= 255 ; accumulator-=255) *op++ = 255;
   936             *op++ = (BYTE) accumulator;
   937         } else {
   938             *op++ = (BYTE)(lastRunSize<<ML_BITS);
   939         }
   940         memcpy(op, anchor, lastRunSize);
   941         op += lastRunSize;
   942     }
   943 
   944     /* End */
   945     *srcSizePtr = (int) (((const char*)ip)-src);
   946     return (int) (((char*)op)-dst);
   947 }
   948 
   949 
   950 static int LZ4_compress_destSize_extState (LZ4_stream_t* state, const char* src, char* dst, int* srcSizePtr, int targetDstSize)
   951 {
   952     LZ4_resetStream(state);
   953 
   954     if (targetDstSize >= LZ4_compressBound(*srcSizePtr)) {  /* compression success is guaranteed */
   955         return LZ4_compress_fast_extState(state, src, dst, *srcSizePtr, targetDstSize, 1);
   956     } else {
   957         if (*srcSizePtr < LZ4_64Klimit)
   958             return LZ4_compress_destSize_generic(&state->internal_donotuse, src, dst, srcSizePtr, targetDstSize, byU16);
   959         else
   960             return LZ4_compress_destSize_generic(&state->internal_donotuse, src, dst, srcSizePtr, targetDstSize, sizeof(void*)==8 ? byU32 : byPtr);
   961     }
   962 }
   963 
   964 
   965 int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targetDstSize)
   966 {
   967 #if (LZ4_HEAPMODE)
   968     LZ4_stream_t* ctx = (LZ4_stream_t*)ALLOCATOR(1, sizeof(LZ4_stream_t));   /* malloc-calloc always properly aligned */
   969 #else
   970     LZ4_stream_t ctxBody;
   971     LZ4_stream_t* ctx = &ctxBody;
   972 #endif
   973 
   974     int result = LZ4_compress_destSize_extState(ctx, src, dst, srcSizePtr, targetDstSize);
   975 
   976 #if (LZ4_HEAPMODE)
   977     FREEMEM(ctx);
   978 #endif
   979     return result;
   980 }
   981 
   982 
   983 
   984 /*-******************************
   985 *  Streaming functions
   986 ********************************/
   987 
   988 LZ4_stream_t* LZ4_createStream(void)
   989 {
   990     LZ4_stream_t* lz4s = (LZ4_stream_t*)ALLOCATOR(8, LZ4_STREAMSIZE_U64);
   991     LZ4_STATIC_ASSERT(LZ4_STREAMSIZE >= sizeof(LZ4_stream_t_internal));    /* A compilation error here means LZ4_STREAMSIZE is not large enough */
   992     LZ4_resetStream(lz4s);
   993     return lz4s;
   994 }
   995 
   996 void LZ4_resetStream (LZ4_stream_t* LZ4_stream)
   997 {
   998     DEBUGLOG(4, "LZ4_resetStream");
   999     MEM_INIT(LZ4_stream, 0, sizeof(LZ4_stream_t));
  1000 }
  1001 
  1002 int LZ4_freeStream (LZ4_stream_t* LZ4_stream)
  1003 {
  1004     if (!LZ4_stream) return 0;   /* support free on NULL */
  1005     FREEMEM(LZ4_stream);
  1006     return (0);
  1007 }
  1008 
  1009 
  1010 #define HASH_UNIT sizeof(reg_t)
  1011 int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize)
  1012 {
  1013     LZ4_stream_t_internal* dict = &LZ4_dict->internal_donotuse;
  1014     const BYTE* p = (const BYTE*)dictionary;
  1015     const BYTE* const dictEnd = p + dictSize;
  1016     const BYTE* base;
  1017 
  1018     if ((dict->initCheck) || (dict->currentOffset > 1 GB))  /* Uninitialized structure, or reuse overflow */
  1019         LZ4_resetStream(LZ4_dict);
  1020 
  1021     if (dictSize < (int)HASH_UNIT) {
  1022         dict->dictionary = NULL;
  1023         dict->dictSize = 0;
  1024         return 0;
  1025     }
  1026 
  1027     if ((dictEnd - p) > 64 KB) p = dictEnd - 64 KB;
  1028     dict->currentOffset += 64 KB;
  1029     base = p - dict->currentOffset;
  1030     dict->dictionary = p;
  1031     dict->dictSize = (U32)(dictEnd - p);
  1032     dict->currentOffset += dict->dictSize;
  1033 
  1034     while (p <= dictEnd-HASH_UNIT) {
  1035         LZ4_putPosition(p, dict->hashTable, byU32, base);
  1036         p+=3;
  1037     }
  1038 
  1039     return dict->dictSize;
  1040 }
  1041 
  1042 
  1043 static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, const BYTE* src)
  1044 {
  1045     if ((LZ4_dict->currentOffset > 0x80000000) ||
  1046         ((uptrval)LZ4_dict->currentOffset > (uptrval)src)) {   /* address space overflow */
  1047         /* rescale hash table */
  1048         U32 const delta = LZ4_dict->currentOffset - 64 KB;
  1049         const BYTE* dictEnd = LZ4_dict->dictionary + LZ4_dict->dictSize;
  1050         int i;
  1051         for (i=0; i<LZ4_HASH_SIZE_U32; i++) {
  1052             if (LZ4_dict->hashTable[i] < delta) LZ4_dict->hashTable[i]=0;
  1053             else LZ4_dict->hashTable[i] -= delta;
  1054         }
  1055         LZ4_dict->currentOffset = 64 KB;
  1056         if (LZ4_dict->dictSize > 64 KB) LZ4_dict->dictSize = 64 KB;
  1057         LZ4_dict->dictionary = dictEnd - LZ4_dict->dictSize;
  1058     }
  1059 }
  1060 
  1061 
  1062 int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
  1063 {
  1064     LZ4_stream_t_internal* streamPtr = &LZ4_stream->internal_donotuse;
  1065     const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize;
  1066 
  1067     const BYTE* smallest = (const BYTE*) source;
  1068     if (streamPtr->initCheck) return 0;   /* Uninitialized structure detected */
  1069     if ((streamPtr->dictSize>0) && (smallest>dictEnd)) smallest = dictEnd;
  1070     LZ4_renormDictT(streamPtr, smallest);
  1071     if (acceleration < 1) acceleration = ACCELERATION_DEFAULT;
  1072 
  1073     /* Check overlapping input/dictionary space */
  1074     {   const BYTE* sourceEnd = (const BYTE*) source + inputSize;
  1075         if ((sourceEnd > streamPtr->dictionary) && (sourceEnd < dictEnd)) {
  1076             streamPtr->dictSize = (U32)(dictEnd - sourceEnd);
  1077             if (streamPtr->dictSize > 64 KB) streamPtr->dictSize = 64 KB;
  1078             if (streamPtr->dictSize < 4) streamPtr->dictSize = 0;
  1079             streamPtr->dictionary = dictEnd - streamPtr->dictSize;
  1080         }
  1081     }
  1082 
  1083     /* prefix mode : source data follows dictionary */
  1084     if (dictEnd == (const BYTE*)source) {
  1085         int result;
  1086         if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset))
  1087             result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, dictSmall, acceleration);
  1088         else
  1089             result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, noDictIssue, acceleration);
  1090         streamPtr->dictSize += (U32)inputSize;
  1091         streamPtr->currentOffset += (U32)inputSize;
  1092         return result;
  1093     }
  1094 
  1095     /* external dictionary mode */
  1096     {   int result;
  1097         if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset))
  1098             result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, dictSmall, acceleration);
  1099         else
  1100             result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, noDictIssue, acceleration);
  1101         streamPtr->dictionary = (const BYTE*)source;
  1102         streamPtr->dictSize = (U32)inputSize;
  1103         streamPtr->currentOffset += (U32)inputSize;
  1104         return result;
  1105     }
  1106 }
  1107 
  1108 
  1109 /* Hidden debug function, to force external dictionary mode */
  1110 int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* dest, int inputSize)
  1111 {
  1112     LZ4_stream_t_internal* streamPtr = &LZ4_dict->internal_donotuse;
  1113     int result;
  1114     const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize;
  1115 
  1116     const BYTE* smallest = dictEnd;
  1117     if (smallest > (const BYTE*) source) smallest = (const BYTE*) source;
  1118     LZ4_renormDictT(streamPtr, smallest);
  1119 
  1120     result = LZ4_compress_generic(streamPtr, source, dest, inputSize, 0, notLimited, byU32, usingExtDict, noDictIssue, 1);
  1121 
  1122     streamPtr->dictionary = (const BYTE*)source;
  1123     streamPtr->dictSize = (U32)inputSize;
  1124     streamPtr->currentOffset += (U32)inputSize;
  1125 
  1126     return result;
  1127 }
  1128 
  1129 
  1130 /*! LZ4_saveDict() :
  1131  *  If previously compressed data block is not guaranteed to remain available at its memory location,
  1132  *  save it into a safer place (char* safeBuffer).
  1133  *  Note : you don't need to call LZ4_loadDict() afterwards,
  1134  *         dictionary is immediately usable, you can therefore call LZ4_compress_fast_continue().
  1135  *  Return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error.
  1136  */
  1137 int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize)
  1138 {
  1139     LZ4_stream_t_internal* const dict = &LZ4_dict->internal_donotuse;
  1140     const BYTE* const previousDictEnd = dict->dictionary + dict->dictSize;
  1141 
  1142     if ((U32)dictSize > 64 KB) dictSize = 64 KB;   /* useless to define a dictionary > 64 KB */
  1143     if ((U32)dictSize > dict->dictSize) dictSize = dict->dictSize;
  1144 
  1145     memmove(safeBuffer, previousDictEnd - dictSize, dictSize);
  1146 
  1147     dict->dictionary = (const BYTE*)safeBuffer;
  1148     dict->dictSize = (U32)dictSize;
  1149 
  1150     return dictSize;
  1151 }
  1152 
  1153 
  1154 
  1155 /*-*****************************
  1156 *  Decompression functions
  1157 *******************************/
  1158 /*! LZ4_decompress_generic() :
  1159  *  This generic decompression function covers all use cases.
  1160  *  It shall be instantiated several times, using different sets of directives.
  1161  *  Note that it is important for performance that this function really get inlined,
  1162  *  in order to remove useless branches during compilation optimization.
  1163  */
  1164 LZ4_FORCE_O2_GCC_PPC64LE
  1165 LZ4_FORCE_INLINE int LZ4_decompress_generic(
  1166                  const char* const src,
  1167                  char* const dst,
  1168                  int srcSize,
  1169                  int outputSize,         /* If endOnInput==endOnInputSize, this value is `dstCapacity` */
  1170 
  1171                  int endOnInput,         /* endOnOutputSize, endOnInputSize */
  1172                  int partialDecoding,    /* full, partial */
  1173                  int targetOutputSize,   /* only used if partialDecoding==partial */
  1174                  int dict,               /* noDict, withPrefix64k, usingExtDict */
  1175                  const BYTE* const lowPrefix,  /* always <= dst, == dst when no prefix */
  1176                  const BYTE* const dictStart,  /* only if dict==usingExtDict */
  1177                  const size_t dictSize         /* note : = 0 if noDict */
  1178                  )
  1179 {
  1180     const BYTE* ip = (const BYTE*) src;
  1181     const BYTE* const iend = ip + srcSize;
  1182 
  1183     BYTE* op = (BYTE*) dst;
  1184     BYTE* const oend = op + outputSize;
  1185     BYTE* cpy;
  1186     BYTE* oexit = op + targetOutputSize;
  1187 
  1188     const BYTE* const dictEnd = (const BYTE*)dictStart + dictSize;
  1189     const unsigned inc32table[8] = {0, 1, 2,  1,  0,  4, 4, 4};
  1190     const int      dec64table[8] = {0, 0, 0, -1, -4,  1, 2, 3};
  1191 
  1192     const int safeDecode = (endOnInput==endOnInputSize);
  1193     const int checkOffset = ((safeDecode) && (dictSize < (int)(64 KB)));
  1194 
  1195 
  1196     /* Special cases */
  1197     if ((partialDecoding) && (oexit > oend-MFLIMIT)) oexit = oend-MFLIMIT;                      /* targetOutputSize too high => just decode everything */
  1198     if ((endOnInput) && (unlikely(outputSize==0))) return ((srcSize==1) && (*ip==0)) ? 0 : -1;  /* Empty output buffer */
  1199     if ((!endOnInput) && (unlikely(outputSize==0))) return (*ip==0?1:-1);
  1200 
  1201     /* Main Loop : decode sequences */
  1202     while (1) {
  1203         size_t length;
  1204         const BYTE* match;
  1205         size_t offset;
  1206 
  1207         unsigned const token = *ip++;
  1208 
  1209         /* shortcut for common case :
  1210          * in most circumstances, we expect to decode small matches (<= 18 bytes) separated by few literals (<= 14 bytes).
  1211          * this shortcut was tested on x86 and x64, where it improves decoding speed.
  1212          * it has not yet been benchmarked on ARM, Power, mips, etc. */
  1213         if (((ip + 14 /*maxLL*/ + 2 /*offset*/ <= iend)
  1214           & (op + 14 /*maxLL*/ + 18 /*maxML*/ <= oend))
  1215           & ((token < (15<<ML_BITS)) & ((token & ML_MASK) != 15)) ) {
  1216             size_t const ll = token >> ML_BITS;
  1217             size_t const off = LZ4_readLE16(ip+ll);
  1218             const BYTE* const matchPtr = op + ll - off;  /* pointer underflow risk ? */
  1219             if ((off >= 8) /* do not deal with overlapping matches */ & (matchPtr >= lowPrefix)) {
  1220                 size_t const ml = (token & ML_MASK) + MINMATCH;
  1221                 memcpy(op, ip, 16); op += ll; ip += ll + 2 /*offset*/;
  1222                 memcpy(op + 0, matchPtr + 0, 8);
  1223                 memcpy(op + 8, matchPtr + 8, 8);
  1224                 memcpy(op +16, matchPtr +16, 2);
  1225                 op += ml;
  1226                 continue;
  1227             }
  1228         }
  1229 
  1230         /* decode literal length */
  1231         if ((length=(token>>ML_BITS)) == RUN_MASK) {
  1232             unsigned s;
  1233             do {
  1234                 s = *ip++;
  1235                 length += s;
  1236             } while ( likely(endOnInput ? ip<iend-RUN_MASK : 1) & (s==255) );
  1237             if ((safeDecode) && unlikely((uptrval)(op)+length<(uptrval)(op))) goto _output_error;   /* overflow detection */
  1238             if ((safeDecode) && unlikely((uptrval)(ip)+length<(uptrval)(ip))) goto _output_error;   /* overflow detection */
  1239         }
  1240 
  1241         /* copy literals */
  1242         cpy = op+length;
  1243         if ( ((endOnInput) && ((cpy>(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) )
  1244             || ((!endOnInput) && (cpy>oend-WILDCOPYLENGTH)) )
  1245         {
  1246             if (partialDecoding) {
  1247                 if (cpy > oend) goto _output_error;                           /* Error : write attempt beyond end of output buffer */
  1248                 if ((endOnInput) && (ip+length > iend)) goto _output_error;   /* Error : read attempt beyond end of input buffer */
  1249             } else {
  1250                 if ((!endOnInput) && (cpy != oend)) goto _output_error;       /* Error : block decoding must stop exactly there */
  1251                 if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) goto _output_error;   /* Error : input must be consumed */
  1252             }
  1253             memcpy(op, ip, length);
  1254             ip += length;
  1255             op += length;
  1256             break;     /* Necessarily EOF, due to parsing restrictions */
  1257         }
  1258         LZ4_wildCopy(op, ip, cpy);
  1259         ip += length; op = cpy;
  1260 
  1261         /* get offset */
  1262         offset = LZ4_readLE16(ip); ip+=2;
  1263         match = op - offset;
  1264         if ((checkOffset) && (unlikely(match + dictSize < lowPrefix))) goto _output_error;   /* Error : offset outside buffers */
  1265         LZ4_write32(op, (U32)offset);   /* costs ~1%; silence an msan warning when offset==0 */
  1266 
  1267         /* get matchlength */
  1268         length = token & ML_MASK;
  1269         if (length == ML_MASK) {
  1270             unsigned s;
  1271             do {
  1272                 s = *ip++;
  1273                 if ((endOnInput) && (ip > iend-LASTLITERALS)) goto _output_error;
  1274                 length += s;
  1275             } while (s==255);
  1276             if ((safeDecode) && unlikely((uptrval)(op)+length<(uptrval)op)) goto _output_error;   /* overflow detection */
  1277         }
  1278         length += MINMATCH;
  1279 
  1280         /* check external dictionary */
  1281         if ((dict==usingExtDict) && (match < lowPrefix)) {
  1282             if (unlikely(op+length > oend-LASTLITERALS)) goto _output_error;   /* doesn't respect parsing restriction */
  1283 
  1284             if (length <= (size_t)(lowPrefix-match)) {
  1285                 /* match can be copied as a single segment from external dictionary */
  1286                 memmove(op, dictEnd - (lowPrefix-match), length);
  1287                 op += length;
  1288             } else {
  1289                 /* match encompass external dictionary and current block */
  1290                 size_t const copySize = (size_t)(lowPrefix-match);
  1291                 size_t const restSize = length - copySize;
  1292                 memcpy(op, dictEnd - copySize, copySize);
  1293                 op += copySize;
  1294                 if (restSize > (size_t)(op-lowPrefix)) {  /* overlap copy */
  1295                     BYTE* const endOfMatch = op + restSize;
  1296                     const BYTE* copyFrom = lowPrefix;
  1297                     while (op < endOfMatch) *op++ = *copyFrom++;
  1298                 } else {
  1299                     memcpy(op, lowPrefix, restSize);
  1300                     op += restSize;
  1301             }   }
  1302             continue;
  1303         }
  1304 
  1305         /* copy match within block */
  1306         cpy = op + length;
  1307         if (unlikely(offset<8)) {
  1308             op[0] = match[0];
  1309             op[1] = match[1];
  1310             op[2] = match[2];
  1311             op[3] = match[3];
  1312             match += inc32table[offset];
  1313             memcpy(op+4, match, 4);
  1314             match -= dec64table[offset];
  1315         } else { memcpy(op, match, 8); match+=8; }
  1316         op += 8;
  1317 
  1318         if (unlikely(cpy>oend-12)) {
  1319             BYTE* const oCopyLimit = oend-(WILDCOPYLENGTH-1);
  1320             if (cpy > oend-LASTLITERALS) goto _output_error;    /* Error : last LASTLITERALS bytes must be literals (uncompressed) */
  1321             if (op < oCopyLimit) {
  1322                 LZ4_wildCopy(op, match, oCopyLimit);
  1323                 match += oCopyLimit - op;
  1324                 op = oCopyLimit;
  1325             }
  1326             while (op<cpy) *op++ = *match++;
  1327         } else {
  1328             memcpy(op, match, 8);
  1329             if (length>16) LZ4_wildCopy(op+8, match+8, cpy);
  1330         }
  1331         op = cpy;   /* correction */
  1332     }
  1333 
  1334     /* end of decoding */
  1335     if (endOnInput)
  1336        return (int) (((char*)op)-dst);     /* Nb of output bytes decoded */
  1337     else
  1338        return (int) (((const char*)ip)-src);   /* Nb of input bytes read */
  1339 
  1340     /* Overflow error detected */
  1341 _output_error:
  1342     return (int) (-(((const char*)ip)-src))-1;
  1343 }
  1344 
  1345 
  1346 LZ4_FORCE_O2_GCC_PPC64LE
  1347 int LZ4_decompress_safe(const char* source, char* dest, int compressedSize, int maxDecompressedSize)
  1348 {
  1349     return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, endOnInputSize, full, 0, noDict, (BYTE*)dest, NULL, 0);
  1350 }
  1351 
  1352 LZ4_FORCE_O2_GCC_PPC64LE
  1353 int LZ4_decompress_safe_partial(const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize)
  1354 {
  1355     return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, endOnInputSize, partial, targetOutputSize, noDict, (BYTE*)dest, NULL, 0);
  1356 }
  1357 
  1358 LZ4_FORCE_O2_GCC_PPC64LE
  1359 int LZ4_decompress_fast(const char* source, char* dest, int originalSize)
  1360 {
  1361     return LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, withPrefix64k, (BYTE*)(dest - 64 KB), NULL, 64 KB);
  1362 }
  1363 
  1364 
  1365 /*===== streaming decompression functions =====*/
  1366 
  1367 LZ4_streamDecode_t* LZ4_createStreamDecode(void)
  1368 {
  1369     LZ4_streamDecode_t* lz4s = (LZ4_streamDecode_t*) ALLOCATOR(1, sizeof(LZ4_streamDecode_t));
  1370     return lz4s;
  1371 }
  1372 
  1373 int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream)
  1374 {
  1375     if (!LZ4_stream) return 0;   /* support free on NULL */
  1376     FREEMEM(LZ4_stream);
  1377     return 0;
  1378 }
  1379 
  1380 /*!
  1381  * LZ4_setStreamDecode() :
  1382  * Use this function to instruct where to find the dictionary.
  1383  * This function is not necessary if previous data is still available where it was decoded.
  1384  * Loading a size of 0 is allowed (same effect as no dictionary).
  1385  * Return : 1 if OK, 0 if error
  1386  */
  1387 int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize)
  1388 {
  1389     LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse;
  1390     lz4sd->prefixSize = (size_t) dictSize;
  1391     lz4sd->prefixEnd = (const BYTE*) dictionary + dictSize;
  1392     lz4sd->externalDict = NULL;
  1393     lz4sd->extDictSize  = 0;
  1394     return 1;
  1395 }
  1396 
  1397 /*
  1398 *_continue() :
  1399     These decoding functions allow decompression of multiple blocks in "streaming" mode.
  1400     Previously decoded blocks must still be available at the memory position where they were decoded.
  1401     If it's not possible, save the relevant part of decoded data into a safe buffer,
  1402     and indicate where it stands using LZ4_setStreamDecode()
  1403 */
  1404 LZ4_FORCE_O2_GCC_PPC64LE
  1405 int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxOutputSize)
  1406 {
  1407     LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse;
  1408     int result;
  1409 
  1410     if (lz4sd->prefixEnd == (BYTE*)dest) {
  1411         result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize,
  1412                                         endOnInputSize, full, 0,
  1413                                         usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize);
  1414         if (result <= 0) return result;
  1415         lz4sd->prefixSize += result;
  1416         lz4sd->prefixEnd  += result;
  1417     } else {
  1418         lz4sd->extDictSize = lz4sd->prefixSize;
  1419         lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize;
  1420         result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize,
  1421                                         endOnInputSize, full, 0,
  1422                                         usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize);
  1423         if (result <= 0) return result;
  1424         lz4sd->prefixSize = result;
  1425         lz4sd->prefixEnd  = (BYTE*)dest + result;
  1426     }
  1427 
  1428     return result;
  1429 }
  1430 
  1431 LZ4_FORCE_O2_GCC_PPC64LE
  1432 int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize)
  1433 {
  1434     LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse;
  1435     int result;
  1436 
  1437     if (lz4sd->prefixEnd == (BYTE*)dest) {
  1438         result = LZ4_decompress_generic(source, dest, 0, originalSize,
  1439                                         endOnOutputSize, full, 0,
  1440                                         usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize);
  1441         if (result <= 0) return result;
  1442         lz4sd->prefixSize += originalSize;
  1443         lz4sd->prefixEnd  += originalSize;
  1444     } else {
  1445         lz4sd->extDictSize = lz4sd->prefixSize;
  1446         lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize;
  1447         result = LZ4_decompress_generic(source, dest, 0, originalSize,
  1448                                         endOnOutputSize, full, 0,
  1449                                         usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize);
  1450         if (result <= 0) return result;
  1451         lz4sd->prefixSize = originalSize;
  1452         lz4sd->prefixEnd  = (BYTE*)dest + originalSize;
  1453     }
  1454 
  1455     return result;
  1456 }
  1457 
  1458 
  1459 /*
  1460 Advanced decoding functions :
  1461 *_usingDict() :
  1462     These decoding functions work the same as "_continue" ones,
  1463     the dictionary must be explicitly provided within parameters
  1464 */
  1465 
  1466 LZ4_FORCE_O2_GCC_PPC64LE
  1467 LZ4_FORCE_INLINE int LZ4_decompress_usingDict_generic(const char* source, char* dest, int compressedSize, int maxOutputSize, int safe, const char* dictStart, int dictSize)
  1468 {
  1469     if (dictSize==0)
  1470         return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest, NULL, 0);
  1471     if (dictStart+dictSize == dest) {
  1472         if (dictSize >= (int)(64 KB - 1))
  1473             return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, withPrefix64k, (BYTE*)dest-64 KB, NULL, 0);
  1474         return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest-dictSize, NULL, 0);
  1475     }
  1476     return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, usingExtDict, (BYTE*)dest, (const BYTE*)dictStart, dictSize);
  1477 }
  1478 
  1479 LZ4_FORCE_O2_GCC_PPC64LE
  1480 int LZ4_decompress_safe_usingDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize)
  1481 {
  1482     return LZ4_decompress_usingDict_generic(source, dest, compressedSize, maxOutputSize, 1, dictStart, dictSize);
  1483 }
  1484 
  1485 LZ4_FORCE_O2_GCC_PPC64LE
  1486 int LZ4_decompress_fast_usingDict(const char* source, char* dest, int originalSize, const char* dictStart, int dictSize)
  1487 {
  1488     return LZ4_decompress_usingDict_generic(source, dest, 0, originalSize, 0, dictStart, dictSize);
  1489 }
  1490 
  1491 /* debug function */
  1492 LZ4_FORCE_O2_GCC_PPC64LE
  1493 int LZ4_decompress_safe_forceExtDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize)
  1494 {
  1495     return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, usingExtDict, (BYTE*)dest, (const BYTE*)dictStart, dictSize);
  1496 }
  1497 
  1498 
  1499 /*=*************************************************
  1500 *  Obsolete Functions
  1501 ***************************************************/
  1502 /* obsolete compression functions */
  1503 int LZ4_compress_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize) { return LZ4_compress_default(source, dest, inputSize, maxOutputSize); }
  1504 int LZ4_compress(const char* source, char* dest, int inputSize) { return LZ4_compress_default(source, dest, inputSize, LZ4_compressBound(inputSize)); }
  1505 int LZ4_compress_limitedOutput_withState (void* state, const char* src, char* dst, int srcSize, int dstSize) { return LZ4_compress_fast_extState(state, src, dst, srcSize, dstSize, 1); }
  1506 int LZ4_compress_withState (void* state, const char* src, char* dst, int srcSize) { return LZ4_compress_fast_extState(state, src, dst, srcSize, LZ4_compressBound(srcSize), 1); }
  1507 int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_stream, const char* src, char* dst, int srcSize, int maxDstSize) { return LZ4_compress_fast_continue(LZ4_stream, src, dst, srcSize, maxDstSize, 1); }
  1508 int LZ4_compress_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize) { return LZ4_compress_fast_continue(LZ4_stream, source, dest, inputSize, LZ4_compressBound(inputSize), 1); }
  1509 
  1510 /*
  1511 These function names are deprecated and should no longer be used.
  1512 They are only provided here for compatibility with older user programs.
  1513 - LZ4_uncompress is totally equivalent to LZ4_decompress_fast
  1514 - LZ4_uncompress_unknownOutputSize is totally equivalent to LZ4_decompress_safe
  1515 */
  1516 int LZ4_uncompress (const char* source, char* dest, int outputSize) { return LZ4_decompress_fast(source, dest, outputSize); }
  1517 int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize) { return LZ4_decompress_safe(source, dest, isize, maxOutputSize); }
  1518 
  1519 
  1520 /* Obsolete Streaming functions */
  1521 
  1522 int LZ4_sizeofStreamState() { return LZ4_STREAMSIZE; }
  1523 
  1524 static void LZ4_init(LZ4_stream_t* lz4ds, BYTE* base)
  1525 {
  1526     MEM_INIT(lz4ds, 0, sizeof(LZ4_stream_t));
  1527     lz4ds->internal_donotuse.bufferStart = base;
  1528 }
  1529 
  1530 int LZ4_resetStreamState(void* state, char* inputBuffer)
  1531 {
  1532     if ((((uptrval)state) & 3) != 0) return 1;   /* Error : pointer is not aligned on 4-bytes boundary */
  1533     LZ4_init((LZ4_stream_t*)state, (BYTE*)inputBuffer);
  1534     return 0;
  1535 }
  1536 
  1537 void* LZ4_create (char* inputBuffer)
  1538 {
  1539     LZ4_stream_t* lz4ds = (LZ4_stream_t*)ALLOCATOR(8, sizeof(LZ4_stream_t));
  1540     LZ4_init (lz4ds, (BYTE*)inputBuffer);
  1541     return lz4ds;
  1542 }
  1543 
  1544 char* LZ4_slideInputBuffer (void* LZ4_Data)
  1545 {
  1546     LZ4_stream_t_internal* ctx = &((LZ4_stream_t*)LZ4_Data)->internal_donotuse;
  1547     int dictSize = LZ4_saveDict((LZ4_stream_t*)LZ4_Data, (char*)ctx->bufferStart, 64 KB);
  1548     return (char*)(ctx->bufferStart + dictSize);
  1549 }
  1550 
  1551 /* Obsolete streaming decompression functions */
  1552 
  1553 int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int compressedSize, int maxOutputSize)
  1554 {
  1555     return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB);
  1556 }
  1557 
  1558 int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int originalSize)
  1559 {
  1560     return LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB);
  1561 }
  1562 
  1563 #endif   /* LZ4_COMMONDEFS_ONLY */