On Thu, Jun 9, 2016 at 1:51 PM, Gert Doering <g...@greenie.muc.de> wrote:
> Take upstream release from https://github.com/Cyan4973/lz4/releases,
>   copy lz4-r131/lib/lz4.c to src/compat/compat-lz4.c
>   copy lz4-r131/lib/lz4.h to src/compat/compat-lz4.h
>   change #include line in compat-lz4.c to use "compat-lz4.h" not "lz4.h"
>   add "config.h" block and wrap in #ifdef NEED_COMPAT_LZ4 / #endif
>
> No other changes to upstream code.
>
> This commit is quite huge, but this is because we bundled a fairly old
> version and upstream refactored quite a lot of code, changed // comments
> to /* */ style, etc - to review, compare compat-lz4.* files to upstream.
>
> v2: add missing #ifdef NEED_COMPAT_LZ4 wrapping
>
> Signed-off-by: Gert Doering <g...@greenie.muc.de>
> ---
>  src/compat/compat-lz4.c | 1704 
> +++++++++++++++++++++++++++++++++--------------
>  src/compat/compat-lz4.h |  375 ++++++++---
>  2 files changed, 1464 insertions(+), 615 deletions(-)
>
> diff --git a/src/compat/compat-lz4.c b/src/compat/compat-lz4.c
> index c63c18b..5855ca1 100644
> --- a/src/compat/compat-lz4.c
> +++ b/src/compat/compat-lz4.c
> @@ -1,6 +1,7 @@
>  /*
>     LZ4 - Fast LZ compression algorithm
> -   Copyright (C) 2011-2013, Yann Collet.
> +   Copyright (C) 2011-2015, Yann Collet.
> +
>     BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
>
>     Redistribution and use in source and binary forms, with or without
> @@ -27,7 +28,7 @@
>     OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>
>     You can contact the author at :
> -   - LZ4 source repository : http://code.google.com/p/lz4/
> +   - LZ4 source repository : https://github.com/Cyan4973/lz4
>     - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
>  */
>
> @@ -39,109 +40,63 @@
>
>  #ifdef NEED_COMPAT_LZ4
>
> -//**************************************
> -// Tuning parameters
> -//**************************************
> -// MEMORY_USAGE :
> -// Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 
> -> 64KB; 20 -> 1MB; etc.)
> -// Increasing memory usage improves compression ratio
> -// Reduced memory usage can improve speed, due to cache effect
> -// Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache
> -#define MEMORY_USAGE 14
> -
> -// HEAPMODE :
> -// Select how default compression functions will allocate memory for their 
> hash table,
> -// in memory stack (0:default, fastest), or in memory heap (1:requires 
> memory allocation (malloc)).
> +/**************************************
> +*  Tuning parameters
> +**************************************/
> +/*
> + * HEAPMODE :
> + * Select how default compression functions will allocate memory for their 
> hash table,
> + * in memory stack (0:default, fastest), or in memory heap (1:requires 
> malloc()).
> + */
>  #define HEAPMODE 0
>
> +/*
> + * ACCELERATION_DEFAULT :
> + * Select "acceleration" for LZ4_compress_fast() when parameter value <= 0
> + */
> +#define ACCELERATION_DEFAULT 1
>
> -//**************************************
> -// CPU Feature Detection
> -//**************************************
> -// 32 or 64 bits ?
> -#if (defined(__x86_64__) || defined(_M_X64) || defined(_WIN64) \
> -  || defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) \
> -  || defined(__64BIT__) || defined(_LP64) || defined(__LP64__) \
> -  || defined(__ia64) || defined(__itanium__) || defined(_M_IA64) )   // 
> Detects 64 bits mode
> -#  define LZ4_ARCH64 1
> -#else
> -#  define LZ4_ARCH64 0
> -#endif
> -
> -// Little Endian or Big Endian ?
> -// Overwrite the #define below if you know your architecture endianess
> -#if defined (__GLIBC__)
> -#  include <endian.h>
> -#  if (__BYTE_ORDER == __BIG_ENDIAN)
> -#     define LZ4_BIG_ENDIAN 1
> -#  endif
> -#elif (defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || 
> defined(_BIG_ENDIAN)) && !(defined(__LITTLE_ENDIAN__) || 
> defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN))
> -#  define LZ4_BIG_ENDIAN 1
> -#elif defined(__sparc) || defined(__sparc__) \
> -   || defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) \
> -   || defined(__hpux)  || defined(__hppa) \
> -   || defined(_MIPSEB) || defined(__s390__)
> -#  define LZ4_BIG_ENDIAN 1
> -#else
> -// Little Endian assumed. PDP Endian and other very rare endian format are 
> unsupported.
> -#endif
> -
> -// Unaligned memory access is automatically enabled for "common" CPU, such 
> as x86.
> -// For others CPU, such as ARM, the compiler may be more cautious, inserting 
> unnecessary extra code to ensure aligned access property
> -// If you know your target CPU supports unaligned memory access, you want to 
> force this option manually to improve performance
> -#if defined(__ARM_FEATURE_UNALIGNED)
> -#  define LZ4_FORCE_UNALIGNED_ACCESS 1
> -#endif
>
> -// Define this parameter if your target system or compiler does not support 
> hardware bit count
> -#if defined(_MSC_VER) && defined(_WIN32_WCE)            // Visual Studio for 
> Windows CE does not support Hardware bit count
> +/**************************************
> +*  CPU Feature Detection
> +**************************************/
> +/*
> + * LZ4_FORCE_SW_BITCOUNT
> + * Define this parameter if your target system or compiler does not support 
> hardware bit count
> + */
> +#if defined(_MSC_VER) && defined(_WIN32_WCE)   /* Visual Studio for Windows 
> CE does not support Hardware bit count */
>  #  define LZ4_FORCE_SW_BITCOUNT
>  #endif
>
> -// BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE :
> -// This option may provide a small boost to performance for some big endian 
> cpu, although probably modest.
> -// You may set this option to 1 if data will remain within closed 
> environment.
> -// This option is useless on Little_Endian CPU (such as x86)
> -//#define BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE 1
>
> +/**************************************
> +*  Includes
> +**************************************/
> +#include "compat-lz4.h"
>
> -//**************************************
> -// Compiler Options
> -//**************************************
> -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)   // C99
> -/* "restrict" is a known keyword */
> -#else
> -#  define restrict // Disable restrict
> -#endif
>
> -#ifdef _MSC_VER    // Visual Studio
> +/**************************************
> +*  Compiler Options
> +**************************************/
> +#ifdef _MSC_VER    /* Visual Studio */
>  #  define FORCE_INLINE static __forceinline
> -#  include <intrin.h>                    // For Visual 2005
> -#  if LZ4_ARCH64   // 64-bits
> -#    pragma intrinsic(_BitScanForward64) // For Visual 2005
> -#    pragma intrinsic(_BitScanReverse64) // For Visual 2005
> -#  else            // 32-bits
> -#    pragma intrinsic(_BitScanForward)   // For Visual 2005
> -#    pragma intrinsic(_BitScanReverse)   // For Visual 2005
> -#  endif
> -#  pragma warning(disable : 4127)        // disable: C4127: conditional 
> expression is constant
> +#  include <intrin.h>
> +#  pragma warning(disable : 4127)        /* disable: C4127: conditional 
> expression is constant */
> +#  pragma warning(disable : 4293)        /* disable: C4293: too large shift 
> (32-bits) */
>  #else
> -#  ifdef __GNUC__
> -#    define FORCE_INLINE static inline __attribute__((always_inline))
> +#  if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)   /* C99 */
> +#    if defined(__GNUC__) || defined(__clang__)
> +#      define FORCE_INLINE static inline __attribute__((always_inline))
> +#    else
> +#      define FORCE_INLINE static inline
> +#    endif
>  #  else
> -#    define FORCE_INLINE static inline
> -#  endif
> -#endif
> -
> -#ifdef _MSC_VER
> -#  define lz4_bswap16(x) _byteswap_ushort(x)
> -#else
> -#  define lz4_bswap16(x) ((unsigned short int) ((((x) >> 8) & 0xffu) | (((x) 
> & 0xffu) << 8)))
> -#endif
> -
> -#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
> +#    define FORCE_INLINE static
> +#  endif   /* __STDC_VERSION__ */
> +#endif  /* _MSC_VER */
>
> -#if (GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__)
> +/* LZ4_GCC_VERSION is defined into lz4.h */
> +#if (LZ4_GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || 
> defined(__clang__)
>  #  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
>  #else
>  #  define expect(expr,value)    (expr)
> @@ -151,26 +106,20 @@
>  #define unlikely(expr)   expect((expr) != 0, 0)
>
>
> -//**************************************
> -// Memory routines
> -//**************************************
> -#include <stdlib.h>   // malloc, calloc, free
> +/**************************************
> +*  Memory routines
> +**************************************/
> +#include <stdlib.h>   /* malloc, calloc, free */
>  #define ALLOCATOR(n,s) calloc(n,s)
>  #define FREEMEM        free
> -#include <string.h>   // memset, memcpy
> +#include <string.h>   /* memset, memcpy */
>  #define MEM_INIT       memset
>
>
> -//**************************************
> -// Includes
> -//**************************************
> -#include "compat-lz4.h"
> -
> -
> -//**************************************
> -// Basic Types
> -//**************************************
> -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L   // C99
> +/**************************************
> +*  Basic Types
> +**************************************/
> +#if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)   /* C99 */
>  # include <stdint.h>
>    typedef  uint8_t BYTE;
>    typedef uint16_t U16;
> @@ -185,55 +134,105 @@
>    typedef unsigned long long  U64;
>  #endif
>
> -#if defined(__GNUC__)  && !defined(LZ4_FORCE_UNALIGNED_ACCESS)
> -#  define _PACKED __attribute__ ((packed))
> -#else
> -#  define _PACKED
> -#endif
>
> -#if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__)
> -#  if defined(__IBMC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
> -#    pragma pack(1)
> -#  else
> -#    pragma pack(push, 1)
> -#  endif
> -#endif
> +/**************************************
> +*  Reading and writing into memory
> +**************************************/
> +#define STEPSIZE sizeof(size_t)
>
> -typedef struct { U16 v; }  _PACKED U16_S;
> -typedef struct { U32 v; }  _PACKED U32_S;
> -typedef struct { U64 v; }  _PACKED U64_S;
> -typedef struct {size_t v;} _PACKED size_t_S;
> +static unsigned LZ4_64bits(void) { return sizeof(void*)==8; }
>
> -#if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__)
> -#  if defined(__SUNPRO_C) || defined(__SUNPRO_CC)
> -#    pragma pack(0)
> -#  else
> -#    pragma pack(pop)
> -#  endif
> -#endif
> +static unsigned LZ4_isLittleEndian(void)
> +{
> +    const union { U32 i; BYTE c[4]; } one = { 1 };   /* don't use static : 
> performance detrimental  */
> +    return one.c[0];
> +}
> +
> +
> +static U16 LZ4_read16(const void* memPtr)
> +{
> +    U16 val16;
> +    memcpy(&val16, memPtr, 2);
> +    return val16;
> +}
> +
> +static U16 LZ4_readLE16(const void* memPtr)
> +{
> +    if (LZ4_isLittleEndian())
> +    {
> +        return LZ4_read16(memPtr);
> +    }
> +    else
> +    {
> +        const BYTE* p = (const BYTE*)memPtr;
> +        return (U16)((U16)p[0] + (p[1]<<8));
> +    }
> +}
> +
> +static void LZ4_writeLE16(void* memPtr, U16 value)
> +{
> +    if (LZ4_isLittleEndian())
> +    {
> +        memcpy(memPtr, &value, 2);
> +    }
> +    else
> +    {
> +        BYTE* p = (BYTE*)memPtr;
> +        p[0] = (BYTE) value;
> +        p[1] = (BYTE)(value>>8);
> +    }
> +}
>
> -#define A16(x)   (((U16_S *)(x))->v)
> -#define A32(x)   (((U32_S *)(x))->v)
> -#define A64(x)   (((U64_S *)(x))->v)
> -#define AARCH(x) (((size_t_S *)(x))->v)
> +static U32 LZ4_read32(const void* memPtr)
> +{
> +    U32 val32;
> +    memcpy(&val32, memPtr, 4);
> +    return val32;
> +}
>
> +static U64 LZ4_read64(const void* memPtr)
> +{
> +    U64 val64;
> +    memcpy(&val64, memPtr, 8);
> +    return val64;
> +}
>
> -//**************************************
> -// Constants
> -//**************************************
> -#define LZ4_HASHLOG   (MEMORY_USAGE-2)
> -#define HASHTABLESIZE (1 << MEMORY_USAGE)
> -#define HASHNBCELLS4  (1 << LZ4_HASHLOG)
> +static size_t LZ4_read_ARCH(const void* p)
> +{
> +    if (LZ4_64bits())
> +        return (size_t)LZ4_read64(p);
> +    else
> +        return (size_t)LZ4_read32(p);
> +}
> +
> +
> +static void LZ4_copy4(void* dstPtr, const void* srcPtr) { memcpy(dstPtr, 
> srcPtr, 4); }
> +
> +static void LZ4_copy8(void* dstPtr, const void* srcPtr) { memcpy(dstPtr, 
> srcPtr, 8); }
> +
> +/* customized version of memcpy, which may overwrite up to 7 bytes beyond 
> dstEnd */
> +static void LZ4_wildCopy(void* dstPtr, const void* srcPtr, void* dstEnd)
> +{
> +    BYTE* d = (BYTE*)dstPtr;
> +    const BYTE* s = (const BYTE*)srcPtr;
> +    BYTE* e = (BYTE*)dstEnd;
> +    do { LZ4_copy8(d,s); d+=8; s+=8; } while (d<e);
> +}
>
> +
> +/**************************************
> +*  Common Constants
> +**************************************/
>  #define MINMATCH 4
>
>  #define COPYLENGTH 8
>  #define LASTLITERALS 5
>  #define MFLIMIT (COPYLENGTH+MINMATCH)
> -const int LZ4_minLength = (MFLIMIT+1);
> +static const int LZ4_minLength = (MFLIMIT+1);
>
> -#define LZ4_64KLIMIT ((1<<16) + (MFLIMIT-1))
> -#define SKIPSTRENGTH 6     // Increasing this value will make the 
> compression run slower on incompressible data
> +#define KB *(1 <<10)
> +#define MB *(1 <<20)
> +#define GB *(1U<<30)
>
>  #define MAXD_LOG 16
>  #define MAX_DISTANCE ((1 << MAXD_LOG) - 1)
> @@ -243,135 +242,150 @@ const int LZ4_minLength = (MFLIMIT+1);
>  #define RUN_BITS (8-ML_BITS)
>  #define RUN_MASK ((1U<<RUN_BITS)-1)
>
> -#define KB *(1U<<10)
> -#define MB *(1U<<20)
> -#define GB *(1U<<30)
>
> +/**************************************
> +*  Common Utils
> +**************************************/
> +#define LZ4_STATIC_ASSERT(c)    { enum { LZ4_static_assert = 1/(int)(!!(c)) 
> }; }   /* use only *after* variable declarations */
>
> -//**************************************
> -// Structures and local types
> -//**************************************
>
> -typedef struct {
> -    U32 hashTable[HASHNBCELLS4];
> -    const BYTE* bufferStart;
> -    const BYTE* base;
> -    const BYTE* nextBlock;
> -} LZ4_Data_Structure;
> +/**************************************
> +*  Common functions
> +**************************************/
> +static unsigned LZ4_NbCommonBytes (register size_t val)
> +{
> +    if (LZ4_isLittleEndian())
> +    {
> +        if (LZ4_64bits())
> +        {
> +#       if defined(_MSC_VER) && defined(_WIN64) && 
> !defined(LZ4_FORCE_SW_BITCOUNT)
> +            unsigned long r = 0;
> +            _BitScanForward64( &r, (U64)val );
> +            return (int)(r>>3);
> +#       elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && 
> !defined(LZ4_FORCE_SW_BITCOUNT)
> +            return (__builtin_ctzll((U64)val) >> 3);
> +#       else
> +            static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 
> 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 
> 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 
> 7, 6, 7, 7 };
> +            return DeBruijnBytePos[((U64)((val & -(long long)val) * 
> 0x0218A392CDABBD3FULL)) >> 58];
> +#       endif
> +        }
> +        else /* 32 bits */
> +        {
> +#       if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
> +            unsigned long r;
> +            _BitScanForward( &r, (U32)val );
> +            return (int)(r>>3);
> +#       elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && 
> !defined(LZ4_FORCE_SW_BITCOUNT)
> +            return (__builtin_ctz((U32)val) >> 3);
> +#       else
> +            static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 
> 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };
> +            return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) 
> >> 27];
> +#       endif
> +        }
> +    }
> +    else   /* Big Endian CPU */
> +    {
> +        if (LZ4_64bits())
> +        {
> +#       if defined(_MSC_VER) && defined(_WIN64) && 
> !defined(LZ4_FORCE_SW_BITCOUNT)
> +            unsigned long r = 0;
> +            _BitScanReverse64( &r, val );
> +            return (unsigned)(r>>3);
> +#       elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && 
> !defined(LZ4_FORCE_SW_BITCOUNT)
> +            return (__builtin_clzll((U64)val) >> 3);
> +#       else
> +            unsigned r;
> +            if (!(val>>32)) { r=4; } else { r=0; val>>=32; }
> +            if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
> +            r += (!val);
> +            return r;
> +#       endif
> +        }
> +        else /* 32 bits */
> +        {
> +#       if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
> +            unsigned long r = 0;
> +            _BitScanReverse( &r, (unsigned long)val );
> +            return (unsigned)(r>>3);
> +#       elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && 
> !defined(LZ4_FORCE_SW_BITCOUNT)
> +            return (__builtin_clz((U32)val) >> 3);
> +#       else
> +            unsigned r;
> +            if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
> +            r += (!val);
> +            return r;
> +#       endif
> +        }
> +    }
> +}
>
> -typedef enum { notLimited = 0, limited = 1 } limitedOutput_directive;
> -typedef enum { byPtr, byU32, byU16 } tableType_t;
> +static unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* 
> pInLimit)
> +{
> +    const BYTE* const pStart = pIn;
>
> -typedef enum { noPrefix = 0, withPrefix = 1 } prefix64k_directive;
> +    while (likely(pIn<pInLimit-(STEPSIZE-1)))
> +    {
> +        size_t diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn);
> +        if (!diff) { pIn+=STEPSIZE; pMatch+=STEPSIZE; continue; }
> +        pIn += LZ4_NbCommonBytes(diff);
> +        return (unsigned)(pIn - pStart);
> +    }
>
> -typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } 
> endCondition_directive;
> -typedef enum { full = 0, partial = 1 } earlyEnd_directive;
> +    if (LZ4_64bits()) if ((pIn<(pInLimit-3)) && (LZ4_read32(pMatch) == 
> LZ4_read32(pIn))) { pIn+=4; pMatch+=4; }
> +    if ((pIn<(pInLimit-1)) && (LZ4_read16(pMatch) == LZ4_read16(pIn))) { 
> pIn+=2; pMatch+=2; }
> +    if ((pIn<pInLimit) && (*pMatch == *pIn)) pIn++;
> +    return (unsigned)(pIn - pStart);
> +}
>
>
> -//**************************************
> -// Architecture-specific macros
> -//**************************************
> -#define STEPSIZE                  sizeof(size_t)
> -#define LZ4_COPYSTEP(d,s)         { AARCH(d) = AARCH(s); d+=STEPSIZE; 
> s+=STEPSIZE; }
> -#define LZ4_COPY8(d,s)            { LZ4_COPYSTEP(d,s); if (STEPSIZE<8) 
> LZ4_COPYSTEP(d,s); }
> -#define LZ4_SECURECOPY(d,s,e)     { if ((STEPSIZE==4)||(d<e)) 
> LZ4_WILDCOPY(d,s,e); }
> -
> -#if LZ4_ARCH64   // 64-bit
> -#  define HTYPE                   U32
> -#  define INITBASE(base)          const BYTE* const base = ip
> -#else            // 32-bit
> -#  define HTYPE                   const BYTE*
> -#  define INITBASE(base)          const int base = 0
> -#endif
> +#ifndef LZ4_COMMONDEFS_ONLY
> +/**************************************
> +*  Local Constants
> +**************************************/
> +#define LZ4_HASHLOG   (LZ4_MEMORY_USAGE-2)
> +#define HASHTABLESIZE (1 << LZ4_MEMORY_USAGE)
> +#define HASH_SIZE_U32 (1 << LZ4_HASHLOG)       /* required as macro for 
> static allocation */
>
> -#if (defined(LZ4_BIG_ENDIAN) && !defined(BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE))
> -#  define LZ4_READ_LITTLEENDIAN_16(d,s,p) { U16 v = A16(p); v = 
> lz4_bswap16(v); d = (s) - v; }
> -#  define LZ4_WRITE_LITTLEENDIAN_16(p,i)  { U16 v = (U16)(i); v = 
> lz4_bswap16(v); A16(p) = v; p+=2; }
> -#else      // Little Endian
> -#  define LZ4_READ_LITTLEENDIAN_16(d,s,p) { d = (s) - A16(p); }
> -#  define LZ4_WRITE_LITTLEENDIAN_16(p,v)  { A16(p) = v; p+=2; }
> -#endif
> +static const int LZ4_64Klimit = ((64 KB) + (MFLIMIT-1));
> +static const U32 LZ4_skipTrigger = 6;  /* Increase this value ==> 
> compression run slower on incompressible data */
>
>
> -//**************************************
> -// Macros
> -//**************************************
> -#define LZ4_WILDCOPY(d,s,e)     { do { LZ4_COPY8(d,s) } while (d<e); }       
>     // at the end, d>=e;
> -
> -
> -//****************************
> -// Private functions
> -//****************************
> -#if LZ4_ARCH64
> -
> -FORCE_INLINE int LZ4_NbCommonBytes (register U64 val)
> -{
> -# if defined(LZ4_BIG_ENDIAN)
> -#   if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
> -    unsigned long r = 0;
> -    _BitScanReverse64( &r, val );
> -    return (int)(r>>3);
> -#   elif defined(__GNUC__) && (GCC_VERSION >= 304) && 
> !defined(LZ4_FORCE_SW_BITCOUNT)
> -    return (__builtin_clzll(val) >> 3);
> -#   else
> -    int r;
> -    if (!(val>>32)) { r=4; } else { r=0; val>>=32; }
> -    if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
> -    r += (!val);
> -    return r;
> -#   endif
> -# else
> -#   if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
> -    unsigned long r = 0;
> -    _BitScanForward64( &r, val );
> -    return (int)(r>>3);
> -#   elif defined(__GNUC__) && (GCC_VERSION >= 304) && 
> !defined(LZ4_FORCE_SW_BITCOUNT)
> -    return (__builtin_ctzll(val) >> 3);
> -#   else
> -    static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 
> 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 
> 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 
> 7, 7 };
> -    return DeBruijnBytePos[((U64)((val & -(long long)val) * 
> 0x0218A392CDABBD3FULL)) >> 58];
> -#   endif
> -# endif
> -}
> +/**************************************
> +*  Local Structures and types
> +**************************************/
> +typedef struct {
> +    U32 hashTable[HASH_SIZE_U32];
> +    U32 currentOffset;
> +    U32 initCheck;
> +    const BYTE* dictionary;
> +    BYTE* bufferStart;   /* obsolete, used for slideInputBuffer */
> +    U32 dictSize;
> +} LZ4_stream_t_internal;
> +
> +typedef enum { notLimited = 0, limitedOutput = 1 } limitedOutput_directive;
> +typedef enum { byPtr, byU32, byU16 } tableType_t;
>
> -#else
> +typedef enum { noDict = 0, withPrefix64k, usingExtDict } dict_directive;
> +typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive;
>
> -FORCE_INLINE int LZ4_NbCommonBytes (register U32 val)
> -{
> -# if defined(LZ4_BIG_ENDIAN)
> -#   if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
> -    unsigned long r = 0;
> -    _BitScanReverse( &r, val );
> -    return (int)(r>>3);
> -#   elif defined(__GNUC__) && (GCC_VERSION >= 304) && 
> !defined(LZ4_FORCE_SW_BITCOUNT)
> -    return (__builtin_clz(val) >> 3);
> -#   else
> -    int r;
> -    if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
> -    r += (!val);
> -    return r;
> -#   endif
> -# else
> -#   if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
> -    unsigned long r;
> -    _BitScanForward( &r, val );
> -    return (int)(r>>3);
> -#   elif defined(__GNUC__) && (GCC_VERSION >= 304) && 
> !defined(LZ4_FORCE_SW_BITCOUNT)
> -    return (__builtin_ctz(val) >> 3);
> -#   else
> -    static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 
> 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };
> -    return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
> -#   endif
> -# endif
> -}
> +typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } 
> endCondition_directive;
> +typedef enum { full = 0, partial = 1 } earlyEnd_directive;
>
> -#endif
> +
> +/**************************************
> +*  Local Utils
> +**************************************/
> +int LZ4_versionNumber (void) { return LZ4_VERSION_NUMBER; }
> +int LZ4_compressBound(int isize)  { return LZ4_COMPRESSBOUND(isize); }
> +int LZ4_sizeofState() { return LZ4_STREAMSIZE; }
>
>
> -//****************************
> -// Compression functions
> -//****************************
> -FORCE_INLINE int LZ4_hashSequence(U32 sequence, tableType_t tableType)
> +
> +/********************************
> +*  Compression functions
> +********************************/
> +
> +static U32 LZ4_hashSequence(U32 sequence, tableType_t const tableType)
>  {
>      if (tableType == byU16)
>          return (((sequence) * 2654435761U) >> 
> ((MINMATCH*8)-(LZ4_HASHLOG+1)));
> @@ -379,220 +393,539 @@ FORCE_INLINE int LZ4_hashSequence(U32 sequence, 
> tableType_t tableType)
>          return (((sequence) * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG));
>  }
>
> -FORCE_INLINE int LZ4_hashPosition(const BYTE* p, tableType_t tableType) { 
> return LZ4_hashSequence(A32(p), tableType); }
> +static const U64 prime5bytes = 889523592379ULL;
> +static U32 LZ4_hashSequence64(size_t sequence, tableType_t const tableType)
> +{
> +    const U32 hashLog = (tableType == byU16) ? LZ4_HASHLOG+1 : LZ4_HASHLOG;
> +    const U32 hashMask = (1<<hashLog) - 1;
> +    return ((sequence * prime5bytes) >> (40 - hashLog)) & hashMask;
> +}
>
> -FORCE_INLINE void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* 
> tableBase, tableType_t tableType, const BYTE* srcBase)
> +static U32 LZ4_hashSequenceT(size_t sequence, tableType_t const tableType)
> +{
> +    if (LZ4_64bits())
> +        return LZ4_hashSequence64(sequence, tableType);
> +    return LZ4_hashSequence((U32)sequence, tableType);
> +}
> +
> +static U32 LZ4_hashPosition(const void* p, tableType_t tableType) { return 
> LZ4_hashSequenceT(LZ4_read_ARCH(p), tableType); }
> +
> +static void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, 
> tableType_t const tableType, const BYTE* srcBase)
>  {
>      switch (tableType)
>      {
> -    case byPtr: { const BYTE** hashTable = (const BYTE**) tableBase; 
> hashTable[h] = p; break; }
> -    case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = 
> (U32)(p-srcBase); break; }
> -    case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = 
> (U16)(p-srcBase); break; }
> +    case byPtr: { const BYTE** hashTable = (const BYTE**)tableBase; 
> hashTable[h] = p; return; }
> +    case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = 
> (U32)(p-srcBase); return; }
> +    case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = 
> (U16)(p-srcBase); return; }
>      }
>  }
>
> -FORCE_INLINE void LZ4_putPosition(const BYTE* p, void* tableBase, 
> tableType_t tableType, const BYTE* srcBase)
> +static void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t 
> tableType, const BYTE* srcBase)
>  {
>      U32 h = LZ4_hashPosition(p, tableType);
>      LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase);
>  }
>
> -FORCE_INLINE const BYTE* LZ4_getPositionOnHash(U32 h, void* tableBase, 
> tableType_t tableType, const BYTE* srcBase)
> +static const BYTE* LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t 
> tableType, const BYTE* srcBase)
>  {
>      if (tableType == byPtr) { const BYTE** hashTable = (const BYTE**) 
> tableBase; return hashTable[h]; }
>      if (tableType == byU32) { U32* hashTable = (U32*) tableBase; return 
> hashTable[h] + srcBase; }
> -    { U16* hashTable = (U16*) tableBase; return hashTable[h] + srcBase; }   
> // default, to ensure a return
> +    { U16* hashTable = (U16*) tableBase; return hashTable[h] + srcBase; }   
> /* default, to ensure a return */
>  }
>
> -FORCE_INLINE const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, 
> tableType_t tableType, const BYTE* srcBase)
> +static const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, 
> tableType_t tableType, const BYTE* srcBase)
>  {
>      U32 h = LZ4_hashPosition(p, tableType);
>      return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase);
>  }
>
> -
>  FORCE_INLINE int LZ4_compress_generic(
> -                 void* ctx,
> -                 const char* source,
> -                 char* dest,
> -                 int inputSize,
> -                 int maxOutputSize,
> -
> -                 limitedOutput_directive limitedOutput,
> -                 tableType_t tableType,
> -                 prefix64k_directive prefix)
> +                 void* const ctx,
> +                 const char* const source,
> +                 char* const dest,
> +                 const int inputSize,
> +                 const int maxOutputSize,
> +                 const limitedOutput_directive outputLimited,
> +                 const tableType_t tableType,
> +                 const dict_directive dict,
> +                 const dictIssue_directive dictIssue,
> +                 const U32 acceleration)
>  {
> +    LZ4_stream_t_internal* const dictPtr = (LZ4_stream_t_internal*)ctx;
> +
>      const BYTE* ip = (const BYTE*) source;
> -    const BYTE* const base = (prefix==withPrefix) ? 
> ((LZ4_Data_Structure*)ctx)->base : (const BYTE*) source;
> -    const BYTE* const lowLimit = ((prefix==withPrefix) ? 
> ((LZ4_Data_Structure*)ctx)->bufferStart : (const BYTE*)source);
> +    const BYTE* base;
> +    const BYTE* lowLimit;
> +    const BYTE* const lowRefLimit = ip - dictPtr->dictSize;
> +    const BYTE* const dictionary = dictPtr->dictionary;
> +    const BYTE* const dictEnd = dictionary + dictPtr->dictSize;
> +    const size_t dictDelta = dictEnd - (const BYTE*)source;
>      const BYTE* anchor = (const BYTE*) source;
>      const BYTE* const iend = ip + inputSize;
>      const BYTE* const mflimit = iend - MFLIMIT;
>      const BYTE* const matchlimit = iend - LASTLITERALS;
>
>      BYTE* op = (BYTE*) dest;
> -    BYTE* const oend = op + maxOutputSize;
> +    BYTE* const olimit = op + maxOutputSize;
>
> -    int length;
> -    const int skipStrength = SKIPSTRENGTH;
>      U32 forwardH;
> +    size_t refDelta=0;
>
> -    // Init conditions
> -    if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0;                  
>               // Unsupported input size, too large (or negative)
> -    if ((prefix==withPrefix) && (ip != 
> ((LZ4_Data_Structure*)ctx)->nextBlock)) return 0;   // must continue from end 
> of previous block
> -    if (prefix==withPrefix) ((LZ4_Data_Structure*)ctx)->nextBlock=iend;      
>               // do it now, due to potential early exit
> -    if ((tableType == byU16) && (inputSize>=LZ4_64KLIMIT)) return 0;         
>               // Size too large (not within 64K limit)
> -    if (inputSize<LZ4_minLength) goto _last_literals;                        
>               // Input too small, no compression (all literals)
> +    /* Init conditions */
> +    if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0;   /* Unsupported 
> input size, too large (or negative) */
> +    switch(dict)
> +    {
> +    case noDict:
> +    default:
> +        base = (const BYTE*)source;
> +        lowLimit = (const BYTE*)source;
> +        break;
> +    case withPrefix64k:
> +        base = (const BYTE*)source - dictPtr->currentOffset;
> +        lowLimit = (const BYTE*)source - dictPtr->dictSize;
> +        break;
> +    case usingExtDict:
> +        base = (const BYTE*)source - dictPtr->currentOffset;
> +        lowLimit = (const BYTE*)source;
> +        break;
> +    }
> +    if ((tableType == byU16) && (inputSize>=LZ4_64Klimit)) return 0;   /* 
> Size too large (not within 64K limit) */
> +    if (inputSize<LZ4_minLength) goto _last_literals;                  /* 
> Input too small, no compression (all literals) */
>
> -    // First Byte
> +    /* First Byte */
>      LZ4_putPosition(ip, ctx, tableType, base);
>      ip++; forwardH = LZ4_hashPosition(ip, tableType);
>
> -    // Main Loop
> +    /* Main Loop */
>      for ( ; ; )
>      {
> -        int findMatchAttempts = (1U << skipStrength) + 3;
> -        const BYTE* forwardIp = ip;
> -        const BYTE* ref;
> +        const BYTE* match;
>          BYTE* token;
> +        {
> +            const BYTE* forwardIp = ip;
> +            unsigned step = 1;
> +            unsigned searchMatchNb = acceleration << LZ4_skipTrigger;
> +
> +            /* Find a match */
> +            do {
> +                U32 h = forwardH;
> +                ip = forwardIp;
> +                forwardIp += step;
> +                step = (searchMatchNb++ >> LZ4_skipTrigger);
> +
> +                if (unlikely(forwardIp > mflimit)) goto _last_literals;
> +
> +                match = LZ4_getPositionOnHash(h, ctx, tableType, base);
> +                if (dict==usingExtDict)
> +                {
> +                    if (match<(const BYTE*)source)
> +                    {
> +                        refDelta = dictDelta;
> +                        lowLimit = dictionary;
> +                    }
> +                    else
> +                    {
> +                        refDelta = 0;
> +                        lowLimit = (const BYTE*)source;
> +                    }
> +                }
> +                forwardH = LZ4_hashPosition(forwardIp, tableType);
> +                LZ4_putPositionOnHash(ip, h, ctx, tableType, base);
> +
> +            } while ( ((dictIssue==dictSmall) ? (match < lowRefLimit) : 0)
> +                || ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip))
> +                || (LZ4_read32(match+refDelta) != LZ4_read32(ip)) );
> +        }
>
> -        // Find a match
> -        do {
> -            U32 h = forwardH;
> -            int step = findMatchAttempts++ >> skipStrength;
> -            ip = forwardIp;
> -            forwardIp = ip + step;
> -
> -            if unlikely(forwardIp > mflimit) { goto _last_literals; }
> +        /* Catch up */
> +        while ((ip>anchor) && (match+refDelta > lowLimit) && 
> (unlikely(ip[-1]==match[refDelta-1]))) { ip--; match--; }
>
> -            forwardH = LZ4_hashPosition(forwardIp, tableType);
> -            ref = LZ4_getPositionOnHash(h, ctx, tableType, base);
> -            LZ4_putPositionOnHash(ip, h, ctx, tableType, base);
> +        {
> +            /* Encode Literal length */
> +            unsigned litLength = (unsigned)(ip - anchor);
> +            token = op++;
> +            if ((outputLimited) && (unlikely(op + litLength + (2 + 1 + 
> LASTLITERALS) + (litLength/255) > olimit)))
> +                return 0;   /* Check output limit */
> +            if (litLength>=RUN_MASK)
> +            {
> +                int len = (int)litLength-RUN_MASK;
> +                *token=(RUN_MASK<<ML_BITS);
> +                for(; len >= 255 ; len-=255) *op++ = 255;
> +                *op++ = (BYTE)len;
> +            }
> +            else *token = (BYTE)(litLength<<ML_BITS);
>
> -        } while ((ref + MAX_DISTANCE < ip) || (A32(ref) != A32(ip)));
> +            /* Copy Literals */
> +            LZ4_wildCopy(op, anchor, op+litLength);
> +            op+=litLength;
> +        }
>
> -        // Catch up
> -        while ((ip>anchor) && (ref > lowLimit) && unlikely(ip[-1]==ref[-1])) 
> { ip--; ref--; }
> +_next_match:
> +        /* Encode Offset */
> +        LZ4_writeLE16(op, (U16)(ip-match)); op+=2;
>
> -        // Encode Literal length
> -        length = (int)(ip - anchor);
> -        token = op++;
> -        if ((limitedOutput) && unlikely(op + length + (2 + 1 + LASTLITERALS) 
> + (length/255) > oend)) return 0;   // Check output limit
> -        if (length>=(int)RUN_MASK)
> +        /* Encode MatchLength */
>          {
> -            int len = length-RUN_MASK;
> -            *token=(RUN_MASK<<ML_BITS);
> -            for(; len >= 255 ; len-=255) *op++ = 255;
> -            *op++ = (BYTE)len;
> -        }
> -        else *token = (BYTE)(length<<ML_BITS);
> +            unsigned matchLength;
>
> -        // Copy Literals
> -        { BYTE* end=(op)+(length); LZ4_WILDCOPY(op,anchor,end); op=end; }
> +            if ((dict==usingExtDict) && (lowLimit==dictionary))
> +            {
> +                const BYTE* limit;
> +                match += refDelta;
> +                limit = ip + (dictEnd-match);
> +                if (limit > matchlimit) limit = matchlimit;
> +                matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, limit);
> +                ip += MINMATCH + matchLength;
> +                if (ip==limit)
> +                {
> +                    unsigned more = LZ4_count(ip, (const BYTE*)source, 
> matchlimit);
> +                    matchLength += more;
> +                    ip += more;
> +                }
> +            }
> +            else
> +            {
> +                matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, 
> matchlimit);
> +                ip += MINMATCH + matchLength;
> +            }
>
> -_next_match:
> -        // Encode Offset
> -        LZ4_WRITE_LITTLEENDIAN_16(op,(U16)(ip-ref));
> +            if ((outputLimited) && (unlikely(op + (1 + LASTLITERALS) + 
> (matchLength>>8) > olimit)))
> +                return 0;    /* Check output limit */
> +            if (matchLength>=ML_MASK)
> +            {
> +                *token += ML_MASK;
> +                matchLength -= ML_MASK;
> +                for (; matchLength >= 510 ; matchLength-=510) { *op++ = 255; 
> *op++ = 255; }
> +                if (matchLength >= 255) { matchLength-=255; *op++ = 255; }
> +                *op++ = (BYTE)matchLength;
> +            }
> +            else *token += (BYTE)(matchLength);
> +        }
>
> -        // Start Counting
> -        ip+=MINMATCH; ref+=MINMATCH;    // MinMatch already verified
>          anchor = ip;
> -        while likely(ip<matchlimit-(STEPSIZE-1))
> -        {
> -            size_t diff = AARCH(ref) ^ AARCH(ip);
> -            if (!diff) { ip+=STEPSIZE; ref+=STEPSIZE; continue; }
> -            ip += LZ4_NbCommonBytes(diff);
> -            goto _endCount;
> -        }
> -        if (LZ4_ARCH64) if ((ip<(matchlimit-3)) && (A32(ref) == A32(ip))) { 
> ip+=4; ref+=4; }
> -        if ((ip<(matchlimit-1)) && (A16(ref) == A16(ip))) { ip+=2; ref+=2; }
> -        if ((ip<matchlimit) && (*ref == *ip)) ip++;
> -_endCount:
> -
> -        // Encode MatchLength
> -        length = (int)(ip - anchor);
> -        if ((limitedOutput) && unlikely(op + (1 + LASTLITERALS) + 
> (length>>8) > oend)) return 0;    // Check output limit
> -        if (length>=(int)ML_MASK)
> -        {
> -            *token += ML_MASK;
> -            length -= ML_MASK;
> -            for (; length > 509 ; length-=510) { *op++ = 255; *op++ = 255; }
> -            if (length >= 255) { length-=255; *op++ = 255; }
> -            *op++ = (BYTE)length;
> -        }
> -        else *token += (BYTE)(length);
>
> -        // Test end of chunk
> -        if (ip > mflimit) { anchor = ip;  break; }
> +        /* Test end of chunk */
> +        if (ip > mflimit) break;
>
> -        // Fill table
> +        /* Fill table */
>          LZ4_putPosition(ip-2, ctx, tableType, base);
>
> -        // Test next position
> -        ref = LZ4_getPosition(ip, ctx, tableType, base);
> +        /* Test next position */
> +        match = LZ4_getPosition(ip, ctx, tableType, base);
> +        if (dict==usingExtDict)
> +        {
> +            if (match<(const BYTE*)source)
> +            {
> +                refDelta = dictDelta;
> +                lowLimit = dictionary;
> +            }
> +            else
> +            {
> +                refDelta = 0;
> +                lowLimit = (const BYTE*)source;
> +            }
> +        }
>          LZ4_putPosition(ip, ctx, tableType, base);
> -        if ((ref + MAX_DISTANCE >= ip) && (A32(ref) == A32(ip))) { token = 
> op++; *token=0; goto _next_match; }
> +        if ( ((dictIssue==dictSmall) ? (match>=lowRefLimit) : 1)
> +            && (match+MAX_DISTANCE>=ip)
> +            && (LZ4_read32(match+refDelta)==LZ4_read32(ip)) )
> +        { token=op++; *token=0; goto _next_match; }
>
> -        // Prepare next loop
> -        anchor = ip++;
> -        forwardH = LZ4_hashPosition(ip, tableType);
> +        /* Prepare next loop */
> +        forwardH = LZ4_hashPosition(++ip, tableType);
>      }
>
>  _last_literals:
> -    // Encode Last Literals
> +    /* Encode Last Literals */
>      {
> -        int lastRun = (int)(iend - anchor);
> -        if ((limitedOutput) && (((char*)op - dest) + lastRun + 1 + 
> ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0;   // Check 
> output limit
> -        if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); 
> lastRun-=RUN_MASK; for(; lastRun >= 255 ; lastRun-=255) *op++ = 255; *op++ = 
> (BYTE) lastRun; }
> -        else *op++ = (BYTE)(lastRun<<ML_BITS);
> -        memcpy(op, anchor, iend - anchor);
> -        op += iend-anchor;
> +        const size_t lastRun = (size_t)(iend - anchor);
> +        if ((outputLimited) && ((op - (BYTE*)dest) + lastRun + 1 + 
> ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize))
> +            return 0;   /* Check output limit */
> +        if (lastRun >= RUN_MASK)
> +        {
> +            size_t accumulator = lastRun - RUN_MASK;
> +            *op++ = RUN_MASK << ML_BITS;
> +            for(; accumulator >= 255 ; accumulator-=255) *op++ = 255;
> +            *op++ = (BYTE) accumulator;
> +        }
> +        else
> +        {
> +            *op++ = (BYTE)(lastRun<<ML_BITS);
> +        }
> +        memcpy(op, anchor, lastRun);
> +        op += lastRun;
>      }
>
> -    // End
> +    /* End */
>      return (int) (((char*)op)-dest);
>  }
>
>
> -int LZ4_compress(const char* source, char* dest, int inputSize)
> +int LZ4_compress_fast_extState(void* state, const char* source, char* dest, 
> int inputSize, int maxOutputSize, int acceleration)
> +{
> +    LZ4_resetStream((LZ4_stream_t*)state);
> +    if (acceleration < 1) acceleration = ACCELERATION_DEFAULT;
> +
> +    if (maxOutputSize >= LZ4_compressBound(inputSize))
> +    {
> +        if (inputSize < LZ4_64Klimit)
> +            return LZ4_compress_generic(state, source, dest, inputSize, 0, 
> notLimited, byU16,                        noDict, noDictIssue, acceleration);
> +        else
> +            return LZ4_compress_generic(state, source, dest, inputSize, 0, 
> notLimited, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue, acceleration);
> +    }
> +    else
> +    {
> +        if (inputSize < LZ4_64Klimit)
> +            return LZ4_compress_generic(state, source, dest, inputSize, 
> maxOutputSize, limitedOutput, byU16,                        noDict, 
> noDictIssue, acceleration);
> +        else
> +            return LZ4_compress_generic(state, source, dest, inputSize, 
> maxOutputSize, limitedOutput, LZ4_64bits() ? byU32 : byPtr, noDict, 
> noDictIssue, acceleration);
> +    }
> +}
> +
> +
> +int LZ4_compress_fast(const char* source, char* dest, int inputSize, int 
> maxOutputSize, int acceleration)
>  {
>  #if (HEAPMODE)
> -    void* ctx = ALLOCATOR(HASHNBCELLS4, 4);   // Aligned on 4-bytes 
> boundaries
> +    void* ctxPtr = ALLOCATOR(1, sizeof(LZ4_stream_t));   /* malloc-calloc 
> always properly aligned */
>  #else
> -    U32 ctx[1U<<(MEMORY_USAGE-2)] = {0};           // Ensure data is aligned 
> on 4-bytes boundaries
> +    LZ4_stream_t ctx;
> +    void* ctxPtr = &ctx;
>  #endif
> -    int result;
>
> -    if (inputSize < (int)LZ4_64KLIMIT)
> -        result = LZ4_compress_generic((void*)ctx, source, dest, inputSize, 
> 0, notLimited, byU16, noPrefix);
> -    else
> -        result = LZ4_compress_generic((void*)ctx, source, dest, inputSize, 
> 0, notLimited, (sizeof(void*)==8) ? byU32 : byPtr, noPrefix);
> +    int result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, 
> maxOutputSize, acceleration);
>
>  #if (HEAPMODE)
> -    FREEMEM(ctx);
> +    FREEMEM(ctxPtr);
>  #endif
>      return result;
>  }
>
> -int LZ4_compress_continue (void* LZ4_Data, const char* source, char* dest, 
> int inputSize)
> +
> +int LZ4_compress_default(const char* source, char* dest, int inputSize, int 
> maxOutputSize)
> +{
> +    return LZ4_compress_fast(source, dest, inputSize, maxOutputSize, 1);
> +}
> +
> +
> +/* hidden debug function */
> +/* strangely enough, gcc generates faster code when this function is 
> uncommented, even if unused */
> +int LZ4_compress_fast_force(const char* source, char* dest, int inputSize, 
> int maxOutputSize, int acceleration)
> +{
> +    LZ4_stream_t ctx;
> +
> +    LZ4_resetStream(&ctx);
> +
> +    if (inputSize < LZ4_64Klimit)
> +        return LZ4_compress_generic(&ctx, source, dest, inputSize, 
> maxOutputSize, limitedOutput, byU16,                        noDict, 
> noDictIssue, acceleration);
> +    else
> +        return LZ4_compress_generic(&ctx, source, dest, inputSize, 
> maxOutputSize, limitedOutput, LZ4_64bits() ? byU32 : byPtr, noDict, 
> noDictIssue, acceleration);
> +}
> +
> +
> +/********************************
> +*  destSize variant
> +********************************/
> +
> +static int LZ4_compress_destSize_generic(
> +                       void* const ctx,
> +                 const char* const src,
> +                       char* const dst,
> +                       int*  const srcSizePtr,
> +                 const int targetDstSize,
> +                 const tableType_t tableType)
> +{
> +    const BYTE* ip = (const BYTE*) src;
> +    const BYTE* base = (const BYTE*) src;
> +    const BYTE* lowLimit = (const BYTE*) src;
> +    const BYTE* anchor = ip;
> +    const BYTE* const iend = ip + *srcSizePtr;
> +    const BYTE* const mflimit = iend - MFLIMIT;
> +    const BYTE* const matchlimit = iend - LASTLITERALS;
> +
> +    BYTE* op = (BYTE*) dst;
> +    BYTE* const oend = op + targetDstSize;
> +    BYTE* const oMaxLit = op + targetDstSize - 2 /* offset */ - 8 /* because 
> 8+MINMATCH==MFLIMIT */ - 1 /* token */;
> +    BYTE* const oMaxMatch = op + targetDstSize - (LASTLITERALS + 1 /* token 
> */);
> +    BYTE* const oMaxSeq = oMaxLit - 1 /* token */;
> +
> +    U32 forwardH;
> +
> +
> +    /* Init conditions */
> +    if (targetDstSize < 1) return 0;                                     /* 
> Impossible to store anything */
> +    if ((U32)*srcSizePtr > (U32)LZ4_MAX_INPUT_SIZE) return 0;            /* 
> Unsupported input size, too large (or negative) */
> +    if ((tableType == byU16) && (*srcSizePtr>=LZ4_64Klimit)) return 0;   /* 
> Size too large (not within 64K limit) */
> +    if (*srcSizePtr<LZ4_minLength) goto _last_literals;                  /* 
> Input too small, no compression (all literals) */
> +
> +    /* First Byte */
> +    *srcSizePtr = 0;
> +    LZ4_putPosition(ip, ctx, tableType, base);
> +    ip++; forwardH = LZ4_hashPosition(ip, tableType);
> +
> +    /* Main Loop */
> +    for ( ; ; )
> +    {
> +        const BYTE* match;
> +        BYTE* token;
> +        {
> +            const BYTE* forwardIp = ip;
> +            unsigned step = 1;
> +            unsigned searchMatchNb = 1 << LZ4_skipTrigger;
> +
> +            /* Find a match */
> +            do {
> +                U32 h = forwardH;
> +                ip = forwardIp;
> +                forwardIp += step;
> +                step = (searchMatchNb++ >> LZ4_skipTrigger);
> +
> +                if (unlikely(forwardIp > mflimit))
> +                    goto _last_literals;
> +
> +                match = LZ4_getPositionOnHash(h, ctx, tableType, base);
> +                forwardH = LZ4_hashPosition(forwardIp, tableType);
> +                LZ4_putPositionOnHash(ip, h, ctx, tableType, base);
> +
> +            } while ( ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip))
> +                || (LZ4_read32(match) != LZ4_read32(ip)) );
> +        }
> +
> +        /* Catch up */
> +        while ((ip>anchor) && (match > lowLimit) && 
> (unlikely(ip[-1]==match[-1]))) { ip--; match--; }
> +
> +        {
> +            /* Encode Literal length */
> +            unsigned litLength = (unsigned)(ip - anchor);
> +            token = op++;
> +            if (op + ((litLength+240)/255) + litLength > oMaxLit)
> +            {
> +                /* Not enough space for a last match */
> +                op--;
> +                goto _last_literals;
> +            }
> +            if (litLength>=RUN_MASK)
> +            {
> +                unsigned len = litLength - RUN_MASK;
> +                *token=(RUN_MASK<<ML_BITS);
> +                for(; len >= 255 ; len-=255) *op++ = 255;
> +                *op++ = (BYTE)len;
> +            }
> +            else *token = (BYTE)(litLength<<ML_BITS);
> +
> +            /* Copy Literals */
> +            LZ4_wildCopy(op, anchor, op+litLength);
> +            op += litLength;
> +        }
> +
> +_next_match:
> +        /* Encode Offset */
> +        LZ4_writeLE16(op, (U16)(ip-match)); op+=2;
> +
> +        /* Encode MatchLength */
> +        {
> +            size_t matchLength;
> +
> +            matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit);
> +
> +            if (op + ((matchLength+240)/255) > oMaxMatch)
> +            {
> +                /* Match description too long : reduce it */
> +                matchLength = (15-1) + (oMaxMatch-op) * 255;
> +            }
> +            //printf("offset %5i, matchLength%5i \n", (int)(ip-match), 
> matchLength + MINMATCH);
> +            ip += MINMATCH + matchLength;
> +
> +            if (matchLength>=ML_MASK)
> +            {
> +                *token += ML_MASK;
> +                matchLength -= ML_MASK;
> +                while (matchLength >= 255) { matchLength-=255; *op++ = 255; }
> +                *op++ = (BYTE)matchLength;
> +            }
> +            else *token += (BYTE)(matchLength);
> +        }
> +
> +        anchor = ip;
> +
> +        /* Test end of block */
> +        if (ip > mflimit) break;
> +        if (op > oMaxSeq) break;
> +
> +        /* Fill table */
> +        LZ4_putPosition(ip-2, ctx, tableType, base);
> +
> +        /* Test next position */
> +        match = LZ4_getPosition(ip, ctx, tableType, base);
> +        LZ4_putPosition(ip, ctx, tableType, base);
> +        if ( (match+MAX_DISTANCE>=ip)
> +            && (LZ4_read32(match)==LZ4_read32(ip)) )
> +        { token=op++; *token=0; goto _next_match; }
> +
> +        /* Prepare next loop */
> +        forwardH = LZ4_hashPosition(++ip, tableType);
> +    }
> +
> +_last_literals:
> +    /* Encode Last Literals */
> +    {
> +        size_t lastRunSize = (size_t)(iend - anchor);
> +        if (op + 1 /* token */ + ((lastRunSize+240)/255) /* litLength */ + 
> lastRunSize /* literals */ > oend)
> +        {
> +            /* adapt lastRunSize to fill 'dst' */
> +            lastRunSize  = (oend-op) - 1;
> +            lastRunSize -= (lastRunSize+240)/255;
> +        }
> +        ip = anchor + lastRunSize;
> +
> +        if (lastRunSize >= RUN_MASK)
> +        {
> +            size_t accumulator = lastRunSize - RUN_MASK;
> +            *op++ = RUN_MASK << ML_BITS;
> +            for(; accumulator >= 255 ; accumulator-=255) *op++ = 255;
> +            *op++ = (BYTE) accumulator;
> +        }
> +        else
> +        {
> +            *op++ = (BYTE)(lastRunSize<<ML_BITS);
> +        }
> +        memcpy(op, anchor, lastRunSize);
> +        op += lastRunSize;
> +    }
> +
> +    /* End */
> +    *srcSizePtr = (int) (((const char*)ip)-src);
> +    return (int) (((char*)op)-dst);
> +}
> +
> +
> +static int LZ4_compress_destSize_extState (void* state, const char* src, 
> char* dst, int* srcSizePtr, int targetDstSize)
>  {
> -    return LZ4_compress_generic(LZ4_Data, source, dest, inputSize, 0, 
> notLimited, byU32, withPrefix);
> +    LZ4_resetStream((LZ4_stream_t*)state);
> +
> +    if (targetDstSize >= LZ4_compressBound(*srcSizePtr))   /* compression 
> success is guaranteed */
> +    {
> +        return LZ4_compress_fast_extState(state, src, dst, *srcSizePtr, 
> targetDstSize, 1);
> +    }
> +    else
> +    {
> +        if (*srcSizePtr < LZ4_64Klimit)
> +            return LZ4_compress_destSize_generic(state, src, dst, 
> srcSizePtr, targetDstSize, byU16);
> +        else
> +            return LZ4_compress_destSize_generic(state, src, dst, 
> srcSizePtr, targetDstSize, LZ4_64bits() ? byU32 : byPtr);
> +    }
>  }
>
>
> -int LZ4_compress_limitedOutput(const char* source, char* dest, int 
> inputSize, int maxOutputSize)
> +int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int 
> targetDstSize)
>  {
>  #if (HEAPMODE)
> -    void* ctx = ALLOCATOR(HASHNBCELLS4, 4);   // Aligned on 4-bytes 
> boundaries
> +    void* ctx = ALLOCATOR(1, sizeof(LZ4_stream_t));   /* malloc-calloc 
> always properly aligned */
>  #else
> -    U32 ctx[1U<<(MEMORY_USAGE-2)] = {0};           // Ensure data is aligned 
> on 4-bytes boundaries
> +    LZ4_stream_t ctxBody;
> +    void* ctx = &ctxBody;
>  #endif
> -    int result;
>
> -    if (inputSize < (int)LZ4_64KLIMIT)
> -        result = LZ4_compress_generic((void*)ctx, source, dest, inputSize, 
> maxOutputSize, limited, byU16, noPrefix);
> -    else
> -        result = LZ4_compress_generic((void*)ctx, source, dest, inputSize, 
> maxOutputSize, limited, (sizeof(void*)==8) ? byU32 : byPtr, noPrefix);
> +    int result = LZ4_compress_destSize_extState(ctx, src, dst, srcSizePtr, 
> targetDstSize);
>
>  #if (HEAPMODE)
>      FREEMEM(ctx);
> @@ -600,231 +933,592 @@ int LZ4_compress_limitedOutput(const char* source, 
> char* dest, int inputSize, in
>      return result;
>  }
>
> -int LZ4_compress_limitedOutput_continue (void* LZ4_Data, const char* source, 
> char* dest, int inputSize, int maxOutputSize)
> +
> +
> +/********************************
> +*  Streaming functions
> +********************************/
> +
> +LZ4_stream_t* LZ4_createStream(void)
>  {
> -    return LZ4_compress_generic(LZ4_Data, source, dest, inputSize, 
> maxOutputSize, limited, byU32, withPrefix);
> +    LZ4_stream_t* lz4s = (LZ4_stream_t*)ALLOCATOR(8, LZ4_STREAMSIZE_U64);
> +    LZ4_STATIC_ASSERT(LZ4_STREAMSIZE >= sizeof(LZ4_stream_t_internal));    
> /* A compilation error here means LZ4_STREAMSIZE is not large enough */
> +    LZ4_resetStream(lz4s);
> +    return lz4s;
>  }
>
> +void LZ4_resetStream (LZ4_stream_t* LZ4_stream)
> +{
> +    MEM_INIT(LZ4_stream, 0, sizeof(LZ4_stream_t));
> +}
>
> -//****************************
> -// Stream functions
> -//****************************
> -
> -FORCE_INLINE void LZ4_init(LZ4_Data_Structure* lz4ds, const BYTE* base)
> +int LZ4_freeStream (LZ4_stream_t* LZ4_stream)
>  {
> -    MEM_INIT(lz4ds->hashTable, 0, sizeof(lz4ds->hashTable));
> -    lz4ds->bufferStart = base;
> -    lz4ds->base = base;
> -    lz4ds->nextBlock = base;
> +    FREEMEM(LZ4_stream);
> +    return (0);
>  }
>
>
> -void* LZ4_create (const char* inputBuffer)
> +#define HASH_UNIT sizeof(size_t)
> +int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int 
> dictSize)
>  {
> -    void* lz4ds = ALLOCATOR(1, sizeof(LZ4_Data_Structure));
> -    LZ4_init ((LZ4_Data_Structure*)lz4ds, (const BYTE*)inputBuffer);
> -    return lz4ds;
> +    LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict;
> +    const BYTE* p = (const BYTE*)dictionary;
> +    const BYTE* const dictEnd = p + dictSize;
> +    const BYTE* base;
> +
> +    if ((dict->initCheck) || (dict->currentOffset > 1 GB))  /* Uninitialized 
> structure, or reuse overflow */
> +        LZ4_resetStream(LZ4_dict);
> +
> +    if (dictSize < (int)HASH_UNIT)
> +    {
> +        dict->dictionary = NULL;
> +        dict->dictSize = 0;
> +        return 0;
> +    }
> +
> +    if ((dictEnd - p) > 64 KB) p = dictEnd - 64 KB;
> +    dict->currentOffset += 64 KB;
> +    base = p - dict->currentOffset;
> +    dict->dictionary = p;
> +    dict->dictSize = (U32)(dictEnd - p);
> +    dict->currentOffset += dict->dictSize;
> +
> +    while (p <= dictEnd-HASH_UNIT)
> +    {
> +        LZ4_putPosition(p, dict->hashTable, byU32, base);
> +        p+=3;
> +    }
> +
> +    return dict->dictSize;
>  }
>
>
> -int LZ4_free (void* LZ4_Data)
> +static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, const BYTE* src)
>  {
> -    FREEMEM(LZ4_Data);
> -    return (0);
> +    if ((LZ4_dict->currentOffset > 0x80000000) ||
> +        ((size_t)LZ4_dict->currentOffset > (size_t)src))   /* address space 
> overflow */
> +    {
> +        /* rescale hash table */
> +        U32 delta = LZ4_dict->currentOffset - 64 KB;
> +        const BYTE* dictEnd = LZ4_dict->dictionary + LZ4_dict->dictSize;
> +        int i;
> +        for (i=0; i<HASH_SIZE_U32; i++)
> +        {
> +            if (LZ4_dict->hashTable[i] < delta) LZ4_dict->hashTable[i]=0;
> +            else LZ4_dict->hashTable[i] -= delta;
> +        }
> +        LZ4_dict->currentOffset = 64 KB;
> +        if (LZ4_dict->dictSize > 64 KB) LZ4_dict->dictSize = 64 KB;
> +        LZ4_dict->dictionary = dictEnd - LZ4_dict->dictSize;
> +    }
>  }
>
>
> -char* LZ4_slideInputBuffer (void* LZ4_Data)
> +int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream, const char* 
> source, char* dest, int inputSize, int maxOutputSize, int acceleration)
>  {
> -    LZ4_Data_Structure* lz4ds = (LZ4_Data_Structure*)LZ4_Data;
> -    size_t delta = lz4ds->nextBlock - (lz4ds->bufferStart + 64 KB);
> +    LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_stream;
> +    const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize;
>
> -    if ( (lz4ds->base - delta > lz4ds->base)                          // 
> underflow control
> -       || ((size_t)(lz4ds->nextBlock - lz4ds->base) > 0xE0000000) )   // 
> close to 32-bits limit
> -    {
> -        size_t deltaLimit = (lz4ds->nextBlock - 64 KB) - lz4ds->base;
> -        int nH;
> +    const BYTE* smallest = (const BYTE*) source;
> +    if (streamPtr->initCheck) return 0;   /* Uninitialized structure 
> detected */
> +    if ((streamPtr->dictSize>0) && (smallest>dictEnd)) smallest = dictEnd;
> +    LZ4_renormDictT(streamPtr, smallest);
> +    if (acceleration < 1) acceleration = ACCELERATION_DEFAULT;
>
> -        for (nH=0; nH < HASHNBCELLS4; nH++)
> +    /* Check overlapping input/dictionary space */
> +    {
> +        const BYTE* sourceEnd = (const BYTE*) source + inputSize;
> +        if ((sourceEnd > streamPtr->dictionary) && (sourceEnd < dictEnd))
>          {
> -            if ((size_t)(lz4ds->hashTable[nH]) < deltaLimit) 
> lz4ds->hashTable[nH] = 0;
> -            else lz4ds->hashTable[nH] -= (U32)deltaLimit;
> +            streamPtr->dictSize = (U32)(dictEnd - sourceEnd);
> +            if (streamPtr->dictSize > 64 KB) streamPtr->dictSize = 64 KB;
> +            if (streamPtr->dictSize < 4) streamPtr->dictSize = 0;
> +            streamPtr->dictionary = dictEnd - streamPtr->dictSize;
>          }
> -        memcpy((void*)(lz4ds->bufferStart), (const void*)(lz4ds->nextBlock - 
> 64 KB), 64 KB);
> -        lz4ds->base = lz4ds->bufferStart;
> -        lz4ds->nextBlock = lz4ds->base + 64 KB;
>      }
> -    else
> +
> +    /* prefix mode : source data follows dictionary */
> +    if (dictEnd == (const BYTE*)source)
> +    {
> +        int result;
> +        if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < 
> streamPtr->currentOffset))
> +            result = LZ4_compress_generic(LZ4_stream, source, dest, 
> inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, dictSmall, 
> acceleration);
> +        else
> +            result = LZ4_compress_generic(LZ4_stream, source, dest, 
> inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, noDictIssue, 
> acceleration);
> +        streamPtr->dictSize += (U32)inputSize;
> +        streamPtr->currentOffset += (U32)inputSize;
> +        return result;
> +    }
> +
> +    /* external dictionary mode */
>      {
> -        memcpy((void*)(lz4ds->bufferStart), (const void*)(lz4ds->nextBlock - 
> 64 KB), 64 KB);
> -        lz4ds->nextBlock -= delta;
> -        lz4ds->base -= delta;
> +        int result;
> +        if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < 
> streamPtr->currentOffset))
> +            result = LZ4_compress_generic(LZ4_stream, source, dest, 
> inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, dictSmall, 
> acceleration);
> +        else
> +            result = LZ4_compress_generic(LZ4_stream, source, dest, 
> inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, noDictIssue, 
> acceleration);
> +        streamPtr->dictionary = (const BYTE*)source;
> +        streamPtr->dictSize = (U32)inputSize;
> +        streamPtr->currentOffset += (U32)inputSize;
> +        return result;
>      }
> +}
> +
> +
> +/* Hidden debug function, to force external dictionary mode */
> +int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, 
> char* dest, int inputSize)
> +{
> +    LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_dict;
> +    int result;
> +    const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize;
>
> -    return (char*)(lz4ds->nextBlock);
> +    const BYTE* smallest = dictEnd;
> +    if (smallest > (const BYTE*) source) smallest = (const BYTE*) source;
> +    LZ4_renormDictT((LZ4_stream_t_internal*)LZ4_dict, smallest);
> +
> +    result = LZ4_compress_generic(LZ4_dict, source, dest, inputSize, 0, 
> notLimited, byU32, usingExtDict, noDictIssue, 1);
> +
> +    streamPtr->dictionary = (const BYTE*)source;
> +    streamPtr->dictSize = (U32)inputSize;
> +    streamPtr->currentOffset += (U32)inputSize;
> +
> +    return result;
>  }
>
>
> -//****************************
> -// Decompression functions
> -//****************************
> +int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize)
> +{
> +    LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict;
> +    const BYTE* previousDictEnd = dict->dictionary + dict->dictSize;
> +
> +    if ((U32)dictSize > 64 KB) dictSize = 64 KB;   /* useless to define a 
> dictionary > 64 KB */
> +    if ((U32)dictSize > dict->dictSize) dictSize = dict->dictSize;
>
> -// This generic decompression function cover all use cases.
> -// It shall be instanciated several times, using different sets of directives
> -// Note that it is essential this generic function is really inlined,
> -// in order to remove useless branches during compilation optimisation.
> +    memmove(safeBuffer, previousDictEnd - dictSize, dictSize);
> +
> +    dict->dictionary = (const BYTE*)safeBuffer;
> +    dict->dictSize = (U32)dictSize;
> +
> +    return dictSize;
> +}
> +
> +
> +
> +/*******************************
> +*  Decompression functions
> +*******************************/
> +/*
> + * This generic decompression function cover all use cases.
> + * It shall be instantiated several times, using different sets of directives
> + * Note that it is essential this generic function is really inlined,
> + * in order to remove useless branches during compilation optimization.
> + */
>  FORCE_INLINE int LZ4_decompress_generic(
> -                 const char* source,
> -                 char* dest,
> -                 int inputSize,          //
> -                 int outputSize,         // If endOnInput==endOnInputSize, 
> this value is the max size of Output Buffer.
> -
> -                 int endOnInput,         // endOnOutputSize, endOnInputSize
> -                 int prefix64k,          // noPrefix, withPrefix
> -                 int partialDecoding,    // full, partial
> -                 int targetOutputSize    // only used if 
> partialDecoding==partial
> +                 const char* const source,
> +                 char* const dest,
> +                 int inputSize,
> +                 int outputSize,         /* If endOnInput==endOnInputSize, 
> this value is the max size of Output Buffer. */
> +
> +                 int endOnInput,         /* endOnOutputSize, endOnInputSize 
> */
> +                 int partialDecoding,    /* full, partial */
> +                 int targetOutputSize,   /* only used if 
> partialDecoding==partial */
> +                 int dict,               /* noDict, withPrefix64k, 
> usingExtDict */
> +                 const BYTE* const lowPrefix,  /* == dest if dict == noDict 
> */
> +                 const BYTE* const dictStart,  /* only if dict==usingExtDict 
> */
> +                 const size_t dictSize         /* note : = 0 if noDict */
>                   )
>  {
> -    // Local Variables
> -    const BYTE* restrict ip = (const BYTE*) source;
> -    const BYTE* ref;
> +    /* Local Variables */
> +    const BYTE* ip = (const BYTE*) source;
>      const BYTE* const iend = ip + inputSize;
>
>      BYTE* op = (BYTE*) dest;
>      BYTE* const oend = op + outputSize;
>      BYTE* cpy;
>      BYTE* oexit = op + targetOutputSize;
> +    const BYTE* const lowLimit = lowPrefix - dictSize;
>
> -    const size_t dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0};   // static 
> reduces speed for LZ4_decompress_safe() on GCC64
> -    static const size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3};
> +    const BYTE* const dictEnd = (const BYTE*)dictStart + dictSize;
> +    const size_t dec32table[] = {4, 1, 2, 1, 4, 4, 4, 4};
> +    const size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3};
>
> +    const int safeDecode = (endOnInput==endOnInputSize);
> +    const int checkOffset = ((safeDecode) && (dictSize < (int)(64 KB)));
>
> -    // Special cases
> -    if ((partialDecoding) && (oexit> oend-MFLIMIT)) oexit = oend-MFLIMIT;    
>                     // targetOutputSize too high => decode everything
> -    if ((endOnInput) && unlikely(outputSize==0)) return ((inputSize==1) && 
> (*ip==0)) ? 0 : -1;   // Empty output buffer
> -    if ((!endOnInput) && unlikely(outputSize==0)) return (*ip==0?1:-1);
>
> +    /* Special cases */
> +    if ((partialDecoding) && (oexit> oend-MFLIMIT)) oexit = oend-MFLIMIT;    
>                      /* targetOutputSize too high => decode everything */
> +    if ((endOnInput) && (unlikely(outputSize==0))) return ((inputSize==1) && 
> (*ip==0)) ? 0 : -1;  /* Empty output buffer */
> +    if ((!endOnInput) && (unlikely(outputSize==0))) return (*ip==0?1:-1);
>
> -    // Main Loop
> +
> +    /* Main Loop */
>      while (1)
>      {
>          unsigned token;
>          size_t length;
> +        const BYTE* match;
>
> -        // get runlength
> +        /* get literal length */
>          token = *ip++;
>          if ((length=(token>>ML_BITS)) == RUN_MASK)
>          {
> -            unsigned s=255;
> -            while (((endOnInput)?ip<iend:1) && (s==255))
> +            unsigned s;
> +            do
>              {
>                  s = *ip++;
>                  length += s;
>              }
> +            while (likely((endOnInput)?ip<iend-RUN_MASK:1) && (s==255));
> +            if ((safeDecode) && unlikely((size_t)(op+length)<(size_t)(op))) 
> goto _output_error;   /* overflow detection */
> +            if ((safeDecode) && unlikely((size_t)(ip+length)<(size_t)(ip))) 
> goto _output_error;   /* overflow detection */
>          }
>
> -        // copy literals
> +        /* copy literals */
>          cpy = op+length;
>          if (((endOnInput) && ((cpy>(partialDecoding?oexit:oend-MFLIMIT)) || 
> (ip+length>iend-(2+1+LASTLITERALS))) )
>              || ((!endOnInput) && (cpy>oend-COPYLENGTH)))
>          {
>              if (partialDecoding)
>              {
> -                if (cpy > oend) goto _output_error;                          
>  // Error : write attempt beyond end of output buffer
> -                if ((endOnInput) && (ip+length > iend)) goto _output_error;  
>  // Error : read attempt beyond end of input buffer
> +                if (cpy > oend) goto _output_error;                          
>  /* Error : write attempt beyond end of output buffer */
> +                if ((endOnInput) && (ip+length > iend)) goto _output_error;  
>  /* Error : read attempt beyond end of input buffer */
>              }
>              else
>              {
> -                if ((!endOnInput) && (cpy != oend)) goto _output_error;      
>  // Error : block decoding must stop exactly there
> -                if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) 
> goto _output_error;   // Error : input must be consumed
> +                if ((!endOnInput) && (cpy != oend)) goto _output_error;      
>  /* Error : block decoding must stop exactly there */
> +                if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) 
> goto _output_error;   /* Error : input must be consumed */
>              }
>              memcpy(op, ip, length);
>              ip += length;
>              op += length;
> -            break;                                       // Necessarily EOF, 
> due to parsing restrictions
> +            break;     /* Necessarily EOF, due to parsing restrictions */
>          }
> -        LZ4_WILDCOPY(op, ip, cpy); ip -= (op-cpy); op = cpy;
> +        LZ4_wildCopy(op, ip, cpy);
> +        ip += length; op = cpy;
>
> -        // get offset
> -        LZ4_READ_LITTLEENDIAN_16(ref,cpy,ip); ip+=2;
> -        if ((prefix64k==noPrefix) && unlikely(ref < (BYTE* const)dest)) goto 
> _output_error;   // Error : offset outside destination buffer
> +        /* get offset */
> +        match = cpy - LZ4_readLE16(ip); ip+=2;
> +        if ((checkOffset) && (unlikely(match < lowLimit))) goto 
> _output_error;   /* Error : offset outside destination buffer */
>
> -        // get matchlength
> -        if ((length=(token&ML_MASK)) == ML_MASK)
> +        /* get matchlength */
> +        length = token & ML_MASK;
> +        if (length == ML_MASK)
>          {
> -            while ((!endOnInput) || (ip<iend-(LASTLITERALS+1)))   // Ensure 
> enough bytes remain for LASTLITERALS + token
> +            unsigned s;
> +            do
>              {
> -                unsigned s = *ip++;
> +                if ((endOnInput) && (ip > iend-LASTLITERALS)) goto 
> _output_error;
> +                s = *ip++;
>                  length += s;
> -                if (s==255) continue;
> -                break;
> +            } while (s==255);
> +            if ((safeDecode) && unlikely((size_t)(op+length)<(size_t)op)) 
> goto _output_error;   /* overflow detection */
> +        }
> +        length += MINMATCH;
> +
> +        /* check external dictionary */
> +        if ((dict==usingExtDict) && (match < lowPrefix))
> +        {
> +            if (unlikely(op+length > oend-LASTLITERALS)) goto _output_error; 
>   /* doesn't respect parsing restriction */
> +
> +            if (length <= (size_t)(lowPrefix-match))
> +            {
> +                /* match can be copied as a single segment from external 
> dictionary */
> +                match = dictEnd - (lowPrefix-match);
> +                memmove(op, match, length); op += length;
> +            }
> +            else
> +            {
> +                /* match encompass external dictionary and current segment */
> +                size_t copySize = (size_t)(lowPrefix-match);
> +                memcpy(op, dictEnd - copySize, copySize);
> +                op += copySize;
> +                copySize = length - copySize;
> +                if (copySize > (size_t)(op-lowPrefix))   /* overlap within 
> current segment */
> +                {
> +                    BYTE* const endOfMatch = op + copySize;
> +                    const BYTE* copyFrom = lowPrefix;
> +                    while (op < endOfMatch) *op++ = *copyFrom++;
> +                }
> +                else
> +                {
> +                    memcpy(op, lowPrefix, copySize);
> +                    op += copySize;
> +                }
>              }
> +            continue;
>          }
>
> -        // copy repeated sequence
> -        if unlikely((op-ref)<(int)STEPSIZE)
> +        /* copy repeated sequence */
> +        cpy = op + length;
> +        if (unlikely((op-match)<8))
>          {
> -            const size_t dec64 = dec64table[(sizeof(void*)==4) ? 0 : op-ref];
> -            op[0] = ref[0];
> -            op[1] = ref[1];
> -            op[2] = ref[2];
> -            op[3] = ref[3];
> -            op += 4, ref += 4; ref -= dec32table[op-ref];
> -            A32(op) = A32(ref);
> -            op += STEPSIZE-4; ref -= dec64;
> -        } else { LZ4_COPYSTEP(op,ref); }
> -        cpy = op + length - (STEPSIZE-4);
> -
> -        if unlikely(cpy>oend-COPYLENGTH-(STEPSIZE-4))
> +            const size_t dec64 = dec64table[op-match];
> +            op[0] = match[0];
> +            op[1] = match[1];
> +            op[2] = match[2];
> +            op[3] = match[3];
> +            match += dec32table[op-match];
> +            LZ4_copy4(op+4, match);
> +            op += 8; match -= dec64;
> +        } else { LZ4_copy8(op, match); op+=8; match+=8; }
> +
> +        if (unlikely(cpy>oend-12))
>          {
> -            if (cpy > oend-LASTLITERALS) goto _output_error;    // Error : 
> last 5 bytes must be literals
> -            LZ4_SECURECOPY(op, ref, (oend-COPYLENGTH));
> -            while(op<cpy) *op++=*ref++;
> -            op=cpy;
> -            continue;
> +            if (cpy > oend-LASTLITERALS) goto _output_error;    /* Error : 
> last LASTLITERALS bytes must be literals */
> +            if (op < oend-8)
> +            {
> +                LZ4_wildCopy(op, match, oend-8);
> +                match += (oend-8) - op;
> +                op = oend-8;
> +            }
> +            while (op<cpy) *op++ = *match++;
>          }
> -        LZ4_WILDCOPY(op, ref, cpy);
> -        op=cpy;   // correction
> +        else
> +            LZ4_wildCopy(op, match, cpy);
> +        op=cpy;   /* correction */
>      }
>
> -    // end of decoding
> +    /* end of decoding */
>      if (endOnInput)
> -       return (int) (((char*)op)-dest);     // Nb of output bytes decoded
> +       return (int) (((char*)op)-dest);     /* Nb of output bytes decoded */
>      else
> -       return (int) (((char*)ip)-source);   // Nb of input bytes read
> +       return (int) (((const char*)ip)-source);   /* Nb of input bytes read 
> */
>
> -    // Overflow error detected
> +    /* Overflow error detected */
>  _output_error:
> -    return (int) (-(((char*)ip)-source))-1;
> +    return (int) (-(((const char*)ip)-source))-1;
>  }
>
>
> -int LZ4_decompress_safe(const char* source, char* dest, int inputSize, int 
> maxOutputSize)
> +int LZ4_decompress_safe(const char* source, char* dest, int compressedSize, 
> int maxDecompressedSize)
>  {
> -    return LZ4_decompress_generic(source, dest, inputSize, maxOutputSize, 
> endOnInputSize, noPrefix, full, 0);
> +    return LZ4_decompress_generic(source, dest, compressedSize, 
> maxDecompressedSize, endOnInputSize, full, 0, noDict, (BYTE*)dest, NULL, 0);
>  }
>
> -int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int 
> inputSize, int maxOutputSize)
> +int LZ4_decompress_safe_partial(const char* source, char* dest, int 
> compressedSize, int targetOutputSize, int maxDecompressedSize)
>  {
> -    return LZ4_decompress_generic(source, dest, inputSize, maxOutputSize, 
> endOnInputSize, withPrefix, full, 0);
> +    return LZ4_decompress_generic(source, dest, compressedSize, 
> maxDecompressedSize, endOnInputSize, partial, targetOutputSize, noDict, 
> (BYTE*)dest, NULL, 0);
>  }
>
> -int LZ4_decompress_safe_partial(const char* source, char* dest, int 
> inputSize, int targetOutputSize, int maxOutputSize)
> +int LZ4_decompress_fast(const char* source, char* dest, int originalSize)
>  {
> -    return LZ4_decompress_generic(source, dest, inputSize, maxOutputSize, 
> endOnInputSize, noPrefix, partial, targetOutputSize);
> +    return LZ4_decompress_generic(source, dest, 0, originalSize, 
> endOnOutputSize, full, 0, withPrefix64k, (BYTE*)(dest - 64 KB), NULL, 64 KB);
>  }
>
> -int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int 
> outputSize)
> +
> +/* streaming decompression functions */
> +
> +typedef struct
>  {
> -    return LZ4_decompress_generic(source, dest, 0, outputSize, 
> endOnOutputSize, withPrefix, full, 0);
> +    const BYTE* externalDict;
> +    size_t extDictSize;
> +    const BYTE* prefixEnd;
> +    size_t prefixSize;
> +} LZ4_streamDecode_t_internal;
> +
> +/*
> + * If you prefer dynamic allocation methods,
> + * LZ4_createStreamDecode()
> + * provides a pointer (void*) towards an initialized LZ4_streamDecode_t 
> structure.
> + */
> +LZ4_streamDecode_t* LZ4_createStreamDecode(void)
> +{
> +    LZ4_streamDecode_t* lz4s = (LZ4_streamDecode_t*) ALLOCATOR(1, 
> sizeof(LZ4_streamDecode_t));
> +    return lz4s;
>  }
>
> -int LZ4_decompress_fast(const char* source, char* dest, int outputSize)
> +int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream)
>  {
> -#ifdef _MSC_VER   // This version is faster with Visual
> -    return LZ4_decompress_generic(source, dest, 0, outputSize, 
> endOnOutputSize, noPrefix, full, 0);
> -#else
> -    return LZ4_decompress_generic(source, dest, 0, outputSize, 
> endOnOutputSize, withPrefix, full, 0);
> -#endif
> +    FREEMEM(LZ4_stream);
> +    return 0;
>  }
> -#endif
> +
> +/*
> + * LZ4_setStreamDecode
> + * Use this function to instruct where to find the dictionary
> + * This function is not necessary if previous data is still available where 
> it was decoded.
> + * Loading a size of 0 is allowed (same effect as no dictionary).
> + * Return : 1 if OK, 0 if error
> + */
> +int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* 
> dictionary, int dictSize)
> +{
> +    LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) 
> LZ4_streamDecode;
> +    lz4sd->prefixSize = (size_t) dictSize;
> +    lz4sd->prefixEnd = (const BYTE*) dictionary + dictSize;
> +    lz4sd->externalDict = NULL;
> +    lz4sd->extDictSize  = 0;
> +    return 1;
> +}
> +
> +/*
> +*_continue() :
> +    These decoding functions allow decompression of multiple blocks in 
> "streaming" mode.
> +    Previously decoded blocks must still be available at the memory position 
> where they were decoded.
> +    If it's not possible, save the relevant part of decoded data into a safe 
> buffer,
> +    and indicate where it stands using LZ4_setStreamDecode()
> +*/
> +int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, 
> const char* source, char* dest, int compressedSize, int maxOutputSize)
> +{
> +    LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) 
> LZ4_streamDecode;
> +    int result;
> +
> +    if (lz4sd->prefixEnd == (BYTE*)dest)
> +    {
> +        result = LZ4_decompress_generic(source, dest, compressedSize, 
> maxOutputSize,
> +                                        endOnInputSize, full, 0,
> +                                        usingExtDict, lz4sd->prefixEnd - 
> lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize);
> +        if (result <= 0) return result;
> +        lz4sd->prefixSize += result;
> +        lz4sd->prefixEnd  += result;
> +    }
> +    else
> +    {
> +        lz4sd->extDictSize = lz4sd->prefixSize;
> +        lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize;
> +        result = LZ4_decompress_generic(source, dest, compressedSize, 
> maxOutputSize,
> +                                        endOnInputSize, full, 0,
> +                                        usingExtDict, (BYTE*)dest, 
> lz4sd->externalDict, lz4sd->extDictSize);
> +        if (result <= 0) return result;
> +        lz4sd->prefixSize = result;
> +        lz4sd->prefixEnd  = (BYTE*)dest + result;
> +    }
> +
> +    return result;
> +}
> +
> +int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, 
> const char* source, char* dest, int originalSize)
> +{
> +    LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) 
> LZ4_streamDecode;
> +    int result;
> +
> +    if (lz4sd->prefixEnd == (BYTE*)dest)
> +    {
> +        result = LZ4_decompress_generic(source, dest, 0, originalSize,
> +                                        endOnOutputSize, full, 0,
> +                                        usingExtDict, lz4sd->prefixEnd - 
> lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize);
> +        if (result <= 0) return result;
> +        lz4sd->prefixSize += originalSize;
> +        lz4sd->prefixEnd  += originalSize;
> +    }
> +    else
> +    {
> +        lz4sd->extDictSize = lz4sd->prefixSize;
> +        lz4sd->externalDict = (BYTE*)dest - lz4sd->extDictSize;
> +        result = LZ4_decompress_generic(source, dest, 0, originalSize,
> +                                        endOnOutputSize, full, 0,
> +                                        usingExtDict, (BYTE*)dest, 
> lz4sd->externalDict, lz4sd->extDictSize);
> +        if (result <= 0) return result;
> +        lz4sd->prefixSize = originalSize;
> +        lz4sd->prefixEnd  = (BYTE*)dest + originalSize;
> +    }
> +
> +    return result;
> +}
> +
> +
> +/*
> +Advanced decoding functions :
> +*_usingDict() :
> +    These decoding functions work the same as "_continue" ones,
> +    the dictionary must be explicitly provided within parameters
> +*/
> +
> +FORCE_INLINE int LZ4_decompress_usingDict_generic(const char* source, char* 
> dest, int compressedSize, int maxOutputSize, int safe, const char* dictStart, 
> int dictSize)
> +{
> +    if (dictSize==0)
> +        return LZ4_decompress_generic(source, dest, compressedSize, 
> maxOutputSize, safe, full, 0, noDict, (BYTE*)dest, NULL, 0);
> +    if (dictStart+dictSize == dest)
> +    {
> +        if (dictSize >= (int)(64 KB - 1))
> +            return LZ4_decompress_generic(source, dest, compressedSize, 
> maxOutputSize, safe, full, 0, withPrefix64k, (BYTE*)dest-64 KB, NULL, 0);
> +        return LZ4_decompress_generic(source, dest, compressedSize, 
> maxOutputSize, safe, full, 0, noDict, (BYTE*)dest-dictSize, NULL, 0);
> +    }
> +    return LZ4_decompress_generic(source, dest, compressedSize, 
> maxOutputSize, safe, full, 0, usingExtDict, (BYTE*)dest, (const 
> BYTE*)dictStart, dictSize);
> +}
> +
> +int LZ4_decompress_safe_usingDict(const char* source, char* dest, int 
> compressedSize, int maxOutputSize, const char* dictStart, int dictSize)
> +{
> +    return LZ4_decompress_usingDict_generic(source, dest, compressedSize, 
> maxOutputSize, 1, dictStart, dictSize);
> +}
> +
> +int LZ4_decompress_fast_usingDict(const char* source, char* dest, int 
> originalSize, const char* dictStart, int dictSize)
> +{
> +    return LZ4_decompress_usingDict_generic(source, dest, 0, originalSize, 
> 0, dictStart, dictSize);
> +}
> +
> +/* debug function */
> +int LZ4_decompress_safe_forceExtDict(const char* source, char* dest, int 
> compressedSize, int maxOutputSize, const char* dictStart, int dictSize)
> +{
> +    return LZ4_decompress_generic(source, dest, compressedSize, 
> maxOutputSize, endOnInputSize, full, 0, usingExtDict, (BYTE*)dest, (const 
> BYTE*)dictStart, dictSize);
> +}
> +
> +
> +/***************************************************
> +*  Obsolete Functions
> +***************************************************/
> +/* obsolete compression functions */
> +int LZ4_compress_limitedOutput(const char* source, char* dest, int 
> inputSize, int maxOutputSize) { return LZ4_compress_default(source, dest, 
> inputSize, maxOutputSize); }
> +int LZ4_compress(const char* source, char* dest, int inputSize) { return 
> LZ4_compress_default(source, dest, inputSize, LZ4_compressBound(inputSize)); }
> +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); }
> +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); }
> +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); }
> +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); }
> +
> +/*
> +These function names are deprecated and should no longer be used.
> +They are only provided here for compatibility with older user programs.
> +- LZ4_uncompress is totally equivalent to LZ4_decompress_fast
> +- LZ4_uncompress_unknownOutputSize is totally equivalent to 
> LZ4_decompress_safe
> +*/
> +int LZ4_uncompress (const char* source, char* dest, int outputSize) { return 
> LZ4_decompress_fast(source, dest, outputSize); }
> +int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int 
> isize, int maxOutputSize) { return LZ4_decompress_safe(source, dest, isize, 
> maxOutputSize); }
> +
> +
> +/* Obsolete Streaming functions */
> +
> +int LZ4_sizeofStreamState() { return LZ4_STREAMSIZE; }
> +
> +static void LZ4_init(LZ4_stream_t_internal* lz4ds, BYTE* base)
> +{
> +    MEM_INIT(lz4ds, 0, LZ4_STREAMSIZE);
> +    lz4ds->bufferStart = base;
> +}
> +
> +int LZ4_resetStreamState(void* state, char* inputBuffer)
> +{
> +    if ((((size_t)state) & 3) != 0) return 1;   /* Error : pointer is not 
> aligned on 4-bytes boundary */
> +    LZ4_init((LZ4_stream_t_internal*)state, (BYTE*)inputBuffer);
> +    return 0;
> +}
> +
> +void* LZ4_create (char* inputBuffer)
> +{
> +    void* lz4ds = ALLOCATOR(8, LZ4_STREAMSIZE_U64);
> +    LZ4_init ((LZ4_stream_t_internal*)lz4ds, (BYTE*)inputBuffer);
> +    return lz4ds;
> +}
> +
> +char* LZ4_slideInputBuffer (void* LZ4_Data)
> +{
> +    LZ4_stream_t_internal* ctx = (LZ4_stream_t_internal*)LZ4_Data;
> +    int dictSize = LZ4_saveDict((LZ4_stream_t*)LZ4_Data, 
> (char*)ctx->bufferStart, 64 KB);
> +    return (char*)(ctx->bufferStart + dictSize);
> +}
> +
> +/* Obsolete streaming decompression functions */
> +
> +int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int 
> compressedSize, int maxOutputSize)
> +{
> +    return LZ4_decompress_generic(source, dest, compressedSize, 
> maxOutputSize, endOnInputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, 
> NULL, 64 KB);
> +}
> +
> +int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int 
> originalSize)
> +{
> +    return LZ4_decompress_generic(source, dest, 0, originalSize, 
> endOnOutputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB);
> +}
> +
> +#endif   /* LZ4_COMMONDEFS_ONLY */
> +
> +#endif /* NEED_COMPAT_LZ4 */
> diff --git a/src/compat/compat-lz4.h b/src/compat/compat-lz4.h
> index a289fcf..3e74002 100644
> --- a/src/compat/compat-lz4.h
> +++ b/src/compat/compat-lz4.h
> @@ -1,7 +1,8 @@
>  /*
>     LZ4 - Fast LZ compression algorithm
>     Header File
> -   Copyright (C) 2011-2013, Yann Collet.
> +   Copyright (C) 2011-2015, Yann Collet.
> +
>     BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
>
>     Redistribution and use in source and binary forms, with or without
> @@ -28,8 +29,8 @@
>     OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
>
>     You can contact the author at :
> -   - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
> -   - LZ4 source repository : http://code.google.com/p/lz4/
> +   - LZ4 source repository : https://github.com/Cyan4973/lz4
> +   - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
>  */
>  #pragma once
>
> @@ -37,167 +38,321 @@
>  extern "C" {
>  #endif
>
> +/*
> + * lz4.h provides block compression functions, and gives full buffer control 
> to programmer.
> + * If you need to generate inter-operable compressed data (respecting LZ4 
> frame specification),
> + * and can let the library handle its own memory, please use lz4frame.h 
> instead.
> +*/
>
> -//**************************************
> -// Compiler Options
> -//**************************************
> -#if defined(_MSC_VER) && !defined(__cplusplus)   // Visual Studio
> -#  define inline __inline           // Visual C is not C99, but supports 
> some kind of inline
> -#endif
> +/**************************************
> +*  Version
> +**************************************/
> +#define LZ4_VERSION_MAJOR    1    /* for breaking interface changes  */
> +#define LZ4_VERSION_MINOR    7    /* for new (non-breaking) interface 
> capabilities */
> +#define LZ4_VERSION_RELEASE  1    /* for tweaks, bug-fixes, or development */
> +#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR 
> *100 + LZ4_VERSION_RELEASE)
> +int LZ4_versionNumber (void);
> +
> +/**************************************
> +*  Tuning parameter
> +**************************************/
> +/*
> + * LZ4_MEMORY_USAGE :
> + * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 
> -> 64KB; 20 -> 1MB; etc.)
> + * Increasing memory usage improves compression ratio
> + * Reduced memory usage can improve speed, due to cache effect
> + * Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache
> + */
> +#define LZ4_MEMORY_USAGE 14
>
>
> -//****************************
> -// Simple Functions
> -//****************************
> +/**************************************
> +*  Simple Functions
> +**************************************/
>
> -int LZ4_compress        (const char* source, char* dest, int inputSize);
> -int LZ4_decompress_safe (const char* source, char* dest, int inputSize, int 
> maxOutputSize);
> +int LZ4_compress_default(const char* source, char* dest, int sourceSize, int 
> maxDestSize);
> +int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, 
> int maxDecompressedSize);
>
>  /*
> -LZ4_compress() :
> -    Compresses 'inputSize' bytes from 'source' into 'dest'.
> -    Destination buffer must be already allocated,
> -    and must be sized to handle worst cases situations (input data not 
> compressible)
> -    Worst case size evaluation is provided by function LZ4_compressBound()
> -    inputSize : Max supported value is LZ4_MAX_INPUT_VALUE
> -    return : the number of bytes written in buffer dest
> -             or 0 if the compression fails
> +LZ4_compress_default() :
> +    Compresses 'sourceSize' bytes from buffer 'source'
> +    into already allocated 'dest' buffer of size 'maxDestSize'.
> +    Compression is guaranteed to succeed if 'maxDestSize' >= 
> LZ4_compressBound(sourceSize).
> +    It also runs faster, so it's a recommended setting.
> +    If the function cannot compress 'source' into a more limited 'dest' 
> budget,
> +    compression stops *immediately*, and the function result is zero.
> +    As a consequence, 'dest' content is not valid.
> +    This function never writes outside 'dest' buffer, nor read outside 
> 'source' buffer.
> +        sourceSize  : Max supported value is LZ4_MAX_INPUT_VALUE
> +        maxDestSize : full or partial size of buffer 'dest' (which must be 
> already allocated)
> +        return : the number of bytes written into buffer 'dest' (necessarily 
> <= maxOutputSize)
> +              or 0 if compression fails
>
>  LZ4_decompress_safe() :
> -    maxOutputSize : is the size of the destination buffer (which must be 
> already allocated)
> -    return : the number of bytes decoded in the destination buffer 
> (necessarily <= maxOutputSize)
> +    compressedSize : is the precise full size of the compressed block.
> +    maxDecompressedSize : is the size of destination buffer, which must be 
> already allocated.
> +    return : the number of bytes decompressed into destination buffer 
> (necessarily <= maxDecompressedSize)
> +             If destination buffer is not large enough, decoding will stop 
> and output an error code (<0).
>               If the source stream is detected malformed, the function will 
> stop decoding and return a negative result.
> -             This function is protected against buffer overflow exploits 
> (never writes outside of output buffer, and never reads outside of input 
> buffer). Therefore, it is protected against malicious data packets
> +             This function is protected against buffer overflow exploits, 
> including malicious data packets.
> +             It never writes outside output buffer, nor reads outside input 
> buffer.
>  */
>
>
> -//****************************
> -// Advanced Functions
> -//****************************
> -#define LZ4_MAX_INPUT_SIZE        0x7E000000   // 2 113 929 216 bytes
> -#define LZ4_COMPRESSBOUND(isize)  ((unsigned int)(isize) > (unsigned 
> int)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16)
> -static inline int LZ4_compressBound(int isize)  { return 
> LZ4_COMPRESSBOUND(isize); }
> +/**************************************
> +*  Advanced Functions
> +**************************************/
> +#define LZ4_MAX_INPUT_SIZE        0x7E000000   /* 2 113 929 216 bytes */
> +#define LZ4_COMPRESSBOUND(isize)  ((unsigned)(isize) > 
> (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16)
>
>  /*
>  LZ4_compressBound() :
> -    Provides the maximum size that LZ4 may output in a "worst case" scenario 
> (input data not compressible)
> -    primarily useful for memory allocation of output buffer.
> -    inline function is recommended for the general case,
> -    macro is also provided when result needs to be evaluated at compilation 
> (such as stack memory allocation).
> -
> -    isize  : is the input size. Max supported value is LZ4_MAX_INPUT_SIZE
> -    return : maximum output size in a "worst case" scenario
> -             or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE)
> +    Provides the maximum size that LZ4 compression may output in a "worst 
> case" scenario (input data not compressible)
> +    This function is primarily useful for memory allocation purposes 
> (destination buffer size).
> +    Macro LZ4_COMPRESSBOUND() is also provided for compilation-time 
> evaluation (stack memory allocation for example).
> +    Note that LZ4_compress_default() compress faster when dest buffer size 
> is >= LZ4_compressBound(srcSize)
> +        inputSize  : max supported value is LZ4_MAX_INPUT_SIZE
> +        return : maximum output size in a "worst case" scenario
> +              or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE)
>  */
> +int LZ4_compressBound(int inputSize);
>
> +/*
> +LZ4_compress_fast() :
> +    Same as LZ4_compress_default(), but allows to select an "acceleration" 
> factor.
> +    The larger the acceleration value, the faster the algorithm, but also 
> the lesser the compression.
> +    It's a trade-off. It can be fine tuned, with each successive value 
> providing roughly +~3% to speed.
> +    An acceleration value of "1" is the same as regular 
> LZ4_compress_default()
> +    Values <= 0 will be replaced by ACCELERATION_DEFAULT (see lz4.c), which 
> is 1.
> +*/
> +int LZ4_compress_fast (const char* source, char* dest, int sourceSize, int 
> maxDestSize, int acceleration);
>
> -int LZ4_compress_limitedOutput (const char* source, char* dest, int 
> inputSize, int maxOutputSize);
>
>  /*
> -LZ4_compress_limitedOutput() :
> -    Compress 'inputSize' bytes from 'source' into an output buffer 'dest' of 
> maximum size 'maxOutputSize'.
> -    If it cannot achieve it, compression will stop, and result of the 
> function will be zero.
> -    This function never writes outside of provided output buffer.
> -
> -    inputSize  : Max supported value is LZ4_MAX_INPUT_VALUE
> -    maxOutputSize : is the size of the destination buffer (which must be 
> already allocated)
> -    return : the number of bytes written in buffer 'dest'
> -             or 0 if the compression fails
> +LZ4_compress_fast_extState() :
> +    Same compression function, just using an externally allocated memory 
> space to store compression state.
> +    Use LZ4_sizeofState() to know how much memory must be allocated,
> +    and allocate it on 8-bytes boundaries (using malloc() typically).
> +    Then, provide it as 'void* state' to compression function.
>  */
> +int LZ4_sizeofState(void);
> +int LZ4_compress_fast_extState (void* state, const char* source, char* dest, 
> int inputSize, int maxDestSize, int acceleration);
> +
>
> +/*
> +LZ4_compress_destSize() :
> +    Reverse the logic, by compressing as much data as possible from 'source' 
> buffer
> +    into already allocated buffer 'dest' of size 'targetDestSize'.
> +    This function either compresses the entire 'source' content into 'dest' 
> if it's large enough,
> +    or fill 'dest' buffer completely with as much data as possible from 
> 'source'.
> +        *sourceSizePtr : will be modified to indicate how many bytes where 
> read from 'source' to fill 'dest'.
> +                         New value is necessarily <= old value.
> +        return : Nb bytes written into 'dest' (necessarily <= targetDestSize)
> +              or 0 if compression fails
> +*/
> +int LZ4_compress_destSize (const char* source, char* dest, int* 
> sourceSizePtr, int targetDestSize);
>
> -int LZ4_decompress_fast (const char* source, char* dest, int outputSize);
>
>  /*
>  LZ4_decompress_fast() :
> -    outputSize : is the original (uncompressed) size
> +    originalSize : is the original and therefore uncompressed size
>      return : the number of bytes read from the source buffer (in other 
> words, the compressed size)
> -             If the source stream is malformed, the function will stop 
> decoding and return a negative result.
> -    note : This function is a bit faster than LZ4_decompress_safe()
> -           This function never writes outside of output buffers, but may 
> read beyond input buffer in case of malicious data packet.
> -           Use this function preferably into a trusted environment (data to 
> decode comes from a trusted source).
> -           Destination buffer must be already allocated. Its size must be a 
> minimum of 'outputSize' bytes.
> +             If the source stream is detected malformed, the function will 
> stop decoding and return a negative result.
> +             Destination buffer must be already allocated. Its size must be 
> a minimum of 'originalSize' bytes.
> +    note : This function fully respect memory boundaries for properly formed 
> compressed data.
> +           It is a bit faster than LZ4_decompress_safe().
> +           However, it does not provide any protection against intentionally 
> modified data stream (malicious input).
> +           Use this function in trusted environment only (data to decode 
> comes from a trusted source).
>  */
> -
> -int LZ4_decompress_safe_partial (const char* source, char* dest, int 
> inputSize, int targetOutputSize, int maxOutputSize);
> +int LZ4_decompress_fast (const char* source, char* dest, int originalSize);
>
>  /*
>  LZ4_decompress_safe_partial() :
> -    This function decompress a compressed block of size 'inputSize' at 
> position 'source'
> -    into output buffer 'dest' of size 'maxOutputSize'.
> +    This function decompress a compressed block of size 'compressedSize' at 
> position 'source'
> +    into destination buffer 'dest' of size 'maxDecompressedSize'.
>      The function tries to stop decompressing operation as soon as 
> 'targetOutputSize' has been reached,
>      reducing decompression time.
> -    return : the number of bytes decoded in the destination buffer 
> (necessarily <= maxOutputSize)
> +    return : the number of bytes decoded in the destination buffer 
> (necessarily <= maxDecompressedSize)
>         Note : this number can be < 'targetOutputSize' should the compressed 
> block to decode be smaller.
>               Always control how many bytes were decoded.
>               If the source stream is detected malformed, the function will 
> stop decoding and return a negative result.
>               This function never writes outside of output buffer, and never 
> reads outside of input buffer. It is therefore protected against malicious 
> data packets
>  */
> +int LZ4_decompress_safe_partial (const char* source, char* dest, int 
> compressedSize, int targetOutputSize, int maxDecompressedSize);
>
>
> -//****************************
> -// Stream Functions
> -//****************************
> -
> -void* LZ4_create (const char* inputBuffer);
> -int   LZ4_compress_continue (void* LZ4_Data, const char* source, char* dest, 
> int inputSize);
> -int   LZ4_compress_limitedOutput_continue (void* LZ4_Data, const char* 
> source, char* dest, int inputSize, int maxOutputSize);
> -char* LZ4_slideInputBuffer (void* LZ4_Data);
> -int   LZ4_free (void* LZ4_Data);
> -
> +/***********************************************
> +*  Streaming Compression Functions
> +***********************************************/
> +#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4)
> +#define LZ4_STREAMSIZE     (LZ4_STREAMSIZE_U64 * sizeof(long long))
>  /*
> -These functions allow the compression of dependent blocks, where each block 
> benefits from prior 64 KB within preceding blocks.
> -In order to achieve this, it is necessary to start creating the LZ4 Data 
> Structure, thanks to the function :
> -
> -void* LZ4_create (const char* inputBuffer);
> -The result of the function is the (void*) pointer on the LZ4 Data Structure.
> -This pointer will be needed in all other functions.
> -If the pointer returned is NULL, then the allocation has failed, and 
> compression must be aborted.
> -The only parameter 'const char* inputBuffer' must, obviously, point at the 
> beginning of input buffer.
> -The input buffer must be already allocated, and size at least 192KB.
> -'inputBuffer' will also be the 'const char* source' of the first block.
> + * LZ4_stream_t
> + * information structure to track an LZ4 stream.
> + * important : init this structure content before first use !
> + * note : only allocated directly the structure if you are statically 
> linking LZ4
> + *        If you are using liblz4 as a DLL, please use below construction 
> methods instead.
> + */
> +typedef struct { long long table[LZ4_STREAMSIZE_U64]; } LZ4_stream_t;
>
> -All blocks are expected to lay next to each other within the input buffer, 
> starting from 'inputBuffer'.
> -To compress each block, use either LZ4_compress_continue() or 
> LZ4_compress_limitedOutput_continue().
> -Their behavior are identical to LZ4_compress() or 
> LZ4_compress_limitedOutput(),
> -but require the LZ4 Data Structure as their first argument, and check that 
> each block starts right after the previous one.
> -If next block does not begin immediately after the previous one, the 
> compression will fail (return 0).
> +/*
> + * LZ4_resetStream
> + * Use this function to init an allocated LZ4_stream_t structure
> + */
> +void LZ4_resetStream (LZ4_stream_t* streamPtr);
>
> -When it's no longer possible to lay the next block after the previous one 
> (not enough space left into input buffer), a call to :
> -char* LZ4_slideInputBuffer(void* LZ4_Data);
> -must be performed. It will typically copy the latest 64KB of input at the 
> beginning of input buffer.
> -Note that, for this function to work properly, minimum size of an input 
> buffer must be 192KB.
> -==> The memory position where the next input data block must start is 
> provided as the result of the function.
> +/*
> + * LZ4_createStream will allocate and initialize an LZ4_stream_t structure
> + * LZ4_freeStream releases its memory.
> + * In the context of a DLL (liblz4), please use these methods rather than 
> the static struct.
> + * They are more future proof, in case of a change of LZ4_stream_t size.
> + */
> +LZ4_stream_t* LZ4_createStream(void);
> +int           LZ4_freeStream (LZ4_stream_t* streamPtr);
>
> -Compression can then resume, using LZ4_compress_continue() or 
> LZ4_compress_limitedOutput_continue(), as usual.
> +/*
> + * LZ4_loadDict
> + * Use this function to load a static dictionary into LZ4_stream.
> + * Any previous data will be forgotten, only 'dictionary' will remain in 
> memory.
> + * Loading a size of 0 is allowed.
> + * Return : dictionary size, in bytes (necessarily <= 64 KB)
> + */
> +int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int 
> dictSize);
>
> -When compression is completed, a call to LZ4_free() will release the memory 
> used by the LZ4 Data Structure.
> -*/
> +/*
> + * LZ4_compress_fast_continue
> + * Compress buffer content 'src', using data from previously compressed 
> blocks as dictionary to improve compression ratio.
> + * Important : Previous data blocks are assumed to still be present and 
> unmodified !
> + * 'dst' buffer must be already allocated.
> + * If maxDstSize >= LZ4_compressBound(srcSize), compression is guaranteed to 
> succeed, and runs faster.
> + * If not, and if compressed data cannot fit into 'dst' buffer size, 
> compression stops, and function returns a zero.
> + */
> +int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, 
> char* dst, int srcSize, int maxDstSize, int acceleration);
>
> +/*
> + * LZ4_saveDict
> + * If previously compressed data block is not guaranteed to remain available 
> at its memory location
> + * save it into a safer place (char* safeBuffer)
> + * Note : you don't need to call LZ4_loadDict() afterwards,
> + *        dictionary is immediately usable, you can therefore call 
> LZ4_compress_fast_continue()
> + * Return : saved dictionary size in bytes (necessarily <= dictSize), or 0 
> if error
> + */
> +int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int dictSize);
> +
> +
> +/************************************************
> +*  Streaming Decompression Functions
> +************************************************/
> +
> +#define LZ4_STREAMDECODESIZE_U64  4
> +#define LZ4_STREAMDECODESIZE     (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned 
> long long))
> +typedef struct { unsigned long long table[LZ4_STREAMDECODESIZE_U64]; } 
> LZ4_streamDecode_t;
> +/*
> + * LZ4_streamDecode_t
> + * information structure to track an LZ4 stream.
> + * init this structure content using LZ4_setStreamDecode or memset() before 
> first use !
> + *
> + * In the context of a DLL (liblz4) please prefer usage of construction 
> methods below.
> + * They are more future proof, in case of a change of LZ4_streamDecode_t 
> size in the future.
> + * LZ4_createStreamDecode will allocate and initialize an LZ4_streamDecode_t 
> structure
> + * LZ4_freeStreamDecode releases its memory.
> + */
> +LZ4_streamDecode_t* LZ4_createStreamDecode(void);
> +int                 LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream);
>
> -int LZ4_decompress_safe_withPrefix64k (const char* source, char* dest, int 
> inputSize, int maxOutputSize);
> -int LZ4_decompress_fast_withPrefix64k (const char* source, char* dest, int 
> outputSize);
> +/*
> + * LZ4_setStreamDecode
> + * Use this function to instruct where to find the dictionary.
> + * Setting a size of 0 is allowed (same effect as reset).
> + * Return : 1 if OK, 0 if error
> + */
> +int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* 
> dictionary, int dictSize);
>
>  /*
> -*_withPrefix64k() :
> -    These decoding functions work the same as their "normal name" versions,
> -    but can use up to 64KB of data in front of 'char* dest'.
> -    These functions are necessary to decode inter-dependant blocks.
> +*_continue() :
> +    These decoding functions allow decompression of multiple blocks in 
> "streaming" mode.
> +    Previously decoded blocks *must* remain available at the memory position 
> where they were decoded (up to 64 KB)
> +    In the case of a ring buffers, decoding buffer must be either :
> +    - Exactly same size as encoding buffer, with same update rule (block 
> boundaries at same positions)
> +      In which case, the decoding & encoding ring buffer can have any size, 
> including very small ones ( < 64 KB).
> +    - Larger than encoding buffer, by a minimum of maxBlockSize more bytes.
> +      maxBlockSize is implementation dependent. It's the maximum size you 
> intend to compress into a single block.
> +      In which case, encoding and decoding buffers do not need to be 
> synchronized,
> +      and encoding ring buffer can have any size, including small ones ( < 
> 64 KB).
> +    - _At least_ 64 KB + 8 bytes + maxBlockSize.
> +      In which case, encoding and decoding buffers do not need to be 
> synchronized,
> +      and encoding ring buffer can have any size, including larger than 
> decoding buffer.
> +    Whenever these conditions are not possible, save the last 64KB of 
> decoded data into a safe buffer,
> +    and indicate where it is saved using LZ4_setStreamDecode()
>  */
> +int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, 
> const char* source, char* dest, int compressedSize, int maxDecompressedSize);
> +int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, 
> const char* source, char* dest, int originalSize);
>
>
> -//****************************
> -// Obsolete Functions
> -//****************************
> -
> -static inline int LZ4_uncompress (const char* source, char* dest, int 
> outputSize) { return LZ4_decompress_fast(source, dest, outputSize); }
> -static inline int LZ4_uncompress_unknownOutputSize (const char* source, 
> char* dest, int isize, int maxOutputSize) { return 
> LZ4_decompress_safe(source, dest, isize, maxOutputSize); }
> -
>  /*
> -These functions are deprecated and should no longer be used.
> -They are provided here for compatibility with existing user programs.
> +Advanced decoding functions :
> +*_usingDict() :
> +    These decoding functions work the same as
> +    a combination of LZ4_setStreamDecode() followed by 
> LZ4_decompress_x_continue()
> +    They are stand-alone. They don't need nor update an LZ4_streamDecode_t 
> structure.
>  */
> -
> +int LZ4_decompress_safe_usingDict (const char* source, char* dest, int 
> compressedSize, int maxDecompressedSize, const char* dictStart, int dictSize);
> +int LZ4_decompress_fast_usingDict (const char* source, char* dest, int 
> originalSize, const char* dictStart, int dictSize);
> +
> +
> +
> +/**************************************
> +*  Obsolete Functions
> +**************************************/
> +/* Deprecate Warnings */
> +/* Should these warnings messages be a problem,
> +   it is generally possible to disable them,
> +   with -Wno-deprecated-declarations for gcc
> +   or _CRT_SECURE_NO_WARNINGS in Visual for example.
> +   You can also define LZ4_DEPRECATE_WARNING_DEFBLOCK. */
> +#ifndef LZ4_DEPRECATE_WARNING_DEFBLOCK
> +#  define LZ4_DEPRECATE_WARNING_DEFBLOCK
> +#  define LZ4_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
> +#  if (LZ4_GCC_VERSION >= 405) || defined(__clang__)
> +#    define LZ4_DEPRECATED(message) __attribute__((deprecated(message)))
> +#  elif (LZ4_GCC_VERSION >= 301)
> +#    define LZ4_DEPRECATED(message) __attribute__((deprecated))
> +#  elif defined(_MSC_VER)
> +#    define LZ4_DEPRECATED(message) __declspec(deprecated(message))
> +#  else
> +#    pragma message("WARNING: You need to implement LZ4_DEPRECATED for this 
> compiler")
> +#    define LZ4_DEPRECATED(message)
> +#  endif
> +#endif /* LZ4_DEPRECATE_WARNING_DEFBLOCK */
> +
> +/* Obsolete compression functions */
> +/* These functions are planned to start generate warnings by r131 
> approximately */
> +int LZ4_compress               (const char* source, char* dest, int 
> sourceSize);
> +int LZ4_compress_limitedOutput (const char* source, char* dest, int 
> sourceSize, int maxOutputSize);
> +int LZ4_compress_withState               (void* state, const char* source, 
> char* dest, int inputSize);
> +int LZ4_compress_limitedOutput_withState (void* state, const char* source, 
> char* dest, int inputSize, int maxOutputSize);
> +int LZ4_compress_continue                (LZ4_stream_t* LZ4_streamPtr, const 
> char* source, char* dest, int inputSize);
> +int LZ4_compress_limitedOutput_continue  (LZ4_stream_t* LZ4_streamPtr, const 
> char* source, char* dest, int inputSize, int maxOutputSize);
> +
> +/* Obsolete decompression functions */
> +/* These function names are completely deprecated and must no longer be used.
> +   They are only provided here for compatibility with older programs.
> +    - LZ4_uncompress is the same as LZ4_decompress_fast
> +    - LZ4_uncompress_unknownOutputSize is the same as LZ4_decompress_safe
> +   These function prototypes are now disabled; uncomment them only if you 
> really need them.
> +   It is highly recommended to stop using these prototypes and migrate to 
> maintained ones */
> +/* int LZ4_uncompress (const char* source, char* dest, int outputSize); */
> +/* int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int 
> isize, int maxOutputSize); */
> +
> +/* Obsolete streaming functions; use new streaming interface whenever 
> possible */
> +LZ4_DEPRECATED("use LZ4_createStream() instead") void* LZ4_create (char* 
> inputBuffer);
> +LZ4_DEPRECATED("use LZ4_createStream() instead") int   
> LZ4_sizeofStreamState(void);
> +LZ4_DEPRECATED("use LZ4_resetStream() instead")  int   
> LZ4_resetStreamState(void* state, char* inputBuffer);
> +LZ4_DEPRECATED("use LZ4_saveDict() instead")     char* LZ4_slideInputBuffer 
> (void* state);
> +
> +/* Obsolete streaming decoding functions */
> +LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") int 
> LZ4_decompress_safe_withPrefix64k (const char* src, char* dst, int 
> compressedSize, int maxDstSize);
> +LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") int 
> LZ4_decompress_fast_withPrefix64k (const char* src, char* dst, int 
> originalSize);
>
>
>  #if defined (__cplusplus)
> --
> 2.7.3

ACK, diff looks sane:

$ diff -u ~/Downloads/lz4-r131/lib/lz4.h src/compat/compat-lz4.h
$ diff -u ~/Downloads/lz4-r131/lib/lz4.c src/compat/compat-lz4.c
--- /home/steffan/Downloads/lz4-r131/lib/lz4.c    2015-06-29
11:48:37.000000000 +0200
+++ src/compat/compat-lz4.c    2016-06-09 14:01:26.929361853 +0200
@@ -32,6 +32,13 @@
    - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
 */

+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+
+#ifdef NEED_COMPAT_LZ4

 /**************************************
 *  Tuning parameters
@@ -65,7 +72,7 @@
 /**************************************
 *  Includes
 **************************************/
-#include "lz4.h"
+#include "compat-lz4.h"


 /**************************************
@@ -1514,3 +1521,4 @@

 #endif   /* LZ4_COMMONDEFS_ONLY */

+#endif /* NEED_COMPAT_LZ4 */

-Steffan

Reply via email to