lz4hc.c revision 33dca250ee0afa3aec58bf3bf1a34b09bebf3fb5
1fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet./*
2508855c48826aa0544a907f02b52515aabba5e16Yann ColletLZ4 HC - High Compression Mode of LZ4
3508855c48826aa0544a907f02b52515aabba5e16Yann ColletCopyright (C) 2011-2014, Yann Collet.
4508855c48826aa0544a907f02b52515aabba5e16Yann ColletBSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
5508855c48826aa0544a907f02b52515aabba5e16Yann Collet
6508855c48826aa0544a907f02b52515aabba5e16Yann ColletRedistribution and use in source and binary forms, with or without
7508855c48826aa0544a907f02b52515aabba5e16Yann Colletmodification, are permitted provided that the following conditions are
8508855c48826aa0544a907f02b52515aabba5e16Yann Colletmet:
9508855c48826aa0544a907f02b52515aabba5e16Yann Collet
10508855c48826aa0544a907f02b52515aabba5e16Yann Collet* Redistributions of source code must retain the above copyright
11508855c48826aa0544a907f02b52515aabba5e16Yann Colletnotice, this list of conditions and the following disclaimer.
12508855c48826aa0544a907f02b52515aabba5e16Yann Collet* Redistributions in binary form must reproduce the above
13508855c48826aa0544a907f02b52515aabba5e16Yann Colletcopyright notice, this list of conditions and the following disclaimer
14508855c48826aa0544a907f02b52515aabba5e16Yann Colletin the documentation and/or other materials provided with the
15508855c48826aa0544a907f02b52515aabba5e16Yann Colletdistribution.
16508855c48826aa0544a907f02b52515aabba5e16Yann Collet
17508855c48826aa0544a907f02b52515aabba5e16Yann ColletTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18508855c48826aa0544a907f02b52515aabba5e16Yann Collet"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19508855c48826aa0544a907f02b52515aabba5e16Yann ColletLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20508855c48826aa0544a907f02b52515aabba5e16Yann ColletA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21508855c48826aa0544a907f02b52515aabba5e16Yann ColletOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22508855c48826aa0544a907f02b52515aabba5e16Yann ColletSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23508855c48826aa0544a907f02b52515aabba5e16Yann ColletLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24508855c48826aa0544a907f02b52515aabba5e16Yann ColletDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25508855c48826aa0544a907f02b52515aabba5e16Yann ColletTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26508855c48826aa0544a907f02b52515aabba5e16Yann Collet(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27508855c48826aa0544a907f02b52515aabba5e16Yann ColletOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28508855c48826aa0544a907f02b52515aabba5e16Yann Collet
29508855c48826aa0544a907f02b52515aabba5e16Yann ColletYou can contact the author at :
30508855c48826aa0544a907f02b52515aabba5e16Yann Collet- LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html
31508855c48826aa0544a907f02b52515aabba5e16Yann Collet- LZ4 source repository : http://code.google.com/p/lz4/
32fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.*/
33fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
3469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.
3569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.
3669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./**************************************
37508855c48826aa0544a907f02b52515aabba5e16Yann ColletTuning Parameter
3869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.**************************************/
3969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#define LZ4HC_DEFAULT_COMPRESSIONLEVEL 8
4069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.
4169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.
4269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./**************************************
43508855c48826aa0544a907f02b52515aabba5e16Yann ColletMemory routines
4469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.**************************************/
4569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#include <stdlib.h>   /* calloc, free */
46fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define ALLOCATOR(s)  calloc(1,s)
47fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define FREEMEM       free
4869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#include <string.h>   /* memset, memcpy */
49fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define MEM_INIT      memset
50fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
51fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
5269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./**************************************
5333dca250ee0afa3aec58bf3bf1a34b09bebf3fb5Yann Collet   CPU Feature Detection
5469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.**************************************/
5569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./* 32 or 64 bits ? */
56fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#if (defined(__x86_64__) || defined(_M_X64) || defined(_WIN64) \
57508855c48826aa0544a907f02b52515aabba5e16Yann Collet    || defined(__64BIT__)  || defined(__mips64) \
58508855c48826aa0544a907f02b52515aabba5e16Yann Collet    || defined(__powerpc64__) || defined(__powerpc64le__) \
59508855c48826aa0544a907f02b52515aabba5e16Yann Collet    || defined(__ppc64__) || defined(__ppc64le__) \
60508855c48826aa0544a907f02b52515aabba5e16Yann Collet    || defined(__PPC64__) || defined(__PPC64LE__) \
61508855c48826aa0544a907f02b52515aabba5e16Yann Collet    || defined(__ia64) || defined(__itanium__) || defined(_M_IA64) \
62508855c48826aa0544a907f02b52515aabba5e16Yann Collet    || defined(__s390x__) )   /* Detects 64 bits mode */
63fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  define LZ4_ARCH64 1
64fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#else
65fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  define LZ4_ARCH64 0
66fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#endif
67fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
6869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./*
69508855c48826aa0544a907f02b52515aabba5e16Yann Collet* Little Endian or Big Endian ?
70508855c48826aa0544a907f02b52515aabba5e16Yann Collet* Overwrite the #define below if you know your architecture endianess
71508855c48826aa0544a907f02b52515aabba5e16Yann Collet*/
720c62103105143eaaf0fa5caae09e65318063a417Yann Collet#include <stdlib.h>   /* Apparently required to detect endianess */
73fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#if defined (__GLIBC__)
74fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  include <endian.h>
75fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  if (__BYTE_ORDER == __BIG_ENDIAN)
76fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#     define LZ4_BIG_ENDIAN 1
77fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  endif
78fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#elif (defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN)) && !(defined(__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN))
79fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  define LZ4_BIG_ENDIAN 1
80fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#elif defined(__sparc) || defined(__sparc__) \
81508855c48826aa0544a907f02b52515aabba5e16Yann Collet    || defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) \
82508855c48826aa0544a907f02b52515aabba5e16Yann Collet    || defined(__hpux)  || defined(__hppa) \
83508855c48826aa0544a907f02b52515aabba5e16Yann Collet    || defined(_MIPSEB) || defined(__s390__)
84fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  define LZ4_BIG_ENDIAN 1
85fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#else
8669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./* Little Endian assumed. PDP Endian and other very rare endian format are unsupported. */
87fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#endif
88fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
8969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./*
90508855c48826aa0544a907f02b52515aabba5e16Yann Collet* Unaligned memory access is automatically enabled for "common" CPU, such as x86.
91508855c48826aa0544a907f02b52515aabba5e16Yann Collet* For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected
92508855c48826aa0544a907f02b52515aabba5e16Yann Collet* If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance
93508855c48826aa0544a907f02b52515aabba5e16Yann Collet*/
94fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#if defined(__ARM_FEATURE_UNALIGNED)
95fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  define LZ4_FORCE_UNALIGNED_ACCESS 1
96fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#endif
97fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
9869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./* Define this parameter if your target system or compiler does not support hardware bit count */
9969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#if defined(_MSC_VER) && defined(_WIN32_WCE)            /* Visual Studio for Windows CE does not support Hardware bit count */
100fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  define LZ4_FORCE_SW_BITCOUNT
101fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#endif
102fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
103fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
10469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./**************************************
10533dca250ee0afa3aec58bf3bf1a34b09bebf3fb5Yann Collet   Compiler Options
10669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.**************************************/
10769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)   /* C99 */
10869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./* "restrict" is a known keyword */
109fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#else
11069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#  define restrict /* Disable restrict */
111fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#endif
112fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
11369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#ifdef _MSC_VER    /* Visual Studio */
114fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  define FORCE_INLINE static __forceinline
11569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#  include <intrin.h>                    /* For Visual 2005 */
11669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#  if LZ4_ARCH64   /* 64-bits */
11769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#    pragma intrinsic(_BitScanForward64) /* For Visual 2005 */
11869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#    pragma intrinsic(_BitScanReverse64) /* For Visual 2005 */
11969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#  else            /* 32-bits */
12069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#    pragma intrinsic(_BitScanForward)   /* For Visual 2005 */
12169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#    pragma intrinsic(_BitScanReverse)   /* For Visual 2005 */
122fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  endif
12369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#  pragma warning(disable : 4127)        /* disable: C4127: conditional expression is constant */
12469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#  pragma warning(disable : 4701)        /* disable: C4701: potentially uninitialized local variable used */
125fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#else
126fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  ifdef __GNUC__
127fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#    define FORCE_INLINE static inline __attribute__((always_inline))
128fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  else
129fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#    define FORCE_INLINE static inline
130fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  endif
131fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#endif
132fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
13369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#ifdef _MSC_VER  /* Visual Studio */
134fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  define lz4_bswap16(x) _byteswap_ushort(x)
135fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#else
136fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  define lz4_bswap16(x)  ((unsigned short int) ((((x) >> 8) & 0xffu) | (((x) & 0xffu) << 8)))
137fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#endif
138fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
139fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
14069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./**************************************
14133dca250ee0afa3aec58bf3bf1a34b09bebf3fb5Yann Collet   Includes
14269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.**************************************/
143fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#include "lz4.h"
14433dca250ee0afa3aec58bf3bf1a34b09bebf3fb5Yann Collet#include "lz4hc.h"
145fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
146fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
14769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./**************************************
14833dca250ee0afa3aec58bf3bf1a34b09bebf3fb5Yann Collet   Basic Types
14969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.**************************************/
15069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)   /* C99 */
151fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.# include <stdint.h>
152508855c48826aa0544a907f02b52515aabba5e16Yann Collettypedef uint8_t  BYTE;
153508855c48826aa0544a907f02b52515aabba5e16Yann Collettypedef uint16_t U16;
154508855c48826aa0544a907f02b52515aabba5e16Yann Collettypedef uint32_t U32;
155508855c48826aa0544a907f02b52515aabba5e16Yann Collettypedef  int32_t S32;
156508855c48826aa0544a907f02b52515aabba5e16Yann Collettypedef uint64_t U64;
157fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#else
158508855c48826aa0544a907f02b52515aabba5e16Yann Collettypedef unsigned char       BYTE;
159508855c48826aa0544a907f02b52515aabba5e16Yann Collettypedef unsigned short      U16;
160508855c48826aa0544a907f02b52515aabba5e16Yann Collettypedef unsigned int        U32;
161508855c48826aa0544a907f02b52515aabba5e16Yann Collettypedef   signed int        S32;
162508855c48826aa0544a907f02b52515aabba5e16Yann Collettypedef unsigned long long  U64;
163fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#endif
164fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
165fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#if defined(__GNUC__)  && !defined(LZ4_FORCE_UNALIGNED_ACCESS)
166fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  define _PACKED __attribute__ ((packed))
167fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#else
168fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  define _PACKED
169fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#endif
170fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
171fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__)
172fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  ifdef __IBMC__
173fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#    pragma pack(1)
174fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  else
175fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#    pragma pack(push, 1)
176fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  endif
177fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#endif
178fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
179fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.typedef struct _U16_S { U16 v; } _PACKED U16_S;
180fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.typedef struct _U32_S { U32 v; } _PACKED U32_S;
181fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.typedef struct _U64_S { U64 v; } _PACKED U64_S;
182fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
183fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#if !defined(LZ4_FORCE_UNALIGNED_ACCESS) && !defined(__GNUC__)
184fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  pragma pack(pop)
185fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#endif
186fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
187fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define A64(x) (((U64_S *)(x))->v)
188fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define A32(x) (((U32_S *)(x))->v)
189fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define A16(x) (((U16_S *)(x))->v)
190fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
191fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
19269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./**************************************
193508855c48826aa0544a907f02b52515aabba5e16Yann ColletConstants
19469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.**************************************/
195fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define MINMATCH 4
196fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
197fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define DICTIONARY_LOGSIZE 16
198fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define MAXD (1<<DICTIONARY_LOGSIZE)
199fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define MAXD_MASK ((U32)(MAXD - 1))
200fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define MAX_DISTANCE (MAXD - 1)
201fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
202fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define HASH_LOG (DICTIONARY_LOGSIZE-1)
203fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define HASHTABLESIZE (1 << HASH_LOG)
204fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define HASH_MASK (HASHTABLESIZE - 1)
205fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
206fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define ML_BITS  4
207fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define ML_MASK  (size_t)((1U<<ML_BITS)-1)
208fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define RUN_BITS (8-ML_BITS)
209fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define RUN_MASK ((1U<<RUN_BITS)-1)
210fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
211fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define COPYLENGTH 8
212fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define LASTLITERALS 5
213fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define MFLIMIT (COPYLENGTH+MINMATCH)
214fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define MINLENGTH (MFLIMIT+1)
215fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define OPTIMAL_ML (int)((ML_MASK-1)+MINMATCH)
216fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
217d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet#define KB *(1<<10)
218d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet#define MB *(1<<20)
219fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define GB *(1U<<30)
220fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
221fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
22269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./**************************************
223508855c48826aa0544a907f02b52515aabba5e16Yann ColletArchitecture-specific macros
22469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.**************************************/
22569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#if LZ4_ARCH64   /* 64-bit */
226fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  define STEPSIZE 8
227fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  define LZ4_COPYSTEP(s,d)     A64(d) = A64(s); d+=8; s+=8;
228fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  define LZ4_COPYPACKET(s,d)   LZ4_COPYSTEP(s,d)
229d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet#  define AARCH                 A64
23069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#else            /* 32-bit */
231fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  define STEPSIZE 4
232fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  define LZ4_COPYSTEP(s,d)     A32(d) = A32(s); d+=4; s+=4;
233fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  define LZ4_COPYPACKET(s,d)   LZ4_COPYSTEP(s,d); LZ4_COPYSTEP(s,d);
234d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet#  define AARCH                 A32
235fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#endif
236fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
237fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#if defined(LZ4_BIG_ENDIAN)
238fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  define LZ4_READ_LITTLEENDIAN_16(d,s,p) { U16 v = A16(p); v = lz4_bswap16(v); d = (s) - v; }
239fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  define LZ4_WRITE_LITTLEENDIAN_16(p,i)  { U16 v = (U16)(i); v = lz4_bswap16(v); A16(p) = v; p+=2; }
24069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#else      /* Little Endian */
241fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  define LZ4_READ_LITTLEENDIAN_16(d,s,p) { d = (s) - A16(p); }
242fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  define LZ4_WRITE_LITTLEENDIAN_16(p,v)  { A16(p) = v; p+=2; }
243fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#endif
244fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
245fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
24669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./**************************************
247508855c48826aa0544a907f02b52515aabba5e16Yann Collet Local Types
24869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.**************************************/
249fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.typedef struct
250fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
25133dca250ee0afa3aec58bf3bf1a34b09bebf3fb5Yann Collet    union {
25233dca250ee0afa3aec58bf3bf1a34b09bebf3fb5Yann Collet      U64 alignedOn8Bytes;  /* force 8-bytes alignment on 32-bits systems */
25333dca250ee0afa3aec58bf3bf1a34b09bebf3fb5Yann Collet      U32 hashTable[HASHTABLESIZE];
25433dca250ee0afa3aec58bf3bf1a34b09bebf3fb5Yann Collet    };
255d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    U16   chainTable[MAXD];
25633dca250ee0afa3aec58bf3bf1a34b09bebf3fb5Yann Collet    const BYTE* end;        /* next block here to continue on current prefix */
25761289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    const BYTE* base;       /* All index relative to this position */
25861289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    const BYTE* dictBase;   /* alternate base for extDict */
25961289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    U32   dictLimit;        /* below that point, need extDict */
26061289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    U32   lowLimit;         /* below that point, no more dict */
261d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    U32   nextToUpdate;
262d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    U32   compressionLevel;
26361289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    const BYTE* inputBuffer;   /* deprecated */
264fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.} LZ4HC_Data_Structure;
265fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
266fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
26769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./**************************************
268508855c48826aa0544a907f02b52515aabba5e16Yann Collet Macros
26969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.**************************************/
270d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet#define LZ4_STATIC_ASSERT(c)   { enum { LZ4_static_assert = 1/(!!(c)) }; }   /* Visual : use only *after* variable declarations */
271fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define LZ4_WILDCOPY(s,d,e)    do { LZ4_COPYPACKET(s,d) } while (d<e);
272fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define LZ4_BLINDCOPY(s,d,l)   { BYTE* e=d+l; LZ4_WILDCOPY(s,d,e); d=e; }
273fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define HASH_FUNCTION(i)       (((i) * 2654435761U) >> ((MINMATCH*8)-HASH_LOG))
274fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define DELTANEXT(p)           chainTable[(size_t)(p) & MAXD_MASK]
275fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#define GETNEXT(p)             ((p) - (size_t)DELTANEXT(p))
276fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
2773dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Colletstatic U32 LZ4HC_hashPtr(const void* ptr) { return HASH_FUNCTION(A32(ptr)); }
278fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
27969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./**************************************
280508855c48826aa0544a907f02b52515aabba5e16Yann ColletPrivate functions
28169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.**************************************/
282fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#if LZ4_ARCH64
283fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
284fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.FORCE_INLINE int LZ4_NbCommonBytes (register U64 val)
285fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
286fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#if defined(LZ4_BIG_ENDIAN)
287fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
288fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    unsigned long r = 0;
289fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    _BitScanReverse64( &r, val );
290fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    return (int)(r>>3);
291fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
292fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    return (__builtin_clzll(val) >> 3);
293fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  else
294fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    int r;
295fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    if (!(val>>32)) { r=4; } else { r=0; val>>=32; }
296fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
297fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    r += (!val);
298fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    return r;
299fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  endif
300fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#else
301fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
302fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    unsigned long r = 0;
303fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    _BitScanForward64( &r, val );
304fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    return (int)(r>>3);
305fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
306fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    return (__builtin_ctzll(val) >> 3);
307fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  else
308fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    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 };
309fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    return DeBruijnBytePos[((U64)((val & -val) * 0x0218A392CDABBD3F)) >> 58];
310fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  endif
311fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#endif
312fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
313fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
314fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#else
315fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
316fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.FORCE_INLINE int LZ4_NbCommonBytes (register U32 val)
317fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
318fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#if defined(LZ4_BIG_ENDIAN)
319fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
320fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    unsigned long r;
321fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    _BitScanReverse( &r, val );
322fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    return (int)(r>>3);
323fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
324fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    return (__builtin_clz(val) >> 3);
325fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  else
326fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    int r;
327fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
328fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    r += (!val);
329fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    return r;
330fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  endif
331fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#else
332fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
333fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    unsigned long r;
334fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    _BitScanForward( &r, val );
335fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    return (int)(r>>3);
336fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
337fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    return (__builtin_ctz(val) >> 3);
338fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  else
339fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    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 };
340fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
341fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#  endif
342fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#endif
343fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
344fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
345fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.#endif
346fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
347fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
34861289dea1d94510a4d6386bc44c08d3d15083123Yann Colletstatic void LZ4HC_init (LZ4HC_Data_Structure* hc4, const BYTE* base)
349fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
350fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    MEM_INIT((void*)hc4->hashTable, 0, sizeof(hc4->hashTable));
351fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    MEM_INIT(hc4->chainTable, 0xFF, sizeof(hc4->chainTable));
352e450018588560537c2c4b4b2dd3515a9ef3a83f7Yann Collet    hc4->nextToUpdate = 64 KB;
353e450018588560537c2c4b4b2dd3515a9ef3a83f7Yann Collet    hc4->base = base - 64 KB;
354fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    hc4->inputBuffer = base;
355fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    hc4->end = base;
356e450018588560537c2c4b4b2dd3515a9ef3a83f7Yann Collet    hc4->dictBase = base - 64 KB;
357e450018588560537c2c4b4b2dd3515a9ef3a83f7Yann Collet    hc4->dictLimit = 64 KB;
358e450018588560537c2c4b4b2dd3515a9ef3a83f7Yann Collet    hc4->lowLimit = 64 KB;
359fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
360fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
361fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
36269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./* Update chains up to ip (excluded) */
363fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.FORCE_INLINE void LZ4HC_Insert (LZ4HC_Data_Structure* hc4, const BYTE* ip)
364fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
365d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    U16* chainTable = hc4->chainTable;
366d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    U32* HashTable  = hc4->hashTable;
367d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    const BYTE* const base = hc4->base;
3683dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet    const U32 target = (U32)(ip - base);
369d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    U32 idx = hc4->nextToUpdate;
370fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
371d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    while(idx < target)
372fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    {
3733dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet        U32 h = LZ4HC_hashPtr(base+idx);
374d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet        size_t delta = idx - HashTable[h];
375fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        if (delta>MAX_DISTANCE) delta = MAX_DISTANCE;
376d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet        chainTable[idx & 0xFFFF] = (U16)delta;
377d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet        HashTable[h] = idx;
378d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet        idx++;
379fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    }
3807ac18ad9dc5a5555f9129659c007fe9141e422b0Yann Collet
381d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    hc4->nextToUpdate = target;
382fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
383fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
384fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
385e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Colletstatic void LZ4HC_setExternalDict(LZ4HC_Data_Structure* ctxPtr, const BYTE* newBlock)
386e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet{
387508855c48826aa0544a907f02b52515aabba5e16Yann Collet    if (ctxPtr->end >= ctxPtr->base + 4)
388508855c48826aa0544a907f02b52515aabba5e16Yann Collet        LZ4HC_Insert (ctxPtr, ctxPtr->end-3);   // finish referencing dictionary content
389e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet    // Note : need to handle risk of index overflow
390e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet    // Use only one memory segment for dict, so any previous External Dict is lost at this stage
391e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet    ctxPtr->lowLimit  = ctxPtr->dictLimit;
392e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet    ctxPtr->dictLimit = (U32)(ctxPtr->end - ctxPtr->base);
393e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet    ctxPtr->dictBase  = ctxPtr->base;
394e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet    ctxPtr->base = newBlock - ctxPtr->dictLimit;
395e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet    ctxPtr->end  = newBlock;
396e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet    ctxPtr->nextToUpdate = ctxPtr->dictLimit;   // reference table must skip to from beginning of block
397e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet}
398e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet
399e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet
400e2a985f52444ad2e1438d2a71575185f31a08540Yann Colletstatic size_t LZ4HC_CommonLength (const BYTE* p1, const BYTE* p2, const BYTE* const p1Limit)
401fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
402e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet    const BYTE* const p1Start = p1;
403fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
404e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet    while (p1 <= p1Limit - STEPSIZE)
405fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    {
406e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet        size_t diff = AARCH(p2) ^ AARCH(p1);
407e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet        if (!diff) { p1+=STEPSIZE; p2+=STEPSIZE; continue; }
408e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet        p1 += LZ4_NbCommonBytes(diff);
409e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet        return (p1 - p1Start);
410fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    }
411e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet    if (LZ4_ARCH64) if ((p1<(p1Limit-3)) && (A32(p2) == A32(p1))) { p1+=4; p2+=4; }
412e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet    if ((p1<(p1Limit-1)) && (A16(p2) == A16(p1))) { p1+=2; p2+=2; }
413e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet    if ((p1<p1Limit) && (*p2 == *p1)) p1++;
414e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet    return (p1 - p1Start);
415fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
416fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
417fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
4183dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann ColletFORCE_INLINE int LZ4HC_InsertAndFindBestMatch (LZ4HC_Data_Structure* hc4,   // Index table will be updated
419508855c48826aa0544a907f02b52515aabba5e16Yann Collet                                               const BYTE* ip, const BYTE* const iLimit,
420508855c48826aa0544a907f02b52515aabba5e16Yann Collet                                               const BYTE** matchpos,
421508855c48826aa0544a907f02b52515aabba5e16Yann Collet                                               const int maxNbAttempts)
422fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
423fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    U16* const chainTable = hc4->chainTable;
424d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    U32* const HashTable = hc4->hashTable;
425d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    const BYTE* const base = hc4->base;
426e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet    const BYTE* const dictBase = hc4->dictBase;
427e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet    const U32 dictLimit = hc4->dictLimit;
428508855c48826aa0544a907f02b52515aabba5e16Yann Collet    const U32 lowLimit = (hc4->lowLimit + 64 KB > (U32)(ip-base)) ? hc4->lowLimit : (U32)(ip - base) - (64 KB - 1);
429e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet    U32 matchIndex;
430d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    const BYTE* match;
43169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    int nbAttempts=maxNbAttempts;
432d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    size_t ml=0;
433fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
434508855c48826aa0544a907f02b52515aabba5e16Yann Collet    /* HC4 match finder */
435fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    LZ4HC_Insert(hc4, ip);
4363dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet    matchIndex = HashTable[LZ4HC_hashPtr(ip)];
437fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
438e450018588560537c2c4b4b2dd3515a9ef3a83f7Yann Collet    while ((matchIndex>=lowLimit) && (nbAttempts))
439fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    {
440fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        nbAttempts--;
4413dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet        if (matchIndex >= dictLimit)
442fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        {
4433dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet            match = base + matchIndex;
4443dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet            if (*(match+ml) == *(ip+ml)
445508855c48826aa0544a907f02b52515aabba5e16Yann Collet                && (A32(match) == A32(ip)))
4463dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet            {
4473dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                size_t mlt = LZ4HC_CommonLength(ip+MINMATCH, match+MINMATCH, iLimit) + MINMATCH;
4483dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                if (mlt > ml) { ml = mlt; *matchpos = match; }
4493dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet            }
4503dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet        }
4513dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet        else
4523dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet        {
4533dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet            match = dictBase + matchIndex;
4543dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet            if (A32(match) == A32(ip))
4553dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet            {
4563dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                size_t mlt;
4573dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                const BYTE* vLimit = ip + (dictLimit - matchIndex);
4583dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                if (vLimit > iLimit) vLimit = iLimit;
4593dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                mlt = LZ4HC_CommonLength(ip+MINMATCH, match+MINMATCH, vLimit) + MINMATCH;
4603dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                if ((ip+mlt == vLimit) && (vLimit < iLimit))
4613dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                    mlt += LZ4HC_CommonLength(ip+mlt, base+dictLimit, iLimit);
462508855c48826aa0544a907f02b52515aabba5e16Yann Collet                if (mlt > ml) { ml = mlt; *matchpos = base + matchIndex; }   // virtual matchpos
4633dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet            }
464fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        }
465d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet        matchIndex -= chainTable[matchIndex & 0xFFFF];
466fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    }
467fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
468fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    return (int)ml;
469fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
470fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
471fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
472d239a23337e5eba41f557b48eb26f0db81b28f26Yann ColletFORCE_INLINE int LZ4HC_InsertAndGetWiderMatch (
473508855c48826aa0544a907f02b52515aabba5e16Yann Collet    LZ4HC_Data_Structure* hc4,
474508855c48826aa0544a907f02b52515aabba5e16Yann Collet    const BYTE* ip,
475508855c48826aa0544a907f02b52515aabba5e16Yann Collet    const BYTE* iLowLimit,
476508855c48826aa0544a907f02b52515aabba5e16Yann Collet    const BYTE* iHighLimit,
477508855c48826aa0544a907f02b52515aabba5e16Yann Collet    int longest,
478508855c48826aa0544a907f02b52515aabba5e16Yann Collet    const BYTE** matchpos,
479508855c48826aa0544a907f02b52515aabba5e16Yann Collet    const BYTE** startpos,
480508855c48826aa0544a907f02b52515aabba5e16Yann Collet    const int maxNbAttempts)
481fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
482d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    U16* const chainTable = hc4->chainTable;
483d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    U32* const HashTable = hc4->hashTable;
484d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    const BYTE* const base = hc4->base;
4853dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet    const U32 dictLimit = hc4->dictLimit;
486508855c48826aa0544a907f02b52515aabba5e16Yann Collet    const U32 lowLimit = (hc4->lowLimit + 64 KB > (U32)(ip-base)) ? hc4->lowLimit : (U32)(ip - base) - (64 KB - 1);
4873dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet    const BYTE* const dictBase = hc4->dictBase;
488d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    const BYTE* match;
4893dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet    U32   matchIndex;
49069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    int nbAttempts = maxNbAttempts;
4913dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet    int delta = (int)(ip-iLowLimit);
492fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
493e450018588560537c2c4b4b2dd3515a9ef3a83f7Yann Collet
494508855c48826aa0544a907f02b52515aabba5e16Yann Collet    /* First Match */
495fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    LZ4HC_Insert(hc4, ip);
4963dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet    matchIndex = HashTable[LZ4HC_hashPtr(ip)];
497fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
498e450018588560537c2c4b4b2dd3515a9ef3a83f7Yann Collet    while ((matchIndex>=lowLimit) && (nbAttempts))
499fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    {
500fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        nbAttempts--;
5013dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet        if (matchIndex >= dictLimit)
502fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        {
5033dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet            match = base + matchIndex;
5043dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet            if (*(iLowLimit + longest) == *(match - delta + longest))
505508855c48826aa0544a907f02b52515aabba5e16Yann Collet                if (A32(match) == A32(ip))
506508855c48826aa0544a907f02b52515aabba5e16Yann Collet                {
507508855c48826aa0544a907f02b52515aabba5e16Yann Collet                    const BYTE* startt = ip;
508508855c48826aa0544a907f02b52515aabba5e16Yann Collet                    const BYTE* tmpMatch = match;
509508855c48826aa0544a907f02b52515aabba5e16Yann Collet                    const BYTE* const matchEnd = ip + MINMATCH + LZ4HC_CommonLength(ip+MINMATCH, match+MINMATCH, iHighLimit);
510fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
511508855c48826aa0544a907f02b52515aabba5e16Yann Collet                    while ((startt>iLowLimit) && (tmpMatch > iLowLimit) && (startt[-1] == tmpMatch[-1])) {startt--; tmpMatch--;}
512fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
513508855c48826aa0544a907f02b52515aabba5e16Yann Collet                    if ((matchEnd-startt) > longest)
514508855c48826aa0544a907f02b52515aabba5e16Yann Collet                    {
515508855c48826aa0544a907f02b52515aabba5e16Yann Collet                        longest = (int)(matchEnd-startt);
516508855c48826aa0544a907f02b52515aabba5e16Yann Collet                        *matchpos = tmpMatch;
517508855c48826aa0544a907f02b52515aabba5e16Yann Collet                        *startpos = startt;
518508855c48826aa0544a907f02b52515aabba5e16Yann Collet                    }
5193dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                }
5203dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet        }
5213dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet        else
5223dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet        {
5233dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet            match = dictBase + matchIndex;
5243dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet            if (A32(match) == A32(ip))
525fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            {
5263dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                size_t mlt;
527508855c48826aa0544a907f02b52515aabba5e16Yann Collet                int back=0;
5283dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                const BYTE* vLimit = ip + (dictLimit - matchIndex);
5293dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                if (vLimit > iHighLimit) vLimit = iHighLimit;
5303dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                mlt = LZ4HC_CommonLength(ip+MINMATCH, match+MINMATCH, vLimit) + MINMATCH;
5313dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                if ((ip+mlt == vLimit) && (vLimit < iHighLimit))
5323dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                    mlt += LZ4HC_CommonLength(ip+mlt, base+dictLimit, iHighLimit);
533508855c48826aa0544a907f02b52515aabba5e16Yann Collet                while ((ip+back > iLowLimit) && (matchIndex+back > lowLimit) && (ip[back-1] == match[back-1])) back--;
534508855c48826aa0544a907f02b52515aabba5e16Yann Collet                mlt -= back;
5353dab5f476a2e5a0cd4cd9a859e94a5110abda23dYann Collet                if ((int)mlt > longest) { longest = (int)mlt; *matchpos = base + matchIndex + back; *startpos = ip+back; }
536fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            }
537fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        }
538d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet        matchIndex -= chainTable[matchIndex & 0xFFFF];
539fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    }
540fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
541fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    return longest;
542fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
543fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
544fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
545fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.typedef enum { noLimit = 0, limitedOutput = 1 } limitedOutput_directive;
546fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
547508855c48826aa0544a907f02b52515aabba5e16Yann Collet//static unsigned debug = 0;
548508855c48826aa0544a907f02b52515aabba5e16Yann Collet
549fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.FORCE_INLINE int LZ4HC_encodeSequence (
550508855c48826aa0544a907f02b52515aabba5e16Yann Collet    const BYTE** ip,
551508855c48826aa0544a907f02b52515aabba5e16Yann Collet    BYTE** op,
552508855c48826aa0544a907f02b52515aabba5e16Yann Collet    const BYTE** anchor,
553508855c48826aa0544a907f02b52515aabba5e16Yann Collet    int matchLength,
554508855c48826aa0544a907f02b52515aabba5e16Yann Collet    const BYTE* const match,
555508855c48826aa0544a907f02b52515aabba5e16Yann Collet    limitedOutput_directive limitedOutputBuffer,
556508855c48826aa0544a907f02b52515aabba5e16Yann Collet    BYTE* oend)
557fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
558fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    int length;
559fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    BYTE* token;
560fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
5612b421e97d4e7cfbefdc007bf30133b0de7e7e14eYann Collet    //if (debug) printf("literal : %u  --  match : %u  --  offset : %u\n", (U32)(*ip - *anchor), (U32)matchLength, (U32)(*ip-match));   // debug
562e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet
56369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    /* Encode Literal length */
564fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    length = (int)(*ip - *anchor);
565fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    token = (*op)++;
566e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet    if ((limitedOutputBuffer) && ((*op + (length>>8) + length + (2 + 1 + LASTLITERALS)) > oend)) return 1;   /* Check output limit */
567fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    if (length>=(int)RUN_MASK) { int len; *token=(RUN_MASK<<ML_BITS); len = length-RUN_MASK; for(; len > 254 ; len-=255) *(*op)++ = 255;  *(*op)++ = (BYTE)len; }
568fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    else *token = (BYTE)(length<<ML_BITS);
569fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
57069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    /* Copy Literals */
571fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    LZ4_BLINDCOPY(*anchor, *op, length);
572fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
57369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    /* Encode Offset */
574d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    LZ4_WRITE_LITTLEENDIAN_16(*op,(U16)(*ip-match));
575fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
57669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    /* Encode MatchLength */
577fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    length = (int)(matchLength-MINMATCH);
578e2a985f52444ad2e1438d2a71575185f31a08540Yann Collet    if ((limitedOutputBuffer) && (*op + (length>>8) + (1 + LASTLITERALS) > oend)) return 1;   /* Check output limit */
579fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    if (length>=(int)ML_MASK) { *token+=ML_MASK; length-=ML_MASK; for(; length > 509 ; length-=510) { *(*op)++ = 255; *(*op)++ = 255; } if (length > 254) { length-=255; *(*op)++ = 255; } *(*op)++ = (BYTE)length; }
580fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    else *token += (BYTE)(length);
581fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
58269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    /* Prepare next loop */
583fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    *ip += matchLength;
584fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    *anchor = *ip;
585fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
586fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    return 0;
587fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
588fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
589fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
59069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.#define MAX_COMPRESSION_LEVEL 16
591fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.static int LZ4HC_compress_generic (
592508855c48826aa0544a907f02b52515aabba5e16Yann Collet    void* ctxvoid,
593508855c48826aa0544a907f02b52515aabba5e16Yann Collet    const char* source,
594508855c48826aa0544a907f02b52515aabba5e16Yann Collet    char* dest,
595508855c48826aa0544a907f02b52515aabba5e16Yann Collet    int inputSize,
596508855c48826aa0544a907f02b52515aabba5e16Yann Collet    int maxOutputSize,
597508855c48826aa0544a907f02b52515aabba5e16Yann Collet    int compressionLevel,
598508855c48826aa0544a907f02b52515aabba5e16Yann Collet    limitedOutput_directive limit
599508855c48826aa0544a907f02b52515aabba5e16Yann Collet    )
600fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
601fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    LZ4HC_Data_Structure* ctx = (LZ4HC_Data_Structure*) ctxvoid;
602fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    const BYTE* ip = (const BYTE*) source;
603fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    const BYTE* anchor = ip;
604fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    const BYTE* const iend = ip + inputSize;
605fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    const BYTE* const mflimit = iend - MFLIMIT;
606fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    const BYTE* const matchlimit = (iend - LASTLITERALS);
607fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
608fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    BYTE* op = (BYTE*) dest;
609fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    BYTE* const oend = op + maxOutputSize;
610fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
611d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    unsigned maxNbAttempts;
612fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    int   ml, ml2, ml3, ml0;
613fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    const BYTE* ref=NULL;
614fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    const BYTE* start2=NULL;
615fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    const BYTE* ref2=NULL;
616fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    const BYTE* start3=NULL;
617fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    const BYTE* ref3=NULL;
618fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    const BYTE* start0;
619fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    const BYTE* ref0;
620fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
621fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
622d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    /* init */
623d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    if (compressionLevel > MAX_COMPRESSION_LEVEL) compressionLevel = MAX_COMPRESSION_LEVEL;
624d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    if (compressionLevel == 0) compressionLevel = LZ4HC_DEFAULT_COMPRESSIONLEVEL;
625d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    maxNbAttempts = 1 << compressionLevel;
626fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    ctx->end += inputSize;
627fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
628fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    ip++;
629fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
63069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    /* Main Loop */
631fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    while (ip < mflimit)
632fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    {
63369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.        ml = LZ4HC_InsertAndFindBestMatch (ctx, ip, matchlimit, (&ref), maxNbAttempts);
634fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        if (!ml) { ip++; continue; }
635fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
63669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.        /* saved, in case we would skip too much */
637fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        start0 = ip;
638fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        ref0 = ref;
639fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        ml0 = ml;
640fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
641fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet._Search2:
642fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        if (ip+ml < mflimit)
64369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.            ml2 = LZ4HC_InsertAndGetWiderMatch(ctx, ip + ml - 2, ip + 1, matchlimit, ml, &ref2, &start2, maxNbAttempts);
644fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        else ml2 = ml;
645fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
64669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.        if (ml2 == ml)  /* No better match */
647fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        {
648fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
649fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            continue;
650fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        }
651fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
652fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        if (start0 < ip)
653fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        {
65469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.            if (start2 < ip + ml0)   /* empirical */
655fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            {
656fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                ip = start0;
657fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                ref = ref0;
658fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                ml = ml0;
659fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            }
660fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        }
661fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
66269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.        /* Here, start0==ip */
66369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.        if ((start2 - ip) < 3)   /* First Match too small : removed */
664fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        {
665fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            ml = ml2;
666fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            ip = start2;
667fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            ref =ref2;
668fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            goto _Search2;
669fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        }
670fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
671fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet._Search3:
67269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.        /*
673508855c48826aa0544a907f02b52515aabba5e16Yann Collet        * Currently we have :
674508855c48826aa0544a907f02b52515aabba5e16Yann Collet        * ml2 > ml1, and
675508855c48826aa0544a907f02b52515aabba5e16Yann Collet        * ip1+3 <= ip2 (usually < ip1+ml1)
676508855c48826aa0544a907f02b52515aabba5e16Yann Collet        */
677fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        if ((start2 - ip) < OPTIMAL_ML)
678fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        {
679fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            int correction;
680fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            int new_ml = ml;
681fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            if (new_ml > OPTIMAL_ML) new_ml = OPTIMAL_ML;
682fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            if (ip+new_ml > start2 + ml2 - MINMATCH) new_ml = (int)(start2 - ip) + ml2 - MINMATCH;
683fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            correction = new_ml - (int)(start2 - ip);
684fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            if (correction > 0)
685fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            {
686fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                start2 += correction;
687fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                ref2 += correction;
688fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                ml2 -= correction;
689fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            }
690fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        }
69169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.        /* Now, we have start2 = ip+new_ml, with new_ml = min(ml, OPTIMAL_ML=18) */
692fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
693fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        if (start2 + ml2 < mflimit)
69469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.            ml3 = LZ4HC_InsertAndGetWiderMatch(ctx, start2 + ml2 - 3, start2, matchlimit, ml2, &ref3, &start3, maxNbAttempts);
695fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        else ml3 = ml2;
696fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
69769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.        if (ml3 == ml2) /* No better match : 2 sequences to encode */
698fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        {
69969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.            /* ip & ref are known; Now for ml */
700fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            if (start2 < ip+ml)  ml = (int)(start2 - ip);
70169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.            /* Now, encode 2 sequences */
702fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
703fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            ip = start2;
704fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml2, ref2, limit, oend)) return 0;
705fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            continue;
706fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        }
707fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
70869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.        if (start3 < ip+ml+3) /* Not enough space for match 2 : remove it */
709fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        {
71069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.            if (start3 >= (ip+ml)) /* can write Seq1 immediately ==> Seq2 is removed, so Seq3 becomes Seq1 */
711fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            {
712fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                if (start2 < ip+ml)
713fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                {
714fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                    int correction = (int)(ip+ml - start2);
715fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                    start2 += correction;
716fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                    ref2 += correction;
717fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                    ml2 -= correction;
718fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                    if (ml2 < MINMATCH)
719fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                    {
720fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                        start2 = start3;
721fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                        ref2 = ref3;
722fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                        ml2 = ml3;
723fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                    }
724fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                }
725fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
726fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
727fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                ip  = start3;
728fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                ref = ref3;
729fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                ml  = ml3;
730fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
731fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                start0 = start2;
732fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                ref0 = ref2;
733fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                ml0 = ml2;
734fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                goto _Search2;
735fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            }
736fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
737fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            start2 = start3;
738fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            ref2 = ref3;
739fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            ml2 = ml3;
740fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            goto _Search3;
741fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        }
742fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
74369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.        /*
744508855c48826aa0544a907f02b52515aabba5e16Yann Collet        * OK, now we have 3 ascending matches; let's write at least the first one
745508855c48826aa0544a907f02b52515aabba5e16Yann Collet        * ip & ref are known; Now for ml
746508855c48826aa0544a907f02b52515aabba5e16Yann Collet        */
747fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        if (start2 < ip+ml)
748fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        {
749fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            if ((start2 - ip) < (int)ML_MASK)
750fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            {
751fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                int correction;
752fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                if (ml > OPTIMAL_ML) ml = OPTIMAL_ML;
753fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                if (ip + ml > start2 + ml2 - MINMATCH) ml = (int)(start2 - ip) + ml2 - MINMATCH;
754fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                correction = ml - (int)(start2 - ip);
755fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                if (correction > 0)
756fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                {
757fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                    start2 += correction;
758fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                    ref2 += correction;
759fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                    ml2 -= correction;
760fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                }
761fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            }
762fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            else
763fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            {
764fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.                ml = (int)(start2 - ip);
765fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.            }
766fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        }
767fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        if (LZ4HC_encodeSequence(&ip, &op, &anchor, ml, ref, limit, oend)) return 0;
768fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
769fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        ip = start2;
770fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        ref = ref2;
771fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        ml = ml2;
772fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
773fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        start2 = start3;
774fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        ref2 = ref3;
775fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        ml2 = ml3;
776fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
777fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        goto _Search3;
778fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    }
779fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
78069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    /* Encode Last Literals */
781fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    {
782fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        int lastRun = (int)(iend - anchor);
78369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.        if ((limit) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) return 0;  /* Check output limit */
784fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; }
785fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        else *op++ = (BYTE)(lastRun<<ML_BITS);
786fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        memcpy(op, anchor, iend - anchor);
787fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.        op += iend-anchor;
788fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    }
789fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
79069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    /* End */
791fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.    return (int) (((char*)op)-dest);
792fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
793fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
794fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
79569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.int LZ4_compressHC2(const char* source, char* dest, int inputSize, int compressionLevel)
796fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
797d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    LZ4HC_Data_Structure ctx;
798d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    LZ4HC_init(&ctx, (const BYTE*)source);
799d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    return LZ4HC_compress_generic (&ctx, source, dest, inputSize, 0, compressionLevel, noLimit);
800fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
801fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
80269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.int LZ4_compressHC(const char* source, char* dest, int inputSize) { return LZ4_compressHC2(source, dest, inputSize, 0); }
80369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.
80469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.int LZ4_compressHC2_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel)
805fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
806d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    LZ4HC_Data_Structure ctx;
807d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    LZ4HC_init(&ctx, (const BYTE*)source);
808d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    return LZ4HC_compress_generic (&ctx, source, dest, inputSize, maxOutputSize, compressionLevel, limitedOutput);
809fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
810fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
81169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.int LZ4_compressHC_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize)
81269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.{
81369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    return LZ4_compressHC2_limitedOutput(source, dest, inputSize, maxOutputSize, 0);
81469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.}
815fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
816fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
81769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet./*****************************
818508855c48826aa0544a907f02b52515aabba5e16Yann Collet Using external allocation
81969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.*****************************/
820e2a985f52444ad2e1438d2a71575185f31a08540Yann Colletint LZ4_sizeofStateHC(void) { return sizeof(LZ4HC_Data_Structure); }
821fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
822fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
82369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.int LZ4_compressHC2_withStateHC (void* state, const char* source, char* dest, int inputSize, int compressionLevel)
824fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
82569dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    if (((size_t)(state)&(sizeof(void*)-1)) != 0) return 0;   /* Error : state is not aligned for pointers (32 or 64 bits) */
826d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    LZ4HC_init ((LZ4HC_Data_Structure*)state, (const BYTE*)source);
82769dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    return LZ4HC_compress_generic (state, source, dest, inputSize, 0, compressionLevel, noLimit);
828fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
829fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
83069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.int LZ4_compressHC_withStateHC (void* state, const char* source, char* dest, int inputSize)
83169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.{ return LZ4_compressHC2_withStateHC (state, source, dest, inputSize, 0); }
832fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
83369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.
83469dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.int LZ4_compressHC2_limitedOutput_withStateHC (void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel)
835fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
83669dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    if (((size_t)(state)&(sizeof(void*)-1)) != 0) return 0;   /* Error : state is not aligned for pointers (32 or 64 bits) */
837d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    LZ4HC_init ((LZ4HC_Data_Structure*)state, (const BYTE*)source);
83869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    return LZ4HC_compress_generic (state, source, dest, inputSize, maxOutputSize, compressionLevel, limitedOutput);
839fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
840fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
84169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.int LZ4_compressHC_limitedOutput_withStateHC (void* state, const char* source, char* dest, int inputSize, int maxOutputSize)
84269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.{ return LZ4_compressHC2_limitedOutput_withStateHC (state, source, dest, inputSize, maxOutputSize, 0); }
84369dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.
844fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
845d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/**************************************
846508855c48826aa0544a907f02b52515aabba5e16Yann Collet Experimental Streaming Functions
847d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet**************************************/
848d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/* allocation */
849d239a23337e5eba41f557b48eb26f0db81b28f26Yann ColletLZ4_streamHC_t* LZ4_createStreamHC(void) { return (LZ4_streamHC_t*)malloc(sizeof(LZ4_streamHC_t)); }
850d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_freeStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr) { free(LZ4_streamHCPtr); return 0; };
851fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
852d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
853d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/* initialization */
854d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletvoid LZ4_resetStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel)
855fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
856d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    LZ4_STATIC_ASSERT(sizeof(LZ4HC_Data_Structure) <= LZ4_STREAMHCSIZE);   /* if compilation fails here, LZ4_STREAMHCSIZE must be increased */
857d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    ((LZ4HC_Data_Structure*)LZ4_streamHCPtr)->base = NULL;
858d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    ((LZ4HC_Data_Structure*)LZ4_streamHCPtr)->compressionLevel = (unsigned)compressionLevel;
85969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.}
86069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.
861d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_loadDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, const char* dictionary, int dictSize)
86269dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.{
86361289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    LZ4HC_Data_Structure* streamPtr = (LZ4HC_Data_Structure*) LZ4_streamHCPtr;
86461289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    if (dictSize > 64 KB)
86561289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    {
86661289dea1d94510a4d6386bc44c08d3d15083123Yann Collet        dictionary += dictSize - 64 KB;
86761289dea1d94510a4d6386bc44c08d3d15083123Yann Collet        dictSize = 64 KB;
86861289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    }
86961289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    LZ4HC_init (streamPtr, (const BYTE*)dictionary);
87061289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    if (dictSize >= 4) LZ4HC_Insert (streamPtr, (const BYTE*)dictionary +(dictSize-3));
87161289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    streamPtr->end = (const BYTE*)dictionary + dictSize;
87261289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    return dictSize;
873d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet}
874d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
875d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
876d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/* compression */
877d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
878e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Colletstatic int LZ4_compressHC_continue_generic (LZ4HC_Data_Structure* dsPtr,
879e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet                                            const char* source, char* dest,
880e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet                                            int inputSize, int maxOutputSize, limitedOutput_directive limit)
881e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet{
882e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet    /* auto-init if forgotten */
883e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet    if (dsPtr->base == NULL)
884e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet        LZ4HC_init (dsPtr, (const BYTE*) source);
885e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet
886508855c48826aa0544a907f02b52515aabba5e16Yann Collet    /* Check overflow */
887508855c48826aa0544a907f02b52515aabba5e16Yann Collet    if ((size_t)(dsPtr->end - dsPtr->base) > 2 GB)
888508855c48826aa0544a907f02b52515aabba5e16Yann Collet    {
889508855c48826aa0544a907f02b52515aabba5e16Yann Collet        size_t dictSize = (size_t)(dsPtr->end - dsPtr->base) - dsPtr->dictLimit;
890508855c48826aa0544a907f02b52515aabba5e16Yann Collet        if (dictSize > 64 KB) dictSize = 64 KB;
891508855c48826aa0544a907f02b52515aabba5e16Yann Collet
892508855c48826aa0544a907f02b52515aabba5e16Yann Collet        LZ4_loadDictHC((LZ4_streamHC_t*)dsPtr, (const char*)(dsPtr->end) - dictSize, (int)dictSize);
893508855c48826aa0544a907f02b52515aabba5e16Yann Collet    }
894508855c48826aa0544a907f02b52515aabba5e16Yann Collet
895508855c48826aa0544a907f02b52515aabba5e16Yann Collet    /* Check if blocks follow each other */
896e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet    if ((const BYTE*)source != dsPtr->end) LZ4HC_setExternalDict(dsPtr, (const BYTE*)source);
897e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet
898508855c48826aa0544a907f02b52515aabba5e16Yann Collet    /* Check overlapping input/dictionary space */
899e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet    {
900e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet        const BYTE* sourceEnd = (const BYTE*) source + inputSize;
901e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet        const BYTE* dictBegin = dsPtr->dictBase + dsPtr->lowLimit;
902e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet        const BYTE* dictEnd   = dsPtr->dictBase + dsPtr->dictLimit;
9032b421e97d4e7cfbefdc007bf30133b0de7e7e14eYann Collet        if ((sourceEnd > dictBegin) && ((BYTE*)source < dictEnd))
904e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet        {
9052b421e97d4e7cfbefdc007bf30133b0de7e7e14eYann Collet            if (sourceEnd > dictEnd) sourceEnd = dictEnd;
906e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet            dsPtr->lowLimit = (U32)(sourceEnd - dsPtr->dictBase);
907e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet            if (dsPtr->dictLimit - dsPtr->lowLimit < 4) dsPtr->lowLimit = dsPtr->dictLimit;
908e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet        }
909e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet    }
910e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet
911e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet    return LZ4HC_compress_generic (dsPtr, source, dest, inputSize, maxOutputSize, dsPtr->compressionLevel, limit);
912e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet}
913e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet
914d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_compressHC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize)
915d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{
916e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet    return LZ4_compressHC_continue_generic ((LZ4HC_Data_Structure*)LZ4_streamHCPtr, source, dest, inputSize, 0, noLimit);
917d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet}
918d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
919d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize, int maxOutputSize)
920d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{
921e2c84118f52cefe48fd2f751e66ad3ecd904f7b9Yann Collet    return LZ4_compressHC_continue_generic ((LZ4HC_Data_Structure*)LZ4_streamHCPtr, source, dest, inputSize, maxOutputSize, limitedOutput);
922d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet}
923d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
924d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
925d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/* dictionary saving */
926d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
927d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int dictSize)
928d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{
92961289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    LZ4HC_Data_Structure* streamPtr = (LZ4HC_Data_Structure*)LZ4_streamHCPtr;
93061289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    int prefixSize = (int)(streamPtr->end - (streamPtr->base + streamPtr->dictLimit));
931d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    if (dictSize > 64 KB) dictSize = 64 KB;
93261289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    if (dictSize < 4) dictSize = 0;
93361289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    if (dictSize > prefixSize) dictSize = prefixSize;
93461289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    memcpy(safeBuffer, streamPtr->end - dictSize, dictSize);
93561289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    //LZ4_loadDictHC(LZ4_streamHCPtr, safeBuffer, dictSize);
93661289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    {
93761289dea1d94510a4d6386bc44c08d3d15083123Yann Collet        U32 endIndex = (U32)(streamPtr->end - streamPtr->base);
93861289dea1d94510a4d6386bc44c08d3d15083123Yann Collet        streamPtr->end = (const BYTE*)safeBuffer + dictSize;
93961289dea1d94510a4d6386bc44c08d3d15083123Yann Collet        streamPtr->base = streamPtr->end - endIndex;
94061289dea1d94510a4d6386bc44c08d3d15083123Yann Collet        streamPtr->dictLimit = endIndex - dictSize;
94161289dea1d94510a4d6386bc44c08d3d15083123Yann Collet        streamPtr->lowLimit = endIndex - dictSize;
94261289dea1d94510a4d6386bc44c08d3d15083123Yann Collet    }
943d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    return dictSize;
944fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
945fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
946d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
947d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/***********************************
94861289dea1d94510a4d6386bc44c08d3d15083123Yann Collet * Deprecated Functions
94961289dea1d94510a4d6386bc44c08d3d15083123Yann Collet ***********************************/
950d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_sizeofStreamStateHC(void) { return LZ4_STREAMHCSIZE; }
951d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
952d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_resetStreamStateHC(void* state, const char* inputBuffer)
953d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{
954d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    if ((((size_t)state) & (sizeof(void*)-1)) != 0) return 1;   /* Error : pointer is not aligned for pointer (32 or 64 bits) */
955d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    LZ4HC_init((LZ4HC_Data_Structure*)state, (const BYTE*)inputBuffer);
956d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    return 0;
957d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet}
958d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
959d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletvoid* LZ4_createHC (const char* inputBuffer)
960d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{
961d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    void* hc4 = ALLOCATOR(sizeof(LZ4HC_Data_Structure));
962d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    LZ4HC_init ((LZ4HC_Data_Structure*)hc4, (const BYTE*)inputBuffer);
963d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    return hc4;
964d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet}
965d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
966d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_freeHC (void* LZ4HC_Data)
967d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{
968d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    FREEMEM(LZ4HC_Data);
969d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    return (0);
970d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet}
971d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
972d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet/*
973d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_compressHC_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize)
974d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{
975508855c48826aa0544a907f02b52515aabba5e16Yann Colletreturn LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, 0, 0, noLimit);
976d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet}
977fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.int LZ4_compressHC_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize)
978fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.{
979508855c48826aa0544a907f02b52515aabba5e16Yann Colletreturn LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, maxOutputSize, 0, limitedOutput);
980fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.}
981d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet*/
982d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
983d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletint LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel)
984d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{
985d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, 0, compressionLevel, noLimit);
986d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet}
987fb38ddaacb150e05b9d73c2a08d052ce746e37bayann.collet.
98869dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel)
98969dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.{
99069dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.    return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, maxOutputSize, compressionLevel, limitedOutput);
99169dc85b8abe78246bea91a5ba1205e4c07b96a97yann.collet.}
992d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
993d239a23337e5eba41f557b48eb26f0db81b28f26Yann Colletchar* LZ4_slideInputBufferHC(void* LZ4HC_Data)
994d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet{
995d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    LZ4HC_Data_Structure* hc4 = (LZ4HC_Data_Structure*)LZ4HC_Data;
996d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    size_t distance = (hc4->end - 64 KB) - hc4->inputBuffer;
997d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
998d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    if (hc4->end <= hc4->inputBuffer + 64 KB) return (char*)(hc4->end);   /* no update : less than 64KB within buffer */
999d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet
1000d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    distance = (distance >> 16) << 16;   /* Must be a multiple of 64 KB */
1001d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    LZ4HC_Insert(hc4, hc4->end - MINMATCH);
1002d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    memcpy((void*)(hc4->end - 64 KB - distance), (const void*)(hc4->end - 64 KB), 64 KB);
1003d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    hc4->base -= distance;
1004d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    if ((U32)(hc4->inputBuffer - hc4->base) > 1 GB + 64 KB)   /* Avoid overflow */
1005d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    {
1006d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet        int i;
1007d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet        hc4->base += 1 GB;
1008d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet        for (i=0; i<HASHTABLESIZE; i++) hc4->hashTable[i] -= 1 GB;
1009d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    }
1010d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    hc4->end -= distance;
1011d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet    return (char*)(hc4->end);
1012d239a23337e5eba41f557b48eb26f0db81b28f26Yann Collet}
1013