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