summaryrefslogtreecommitdiff
path: root/src/static_libs
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2019-08-07 11:31:03 +0100
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2019-08-07 11:31:03 +0100
commit98e80725a39e41791a05f459027a6f23487732af (patch)
tree86f2afa7aabb8f0beb5ac80b8c176f8bf4223f2f /src/static_libs
parentf7035fac6729b443c9ab2defb20bb5d49870392c (diff)
lz4 - update to 1.9.1 for static lib in src tree
this updates our static zlib to 1.9.1 releases april 23, 2019. fixes T7983
Diffstat (limited to 'src/static_libs')
-rw-r--r--src/static_libs/lz4/lz4.c2441
-rw-r--r--src/static_libs/lz4/lz4.h786
-rw-r--r--src/static_libs/lz4/lz4frame.c1838
-rw-r--r--src/static_libs/lz4/lz4frame.h606
-rw-r--r--src/static_libs/lz4/lz4frame_static.h47
-rw-r--r--src/static_libs/lz4/lz4hc.c1471
-rw-r--r--src/static_libs/lz4/lz4hc.h504
-rw-r--r--src/static_libs/lz4/meson.build4
-rw-r--r--src/static_libs/lz4/xxhash.c1030
-rw-r--r--src/static_libs/lz4/xxhash.h328
10 files changed, 7501 insertions, 1554 deletions
diff --git a/src/static_libs/lz4/lz4.c b/src/static_libs/lz4/lz4.c
index 08cf6b5..e614c45 100644
--- a/src/static_libs/lz4/lz4.c
+++ b/src/static_libs/lz4/lz4.c
@@ -1,6 +1,6 @@
1/* 1/*
2 LZ4 - Fast LZ compression algorithm 2 LZ4 - Fast LZ compression algorithm
3 Copyright (C) 2011-2015, Yann Collet. 3 Copyright (C) 2011-present, Yann Collet.
4 4
5 BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 5 BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
6 6
@@ -28,20 +28,21 @@
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 29
30 You can contact the author at : 30 You can contact the author at :
31 - LZ4 source repository : https://github.com/Cyan4973/lz4 31 - LZ4 homepage : http://www.lz4.org
32 - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c 32 - LZ4 source repository : https://github.com/lz4/lz4
33*/ 33*/
34 34
35 35/*-************************************
36/**************************************
37* Tuning parameters 36* Tuning parameters
38**************************************/ 37**************************************/
39/* 38/*
40 * HEAPMODE : 39 * LZ4_HEAPMODE :
41 * Select how default compression functions will allocate memory for their hash table, 40 * Select how default compression functions will allocate memory for their hash table,
42 * in memory stack (0:default, fastest), or in memory heap (1:requires malloc()). 41 * in memory stack (0:default, fastest), or in memory heap (1:requires malloc()).
43 */ 42 */
44#define HEAPMODE 0 43#ifndef LZ4_HEAPMODE
44# define LZ4_HEAPMODE 0
45#endif
45 46
46/* 47/*
47 * ACCELERATION_DEFAULT : 48 * ACCELERATION_DEFAULT :
@@ -50,113 +51,238 @@
50#define ACCELERATION_DEFAULT 1 51#define ACCELERATION_DEFAULT 1
51 52
52 53
53/************************************** 54/*-************************************
54* CPU Feature Detection 55* CPU Feature Detection
55**************************************/ 56**************************************/
57/* LZ4_FORCE_MEMORY_ACCESS
58 * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.
59 * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.
60 * The below switch allow to select different access method for improved performance.
61 * Method 0 (default) : use `memcpy()`. Safe and portable.
62 * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable).
63 * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.
64 * Method 2 : direct access. This method is portable but violate C standard.
65 * It can generate buggy code on targets which assembly generation depends on alignment.
66 * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6)
67 * See https://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details.
68 * Prefer these methods in priority order (0 > 1 > 2)
69 */
70#ifndef LZ4_FORCE_MEMORY_ACCESS /* can be defined externally */
71# if defined(__GNUC__) && \
72 ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) \
73 || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )
74# define LZ4_FORCE_MEMORY_ACCESS 2
75# elif (defined(__INTEL_COMPILER) && !defined(_WIN32)) || defined(__GNUC__)
76# define LZ4_FORCE_MEMORY_ACCESS 1
77# endif
78#endif
79
56/* 80/*
57 * LZ4_FORCE_SW_BITCOUNT 81 * LZ4_FORCE_SW_BITCOUNT
58 * Define this parameter if your target system or compiler does not support hardware bit count 82 * Define this parameter if your target system or compiler does not support hardware bit count
59 */ 83 */
60#if defined(_MSC_VER) && defined(_WIN32_WCE) /* Visual Studio for Windows CE does not support Hardware bit count */ 84#if defined(_MSC_VER) && defined(_WIN32_WCE) /* Visual Studio for WinCE doesn't support Hardware bit count */
61# define LZ4_FORCE_SW_BITCOUNT 85# define LZ4_FORCE_SW_BITCOUNT
62#endif 86#endif
63 87
64 88
65/************************************** 89
66* Includes 90/*-************************************
91* Dependency
67**************************************/ 92**************************************/
93/*
94 * LZ4_SRC_INCLUDED:
95 * Amalgamation flag, whether lz4.c is included
96 */
97#ifndef LZ4_SRC_INCLUDED
98# define LZ4_SRC_INCLUDED 1
99#endif
100
101#ifndef LZ4_STATIC_LINKING_ONLY
102#define LZ4_STATIC_LINKING_ONLY
103#endif
104
105#ifndef LZ4_DISABLE_DEPRECATE_WARNINGS
106#define LZ4_DISABLE_DEPRECATE_WARNINGS /* due to LZ4_decompress_safe_withPrefix64k */
107#endif
108
68#include "lz4.h" 109#include "lz4.h"
110/* see also "memory routines" below */
69 111
70 112
71/************************************** 113/*-************************************
72* Compiler Options 114* Compiler Options
73**************************************/ 115**************************************/
74#ifdef _MSC_VER /* Visual Studio */ 116#ifdef _MSC_VER /* Visual Studio */
75# define FORCE_INLINE static __forceinline
76# include <intrin.h> 117# include <intrin.h>
77# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */ 118# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
78# pragma warning(disable : 4293) /* disable: C4293: too large shift (32-bits) */ 119# pragma warning(disable : 4293) /* disable: C4293: too large shift (32-bits) */
79#else
80# if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */
81# if defined(__GNUC__) || defined(__clang__)
82# define FORCE_INLINE static inline __attribute__((always_inline))
83# else
84# define FORCE_INLINE static inline
85# endif
86# else
87# define FORCE_INLINE static
88# endif /* __STDC_VERSION__ */
89#endif /* _MSC_VER */ 120#endif /* _MSC_VER */
90 121
91/* LZ4_GCC_VERSION is defined into lz4.h */ 122#ifndef LZ4_FORCE_INLINE
92#if (LZ4_GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__) 123# ifdef _MSC_VER /* Visual Studio */
124# define LZ4_FORCE_INLINE static __forceinline
125# else
126# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
127# ifdef __GNUC__
128# define LZ4_FORCE_INLINE static inline __attribute__((always_inline))
129# else
130# define LZ4_FORCE_INLINE static inline
131# endif
132# else
133# define LZ4_FORCE_INLINE static
134# endif /* __STDC_VERSION__ */
135# endif /* _MSC_VER */
136#endif /* LZ4_FORCE_INLINE */
137
138/* LZ4_FORCE_O2_GCC_PPC64LE and LZ4_FORCE_O2_INLINE_GCC_PPC64LE
139 * gcc on ppc64le generates an unrolled SIMDized loop for LZ4_wildCopy8,
140 * together with a simple 8-byte copy loop as a fall-back path.
141 * However, this optimization hurts the decompression speed by >30%,
142 * because the execution does not go to the optimized loop
143 * for typical compressible data, and all of the preamble checks
144 * before going to the fall-back path become useless overhead.
145 * This optimization happens only with the -O3 flag, and -O2 generates
146 * a simple 8-byte copy loop.
147 * With gcc on ppc64le, all of the LZ4_decompress_* and LZ4_wildCopy8
148 * functions are annotated with __attribute__((optimize("O2"))),
149 * and also LZ4_wildCopy8 is forcibly inlined, so that the O2 attribute
150 * of LZ4_wildCopy8 does not affect the compression speed.
151 */
152#if defined(__PPC64__) && defined(__LITTLE_ENDIAN__) && defined(__GNUC__) && !defined(__clang__)
153# define LZ4_FORCE_O2_GCC_PPC64LE __attribute__((optimize("O2")))
154# define LZ4_FORCE_O2_INLINE_GCC_PPC64LE __attribute__((optimize("O2"))) LZ4_FORCE_INLINE
155#else
156# define LZ4_FORCE_O2_GCC_PPC64LE
157# define LZ4_FORCE_O2_INLINE_GCC_PPC64LE static
158#endif
159
160#if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__)
93# define expect(expr,value) (__builtin_expect ((expr),(value)) ) 161# define expect(expr,value) (__builtin_expect ((expr),(value)) )
94#else 162#else
95# define expect(expr,value) (expr) 163# define expect(expr,value) (expr)
96#endif 164#endif
97 165
166#ifndef likely
98#define likely(expr) expect((expr) != 0, 1) 167#define likely(expr) expect((expr) != 0, 1)
168#endif
169#ifndef unlikely
99#define unlikely(expr) expect((expr) != 0, 0) 170#define unlikely(expr) expect((expr) != 0, 0)
171#endif
100 172
101 173
102/************************************** 174/*-************************************
103* Memory routines 175* Memory routines
104**************************************/ 176**************************************/
105#include <stdlib.h> /* malloc, calloc, free */ 177#include <stdlib.h> /* malloc, calloc, free */
106#define ALLOCATOR(n,s) calloc(n,s) 178#define ALLOC(s) malloc(s)
107#define FREEMEM free 179#define ALLOC_AND_ZERO(s) calloc(1,s)
180#define FREEMEM(p) free(p)
108#include <string.h> /* memset, memcpy */ 181#include <string.h> /* memset, memcpy */
109#define MEM_INIT memset 182#define MEM_INIT(p,v,s) memset((p),(v),(s))
110 183
111 184
112/************************************** 185/*-************************************
113* Basic Types 186* Types
114**************************************/ 187**************************************/
115#if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */ 188#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
116# include <stdint.h> 189# include <stdint.h>
117 typedef uint8_t BYTE; 190 typedef uint8_t BYTE;
118 typedef uint16_t U16; 191 typedef uint16_t U16;
119 typedef uint32_t U32; 192 typedef uint32_t U32;
120 typedef int32_t S32; 193 typedef int32_t S32;
121 typedef uint64_t U64; 194 typedef uint64_t U64;
195 typedef uintptr_t uptrval;
122#else 196#else
123 typedef unsigned char BYTE; 197 typedef unsigned char BYTE;
124 typedef unsigned short U16; 198 typedef unsigned short U16;
125 typedef unsigned int U32; 199 typedef unsigned int U32;
126 typedef signed int S32; 200 typedef signed int S32;
127 typedef unsigned long long U64; 201 typedef unsigned long long U64;
202 typedef size_t uptrval; /* generally true, except OpenVMS-64 */
128#endif 203#endif
129 204
205#if defined(__x86_64__)
206 typedef U64 reg_t; /* 64-bits in x32 mode */
207#else
208 typedef size_t reg_t; /* 32-bits in x32 mode */
209#endif
130 210
131/************************************** 211typedef enum {
132* Reading and writing into memory 212 notLimited = 0,
133**************************************/ 213 limitedOutput = 1,
134#define STEPSIZE sizeof(size_t) 214 fillOutput = 2
215} limitedOutput_directive;
135 216
136static unsigned LZ4_64bits(void) { return sizeof(void*)==8; }
137 217
218/*-************************************
219* Reading and writing into memory
220**************************************/
138static unsigned LZ4_isLittleEndian(void) 221static unsigned LZ4_isLittleEndian(void)
139{ 222{
140 const union { U32 i; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */ 223 const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */
141 return one.c[0]; 224 return one.c[0];
142} 225}
143 226
144 227
228#if defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS==2)
229/* lie to the compiler about data alignment; use with caution */
230
231static U16 LZ4_read16(const void* memPtr) { return *(const U16*) memPtr; }
232static U32 LZ4_read32(const void* memPtr) { return *(const U32*) memPtr; }
233static reg_t LZ4_read_ARCH(const void* memPtr) { return *(const reg_t*) memPtr; }
234
235static void LZ4_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; }
236static void LZ4_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; }
237
238#elif defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS==1)
239
240/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
241/* currently only defined for gcc and icc */
242typedef union { U16 u16; U32 u32; reg_t uArch; } __attribute__((packed)) unalign;
243
244static U16 LZ4_read16(const void* ptr) { return ((const unalign*)ptr)->u16; }
245static U32 LZ4_read32(const void* ptr) { return ((const unalign*)ptr)->u32; }
246static reg_t LZ4_read_ARCH(const void* ptr) { return ((const unalign*)ptr)->uArch; }
247
248static void LZ4_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u16 = value; }
249static void LZ4_write32(void* memPtr, U32 value) { ((unalign*)memPtr)->u32 = value; }
250
251#else /* safe and portable access using memcpy() */
252
145static U16 LZ4_read16(const void* memPtr) 253static U16 LZ4_read16(const void* memPtr)
146{ 254{
147 U16 val16; 255 U16 val; memcpy(&val, memPtr, sizeof(val)); return val;
148 memcpy(&val16, memPtr, 2); 256}
149 return val16; 257
258static U32 LZ4_read32(const void* memPtr)
259{
260 U32 val; memcpy(&val, memPtr, sizeof(val)); return val;
261}
262
263static reg_t LZ4_read_ARCH(const void* memPtr)
264{
265 reg_t val; memcpy(&val, memPtr, sizeof(val)); return val;
266}
267
268static void LZ4_write16(void* memPtr, U16 value)
269{
270 memcpy(memPtr, &value, sizeof(value));
150} 271}
151 272
273static void LZ4_write32(void* memPtr, U32 value)
274{
275 memcpy(memPtr, &value, sizeof(value));
276}
277
278#endif /* LZ4_FORCE_MEMORY_ACCESS */
279
280
152static U16 LZ4_readLE16(const void* memPtr) 281static U16 LZ4_readLE16(const void* memPtr)
153{ 282{
154 if (LZ4_isLittleEndian()) 283 if (LZ4_isLittleEndian()) {
155 {
156 return LZ4_read16(memPtr); 284 return LZ4_read16(memPtr);
157 } 285 } else {
158 else
159 {
160 const BYTE* p = (const BYTE*)memPtr; 286 const BYTE* p = (const BYTE*)memPtr;
161 return (U16)((U16)p[0] + (p[1]<<8)); 287 return (U16)((U16)p[0] + (p[1]<<8));
162 } 288 }
@@ -164,71 +290,130 @@ static U16 LZ4_readLE16(const void* memPtr)
164 290
165static void LZ4_writeLE16(void* memPtr, U16 value) 291static void LZ4_writeLE16(void* memPtr, U16 value)
166{ 292{
167 if (LZ4_isLittleEndian()) 293 if (LZ4_isLittleEndian()) {
168 { 294 LZ4_write16(memPtr, value);
169 memcpy(memPtr, &value, 2); 295 } else {
170 }
171 else
172 {
173 BYTE* p = (BYTE*)memPtr; 296 BYTE* p = (BYTE*)memPtr;
174 p[0] = (BYTE) value; 297 p[0] = (BYTE) value;
175 p[1] = (BYTE)(value>>8); 298 p[1] = (BYTE)(value>>8);
176 } 299 }
177} 300}
178 301
179static U32 LZ4_read32(const void* memPtr) 302/* customized variant of memcpy, which can overwrite up to 8 bytes beyond dstEnd */
303LZ4_FORCE_O2_INLINE_GCC_PPC64LE
304void LZ4_wildCopy8(void* dstPtr, const void* srcPtr, void* dstEnd)
180{ 305{
181 U32 val32; 306 BYTE* d = (BYTE*)dstPtr;
182 memcpy(&val32, memPtr, 4); 307 const BYTE* s = (const BYTE*)srcPtr;
183 return val32; 308 BYTE* const e = (BYTE*)dstEnd;
184}
185 309
186static U64 LZ4_read64(const void* memPtr) 310 do { memcpy(d,s,8); d+=8; s+=8; } while (d<e);
187{
188 U64 val64;
189 memcpy(&val64, memPtr, 8);
190 return val64;
191} 311}
192 312
193static size_t LZ4_read_ARCH(const void* p) 313static const unsigned inc32table[8] = {0, 1, 2, 1, 0, 4, 4, 4};
194{ 314static const int dec64table[8] = {0, 0, 0, -1, -4, 1, 2, 3};
195 if (LZ4_64bits())
196 return (size_t)LZ4_read64(p);
197 else
198 return (size_t)LZ4_read32(p);
199}
200 315
201 316
202static void LZ4_copy4(void* dstPtr, const void* srcPtr) { memcpy(dstPtr, srcPtr, 4); } 317#ifndef LZ4_FAST_DEC_LOOP
318# if defined(__i386__) || defined(__x86_64__)
319# define LZ4_FAST_DEC_LOOP 1
320# else
321# define LZ4_FAST_DEC_LOOP 0
322# endif
323#endif
203 324
204static void LZ4_copy8(void* dstPtr, const void* srcPtr) { memcpy(dstPtr, srcPtr, 8); } 325#if LZ4_FAST_DEC_LOOP
205 326
206/* customized version of memcpy, which may overwrite up to 7 bytes beyond dstEnd */ 327LZ4_FORCE_O2_INLINE_GCC_PPC64LE void
207static void LZ4_wildCopy(void* dstPtr, const void* srcPtr, void* dstEnd) 328LZ4_memcpy_using_offset_base(BYTE* dstPtr, const BYTE* srcPtr, BYTE* dstEnd, const size_t offset)
329{
330 if (offset < 8) {
331 dstPtr[0] = srcPtr[0];
332 dstPtr[1] = srcPtr[1];
333 dstPtr[2] = srcPtr[2];
334 dstPtr[3] = srcPtr[3];
335 srcPtr += inc32table[offset];
336 memcpy(dstPtr+4, srcPtr, 4);
337 srcPtr -= dec64table[offset];
338 dstPtr += 8;
339 } else {
340 memcpy(dstPtr, srcPtr, 8);
341 dstPtr += 8;
342 srcPtr += 8;
343 }
344
345 LZ4_wildCopy8(dstPtr, srcPtr, dstEnd);
346}
347
348/* customized variant of memcpy, which can overwrite up to 32 bytes beyond dstEnd
349 * this version copies two times 16 bytes (instead of one time 32 bytes)
350 * because it must be compatible with offsets >= 16. */
351LZ4_FORCE_O2_INLINE_GCC_PPC64LE void
352LZ4_wildCopy32(void* dstPtr, const void* srcPtr, void* dstEnd)
208{ 353{
209 BYTE* d = (BYTE*)dstPtr; 354 BYTE* d = (BYTE*)dstPtr;
210 const BYTE* s = (const BYTE*)srcPtr; 355 const BYTE* s = (const BYTE*)srcPtr;
211 BYTE* e = (BYTE*)dstEnd; 356 BYTE* const e = (BYTE*)dstEnd;
212 do { LZ4_copy8(d,s); d+=8; s+=8; } while (d<e); 357
358 do { memcpy(d,s,16); memcpy(d+16,s+16,16); d+=32; s+=32; } while (d<e);
213} 359}
214 360
361LZ4_FORCE_O2_INLINE_GCC_PPC64LE void
362LZ4_memcpy_using_offset(BYTE* dstPtr, const BYTE* srcPtr, BYTE* dstEnd, const size_t offset)
363{
364 BYTE v[8];
365 switch(offset) {
366 case 1:
367 memset(v, *srcPtr, 8);
368 goto copy_loop;
369 case 2:
370 memcpy(v, srcPtr, 2);
371 memcpy(&v[2], srcPtr, 2);
372 memcpy(&v[4], &v[0], 4);
373 goto copy_loop;
374 case 4:
375 memcpy(v, srcPtr, 4);
376 memcpy(&v[4], srcPtr, 4);
377 goto copy_loop;
378 default:
379 LZ4_memcpy_using_offset_base(dstPtr, srcPtr, dstEnd, offset);
380 return;
381 }
215 382
216/************************************** 383 copy_loop:
384 memcpy(dstPtr, v, 8);
385 dstPtr += 8;
386 while (dstPtr < dstEnd) {
387 memcpy(dstPtr, v, 8);
388 dstPtr += 8;
389 }
390}
391#endif
392
393
394/*-************************************
217* Common Constants 395* Common Constants
218**************************************/ 396**************************************/
219#define MINMATCH 4 397#define MINMATCH 4
220 398
221#define COPYLENGTH 8 399#define WILDCOPYLENGTH 8
222#define LASTLITERALS 5 400#define LASTLITERALS 5 /* see ../doc/lz4_Block_format.md#parsing-restrictions */
223#define MFLIMIT (COPYLENGTH+MINMATCH) 401#define MFLIMIT 12 /* see ../doc/lz4_Block_format.md#parsing-restrictions */
402#define MATCH_SAFEGUARD_DISTANCE ((2*WILDCOPYLENGTH) - MINMATCH) /* ensure it's possible to write 2 x wildcopyLength without overflowing output buffer */
403#define FASTLOOP_SAFE_DISTANCE 64
224static const int LZ4_minLength = (MFLIMIT+1); 404static const int LZ4_minLength = (MFLIMIT+1);
225 405
226#define KB *(1 <<10) 406#define KB *(1 <<10)
227#define MB *(1 <<20) 407#define MB *(1 <<20)
228#define GB *(1U<<30) 408#define GB *(1U<<30)
229 409
230#define MAXD_LOG 16 410#ifndef LZ4_DISTANCE_MAX /* can be user - defined at compile time */
231#define MAX_DISTANCE ((1 << MAXD_LOG) - 1) 411# define LZ4_DISTANCE_MAX 65535
412#endif
413
414#if (LZ4_DISTANCE_MAX > 65535) /* max supported by LZ4 format */
415# error "LZ4_DISTANCE_MAX is too big : must be <= 65535"
416#endif
232 417
233#define ML_BITS 4 418#define ML_BITS 4
234#define ML_MASK ((1U<<ML_BITS)-1) 419#define ML_MASK ((1U<<ML_BITS)-1)
@@ -236,71 +421,96 @@ static const int LZ4_minLength = (MFLIMIT+1);
236#define RUN_MASK ((1U<<RUN_BITS)-1) 421#define RUN_MASK ((1U<<RUN_BITS)-1)
237 422
238 423
239/************************************** 424/*-************************************
240* Common Utils 425* Error detection
241**************************************/ 426**************************************/
242#define LZ4_STATIC_ASSERT(c) { enum { LZ4_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */ 427#if defined(LZ4_DEBUG) && (LZ4_DEBUG>=1)
428# include <assert.h>
429#else
430# ifndef assert
431# define assert(condition) ((void)0)
432# endif
433#endif
434
435#define LZ4_STATIC_ASSERT(c) { enum { LZ4_static_assert = 1/(int)(!!(c)) }; } /* use after variable declarations */
436
437#if defined(LZ4_DEBUG) && (LZ4_DEBUG>=2)
438# include <stdio.h>
439static int g_debuglog_enable = 1;
440# define DEBUGLOG(l, ...) { \
441 if ((g_debuglog_enable) && (l<=LZ4_DEBUG)) { \
442 fprintf(stderr, __FILE__ ": "); \
443 fprintf(stderr, __VA_ARGS__); \
444 fprintf(stderr, " \n"); \
445 } }
446#else
447# define DEBUGLOG(l, ...) {} /* disabled */
448#endif
243 449
244 450
245/************************************** 451/*-************************************
246* Common functions 452* Common functions
247**************************************/ 453**************************************/
248static unsigned LZ4_NbCommonBytes (register size_t val) 454static unsigned LZ4_NbCommonBytes (reg_t val)
249{ 455{
250 if (LZ4_isLittleEndian()) 456 if (LZ4_isLittleEndian()) {
251 { 457 if (sizeof(val)==8) {
252 if (LZ4_64bits())
253 {
254# if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT) 458# if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT)
255 unsigned long r = 0; 459 unsigned long r = 0;
256 _BitScanForward64( &r, (U64)val ); 460 _BitScanForward64( &r, (U64)val );
257 return (int)(r>>3); 461 return (int)(r>>3);
258# elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT) 462# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT)
259 return (__builtin_ctzll((U64)val) >> 3); 463 return (__builtin_ctzll((U64)val) >> 3);
260# else 464# else
261 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 }; 465 static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2,
466 0, 3, 1, 3, 1, 4, 2, 7,
467 0, 2, 3, 6, 1, 5, 3, 5,
468 1, 3, 4, 4, 2, 5, 6, 7,
469 7, 0, 1, 2, 3, 3, 4, 6,
470 2, 6, 5, 5, 3, 4, 5, 6,
471 7, 1, 2, 4, 6, 4, 4, 5,
472 7, 2, 6, 5, 7, 6, 7, 7 };
262 return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58]; 473 return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];
263# endif 474# endif
264 } 475 } else /* 32 bits */ {
265 else /* 32 bits */
266 {
267# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) 476# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
268 unsigned long r; 477 unsigned long r;
269 _BitScanForward( &r, (U32)val ); 478 _BitScanForward( &r, (U32)val );
270 return (int)(r>>3); 479 return (int)(r>>3);
271# elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT) 480# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT)
272 return (__builtin_ctz((U32)val) >> 3); 481 return (__builtin_ctz((U32)val) >> 3);
273# else 482# else
274 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 }; 483 static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0,
484 3, 2, 2, 1, 3, 2, 0, 1,
485 3, 3, 1, 2, 2, 2, 2, 0,
486 3, 1, 2, 0, 1, 0, 1, 1 };
275 return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27]; 487 return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
276# endif 488# endif
277 } 489 }
278 } 490 } else /* Big Endian CPU */ {
279 else /* Big Endian CPU */ 491 if (sizeof(val)==8) { /* 64-bits */
280 {
281 if (LZ4_64bits())
282 {
283# if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT) 492# if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT)
284 unsigned long r = 0; 493 unsigned long r = 0;
285 _BitScanReverse64( &r, val ); 494 _BitScanReverse64( &r, val );
286 return (unsigned)(r>>3); 495 return (unsigned)(r>>3);
287# elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT) 496# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT)
288 return (__builtin_clzll((U64)val) >> 3); 497 return (__builtin_clzll((U64)val) >> 3);
289# else 498# else
499 static const U32 by32 = sizeof(val)*4; /* 32 on 64 bits (goal), 16 on 32 bits.
500 Just to avoid some static analyzer complaining about shift by 32 on 32-bits target.
501 Note that this code path is never triggered in 32-bits mode. */
290 unsigned r; 502 unsigned r;
291 if (!(val>>32)) { r=4; } else { r=0; val>>=32; } 503 if (!(val>>by32)) { r=4; } else { r=0; val>>=by32; }
292 if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; } 504 if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
293 r += (!val); 505 r += (!val);
294 return r; 506 return r;
295# endif 507# endif
296 } 508 } else /* 32 bits */ {
297 else /* 32 bits */
298 {
299# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT) 509# if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
300 unsigned long r = 0; 510 unsigned long r = 0;
301 _BitScanReverse( &r, (unsigned long)val ); 511 _BitScanReverse( &r, (unsigned long)val );
302 return (unsigned)(r>>3); 512 return (unsigned)(r>>3);
303# elif (defined(__clang__) || (LZ4_GCC_VERSION >= 304)) && !defined(LZ4_FORCE_SW_BITCOUNT) 513# elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT)
304 return (__builtin_clz((U32)val) >> 3); 514 return (__builtin_clz((U32)val) >> 3);
305# else 515# else
306 unsigned r; 516 unsigned r;
@@ -312,19 +522,28 @@ static unsigned LZ4_NbCommonBytes (register size_t val)
312 } 522 }
313} 523}
314 524
315static unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLimit) 525#define STEPSIZE sizeof(reg_t)
526LZ4_FORCE_INLINE
527unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLimit)
316{ 528{
317 const BYTE* const pStart = pIn; 529 const BYTE* const pStart = pIn;
318 530
319 while (likely(pIn<pInLimit-(STEPSIZE-1))) 531 if (likely(pIn < pInLimit-(STEPSIZE-1))) {
320 { 532 reg_t const diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn);
321 size_t diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn); 533 if (!diff) {
534 pIn+=STEPSIZE; pMatch+=STEPSIZE;
535 } else {
536 return LZ4_NbCommonBytes(diff);
537 } }
538
539 while (likely(pIn < pInLimit-(STEPSIZE-1))) {
540 reg_t const diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn);
322 if (!diff) { pIn+=STEPSIZE; pMatch+=STEPSIZE; continue; } 541 if (!diff) { pIn+=STEPSIZE; pMatch+=STEPSIZE; continue; }
323 pIn += LZ4_NbCommonBytes(diff); 542 pIn += LZ4_NbCommonBytes(diff);
324 return (unsigned)(pIn - pStart); 543 return (unsigned)(pIn - pStart);
325 } 544 }
326 545
327 if (LZ4_64bits()) if ((pIn<(pInLimit-3)) && (LZ4_read32(pMatch) == LZ4_read32(pIn))) { pIn+=4; pMatch+=4; } 546 if ((STEPSIZE==8) && (pIn<(pInLimit-3)) && (LZ4_read32(pMatch) == LZ4_read32(pIn))) { pIn+=4; pMatch+=4; }
328 if ((pIn<(pInLimit-1)) && (LZ4_read16(pMatch) == LZ4_read16(pIn))) { pIn+=2; pMatch+=2; } 547 if ((pIn<(pInLimit-1)) && (LZ4_read16(pMatch) == LZ4_read16(pIn))) { pIn+=2; pMatch+=2; }
329 if ((pIn<pInLimit) && (*pMatch == *pIn)) pIn++; 548 if ((pIn<pInLimit) && (*pMatch == *pIn)) pIn++;
330 return (unsigned)(pIn - pStart); 549 return (unsigned)(pIn - pStart);
@@ -332,595 +551,727 @@ static unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLi
332 551
333 552
334#ifndef LZ4_COMMONDEFS_ONLY 553#ifndef LZ4_COMMONDEFS_ONLY
335/************************************** 554/*-************************************
336* Local Constants 555* Local Constants
337**************************************/ 556**************************************/
338#define LZ4_HASHLOG (LZ4_MEMORY_USAGE-2)
339#define HASHTABLESIZE (1 << LZ4_MEMORY_USAGE)
340#define HASH_SIZE_U32 (1 << LZ4_HASHLOG) /* required as macro for static allocation */
341
342static const int LZ4_64Klimit = ((64 KB) + (MFLIMIT-1)); 557static const int LZ4_64Klimit = ((64 KB) + (MFLIMIT-1));
343static const U32 LZ4_skipTrigger = 6; /* Increase this value ==> compression run slower on incompressible data */ 558static const U32 LZ4_skipTrigger = 6; /* Increase this value ==> compression run slower on incompressible data */
344 559
345 560
346/************************************** 561/*-************************************
347* Local Structures and types 562* Local Structures and types
348**************************************/ 563**************************************/
349typedef struct { 564typedef enum { clearedTable = 0, byPtr, byU32, byU16 } tableType_t;
350 U32 hashTable[HASH_SIZE_U32]; 565
351 U32 currentOffset; 566/**
352 U32 initCheck; 567 * This enum distinguishes several different modes of accessing previous
353 const BYTE* dictionary; 568 * content in the stream.
354 BYTE* bufferStart; /* obsolete, used for slideInputBuffer */ 569 *
355 U32 dictSize; 570 * - noDict : There is no preceding content.
356} LZ4_stream_t_internal; 571 * - withPrefix64k : Table entries up to ctx->dictSize before the current blob
357 572 * blob being compressed are valid and refer to the preceding
358typedef enum { notLimited = 0, limitedOutput = 1 } limitedOutput_directive; 573 * content (of length ctx->dictSize), which is available
359typedef enum { byPtr, byU32, byU16 } tableType_t; 574 * contiguously preceding in memory the content currently
360 575 * being compressed.
361typedef enum { noDict = 0, withPrefix64k, usingExtDict } dict_directive; 576 * - usingExtDict : Like withPrefix64k, but the preceding content is somewhere
577 * else in memory, starting at ctx->dictionary with length
578 * ctx->dictSize.
579 * - usingDictCtx : Like usingExtDict, but everything concerning the preceding
580 * content is in a separate context, pointed to by
581 * ctx->dictCtx. ctx->dictionary, ctx->dictSize, and table
582 * entries in the current context that refer to positions
583 * preceding the beginning of the current compression are
584 * ignored. Instead, ctx->dictCtx->dictionary and ctx->dictCtx
585 * ->dictSize describe the location and size of the preceding
586 * content, and matches are found by looking in the ctx
587 * ->dictCtx->hashTable.
588 */
589typedef enum { noDict = 0, withPrefix64k, usingExtDict, usingDictCtx } dict_directive;
362typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive; 590typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive;
363 591
364typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive;
365typedef enum { full = 0, partial = 1 } earlyEnd_directive;
366
367 592
368/************************************** 593/*-************************************
369* Local Utils 594* Local Utils
370**************************************/ 595**************************************/
371int LZ4_versionNumber (void) { return LZ4_VERSION_NUMBER; } 596int LZ4_versionNumber (void) { return LZ4_VERSION_NUMBER; }
597const char* LZ4_versionString(void) { return LZ4_VERSION_STRING; }
372int LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); } 598int LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); }
373int LZ4_sizeofState() { return LZ4_STREAMSIZE; } 599int LZ4_sizeofState() { return LZ4_STREAMSIZE; }
374 600
375 601
602/*-************************************
603* Internal Definitions used in Tests
604**************************************/
605#if defined (__cplusplus)
606extern "C" {
607#endif
608
609int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize);
610
611int LZ4_decompress_safe_forceExtDict(const char* in, char* out, int inSize, int outSize, const void* dict, size_t dictSize);
612
613#if defined (__cplusplus)
614}
615#endif
376 616
377/******************************** 617/*-******************************
378* Compression functions 618* Compression functions
379********************************/ 619********************************/
380 620static U32 LZ4_hash4(U32 sequence, tableType_t const tableType)
381static U32 LZ4_hashSequence(U32 sequence, tableType_t const tableType)
382{ 621{
383 if (tableType == byU16) 622 if (tableType == byU16)
384 return (((sequence) * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1))); 623 return ((sequence * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1)));
385 else 624 else
386 return (((sequence) * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG)); 625 return ((sequence * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG));
387} 626}
388 627
389static const U64 prime5bytes = 889523592379ULL; 628static U32 LZ4_hash5(U64 sequence, tableType_t const tableType)
390static U32 LZ4_hashSequence64(size_t sequence, tableType_t const tableType)
391{ 629{
392 const U32 hashLog = (tableType == byU16) ? LZ4_HASHLOG+1 : LZ4_HASHLOG; 630 const U32 hashLog = (tableType == byU16) ? LZ4_HASHLOG+1 : LZ4_HASHLOG;
393 const U32 hashMask = (1<<hashLog) - 1; 631 if (LZ4_isLittleEndian()) {
394 return ((sequence * prime5bytes) >> (40 - hashLog)) & hashMask; 632 const U64 prime5bytes = 889523592379ULL;
633 return (U32)(((sequence << 24) * prime5bytes) >> (64 - hashLog));
634 } else {
635 const U64 prime8bytes = 11400714785074694791ULL;
636 return (U32)(((sequence >> 24) * prime8bytes) >> (64 - hashLog));
637 }
395} 638}
396 639
397static U32 LZ4_hashSequenceT(size_t sequence, tableType_t const tableType) 640LZ4_FORCE_INLINE U32 LZ4_hashPosition(const void* const p, tableType_t const tableType)
398{ 641{
399 if (LZ4_64bits()) 642 if ((sizeof(reg_t)==8) && (tableType != byU16)) return LZ4_hash5(LZ4_read_ARCH(p), tableType);
400 return LZ4_hashSequence64(sequence, tableType); 643 return LZ4_hash4(LZ4_read32(p), tableType);
401 return LZ4_hashSequence((U32)sequence, tableType);
402} 644}
403 645
404static U32 LZ4_hashPosition(const void* p, tableType_t tableType) { return LZ4_hashSequenceT(LZ4_read_ARCH(p), tableType); } 646static void LZ4_putIndexOnHash(U32 idx, U32 h, void* tableBase, tableType_t const tableType)
647{
648 switch (tableType)
649 {
650 default: /* fallthrough */
651 case clearedTable: /* fallthrough */
652 case byPtr: { /* illegal! */ assert(0); return; }
653 case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = idx; return; }
654 case byU16: { U16* hashTable = (U16*) tableBase; assert(idx < 65536); hashTable[h] = (U16)idx; return; }
655 }
656}
405 657
406static void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableType_t const tableType, const BYTE* srcBase) 658static void LZ4_putPositionOnHash(const BYTE* p, U32 h,
659 void* tableBase, tableType_t const tableType,
660 const BYTE* srcBase)
407{ 661{
408 switch (tableType) 662 switch (tableType)
409 { 663 {
664 case clearedTable: { /* illegal! */ assert(0); return; }
410 case byPtr: { const BYTE** hashTable = (const BYTE**)tableBase; hashTable[h] = p; return; } 665 case byPtr: { const BYTE** hashTable = (const BYTE**)tableBase; hashTable[h] = p; return; }
411 case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = (U32)(p-srcBase); return; } 666 case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = (U32)(p-srcBase); return; }
412 case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = (U16)(p-srcBase); return; } 667 case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = (U16)(p-srcBase); return; }
413 } 668 }
414} 669}
415 670
416static void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) 671LZ4_FORCE_INLINE void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase)
417{ 672{
418 U32 h = LZ4_hashPosition(p, tableType); 673 U32 const h = LZ4_hashPosition(p, tableType);
419 LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase); 674 LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase);
420} 675}
421 676
422static const BYTE* LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase) 677/* LZ4_getIndexOnHash() :
678 * Index of match position registered in hash table.
679 * hash position must be calculated by using base+index, or dictBase+index.
680 * Assumption 1 : only valid if tableType == byU32 or byU16.
681 * Assumption 2 : h is presumed valid (within limits of hash table)
682 */
683static U32 LZ4_getIndexOnHash(U32 h, const void* tableBase, tableType_t tableType)
684{
685 LZ4_STATIC_ASSERT(LZ4_MEMORY_USAGE > 2);
686 if (tableType == byU32) {
687 const U32* const hashTable = (const U32*) tableBase;
688 assert(h < (1U << (LZ4_MEMORY_USAGE-2)));
689 return hashTable[h];
690 }
691 if (tableType == byU16) {
692 const U16* const hashTable = (const U16*) tableBase;
693 assert(h < (1U << (LZ4_MEMORY_USAGE-1)));
694 return hashTable[h];
695 }
696 assert(0); return 0; /* forbidden case */
697}
698
699static const BYTE* LZ4_getPositionOnHash(U32 h, const void* tableBase, tableType_t tableType, const BYTE* srcBase)
423{ 700{
424 if (tableType == byPtr) { const BYTE** hashTable = (const BYTE**) tableBase; return hashTable[h]; } 701 if (tableType == byPtr) { const BYTE* const* hashTable = (const BYTE* const*) tableBase; return hashTable[h]; }
425 if (tableType == byU32) { U32* hashTable = (U32*) tableBase; return hashTable[h] + srcBase; } 702 if (tableType == byU32) { const U32* const hashTable = (const U32*) tableBase; return hashTable[h] + srcBase; }
426 { U16* hashTable = (U16*) tableBase; return hashTable[h] + srcBase; } /* default, to ensure a return */ 703 { const U16* const hashTable = (const U16*) tableBase; return hashTable[h] + srcBase; } /* default, to ensure a return */
427} 704}
428 705
429static const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase) 706LZ4_FORCE_INLINE const BYTE* LZ4_getPosition(const BYTE* p,
707 const void* tableBase, tableType_t tableType,
708 const BYTE* srcBase)
430{ 709{
431 U32 h = LZ4_hashPosition(p, tableType); 710 U32 const h = LZ4_hashPosition(p, tableType);
432 return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase); 711 return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase);
433} 712}
434 713
435FORCE_INLINE int LZ4_compress_generic( 714LZ4_FORCE_INLINE void LZ4_prepareTable(
436 void* const ctx, 715 LZ4_stream_t_internal* const cctx,
716 const int inputSize,
717 const tableType_t tableType) {
718 /* If compression failed during the previous step, then the context
719 * is marked as dirty, therefore, it has to be fully reset.
720 */
721 if (cctx->dirty) {
722 DEBUGLOG(5, "LZ4_prepareTable: Full reset for %p", cctx);
723 MEM_INIT(cctx, 0, sizeof(LZ4_stream_t_internal));
724 return;
725 }
726
727 /* If the table hasn't been used, it's guaranteed to be zeroed out, and is
728 * therefore safe to use no matter what mode we're in. Otherwise, we figure
729 * out if it's safe to leave as is or whether it needs to be reset.
730 */
731 if (cctx->tableType != clearedTable) {
732 if (cctx->tableType != tableType
733 || (tableType == byU16 && cctx->currentOffset + inputSize >= 0xFFFFU)
734 || (tableType == byU32 && cctx->currentOffset > 1 GB)
735 || tableType == byPtr
736 || inputSize >= 4 KB)
737 {
738 DEBUGLOG(4, "LZ4_prepareTable: Resetting table in %p", cctx);
739 MEM_INIT(cctx->hashTable, 0, LZ4_HASHTABLESIZE);
740 cctx->currentOffset = 0;
741 cctx->tableType = clearedTable;
742 } else {
743 DEBUGLOG(4, "LZ4_prepareTable: Re-use hash table (no reset)");
744 }
745 }
746
747 /* Adding a gap, so all previous entries are > LZ4_DISTANCE_MAX back, is faster
748 * than compressing without a gap. However, compressing with
749 * currentOffset == 0 is faster still, so we preserve that case.
750 */
751 if (cctx->currentOffset != 0 && tableType == byU32) {
752 DEBUGLOG(5, "LZ4_prepareTable: adding 64KB to currentOffset");
753 cctx->currentOffset += 64 KB;
754 }
755
756 /* Finally, clear history */
757 cctx->dictCtx = NULL;
758 cctx->dictionary = NULL;
759 cctx->dictSize = 0;
760}
761
762/** LZ4_compress_generic() :
763 inlined, to ensure branches are decided at compilation time */
764LZ4_FORCE_INLINE int LZ4_compress_generic(
765 LZ4_stream_t_internal* const cctx,
437 const char* const source, 766 const char* const source,
438 char* const dest, 767 char* const dest,
439 const int inputSize, 768 const int inputSize,
769 int *inputConsumed, /* only written when outputDirective == fillOutput */
440 const int maxOutputSize, 770 const int maxOutputSize,
441 const limitedOutput_directive outputLimited, 771 const limitedOutput_directive outputDirective,
442 const tableType_t tableType, 772 const tableType_t tableType,
443 const dict_directive dict, 773 const dict_directive dictDirective,
444 const dictIssue_directive dictIssue, 774 const dictIssue_directive dictIssue,
445 const U32 acceleration) 775 const int acceleration)
446{ 776{
447 LZ4_stream_t_internal* const dictPtr = (LZ4_stream_t_internal*)ctx; 777 int result;
448
449 const BYTE* ip = (const BYTE*) source; 778 const BYTE* ip = (const BYTE*) source;
450 const BYTE* base; 779
780 U32 const startIndex = cctx->currentOffset;
781 const BYTE* base = (const BYTE*) source - startIndex;
451 const BYTE* lowLimit; 782 const BYTE* lowLimit;
452 const BYTE* const lowRefLimit = ip - dictPtr->dictSize; 783
453 const BYTE* const dictionary = dictPtr->dictionary; 784 const LZ4_stream_t_internal* dictCtx = (const LZ4_stream_t_internal*) cctx->dictCtx;
454 const BYTE* const dictEnd = dictionary + dictPtr->dictSize; 785 const BYTE* const dictionary =
455 const size_t dictDelta = dictEnd - (const BYTE*)source; 786 dictDirective == usingDictCtx ? dictCtx->dictionary : cctx->dictionary;
787 const U32 dictSize =
788 dictDirective == usingDictCtx ? dictCtx->dictSize : cctx->dictSize;
789 const U32 dictDelta = (dictDirective == usingDictCtx) ? startIndex - dictCtx->currentOffset : 0; /* make indexes in dictCtx comparable with index in current context */
790
791 int const maybe_extMem = (dictDirective == usingExtDict) || (dictDirective == usingDictCtx);
792 U32 const prefixIdxLimit = startIndex - dictSize; /* used when dictDirective == dictSmall */
793 const BYTE* const dictEnd = dictionary + dictSize;
456 const BYTE* anchor = (const BYTE*) source; 794 const BYTE* anchor = (const BYTE*) source;
457 const BYTE* const iend = ip + inputSize; 795 const BYTE* const iend = ip + inputSize;
458 const BYTE* const mflimit = iend - MFLIMIT; 796 const BYTE* const mflimitPlusOne = iend - MFLIMIT + 1;
459 const BYTE* const matchlimit = iend - LASTLITERALS; 797 const BYTE* const matchlimit = iend - LASTLITERALS;
460 798
799 /* the dictCtx currentOffset is indexed on the start of the dictionary,
800 * while a dictionary in the current context precedes the currentOffset */
801 const BYTE* dictBase = (dictDirective == usingDictCtx) ?
802 dictionary + dictSize - dictCtx->currentOffset :
803 dictionary + dictSize - startIndex;
804
461 BYTE* op = (BYTE*) dest; 805 BYTE* op = (BYTE*) dest;
462 BYTE* const olimit = op + maxOutputSize; 806 BYTE* const olimit = op + maxOutputSize;
463 807
808 U32 offset = 0;
464 U32 forwardH; 809 U32 forwardH;
465 size_t refDelta=0;
466 810
467 /* Init conditions */ 811 DEBUGLOG(5, "LZ4_compress_generic: srcSize=%i, tableType=%u", inputSize, tableType);
468 if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size, too large (or negative) */ 812 /* If init conditions are not met, we don't have to mark stream
469 switch(dict) 813 * as having dirty context, since no action was taken yet */
470 { 814 if (outputDirective == fillOutput && maxOutputSize < 1) return 0; /* Impossible to store anything */
471 case noDict: 815 if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported inputSize, too large (or negative) */
472 default: 816 if ((tableType == byU16) && (inputSize>=LZ4_64Klimit)) return 0; /* Size too large (not within 64K limit) */
473 base = (const BYTE*)source; 817 if (tableType==byPtr) assert(dictDirective==noDict); /* only supported use case with byPtr */
474 lowLimit = (const BYTE*)source; 818 assert(acceleration >= 1);
475 break; 819
476 case withPrefix64k: 820 lowLimit = (const BYTE*)source - (dictDirective == withPrefix64k ? dictSize : 0);
477 base = (const BYTE*)source - dictPtr->currentOffset; 821
478 lowLimit = (const BYTE*)source - dictPtr->dictSize; 822 /* Update context state */
479 break; 823 if (dictDirective == usingDictCtx) {
480 case usingExtDict: 824 /* Subsequent linked blocks can't use the dictionary. */
481 base = (const BYTE*)source - dictPtr->currentOffset; 825 /* Instead, they use the block we just compressed. */
482 lowLimit = (const BYTE*)source; 826 cctx->dictCtx = NULL;
483 break; 827 cctx->dictSize = (U32)inputSize;
828 } else {
829 cctx->dictSize += (U32)inputSize;
484 } 830 }
485 if ((tableType == byU16) && (inputSize>=LZ4_64Klimit)) return 0; /* Size too large (not within 64K limit) */ 831 cctx->currentOffset += (U32)inputSize;
486 if (inputSize<LZ4_minLength) goto _last_literals; /* Input too small, no compression (all literals) */ 832 cctx->tableType = (U16)tableType;
833
834 if (inputSize<LZ4_minLength) goto _last_literals; /* Input too small, no compression (all literals) */
487 835
488 /* First Byte */ 836 /* First Byte */
489 LZ4_putPosition(ip, ctx, tableType, base); 837 LZ4_putPosition(ip, cctx->hashTable, tableType, base);
490 ip++; forwardH = LZ4_hashPosition(ip, tableType); 838 ip++; forwardH = LZ4_hashPosition(ip, tableType);
491 839
492 /* Main Loop */ 840 /* Main Loop */
493 for ( ; ; ) 841 for ( ; ; ) {
494 {
495 const BYTE* match; 842 const BYTE* match;
496 BYTE* token; 843 BYTE* token;
497 { 844
845 /* Find a match */
846 if (tableType == byPtr) {
498 const BYTE* forwardIp = ip; 847 const BYTE* forwardIp = ip;
499 unsigned step = 1; 848 int step = 1;
500 unsigned searchMatchNb = acceleration << LZ4_skipTrigger; 849 int searchMatchNb = acceleration << LZ4_skipTrigger;
850 do {
851 U32 const h = forwardH;
852 ip = forwardIp;
853 forwardIp += step;
854 step = (searchMatchNb++ >> LZ4_skipTrigger);
855
856 if (unlikely(forwardIp > mflimitPlusOne)) goto _last_literals;
857 assert(ip < mflimitPlusOne);
858
859 match = LZ4_getPositionOnHash(h, cctx->hashTable, tableType, base);
860 forwardH = LZ4_hashPosition(forwardIp, tableType);
861 LZ4_putPositionOnHash(ip, h, cctx->hashTable, tableType, base);
501 862
502 /* Find a match */ 863 } while ( (match+LZ4_DISTANCE_MAX < ip)
864 || (LZ4_read32(match) != LZ4_read32(ip)) );
865
866 } else { /* byU32, byU16 */
867
868 const BYTE* forwardIp = ip;
869 int step = 1;
870 int searchMatchNb = acceleration << LZ4_skipTrigger;
503 do { 871 do {
504 U32 h = forwardH; 872 U32 const h = forwardH;
873 U32 const current = (U32)(forwardIp - base);
874 U32 matchIndex = LZ4_getIndexOnHash(h, cctx->hashTable, tableType);
875 assert(matchIndex <= current);
876 assert(forwardIp - base < (ptrdiff_t)(2 GB - 1));
505 ip = forwardIp; 877 ip = forwardIp;
506 forwardIp += step; 878 forwardIp += step;
507 step = (searchMatchNb++ >> LZ4_skipTrigger); 879 step = (searchMatchNb++ >> LZ4_skipTrigger);
508 880
509 if (unlikely(forwardIp > mflimit)) goto _last_literals; 881 if (unlikely(forwardIp > mflimitPlusOne)) goto _last_literals;
882 assert(ip < mflimitPlusOne);
510 883
511 match = LZ4_getPositionOnHash(h, ctx, tableType, base); 884 if (dictDirective == usingDictCtx) {
512 if (dict==usingExtDict) 885 if (matchIndex < startIndex) {
513 { 886 /* there was no match, try the dictionary */
514 if (match<(const BYTE*)source) 887 assert(tableType == byU32);
515 { 888 matchIndex = LZ4_getIndexOnHash(h, dictCtx->hashTable, byU32);
516 refDelta = dictDelta; 889 match = dictBase + matchIndex;
890 matchIndex += dictDelta; /* make dictCtx index comparable with current context */
517 lowLimit = dictionary; 891 lowLimit = dictionary;
892 } else {
893 match = base + matchIndex;
894 lowLimit = (const BYTE*)source;
518 } 895 }
519 else 896 } else if (dictDirective==usingExtDict) {
520 { 897 if (matchIndex < startIndex) {
521 refDelta = 0; 898 DEBUGLOG(7, "extDict candidate: matchIndex=%5u < startIndex=%5u", matchIndex, startIndex);
899 assert(startIndex - matchIndex >= MINMATCH);
900 match = dictBase + matchIndex;
901 lowLimit = dictionary;
902 } else {
903 match = base + matchIndex;
522 lowLimit = (const BYTE*)source; 904 lowLimit = (const BYTE*)source;
523 } 905 }
906 } else { /* single continuous memory segment */
907 match = base + matchIndex;
524 } 908 }
525 forwardH = LZ4_hashPosition(forwardIp, tableType); 909 forwardH = LZ4_hashPosition(forwardIp, tableType);
526 LZ4_putPositionOnHash(ip, h, ctx, tableType, base); 910 LZ4_putIndexOnHash(current, h, cctx->hashTable, tableType);
911
912 if ((dictIssue == dictSmall) && (matchIndex < prefixIdxLimit)) continue; /* match outside of valid area */
913 assert(matchIndex < current);
914 if ((tableType != byU16) && (matchIndex+LZ4_DISTANCE_MAX < current)) continue; /* too far */
915 if (tableType == byU16) assert((current - matchIndex) <= LZ4_DISTANCE_MAX); /* too_far presumed impossible with byU16 */
916
917 if (LZ4_read32(match) == LZ4_read32(ip)) {
918 if (maybe_extMem) offset = current - matchIndex;
919 break; /* match found */
920 }
527 921
528 } while ( ((dictIssue==dictSmall) ? (match < lowRefLimit) : 0) 922 } while(1);
529 || ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip))
530 || (LZ4_read32(match+refDelta) != LZ4_read32(ip)) );
531 } 923 }
532 924
533 /* Catch up */ 925 /* Catch up */
534 while ((ip>anchor) && (match+refDelta > lowLimit) && (unlikely(ip[-1]==match[refDelta-1]))) { ip--; match--; } 926 while (((ip>anchor) & (match > lowLimit)) && (unlikely(ip[-1]==match[-1]))) { ip--; match--; }
535 927
536 { 928 /* Encode Literals */
537 /* Encode Literal length */ 929 { unsigned const litLength = (unsigned)(ip - anchor);
538 unsigned litLength = (unsigned)(ip - anchor);
539 token = op++; 930 token = op++;
540 if ((outputLimited) && (unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit))) 931 if ((outputDirective == limitedOutput) && /* Check output buffer overflow */
541 return 0; /* Check output limit */ 932 (unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit)) )
542 if (litLength>=RUN_MASK) 933 return 0; /* cannot compress within `dst` budget. Stored indexes in hash table are nonetheless fine */
543 { 934
544 int len = (int)litLength-RUN_MASK; 935 if ((outputDirective == fillOutput) &&
545 *token=(RUN_MASK<<ML_BITS); 936 (unlikely(op + (litLength+240)/255 /* litlen */ + litLength /* literals */ + 2 /* offset */ + 1 /* token */ + MFLIMIT - MINMATCH /* min last literals so last match is <= end - MFLIMIT */ > olimit))) {
937 op--;
938 goto _last_literals;
939 }
940 if (litLength >= RUN_MASK) {
941 int len = (int)(litLength - RUN_MASK);
942 *token = (RUN_MASK<<ML_BITS);
546 for(; len >= 255 ; len-=255) *op++ = 255; 943 for(; len >= 255 ; len-=255) *op++ = 255;
547 *op++ = (BYTE)len; 944 *op++ = (BYTE)len;
548 } 945 }
549 else *token = (BYTE)(litLength<<ML_BITS); 946 else *token = (BYTE)(litLength<<ML_BITS);
550 947
551 /* Copy Literals */ 948 /* Copy Literals */
552 LZ4_wildCopy(op, anchor, op+litLength); 949 LZ4_wildCopy8(op, anchor, op+litLength);
553 op+=litLength; 950 op+=litLength;
951 DEBUGLOG(6, "seq.start:%i, literals=%u, match.start:%i",
952 (int)(anchor-(const BYTE*)source), litLength, (int)(ip-(const BYTE*)source));
554 } 953 }
555 954
556_next_match: 955_next_match:
956 /* at this stage, the following variables must be correctly set :
957 * - ip : at start of LZ operation
958 * - match : at start of previous pattern occurence; can be within current prefix, or within extDict
959 * - offset : if maybe_ext_memSegment==1 (constant)
960 * - lowLimit : must be == dictionary to mean "match is within extDict"; must be == source otherwise
961 * - token and *token : position to write 4-bits for match length; higher 4-bits for literal length supposed already written
962 */
963
964 if ((outputDirective == fillOutput) &&
965 (op + 2 /* offset */ + 1 /* token */ + MFLIMIT - MINMATCH /* min last literals so last match is <= end - MFLIMIT */ > olimit)) {
966 /* the match was too close to the end, rewind and go to last literals */
967 op = token;
968 goto _last_literals;
969 }
970
557 /* Encode Offset */ 971 /* Encode Offset */
558 LZ4_writeLE16(op, (U16)(ip-match)); op+=2; 972 if (maybe_extMem) { /* static test */
973 DEBUGLOG(6, " with offset=%u (ext if > %i)", offset, (int)(ip - (const BYTE*)source));
974 assert(offset <= LZ4_DISTANCE_MAX && offset > 0);
975 LZ4_writeLE16(op, (U16)offset); op+=2;
976 } else {
977 DEBUGLOG(6, " with offset=%u (same segment)", (U32)(ip - match));
978 assert(ip-match <= LZ4_DISTANCE_MAX);
979 LZ4_writeLE16(op, (U16)(ip - match)); op+=2;
980 }
559 981
560 /* Encode MatchLength */ 982 /* Encode MatchLength */
561 { 983 { unsigned matchCode;
562 unsigned matchLength;
563 984
564 if ((dict==usingExtDict) && (lowLimit==dictionary)) 985 if ( (dictDirective==usingExtDict || dictDirective==usingDictCtx)
565 { 986 && (lowLimit==dictionary) /* match within extDict */ ) {
566 const BYTE* limit; 987 const BYTE* limit = ip + (dictEnd-match);
567 match += refDelta; 988 assert(dictEnd > match);
568 limit = ip + (dictEnd-match);
569 if (limit > matchlimit) limit = matchlimit; 989 if (limit > matchlimit) limit = matchlimit;
570 matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, limit); 990 matchCode = LZ4_count(ip+MINMATCH, match+MINMATCH, limit);
571 ip += MINMATCH + matchLength; 991 ip += (size_t)matchCode + MINMATCH;
572 if (ip==limit) 992 if (ip==limit) {
573 { 993 unsigned const more = LZ4_count(limit, (const BYTE*)source, matchlimit);
574 unsigned more = LZ4_count(ip, (const BYTE*)source, matchlimit); 994 matchCode += more;
575 matchLength += more;
576 ip += more; 995 ip += more;
577 } 996 }
578 } 997 DEBUGLOG(6, " with matchLength=%u starting in extDict", matchCode+MINMATCH);
579 else 998 } else {
580 { 999 matchCode = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit);
581 matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit); 1000 ip += (size_t)matchCode + MINMATCH;
582 ip += MINMATCH + matchLength; 1001 DEBUGLOG(6, " with matchLength=%u", matchCode+MINMATCH);
583 } 1002 }
584 1003
585 if ((outputLimited) && (unlikely(op + (1 + LASTLITERALS) + (matchLength>>8) > olimit))) 1004 if ((outputDirective) && /* Check output buffer overflow */
586 return 0; /* Check output limit */ 1005 (unlikely(op + (1 + LASTLITERALS) + (matchCode>>8) > olimit)) ) {
587 if (matchLength>=ML_MASK) 1006 if (outputDirective == fillOutput) {
588 { 1007 /* Match description too long : reduce it */
589 *token += ML_MASK; 1008 U32 newMatchCode = 15 /* in token */ - 1 /* to avoid needing a zero byte */ + ((U32)(olimit - op) - 2 - 1 - LASTLITERALS) * 255;
590 matchLength -= ML_MASK; 1009 ip -= matchCode - newMatchCode;
591 for (; matchLength >= 510 ; matchLength-=510) { *op++ = 255; *op++ = 255; } 1010 matchCode = newMatchCode;
592 if (matchLength >= 255) { matchLength-=255; *op++ = 255; } 1011 } else {
593 *op++ = (BYTE)matchLength; 1012 assert(outputDirective == limitedOutput);
1013 return 0; /* cannot compress within `dst` budget. Stored indexes in hash table are nonetheless fine */
1014 }
594 } 1015 }
595 else *token += (BYTE)(matchLength); 1016 if (matchCode >= ML_MASK) {
1017 *token += ML_MASK;
1018 matchCode -= ML_MASK;
1019 LZ4_write32(op, 0xFFFFFFFF);
1020 while (matchCode >= 4*255) {
1021 op+=4;
1022 LZ4_write32(op, 0xFFFFFFFF);
1023 matchCode -= 4*255;
1024 }
1025 op += matchCode / 255;
1026 *op++ = (BYTE)(matchCode % 255);
1027 } else
1028 *token += (BYTE)(matchCode);
596 } 1029 }
597 1030
598 anchor = ip; 1031 anchor = ip;
599 1032
600 /* Test end of chunk */ 1033 /* Test end of chunk */
601 if (ip > mflimit) break; 1034 if (ip >= mflimitPlusOne) break;
602 1035
603 /* Fill table */ 1036 /* Fill table */
604 LZ4_putPosition(ip-2, ctx, tableType, base); 1037 LZ4_putPosition(ip-2, cctx->hashTable, tableType, base);
605 1038
606 /* Test next position */ 1039 /* Test next position */
607 match = LZ4_getPosition(ip, ctx, tableType, base); 1040 if (tableType == byPtr) {
608 if (dict==usingExtDict) 1041
609 { 1042 match = LZ4_getPosition(ip, cctx->hashTable, tableType, base);
610 if (match<(const BYTE*)source) 1043 LZ4_putPosition(ip, cctx->hashTable, tableType, base);
611 { 1044 if ( (match+LZ4_DISTANCE_MAX >= ip)
612 refDelta = dictDelta; 1045 && (LZ4_read32(match) == LZ4_read32(ip)) )
613 lowLimit = dictionary; 1046 { token=op++; *token=0; goto _next_match; }
1047
1048 } else { /* byU32, byU16 */
1049
1050 U32 const h = LZ4_hashPosition(ip, tableType);
1051 U32 const current = (U32)(ip-base);
1052 U32 matchIndex = LZ4_getIndexOnHash(h, cctx->hashTable, tableType);
1053 assert(matchIndex < current);
1054 if (dictDirective == usingDictCtx) {
1055 if (matchIndex < startIndex) {
1056 /* there was no match, try the dictionary */
1057 matchIndex = LZ4_getIndexOnHash(h, dictCtx->hashTable, byU32);
1058 match = dictBase + matchIndex;
1059 lowLimit = dictionary; /* required for match length counter */
1060 matchIndex += dictDelta;
1061 } else {
1062 match = base + matchIndex;
1063 lowLimit = (const BYTE*)source; /* required for match length counter */
1064 }
1065 } else if (dictDirective==usingExtDict) {
1066 if (matchIndex < startIndex) {
1067 match = dictBase + matchIndex;
1068 lowLimit = dictionary; /* required for match length counter */
1069 } else {
1070 match = base + matchIndex;
1071 lowLimit = (const BYTE*)source; /* required for match length counter */
1072 }
1073 } else { /* single memory segment */
1074 match = base + matchIndex;
614 } 1075 }
615 else 1076 LZ4_putIndexOnHash(current, h, cctx->hashTable, tableType);
616 { 1077 assert(matchIndex < current);
617 refDelta = 0; 1078 if ( ((dictIssue==dictSmall) ? (matchIndex >= prefixIdxLimit) : 1)
618 lowLimit = (const BYTE*)source; 1079 && ((tableType==byU16) ? 1 : (matchIndex+LZ4_DISTANCE_MAX >= current))
1080 && (LZ4_read32(match) == LZ4_read32(ip)) ) {
1081 token=op++;
1082 *token=0;
1083 if (maybe_extMem) offset = current - matchIndex;
1084 DEBUGLOG(6, "seq.start:%i, literals=%u, match.start:%i",
1085 (int)(anchor-(const BYTE*)source), 0, (int)(ip-(const BYTE*)source));
1086 goto _next_match;
619 } 1087 }
620 } 1088 }
621 LZ4_putPosition(ip, ctx, tableType, base);
622 if ( ((dictIssue==dictSmall) ? (match>=lowRefLimit) : 1)
623 && (match+MAX_DISTANCE>=ip)
624 && (LZ4_read32(match+refDelta)==LZ4_read32(ip)) )
625 { token=op++; *token=0; goto _next_match; }
626 1089
627 /* Prepare next loop */ 1090 /* Prepare next loop */
628 forwardH = LZ4_hashPosition(++ip, tableType); 1091 forwardH = LZ4_hashPosition(++ip, tableType);
1092
629 } 1093 }
630 1094
631_last_literals: 1095_last_literals:
632 /* Encode Last Literals */ 1096 /* Encode Last Literals */
633 { 1097 { size_t lastRun = (size_t)(iend - anchor);
634 const size_t lastRun = (size_t)(iend - anchor); 1098 if ( (outputDirective) && /* Check output buffer overflow */
635 if ((outputLimited) && ((op - (BYTE*)dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize)) 1099 (op + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > olimit)) {
636 return 0; /* Check output limit */ 1100 if (outputDirective == fillOutput) {
637 if (lastRun >= RUN_MASK) 1101 /* adapt lastRun to fill 'dst' */
638 { 1102 assert(olimit >= op);
1103 lastRun = (size_t)(olimit-op) - 1;
1104 lastRun -= (lastRun+240)/255;
1105 } else {
1106 assert(outputDirective == limitedOutput);
1107 return 0; /* cannot compress within `dst` budget. Stored indexes in hash table are nonetheless fine */
1108 }
1109 }
1110 if (lastRun >= RUN_MASK) {
639 size_t accumulator = lastRun - RUN_MASK; 1111 size_t accumulator = lastRun - RUN_MASK;
640 *op++ = RUN_MASK << ML_BITS; 1112 *op++ = RUN_MASK << ML_BITS;
641 for(; accumulator >= 255 ; accumulator-=255) *op++ = 255; 1113 for(; accumulator >= 255 ; accumulator-=255) *op++ = 255;
642 *op++ = (BYTE) accumulator; 1114 *op++ = (BYTE) accumulator;
643 } 1115 } else {
644 else
645 {
646 *op++ = (BYTE)(lastRun<<ML_BITS); 1116 *op++ = (BYTE)(lastRun<<ML_BITS);
647 } 1117 }
648 memcpy(op, anchor, lastRun); 1118 memcpy(op, anchor, lastRun);
1119 ip = anchor + lastRun;
649 op += lastRun; 1120 op += lastRun;
650 } 1121 }
651 1122
652 /* End */ 1123 if (outputDirective == fillOutput) {
653 return (int) (((char*)op)-dest); 1124 *inputConsumed = (int) (((const char*)ip)-source);
1125 }
1126 DEBUGLOG(5, "LZ4_compress_generic: compressed %i bytes into %i bytes", inputSize, (int)(((char*)op) - dest));
1127 result = (int)(((char*)op) - dest);
1128 assert(result > 0);
1129 return result;
654} 1130}
655 1131
656 1132
657int LZ4_compress_fast_extState(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) 1133int LZ4_compress_fast_extState(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
658{ 1134{
659 LZ4_resetStream((LZ4_stream_t*)state); 1135 LZ4_stream_t_internal* const ctx = & LZ4_initStream(state, sizeof(LZ4_stream_t)) -> internal_donotuse;
1136 assert(ctx != NULL);
660 if (acceleration < 1) acceleration = ACCELERATION_DEFAULT; 1137 if (acceleration < 1) acceleration = ACCELERATION_DEFAULT;
661 1138 if (maxOutputSize >= LZ4_compressBound(inputSize)) {
662 if (maxOutputSize >= LZ4_compressBound(inputSize)) 1139 if (inputSize < LZ4_64Klimit) {
663 { 1140 return LZ4_compress_generic(ctx, source, dest, inputSize, NULL, 0, notLimited, byU16, noDict, noDictIssue, acceleration);
664 if (inputSize < LZ4_64Klimit) 1141 } else {
665 return LZ4_compress_generic(state, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue, acceleration); 1142 const tableType_t tableType = ((sizeof(void*)==4) && ((uptrval)source > LZ4_DISTANCE_MAX)) ? byPtr : byU32;
666 else 1143 return LZ4_compress_generic(ctx, source, dest, inputSize, NULL, 0, notLimited, tableType, noDict, noDictIssue, acceleration);
667 return LZ4_compress_generic(state, source, dest, inputSize, 0, notLimited, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue, acceleration); 1144 }
1145 } else {
1146 if (inputSize < LZ4_64Klimit) {;
1147 return LZ4_compress_generic(ctx, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration);
1148 } else {
1149 const tableType_t tableType = ((sizeof(void*)==4) && ((uptrval)source > LZ4_DISTANCE_MAX)) ? byPtr : byU32;
1150 return LZ4_compress_generic(ctx, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, noDict, noDictIssue, acceleration);
1151 }
668 } 1152 }
669 else 1153}
670 { 1154
671 if (inputSize < LZ4_64Klimit) 1155/**
672 return LZ4_compress_generic(state, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); 1156 * LZ4_compress_fast_extState_fastReset() :
673 else 1157 * A variant of LZ4_compress_fast_extState().
674 return LZ4_compress_generic(state, source, dest, inputSize, maxOutputSize, limitedOutput, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue, acceleration); 1158 *
1159 * Using this variant avoids an expensive initialization step. It is only safe
1160 * to call if the state buffer is known to be correctly initialized already
1161 * (see comment in lz4.h on LZ4_resetStream_fast() for a definition of
1162 * "correctly initialized").
1163 */
1164int LZ4_compress_fast_extState_fastReset(void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration)
1165{
1166 LZ4_stream_t_internal* ctx = &((LZ4_stream_t*)state)->internal_donotuse;
1167 if (acceleration < 1) acceleration = ACCELERATION_DEFAULT;
1168
1169 if (dstCapacity >= LZ4_compressBound(srcSize)) {
1170 if (srcSize < LZ4_64Klimit) {
1171 const tableType_t tableType = byU16;
1172 LZ4_prepareTable(ctx, srcSize, tableType);
1173 if (ctx->currentOffset) {
1174 return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, 0, notLimited, tableType, noDict, dictSmall, acceleration);
1175 } else {
1176 return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, 0, notLimited, tableType, noDict, noDictIssue, acceleration);
1177 }
1178 } else {
1179 const tableType_t tableType = ((sizeof(void*)==4) && ((uptrval)src > LZ4_DISTANCE_MAX)) ? byPtr : byU32;
1180 LZ4_prepareTable(ctx, srcSize, tableType);
1181 return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, 0, notLimited, tableType, noDict, noDictIssue, acceleration);
1182 }
1183 } else {
1184 if (srcSize < LZ4_64Klimit) {
1185 const tableType_t tableType = byU16;
1186 LZ4_prepareTable(ctx, srcSize, tableType);
1187 if (ctx->currentOffset) {
1188 return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, dstCapacity, limitedOutput, tableType, noDict, dictSmall, acceleration);
1189 } else {
1190 return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, dstCapacity, limitedOutput, tableType, noDict, noDictIssue, acceleration);
1191 }
1192 } else {
1193 const tableType_t tableType = ((sizeof(void*)==4) && ((uptrval)src > LZ4_DISTANCE_MAX)) ? byPtr : byU32;
1194 LZ4_prepareTable(ctx, srcSize, tableType);
1195 return LZ4_compress_generic(ctx, src, dst, srcSize, NULL, dstCapacity, limitedOutput, tableType, noDict, noDictIssue, acceleration);
1196 }
675 } 1197 }
676} 1198}
677 1199
678 1200
679int LZ4_compress_fast(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) 1201int LZ4_compress_fast(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
680{ 1202{
681#if (HEAPMODE) 1203 int result;
682 void* ctxPtr = ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ 1204#if (LZ4_HEAPMODE)
1205 LZ4_stream_t* ctxPtr = ALLOC(sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */
1206 if (ctxPtr == NULL) return 0;
683#else 1207#else
684 LZ4_stream_t ctx; 1208 LZ4_stream_t ctx;
685 void* ctxPtr = &ctx; 1209 LZ4_stream_t* const ctxPtr = &ctx;
686#endif 1210#endif
1211 result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, maxOutputSize, acceleration);
687 1212
688 int result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, maxOutputSize, acceleration); 1213#if (LZ4_HEAPMODE)
689
690#if (HEAPMODE)
691 FREEMEM(ctxPtr); 1214 FREEMEM(ctxPtr);
692#endif 1215#endif
693 return result; 1216 return result;
694} 1217}
695 1218
696 1219
697int LZ4_compress_default(const char* source, char* dest, int inputSize, int maxOutputSize) 1220int LZ4_compress_default(const char* src, char* dst, int srcSize, int maxOutputSize)
698{ 1221{
699 return LZ4_compress_fast(source, dest, inputSize, maxOutputSize, 1); 1222 return LZ4_compress_fast(src, dst, srcSize, maxOutputSize, 1);
700} 1223}
701 1224
702 1225
703/* hidden debug function */ 1226/* hidden debug function */
704/* strangely enough, gcc generates faster code when this function is uncommented, even if unused */ 1227/* strangely enough, gcc generates faster code when this function is uncommented, even if unused */
705int LZ4_compress_fast_force(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) 1228int LZ4_compress_fast_force(const char* src, char* dst, int srcSize, int dstCapacity, int acceleration)
706{ 1229{
707 LZ4_stream_t ctx; 1230 LZ4_stream_t ctx;
1231 LZ4_initStream(&ctx, sizeof(ctx));
708 1232
709 LZ4_resetStream(&ctx); 1233 if (srcSize < LZ4_64Klimit) {
710 1234 return LZ4_compress_generic(&ctx.internal_donotuse, src, dst, srcSize, NULL, dstCapacity, limitedOutput, byU16, noDict, noDictIssue, acceleration);
711 if (inputSize < LZ4_64Klimit) 1235 } else {
712 return LZ4_compress_generic(&ctx, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration); 1236 tableType_t const addrMode = (sizeof(void*) > 4) ? byU32 : byPtr;
713 else 1237 return LZ4_compress_generic(&ctx.internal_donotuse, src, dst, srcSize, NULL, dstCapacity, limitedOutput, addrMode, noDict, noDictIssue, acceleration);
714 return LZ4_compress_generic(&ctx, source, dest, inputSize, maxOutputSize, limitedOutput, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue, acceleration);
715}
716
717
718/********************************
719* destSize variant
720********************************/
721
722static int LZ4_compress_destSize_generic(
723 void* const ctx,
724 const char* const src,
725 char* const dst,
726 int* const srcSizePtr,
727 const int targetDstSize,
728 const tableType_t tableType)
729{
730 const BYTE* ip = (const BYTE*) src;
731 const BYTE* base = (const BYTE*) src;
732 const BYTE* lowLimit = (const BYTE*) src;
733 const BYTE* anchor = ip;
734 const BYTE* const iend = ip + *srcSizePtr;
735 const BYTE* const mflimit = iend - MFLIMIT;
736 const BYTE* const matchlimit = iend - LASTLITERALS;
737
738 BYTE* op = (BYTE*) dst;
739 BYTE* const oend = op + targetDstSize;
740 BYTE* const oMaxLit = op + targetDstSize - 2 /* offset */ - 8 /* because 8+MINMATCH==MFLIMIT */ - 1 /* token */;
741 BYTE* const oMaxMatch = op + targetDstSize - (LASTLITERALS + 1 /* token */);
742 BYTE* const oMaxSeq = oMaxLit - 1 /* token */;
743
744 U32 forwardH;
745
746
747 /* Init conditions */
748 if (targetDstSize < 1) return 0; /* Impossible to store anything */
749 if ((U32)*srcSizePtr > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size, too large (or negative) */
750 if ((tableType == byU16) && (*srcSizePtr>=LZ4_64Klimit)) return 0; /* Size too large (not within 64K limit) */
751 if (*srcSizePtr<LZ4_minLength) goto _last_literals; /* Input too small, no compression (all literals) */
752
753 /* First Byte */
754 *srcSizePtr = 0;
755 LZ4_putPosition(ip, ctx, tableType, base);
756 ip++; forwardH = LZ4_hashPosition(ip, tableType);
757
758 /* Main Loop */
759 for ( ; ; )
760 {
761 const BYTE* match;
762 BYTE* token;
763 {
764 const BYTE* forwardIp = ip;
765 unsigned step = 1;
766 unsigned searchMatchNb = 1 << LZ4_skipTrigger;
767
768 /* Find a match */
769 do {
770 U32 h = forwardH;
771 ip = forwardIp;
772 forwardIp += step;
773 step = (searchMatchNb++ >> LZ4_skipTrigger);
774
775 if (unlikely(forwardIp > mflimit))
776 goto _last_literals;
777
778 match = LZ4_getPositionOnHash(h, ctx, tableType, base);
779 forwardH = LZ4_hashPosition(forwardIp, tableType);
780 LZ4_putPositionOnHash(ip, h, ctx, tableType, base);
781
782 } while ( ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip))
783 || (LZ4_read32(match) != LZ4_read32(ip)) );
784 }
785
786 /* Catch up */
787 while ((ip>anchor) && (match > lowLimit) && (unlikely(ip[-1]==match[-1]))) { ip--; match--; }
788
789 {
790 /* Encode Literal length */
791 unsigned litLength = (unsigned)(ip - anchor);
792 token = op++;
793 if (op + ((litLength+240)/255) + litLength > oMaxLit)
794 {
795 /* Not enough space for a last match */
796 op--;
797 goto _last_literals;
798 }
799 if (litLength>=RUN_MASK)
800 {
801 unsigned len = litLength - RUN_MASK;
802 *token=(RUN_MASK<<ML_BITS);
803 for(; len >= 255 ; len-=255) *op++ = 255;
804 *op++ = (BYTE)len;
805 }
806 else *token = (BYTE)(litLength<<ML_BITS);
807
808 /* Copy Literals */
809 LZ4_wildCopy(op, anchor, op+litLength);
810 op += litLength;
811 }
812
813_next_match:
814 /* Encode Offset */
815 LZ4_writeLE16(op, (U16)(ip-match)); op+=2;
816
817 /* Encode MatchLength */
818 {
819 size_t matchLength;
820
821 matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit);
822
823 if (op + ((matchLength+240)/255) > oMaxMatch)
824 {
825 /* Match description too long : reduce it */
826 matchLength = (15-1) + (oMaxMatch-op) * 255;
827 }
828 //printf("offset %5i, matchLength%5i \n", (int)(ip-match), matchLength + MINMATCH);
829 ip += MINMATCH + matchLength;
830
831 if (matchLength>=ML_MASK)
832 {
833 *token += ML_MASK;
834 matchLength -= ML_MASK;
835 while (matchLength >= 255) { matchLength-=255; *op++ = 255; }
836 *op++ = (BYTE)matchLength;
837 }
838 else *token += (BYTE)(matchLength);
839 }
840
841 anchor = ip;
842
843 /* Test end of block */
844 if (ip > mflimit) break;
845 if (op > oMaxSeq) break;
846
847 /* Fill table */
848 LZ4_putPosition(ip-2, ctx, tableType, base);
849
850 /* Test next position */
851 match = LZ4_getPosition(ip, ctx, tableType, base);
852 LZ4_putPosition(ip, ctx, tableType, base);
853 if ( (match+MAX_DISTANCE>=ip)
854 && (LZ4_read32(match)==LZ4_read32(ip)) )
855 { token=op++; *token=0; goto _next_match; }
856
857 /* Prepare next loop */
858 forwardH = LZ4_hashPosition(++ip, tableType);
859 }
860
861_last_literals:
862 /* Encode Last Literals */
863 {
864 size_t lastRunSize = (size_t)(iend - anchor);
865 if (op + 1 /* token */ + ((lastRunSize+240)/255) /* litLength */ + lastRunSize /* literals */ > oend)
866 {
867 /* adapt lastRunSize to fill 'dst' */
868 lastRunSize = (oend-op) - 1;
869 lastRunSize -= (lastRunSize+240)/255;
870 }
871 ip = anchor + lastRunSize;
872
873 if (lastRunSize >= RUN_MASK)
874 {
875 size_t accumulator = lastRunSize - RUN_MASK;
876 *op++ = RUN_MASK << ML_BITS;
877 for(; accumulator >= 255 ; accumulator-=255) *op++ = 255;
878 *op++ = (BYTE) accumulator;
879 }
880 else
881 {
882 *op++ = (BYTE)(lastRunSize<<ML_BITS);
883 }
884 memcpy(op, anchor, lastRunSize);
885 op += lastRunSize;
886 } 1238 }
887
888 /* End */
889 *srcSizePtr = (int) (((const char*)ip)-src);
890 return (int) (((char*)op)-dst);
891} 1239}
892 1240
893 1241
894static int LZ4_compress_destSize_extState (void* state, const char* src, char* dst, int* srcSizePtr, int targetDstSize) 1242/* Note!: This function leaves the stream in an unclean/broken state!
1243 * It is not safe to subsequently use the same state with a _fastReset() or
1244 * _continue() call without resetting it. */
1245static int LZ4_compress_destSize_extState (LZ4_stream_t* state, const char* src, char* dst, int* srcSizePtr, int targetDstSize)
895{ 1246{
896 LZ4_resetStream((LZ4_stream_t*)state); 1247 void* const s = LZ4_initStream(state, sizeof (*state));
1248 assert(s != NULL); (void)s;
897 1249
898 if (targetDstSize >= LZ4_compressBound(*srcSizePtr)) /* compression success is guaranteed */ 1250 if (targetDstSize >= LZ4_compressBound(*srcSizePtr)) { /* compression success is guaranteed */
899 {
900 return LZ4_compress_fast_extState(state, src, dst, *srcSizePtr, targetDstSize, 1); 1251 return LZ4_compress_fast_extState(state, src, dst, *srcSizePtr, targetDstSize, 1);
901 } 1252 } else {
902 else 1253 if (*srcSizePtr < LZ4_64Klimit) {
903 { 1254 return LZ4_compress_generic(&state->internal_donotuse, src, dst, *srcSizePtr, srcSizePtr, targetDstSize, fillOutput, byU16, noDict, noDictIssue, 1);
904 if (*srcSizePtr < LZ4_64Klimit) 1255 } else {
905 return LZ4_compress_destSize_generic(state, src, dst, srcSizePtr, targetDstSize, byU16); 1256 tableType_t const addrMode = ((sizeof(void*)==4) && ((uptrval)src > LZ4_DISTANCE_MAX)) ? byPtr : byU32;
906 else 1257 return LZ4_compress_generic(&state->internal_donotuse, src, dst, *srcSizePtr, srcSizePtr, targetDstSize, fillOutput, addrMode, noDict, noDictIssue, 1);
907 return LZ4_compress_destSize_generic(state, src, dst, srcSizePtr, targetDstSize, LZ4_64bits() ? byU32 : byPtr); 1258 } }
908 }
909} 1259}
910 1260
911 1261
912int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targetDstSize) 1262int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targetDstSize)
913{ 1263{
914#if (HEAPMODE) 1264#if (LZ4_HEAPMODE)
915 void* ctx = ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */ 1265 LZ4_stream_t* ctx = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */
1266 if (ctx == NULL) return 0;
916#else 1267#else
917 LZ4_stream_t ctxBody; 1268 LZ4_stream_t ctxBody;
918 void* ctx = &ctxBody; 1269 LZ4_stream_t* ctx = &ctxBody;
919#endif 1270#endif
920 1271
921 int result = LZ4_compress_destSize_extState(ctx, src, dst, srcSizePtr, targetDstSize); 1272 int result = LZ4_compress_destSize_extState(ctx, src, dst, srcSizePtr, targetDstSize);
922 1273
923#if (HEAPMODE) 1274#if (LZ4_HEAPMODE)
924 FREEMEM(ctx); 1275 FREEMEM(ctx);
925#endif 1276#endif
926 return result; 1277 return result;
@@ -928,76 +1279,141 @@ int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targe
928 1279
929 1280
930 1281
931/******************************** 1282/*-******************************
932* Streaming functions 1283* Streaming functions
933********************************/ 1284********************************/
934 1285
935LZ4_stream_t* LZ4_createStream(void) 1286LZ4_stream_t* LZ4_createStream(void)
936{ 1287{
937 LZ4_stream_t* lz4s = (LZ4_stream_t*)ALLOCATOR(8, LZ4_STREAMSIZE_U64); 1288 LZ4_stream_t* const lz4s = (LZ4_stream_t*)ALLOC(sizeof(LZ4_stream_t));
938 LZ4_STATIC_ASSERT(LZ4_STREAMSIZE >= sizeof(LZ4_stream_t_internal)); /* A compilation error here means LZ4_STREAMSIZE is not large enough */ 1289 LZ4_STATIC_ASSERT(LZ4_STREAMSIZE >= sizeof(LZ4_stream_t_internal)); /* A compilation error here means LZ4_STREAMSIZE is not large enough */
939 LZ4_resetStream(lz4s); 1290 DEBUGLOG(4, "LZ4_createStream %p", lz4s);
1291 if (lz4s == NULL) return NULL;
1292 LZ4_initStream(lz4s, sizeof(*lz4s));
940 return lz4s; 1293 return lz4s;
941} 1294}
942 1295
1296#ifndef _MSC_VER /* for some reason, Visual fails the aligment test on 32-bit x86 :
1297 it reports an aligment of 8-bytes,
1298 while actually aligning LZ4_stream_t on 4 bytes. */
1299static size_t LZ4_stream_t_alignment(void)
1300{
1301 struct { char c; LZ4_stream_t t; } t_a;
1302 return sizeof(t_a) - sizeof(t_a.t);
1303}
1304#endif
1305
1306LZ4_stream_t* LZ4_initStream (void* buffer, size_t size)
1307{
1308 DEBUGLOG(5, "LZ4_initStream");
1309 if (buffer == NULL) return NULL;
1310 if (size < sizeof(LZ4_stream_t)) return NULL;
1311#ifndef _MSC_VER /* for some reason, Visual fails the aligment test on 32-bit x86 :
1312 it reports an aligment of 8-bytes,
1313 while actually aligning LZ4_stream_t on 4 bytes. */
1314 if (((size_t)buffer) & (LZ4_stream_t_alignment() - 1)) return NULL; /* alignment check */
1315#endif
1316 MEM_INIT(buffer, 0, sizeof(LZ4_stream_t));
1317 return (LZ4_stream_t*)buffer;
1318}
1319
1320/* resetStream is now deprecated,
1321 * prefer initStream() which is more general */
943void LZ4_resetStream (LZ4_stream_t* LZ4_stream) 1322void LZ4_resetStream (LZ4_stream_t* LZ4_stream)
944{ 1323{
1324 DEBUGLOG(5, "LZ4_resetStream (ctx:%p)", LZ4_stream);
945 MEM_INIT(LZ4_stream, 0, sizeof(LZ4_stream_t)); 1325 MEM_INIT(LZ4_stream, 0, sizeof(LZ4_stream_t));
946} 1326}
947 1327
1328void LZ4_resetStream_fast(LZ4_stream_t* ctx) {
1329 LZ4_prepareTable(&(ctx->internal_donotuse), 0, byU32);
1330}
1331
948int LZ4_freeStream (LZ4_stream_t* LZ4_stream) 1332int LZ4_freeStream (LZ4_stream_t* LZ4_stream)
949{ 1333{
1334 if (!LZ4_stream) return 0; /* support free on NULL */
1335 DEBUGLOG(5, "LZ4_freeStream %p", LZ4_stream);
950 FREEMEM(LZ4_stream); 1336 FREEMEM(LZ4_stream);
951 return (0); 1337 return (0);
952} 1338}
953 1339
954 1340
955#define HASH_UNIT sizeof(size_t) 1341#define HASH_UNIT sizeof(reg_t)
956int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize) 1342int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize)
957{ 1343{
958 LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict; 1344 LZ4_stream_t_internal* dict = &LZ4_dict->internal_donotuse;
1345 const tableType_t tableType = byU32;
959 const BYTE* p = (const BYTE*)dictionary; 1346 const BYTE* p = (const BYTE*)dictionary;
960 const BYTE* const dictEnd = p + dictSize; 1347 const BYTE* const dictEnd = p + dictSize;
961 const BYTE* base; 1348 const BYTE* base;
962 1349
963 if ((dict->initCheck) || (dict->currentOffset > 1 GB)) /* Uninitialized structure, or reuse overflow */ 1350 DEBUGLOG(4, "LZ4_loadDict (%i bytes from %p into %p)", dictSize, dictionary, LZ4_dict);
964 LZ4_resetStream(LZ4_dict);
965 1351
966 if (dictSize < (int)HASH_UNIT) 1352 /* It's necessary to reset the context,
967 { 1353 * and not just continue it with prepareTable()
968 dict->dictionary = NULL; 1354 * to avoid any risk of generating overflowing matchIndex
969 dict->dictSize = 0; 1355 * when compressing using this dictionary */
970 return 0; 1356 LZ4_resetStream(LZ4_dict);
971 } 1357
1358 /* We always increment the offset by 64 KB, since, if the dict is longer,
1359 * we truncate it to the last 64k, and if it's shorter, we still want to
1360 * advance by a whole window length so we can provide the guarantee that
1361 * there are only valid offsets in the window, which allows an optimization
1362 * in LZ4_compress_fast_continue() where it uses noDictIssue even when the
1363 * dictionary isn't a full 64k. */
972 1364
973 if ((dictEnd - p) > 64 KB) p = dictEnd - 64 KB; 1365 if ((dictEnd - p) > 64 KB) p = dictEnd - 64 KB;
974 dict->currentOffset += 64 KB; 1366 base = dictEnd - 64 KB - dict->currentOffset;
975 base = p - dict->currentOffset;
976 dict->dictionary = p; 1367 dict->dictionary = p;
977 dict->dictSize = (U32)(dictEnd - p); 1368 dict->dictSize = (U32)(dictEnd - p);
978 dict->currentOffset += dict->dictSize; 1369 dict->currentOffset += 64 KB;
1370 dict->tableType = tableType;
979 1371
980 while (p <= dictEnd-HASH_UNIT) 1372 if (dictSize < (int)HASH_UNIT) {
981 { 1373 return 0;
982 LZ4_putPosition(p, dict->hashTable, byU32, base); 1374 }
1375
1376 while (p <= dictEnd-HASH_UNIT) {
1377 LZ4_putPosition(p, dict->hashTable, tableType, base);
983 p+=3; 1378 p+=3;
984 } 1379 }
985 1380
986 return dict->dictSize; 1381 return (int)dict->dictSize;
987} 1382}
988 1383
1384void LZ4_attach_dictionary(LZ4_stream_t *working_stream, const LZ4_stream_t *dictionary_stream) {
1385 /* Calling LZ4_resetStream_fast() here makes sure that changes will not be
1386 * erased by subsequent calls to LZ4_resetStream_fast() in case stream was
1387 * marked as having dirty context, e.g. requiring full reset.
1388 */
1389 LZ4_resetStream_fast(working_stream);
1390
1391 if (dictionary_stream != NULL) {
1392 /* If the current offset is zero, we will never look in the
1393 * external dictionary context, since there is no value a table
1394 * entry can take that indicate a miss. In that case, we need
1395 * to bump the offset to something non-zero.
1396 */
1397 if (working_stream->internal_donotuse.currentOffset == 0) {
1398 working_stream->internal_donotuse.currentOffset = 64 KB;
1399 }
1400 working_stream->internal_donotuse.dictCtx = &(dictionary_stream->internal_donotuse);
1401 } else {
1402 working_stream->internal_donotuse.dictCtx = NULL;
1403 }
1404}
989 1405
990static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, const BYTE* src) 1406
1407static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, int nextSize)
991{ 1408{
992 if ((LZ4_dict->currentOffset > 0x80000000) || 1409 assert(nextSize >= 0);
993 ((size_t)LZ4_dict->currentOffset > (size_t)src)) /* address space overflow */ 1410 if (LZ4_dict->currentOffset + (unsigned)nextSize > 0x80000000) { /* potential ptrdiff_t overflow (32-bits mode) */
994 {
995 /* rescale hash table */ 1411 /* rescale hash table */
996 U32 delta = LZ4_dict->currentOffset - 64 KB; 1412 U32 const delta = LZ4_dict->currentOffset - 64 KB;
997 const BYTE* dictEnd = LZ4_dict->dictionary + LZ4_dict->dictSize; 1413 const BYTE* dictEnd = LZ4_dict->dictionary + LZ4_dict->dictSize;
998 int i; 1414 int i;
999 for (i=0; i<HASH_SIZE_U32; i++) 1415 DEBUGLOG(4, "LZ4_renormDictT");
1000 { 1416 for (i=0; i<LZ4_HASH_SIZE_U32; i++) {
1001 if (LZ4_dict->hashTable[i] < delta) LZ4_dict->hashTable[i]=0; 1417 if (LZ4_dict->hashTable[i] < delta) LZ4_dict->hashTable[i]=0;
1002 else LZ4_dict->hashTable[i] -= delta; 1418 else LZ4_dict->hashTable[i] -= delta;
1003 } 1419 }
@@ -1008,22 +1424,33 @@ static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, const BYTE* src)
1008} 1424}
1009 1425
1010 1426
1011int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration) 1427int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream,
1428 const char* source, char* dest,
1429 int inputSize, int maxOutputSize,
1430 int acceleration)
1012{ 1431{
1013 LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_stream; 1432 const tableType_t tableType = byU32;
1014 const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize; 1433 LZ4_stream_t_internal* streamPtr = &LZ4_stream->internal_donotuse;
1434 const BYTE* dictEnd = streamPtr->dictionary + streamPtr->dictSize;
1435
1436 DEBUGLOG(5, "LZ4_compress_fast_continue (inputSize=%i)", inputSize);
1015 1437
1016 const BYTE* smallest = (const BYTE*) source; 1438 if (streamPtr->dirty) return 0; /* Uninitialized structure detected */
1017 if (streamPtr->initCheck) return 0; /* Uninitialized structure detected */ 1439 LZ4_renormDictT(streamPtr, inputSize); /* avoid index overflow */
1018 if ((streamPtr->dictSize>0) && (smallest>dictEnd)) smallest = dictEnd;
1019 LZ4_renormDictT(streamPtr, smallest);
1020 if (acceleration < 1) acceleration = ACCELERATION_DEFAULT; 1440 if (acceleration < 1) acceleration = ACCELERATION_DEFAULT;
1021 1441
1442 /* invalidate tiny dictionaries */
1443 if ( (streamPtr->dictSize-1 < 4-1) /* intentional underflow */
1444 && (dictEnd != (const BYTE*)source) ) {
1445 DEBUGLOG(5, "LZ4_compress_fast_continue: dictSize(%u) at addr:%p is too small", streamPtr->dictSize, streamPtr->dictionary);
1446 streamPtr->dictSize = 0;
1447 streamPtr->dictionary = (const BYTE*)source;
1448 dictEnd = (const BYTE*)source;
1449 }
1450
1022 /* Check overlapping input/dictionary space */ 1451 /* Check overlapping input/dictionary space */
1023 { 1452 { const BYTE* sourceEnd = (const BYTE*) source + inputSize;
1024 const BYTE* sourceEnd = (const BYTE*) source + inputSize; 1453 if ((sourceEnd > streamPtr->dictionary) && (sourceEnd < dictEnd)) {
1025 if ((sourceEnd > streamPtr->dictionary) && (sourceEnd < dictEnd))
1026 {
1027 streamPtr->dictSize = (U32)(dictEnd - sourceEnd); 1454 streamPtr->dictSize = (U32)(dictEnd - sourceEnd);
1028 if (streamPtr->dictSize > 64 KB) streamPtr->dictSize = 64 KB; 1455 if (streamPtr->dictSize > 64 KB) streamPtr->dictSize = 64 KB;
1029 if (streamPtr->dictSize < 4) streamPtr->dictSize = 0; 1456 if (streamPtr->dictSize < 4) streamPtr->dictSize = 0;
@@ -1032,61 +1459,81 @@ int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream, const char* source, ch
1032 } 1459 }
1033 1460
1034 /* prefix mode : source data follows dictionary */ 1461 /* prefix mode : source data follows dictionary */
1035 if (dictEnd == (const BYTE*)source) 1462 if (dictEnd == (const BYTE*)source) {
1036 {
1037 int result;
1038 if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) 1463 if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset))
1039 result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, dictSmall, acceleration); 1464 return LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, withPrefix64k, dictSmall, acceleration);
1040 else 1465 else
1041 result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, noDictIssue, acceleration); 1466 return LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, withPrefix64k, noDictIssue, acceleration);
1042 streamPtr->dictSize += (U32)inputSize;
1043 streamPtr->currentOffset += (U32)inputSize;
1044 return result;
1045 } 1467 }
1046 1468
1047 /* external dictionary mode */ 1469 /* external dictionary mode */
1048 { 1470 { int result;
1049 int result; 1471 if (streamPtr->dictCtx) {
1050 if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) 1472 /* We depend here on the fact that dictCtx'es (produced by
1051 result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, dictSmall, acceleration); 1473 * LZ4_loadDict) guarantee that their tables contain no references
1052 else 1474 * to offsets between dictCtx->currentOffset - 64 KB and
1053 result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, noDictIssue, acceleration); 1475 * dictCtx->currentOffset - dictCtx->dictSize. This makes it safe
1476 * to use noDictIssue even when the dict isn't a full 64 KB.
1477 */
1478 if (inputSize > 4 KB) {
1479 /* For compressing large blobs, it is faster to pay the setup
1480 * cost to copy the dictionary's tables into the active context,
1481 * so that the compression loop is only looking into one table.
1482 */
1483 memcpy(streamPtr, streamPtr->dictCtx, sizeof(LZ4_stream_t));
1484 result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingExtDict, noDictIssue, acceleration);
1485 } else {
1486 result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingDictCtx, noDictIssue, acceleration);
1487 }
1488 } else {
1489 if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) {
1490 result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingExtDict, dictSmall, acceleration);
1491 } else {
1492 result = LZ4_compress_generic(streamPtr, source, dest, inputSize, NULL, maxOutputSize, limitedOutput, tableType, usingExtDict, noDictIssue, acceleration);
1493 }
1494 }
1054 streamPtr->dictionary = (const BYTE*)source; 1495 streamPtr->dictionary = (const BYTE*)source;
1055 streamPtr->dictSize = (U32)inputSize; 1496 streamPtr->dictSize = (U32)inputSize;
1056 streamPtr->currentOffset += (U32)inputSize;
1057 return result; 1497 return result;
1058 } 1498 }
1059} 1499}
1060 1500
1061 1501
1062/* Hidden debug function, to force external dictionary mode */ 1502/* Hidden debug function, to force-test external dictionary mode */
1063int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* dest, int inputSize) 1503int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* dest, int srcSize)
1064{ 1504{
1065 LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_dict; 1505 LZ4_stream_t_internal* streamPtr = &LZ4_dict->internal_donotuse;
1066 int result; 1506 int result;
1067 const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize;
1068 1507
1069 const BYTE* smallest = dictEnd; 1508 LZ4_renormDictT(streamPtr, srcSize);
1070 if (smallest > (const BYTE*) source) smallest = (const BYTE*) source;
1071 LZ4_renormDictT((LZ4_stream_t_internal*)LZ4_dict, smallest);
1072 1509
1073 result = LZ4_compress_generic(LZ4_dict, source, dest, inputSize, 0, notLimited, byU32, usingExtDict, noDictIssue, 1); 1510 if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset)) {
1511 result = LZ4_compress_generic(streamPtr, source, dest, srcSize, NULL, 0, notLimited, byU32, usingExtDict, dictSmall, 1);
1512 } else {
1513 result = LZ4_compress_generic(streamPtr, source, dest, srcSize, NULL, 0, notLimited, byU32, usingExtDict, noDictIssue, 1);
1514 }
1074 1515
1075 streamPtr->dictionary = (const BYTE*)source; 1516 streamPtr->dictionary = (const BYTE*)source;
1076 streamPtr->dictSize = (U32)inputSize; 1517 streamPtr->dictSize = (U32)srcSize;
1077 streamPtr->currentOffset += (U32)inputSize;
1078 1518
1079 return result; 1519 return result;
1080} 1520}
1081 1521
1082 1522
1523/*! LZ4_saveDict() :
1524 * If previously compressed data block is not guaranteed to remain available at its memory location,
1525 * save it into a safer place (char* safeBuffer).
1526 * Note : you don't need to call LZ4_loadDict() afterwards,
1527 * dictionary is immediately usable, you can therefore call LZ4_compress_fast_continue().
1528 * Return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error.
1529 */
1083int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize) 1530int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize)
1084{ 1531{
1085 LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict; 1532 LZ4_stream_t_internal* const dict = &LZ4_dict->internal_donotuse;
1086 const BYTE* previousDictEnd = dict->dictionary + dict->dictSize; 1533 const BYTE* const previousDictEnd = dict->dictionary + dict->dictSize;
1087 1534
1088 if ((U32)dictSize > 64 KB) dictSize = 64 KB; /* useless to define a dictionary > 64 KB */ 1535 if ((U32)dictSize > 64 KB) dictSize = 64 KB; /* useless to define a dictionary > 64 KB */
1089 if ((U32)dictSize > dict->dictSize) dictSize = dict->dictSize; 1536 if ((U32)dictSize > dict->dictSize) dictSize = (int)dict->dictSize;
1090 1537
1091 memmove(safeBuffer, previousDictEnd - dictSize, dictSize); 1538 memmove(safeBuffer, previousDictEnd - dictSize, dictSize);
1092 1539
@@ -1098,246 +1545,554 @@ int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize)
1098 1545
1099 1546
1100 1547
1101/******************************* 1548/*-*******************************
1102* Decompression functions 1549 * Decompression functions
1103*******************************/ 1550 ********************************/
1104/* 1551
1105 * This generic decompression function cover all use cases. 1552typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive;
1106 * It shall be instantiated several times, using different sets of directives 1553typedef enum { decode_full_block = 0, partial_decode = 1 } earlyEnd_directive;
1107 * Note that it is essential this generic function is really inlined, 1554
1108 * in order to remove useless branches during compilation optimization. 1555#undef MIN
1556#define MIN(a,b) ( (a) < (b) ? (a) : (b) )
1557
1558/* Read the variable-length literal or match length.
1559 *
1560 * ip - pointer to use as input.
1561 * lencheck - end ip. Return an error if ip advances >= lencheck.
1562 * loop_check - check ip >= lencheck in body of loop. Returns loop_error if so.
1563 * initial_check - check ip >= lencheck before start of loop. Returns initial_error if so.
1564 * error (output) - error code. Should be set to 0 before call.
1109 */ 1565 */
1110FORCE_INLINE int LZ4_decompress_generic( 1566typedef enum { loop_error = -2, initial_error = -1, ok = 0 } variable_length_error;
1111 const char* const source, 1567LZ4_FORCE_INLINE unsigned
1112 char* const dest, 1568read_variable_length(const BYTE**ip, const BYTE* lencheck, int loop_check, int initial_check, variable_length_error* error)
1113 int inputSize, 1569{
1114 int outputSize, /* If endOnInput==endOnInputSize, this value is the max size of Output Buffer. */ 1570 unsigned length = 0;
1115 1571 unsigned s;
1116 int endOnInput, /* endOnOutputSize, endOnInputSize */ 1572 if (initial_check && unlikely((*ip) >= lencheck)) { /* overflow detection */
1117 int partialDecoding, /* full, partial */ 1573 *error = initial_error;
1118 int targetOutputSize, /* only used if partialDecoding==partial */ 1574 return length;
1119 int dict, /* noDict, withPrefix64k, usingExtDict */ 1575 }
1120 const BYTE* const lowPrefix, /* == dest if dict == noDict */ 1576 do {
1577 s = **ip;
1578 (*ip)++;
1579 length += s;
1580 if (loop_check && unlikely((*ip) >= lencheck)) { /* overflow detection */
1581 *error = loop_error;
1582 return length;
1583 }
1584 } while (s==255);
1585
1586 return length;
1587}
1588
1589/*! LZ4_decompress_generic() :
1590 * This generic decompression function covers all use cases.
1591 * It shall be instantiated several times, using different sets of directives.
1592 * Note that it is important for performance that this function really get inlined,
1593 * in order to remove useless branches during compilation optimization.
1594 */
1595LZ4_FORCE_INLINE int
1596LZ4_decompress_generic(
1597 const char* const src,
1598 char* const dst,
1599 int srcSize,
1600 int outputSize, /* If endOnInput==endOnInputSize, this value is `dstCapacity` */
1601
1602 endCondition_directive endOnInput, /* endOnOutputSize, endOnInputSize */
1603 earlyEnd_directive partialDecoding, /* full, partial */
1604 dict_directive dict, /* noDict, withPrefix64k, usingExtDict */
1605 const BYTE* const lowPrefix, /* always <= dst, == dst when no prefix */
1121 const BYTE* const dictStart, /* only if dict==usingExtDict */ 1606 const BYTE* const dictStart, /* only if dict==usingExtDict */
1122 const size_t dictSize /* note : = 0 if noDict */ 1607 const size_t dictSize /* note : = 0 if noDict */
1123 ) 1608 )
1124{ 1609{
1125 /* Local Variables */ 1610 if (src == NULL) return -1;
1126 const BYTE* ip = (const BYTE*) source;
1127 const BYTE* const iend = ip + inputSize;
1128 1611
1129 BYTE* op = (BYTE*) dest; 1612 { const BYTE* ip = (const BYTE*) src;
1130 BYTE* const oend = op + outputSize; 1613 const BYTE* const iend = ip + srcSize;
1131 BYTE* cpy;
1132 BYTE* oexit = op + targetOutputSize;
1133 const BYTE* const lowLimit = lowPrefix - dictSize;
1134 1614
1135 const BYTE* const dictEnd = (const BYTE*)dictStart + dictSize; 1615 BYTE* op = (BYTE*) dst;
1136 const size_t dec32table[] = {4, 1, 2, 1, 4, 4, 4, 4}; 1616 BYTE* const oend = op + outputSize;
1137 const size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3}; 1617 BYTE* cpy;
1138 1618
1139 const int safeDecode = (endOnInput==endOnInputSize); 1619 const BYTE* const dictEnd = (dictStart == NULL) ? NULL : dictStart + dictSize;
1140 const int checkOffset = ((safeDecode) && (dictSize < (int)(64 KB)));
1141 1620
1621 const int safeDecode = (endOnInput==endOnInputSize);
1622 const int checkOffset = ((safeDecode) && (dictSize < (int)(64 KB)));
1142 1623
1143 /* Special cases */
1144 if ((partialDecoding) && (oexit> oend-MFLIMIT)) oexit = oend-MFLIMIT; /* targetOutputSize too high => decode everything */
1145 if ((endOnInput) && (unlikely(outputSize==0))) return ((inputSize==1) && (*ip==0)) ? 0 : -1; /* Empty output buffer */
1146 if ((!endOnInput) && (unlikely(outputSize==0))) return (*ip==0?1:-1);
1147 1624
1625 /* Set up the "end" pointers for the shortcut. */
1626 const BYTE* const shortiend = iend - (endOnInput ? 14 : 8) /*maxLL*/ - 2 /*offset*/;
1627 const BYTE* const shortoend = oend - (endOnInput ? 14 : 8) /*maxLL*/ - 18 /*maxML*/;
1148 1628
1149 /* Main Loop */ 1629 const BYTE* match;
1150 while (1) 1630 size_t offset;
1151 {
1152 unsigned token; 1631 unsigned token;
1153 size_t length; 1632 size_t length;
1154 const BYTE* match;
1155 1633
1156 /* get literal length */ 1634
1157 token = *ip++; 1635 DEBUGLOG(5, "LZ4_decompress_generic (srcSize:%i, dstSize:%i)", srcSize, outputSize);
1158 if ((length=(token>>ML_BITS)) == RUN_MASK) 1636
1159 { 1637 /* Special cases */
1160 unsigned s; 1638 assert(lowPrefix <= op);
1161 do 1639 if ((endOnInput) && (unlikely(outputSize==0))) return ((srcSize==1) && (*ip==0)) ? 0 : -1; /* Empty output buffer */
1162 { 1640 if ((!endOnInput) && (unlikely(outputSize==0))) return (*ip==0 ? 1 : -1);
1163 s = *ip++; 1641 if ((endOnInput) && unlikely(srcSize==0)) return -1;
1164 length += s; 1642
1165 } 1643 /* Currently the fast loop shows a regression on qualcomm arm chips. */
1166 while (likely((endOnInput)?ip<iend-RUN_MASK:1) && (s==255)); 1644#if LZ4_FAST_DEC_LOOP
1167 if ((safeDecode) && unlikely((size_t)(op+length)<(size_t)(op))) goto _output_error; /* overflow detection */ 1645 if ((oend - op) < FASTLOOP_SAFE_DISTANCE) {
1168 if ((safeDecode) && unlikely((size_t)(ip+length)<(size_t)(ip))) goto _output_error; /* overflow detection */ 1646 DEBUGLOG(6, "skip fast decode loop");
1647 goto safe_decode;
1169 } 1648 }
1170 1649
1171 /* copy literals */ 1650 /* Fast loop : decode sequences as long as output < iend-FASTLOOP_SAFE_DISTANCE */
1172 cpy = op+length; 1651 while (1) {
1173 if (((endOnInput) && ((cpy>(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) ) 1652 /* Main fastloop assertion: We can always wildcopy FASTLOOP_SAFE_DISTANCE */
1174 || ((!endOnInput) && (cpy>oend-COPYLENGTH))) 1653 assert(oend - op >= FASTLOOP_SAFE_DISTANCE);
1175 { 1654 if (endOnInput) assert(ip < iend);
1176 if (partialDecoding) 1655 token = *ip++;
1177 { 1656 length = token >> ML_BITS; /* literal length */
1178 if (cpy > oend) goto _output_error; /* Error : write attempt beyond end of output buffer */ 1657
1179 if ((endOnInput) && (ip+length > iend)) goto _output_error; /* Error : read attempt beyond end of input buffer */ 1658 assert(!endOnInput || ip <= iend); /* ip < iend before the increment */
1659
1660 /* decode literal length */
1661 if (length == RUN_MASK) {
1662 variable_length_error error = ok;
1663 length += read_variable_length(&ip, iend-RUN_MASK, endOnInput, endOnInput, &error);
1664 if (error == initial_error) goto _output_error;
1665 if ((safeDecode) && unlikely((uptrval)(op)+length<(uptrval)(op))) goto _output_error; /* overflow detection */
1666 if ((safeDecode) && unlikely((uptrval)(ip)+length<(uptrval)(ip))) goto _output_error; /* overflow detection */
1667
1668 /* copy literals */
1669 cpy = op+length;
1670 LZ4_STATIC_ASSERT(MFLIMIT >= WILDCOPYLENGTH);
1671 if (endOnInput) { /* LZ4_decompress_safe() */
1672 if ((cpy>oend-32) || (ip+length>iend-32)) goto safe_literal_copy;
1673 LZ4_wildCopy32(op, ip, cpy);
1674 } else { /* LZ4_decompress_fast() */
1675 if (cpy>oend-8) goto safe_literal_copy;
1676 LZ4_wildCopy8(op, ip, cpy); /* LZ4_decompress_fast() cannot copy more than 8 bytes at a time :
1677 * it doesn't know input length, and only relies on end-of-block properties */
1678 }
1679 ip += length; op = cpy;
1680 } else {
1681 cpy = op+length;
1682 if (endOnInput) { /* LZ4_decompress_safe() */
1683 DEBUGLOG(7, "copy %u bytes in a 16-bytes stripe", (unsigned)length);
1684 /* We don't need to check oend, since we check it once for each loop below */
1685 if (ip > iend-(16 + 1/*max lit + offset + nextToken*/)) goto safe_literal_copy;
1686 /* Literals can only be 14, but hope compilers optimize if we copy by a register size */
1687 memcpy(op, ip, 16);
1688 } else { /* LZ4_decompress_fast() */
1689 /* LZ4_decompress_fast() cannot copy more than 8 bytes at a time :
1690 * it doesn't know input length, and relies on end-of-block properties */
1691 memcpy(op, ip, 8);
1692 if (length > 8) memcpy(op+8, ip+8, 8);
1693 }
1694 ip += length; op = cpy;
1180 } 1695 }
1181 else 1696
1182 { 1697 /* get offset */
1183 if ((!endOnInput) && (cpy != oend)) goto _output_error; /* Error : block decoding must stop exactly there */ 1698 offset = LZ4_readLE16(ip); ip+=2;
1184 if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) goto _output_error; /* Error : input must be consumed */ 1699 match = op - offset;
1700
1701 /* get matchlength */
1702 length = token & ML_MASK;
1703
1704 if ((checkOffset) && (unlikely(match + dictSize < lowPrefix))) goto _output_error; /* Error : offset outside buffers */
1705
1706 if (length == ML_MASK) {
1707 variable_length_error error = ok;
1708 length += read_variable_length(&ip, iend - LASTLITERALS + 1, endOnInput, 0, &error);
1709 if (error != ok) goto _output_error;
1710 if ((safeDecode) && unlikely((uptrval)(op)+length<(uptrval)op)) goto _output_error; /* overflow detection */
1711 length += MINMATCH;
1712 if (op + length >= oend - FASTLOOP_SAFE_DISTANCE) {
1713 goto safe_match_copy;
1714 }
1715 } else {
1716 length += MINMATCH;
1717 if (op + length >= oend - FASTLOOP_SAFE_DISTANCE) {
1718 goto safe_match_copy;
1719 }
1720
1721 /* Fastpath check: Avoids a branch in LZ4_wildCopy32 if true */
1722 if (!(dict == usingExtDict) || (match >= lowPrefix)) {
1723 if (offset >= 8) {
1724 memcpy(op, match, 8);
1725 memcpy(op+8, match+8, 8);
1726 memcpy(op+16, match+16, 2);
1727 op += length;
1728 continue;
1729 } } }
1730
1731 /* match starting within external dictionary */
1732 if ((dict==usingExtDict) && (match < lowPrefix)) {
1733 if (unlikely(op+length > oend-LASTLITERALS)) {
1734 if (partialDecoding) length = MIN(length, (size_t)(oend-op));
1735 else goto _output_error; /* doesn't respect parsing restriction */
1736 }
1737
1738 if (length <= (size_t)(lowPrefix-match)) {
1739 /* match fits entirely within external dictionary : just copy */
1740 memmove(op, dictEnd - (lowPrefix-match), length);
1741 op += length;
1742 } else {
1743 /* match stretches into both external dictionary and current block */
1744 size_t const copySize = (size_t)(lowPrefix - match);
1745 size_t const restSize = length - copySize;
1746 memcpy(op, dictEnd - copySize, copySize);
1747 op += copySize;
1748 if (restSize > (size_t)(op - lowPrefix)) { /* overlap copy */
1749 BYTE* const endOfMatch = op + restSize;
1750 const BYTE* copyFrom = lowPrefix;
1751 while (op < endOfMatch) *op++ = *copyFrom++;
1752 } else {
1753 memcpy(op, lowPrefix, restSize);
1754 op += restSize;
1755 } }
1756 continue;
1185 } 1757 }
1186 memcpy(op, ip, length);
1187 ip += length;
1188 op += length;
1189 break; /* Necessarily EOF, due to parsing restrictions */
1190 }
1191 LZ4_wildCopy(op, ip, cpy);
1192 ip += length; op = cpy;
1193 1758
1194 /* get offset */ 1759 /* copy match within block */
1195 match = cpy - LZ4_readLE16(ip); ip+=2; 1760 cpy = op + length;
1196 if ((checkOffset) && (unlikely(match < lowLimit))) goto _output_error; /* Error : offset outside destination buffer */
1197 1761
1198 /* get matchlength */ 1762 assert((op <= oend) && (oend-op >= 32));
1199 length = token & ML_MASK; 1763 if (unlikely(offset<16)) {
1200 if (length == ML_MASK) 1764 LZ4_memcpy_using_offset(op, match, cpy, offset);
1201 { 1765 } else {
1202 unsigned s; 1766 LZ4_wildCopy32(op, match, cpy);
1203 do 1767 }
1204 { 1768
1205 if ((endOnInput) && (ip > iend-LASTLITERALS)) goto _output_error; 1769 op = cpy; /* wildcopy correction */
1206 s = *ip++;
1207 length += s;
1208 } while (s==255);
1209 if ((safeDecode) && unlikely((size_t)(op+length)<(size_t)op)) goto _output_error; /* overflow detection */
1210 } 1770 }
1211 length += MINMATCH; 1771 safe_decode:
1772#endif
1212 1773
1213 /* check external dictionary */ 1774 /* Main Loop : decode remaining sequences where output < FASTLOOP_SAFE_DISTANCE */
1214 if ((dict==usingExtDict) && (match < lowPrefix)) 1775 while (1) {
1215 { 1776 token = *ip++;
1216 if (unlikely(op+length > oend-LASTLITERALS)) goto _output_error; /* doesn't respect parsing restriction */ 1777 length = token >> ML_BITS; /* literal length */
1778
1779 assert(!endOnInput || ip <= iend); /* ip < iend before the increment */
1780
1781 /* A two-stage shortcut for the most common case:
1782 * 1) If the literal length is 0..14, and there is enough space,
1783 * enter the shortcut and copy 16 bytes on behalf of the literals
1784 * (in the fast mode, only 8 bytes can be safely copied this way).
1785 * 2) Further if the match length is 4..18, copy 18 bytes in a similar
1786 * manner; but we ensure that there's enough space in the output for
1787 * those 18 bytes earlier, upon entering the shortcut (in other words,
1788 * there is a combined check for both stages).
1789 */
1790 if ( (endOnInput ? length != RUN_MASK : length <= 8)
1791 /* strictly "less than" on input, to re-enter the loop with at least one byte */
1792 && likely((endOnInput ? ip < shortiend : 1) & (op <= shortoend)) ) {
1793 /* Copy the literals */
1794 memcpy(op, ip, endOnInput ? 16 : 8);
1795 op += length; ip += length;
1796
1797 /* The second stage: prepare for match copying, decode full info.
1798 * If it doesn't work out, the info won't be wasted. */
1799 length = token & ML_MASK; /* match length */
1800 offset = LZ4_readLE16(ip); ip += 2;
1801 match = op - offset;
1802 assert(match <= op); /* check overflow */
1803
1804 /* Do not deal with overlapping matches. */
1805 if ( (length != ML_MASK)
1806 && (offset >= 8)
1807 && (dict==withPrefix64k || match >= lowPrefix) ) {
1808 /* Copy the match. */
1809 memcpy(op + 0, match + 0, 8);
1810 memcpy(op + 8, match + 8, 8);
1811 memcpy(op +16, match +16, 2);
1812 op += length + MINMATCH;
1813 /* Both stages worked, load the next token. */
1814 continue;
1815 }
1217 1816
1218 if (length <= (size_t)(lowPrefix-match)) 1817 /* The second stage didn't work out, but the info is ready.
1219 { 1818 * Propel it right to the point of match copying. */
1220 /* match can be copied as a single segment from external dictionary */ 1819 goto _copy_match;
1221 match = dictEnd - (lowPrefix-match); 1820 }
1222 memmove(op, match, length); op += length; 1821
1822 /* decode literal length */
1823 if (length == RUN_MASK) {
1824 variable_length_error error = ok;
1825 length += read_variable_length(&ip, iend-RUN_MASK, endOnInput, endOnInput, &error);
1826 if (error == initial_error) goto _output_error;
1827 if ((safeDecode) && unlikely((uptrval)(op)+length<(uptrval)(op))) goto _output_error; /* overflow detection */
1828 if ((safeDecode) && unlikely((uptrval)(ip)+length<(uptrval)(ip))) goto _output_error; /* overflow detection */
1223 } 1829 }
1224 else 1830
1831 /* copy literals */
1832 cpy = op+length;
1833#if LZ4_FAST_DEC_LOOP
1834 safe_literal_copy:
1835#endif
1836 LZ4_STATIC_ASSERT(MFLIMIT >= WILDCOPYLENGTH);
1837 if ( ((endOnInput) && ((cpy>oend-MFLIMIT) || (ip+length>iend-(2+1+LASTLITERALS))) )
1838 || ((!endOnInput) && (cpy>oend-WILDCOPYLENGTH)) )
1225 { 1839 {
1226 /* match encompass external dictionary and current segment */ 1840 if (partialDecoding) {
1227 size_t copySize = (size_t)(lowPrefix-match); 1841 if (cpy > oend) { cpy = oend; assert(op<=oend); length = (size_t)(oend-op); } /* Partial decoding : stop in the middle of literal segment */
1228 memcpy(op, dictEnd - copySize, copySize); 1842 if ((endOnInput) && (ip+length > iend)) goto _output_error; /* Error : read attempt beyond end of input buffer */
1229 op += copySize; 1843 } else {
1230 copySize = length - copySize; 1844 if ((!endOnInput) && (cpy != oend)) goto _output_error; /* Error : block decoding must stop exactly there */
1231 if (copySize > (size_t)(op-lowPrefix)) /* overlap within current segment */ 1845 if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) goto _output_error; /* Error : input must be consumed */
1232 { 1846 }
1233 BYTE* const endOfMatch = op + copySize; 1847 memcpy(op, ip, length);
1234 const BYTE* copyFrom = lowPrefix; 1848 ip += length;
1235 while (op < endOfMatch) *op++ = *copyFrom++; 1849 op += length;
1850 if (!partialDecoding || (cpy == oend)) {
1851 /* Necessarily EOF, due to parsing restrictions */
1852 break;
1236 } 1853 }
1237 else 1854
1238 { 1855 } else {
1239 memcpy(op, lowPrefix, copySize); 1856 LZ4_wildCopy8(op, ip, cpy); /* may overwrite up to WILDCOPYLENGTH beyond cpy */
1857 ip += length; op = cpy;
1858 }
1859
1860 /* get offset */
1861 offset = LZ4_readLE16(ip); ip+=2;
1862 match = op - offset;
1863
1864 /* get matchlength */
1865 length = token & ML_MASK;
1866
1867 _copy_match:
1868 if ((checkOffset) && (unlikely(match + dictSize < lowPrefix))) goto _output_error; /* Error : offset outside buffers */
1869 if (!partialDecoding) {
1870 assert(oend > op);
1871 assert(oend - op >= 4);
1872 LZ4_write32(op, 0); /* silence an msan warning when offset==0; costs <1%; */
1873 } /* note : when partialDecoding, there is no guarantee that at least 4 bytes remain available in output buffer */
1874
1875 if (length == ML_MASK) {
1876 variable_length_error error = ok;
1877 length += read_variable_length(&ip, iend - LASTLITERALS + 1, endOnInput, 0, &error);
1878 if (error != ok) goto _output_error;
1879 if ((safeDecode) && unlikely((uptrval)(op)+length<(uptrval)op)) goto _output_error; /* overflow detection */
1880 }
1881 length += MINMATCH;
1882
1883#if LZ4_FAST_DEC_LOOP
1884 safe_match_copy:
1885#endif
1886 /* match starting within external dictionary */
1887 if ((dict==usingExtDict) && (match < lowPrefix)) {
1888 if (unlikely(op+length > oend-LASTLITERALS)) {
1889 if (partialDecoding) length = MIN(length, (size_t)(oend-op));
1890 else goto _output_error; /* doesn't respect parsing restriction */
1891 }
1892
1893 if (length <= (size_t)(lowPrefix-match)) {
1894 /* match fits entirely within external dictionary : just copy */
1895 memmove(op, dictEnd - (lowPrefix-match), length);
1896 op += length;
1897 } else {
1898 /* match stretches into both external dictionary and current block */
1899 size_t const copySize = (size_t)(lowPrefix - match);
1900 size_t const restSize = length - copySize;
1901 memcpy(op, dictEnd - copySize, copySize);
1240 op += copySize; 1902 op += copySize;
1903 if (restSize > (size_t)(op - lowPrefix)) { /* overlap copy */
1904 BYTE* const endOfMatch = op + restSize;
1905 const BYTE* copyFrom = lowPrefix;
1906 while (op < endOfMatch) *op++ = *copyFrom++;
1907 } else {
1908 memcpy(op, lowPrefix, restSize);
1909 op += restSize;
1910 } }
1911 continue;
1912 }
1913
1914 /* copy match within block */
1915 cpy = op + length;
1916
1917 /* partialDecoding : may end anywhere within the block */
1918 assert(op<=oend);
1919 if (partialDecoding && (cpy > oend-MATCH_SAFEGUARD_DISTANCE)) {
1920 size_t const mlen = MIN(length, (size_t)(oend-op));
1921 const BYTE* const matchEnd = match + mlen;
1922 BYTE* const copyEnd = op + mlen;
1923 if (matchEnd > op) { /* overlap copy */
1924 while (op < copyEnd) *op++ = *match++;
1925 } else {
1926 memcpy(op, match, mlen);
1241 } 1927 }
1928 op = copyEnd;
1929 if (op==oend) break;
1930 continue;
1242 } 1931 }
1243 continue;
1244 }
1245 1932
1246 /* copy repeated sequence */ 1933 if (unlikely(offset<8)) {
1247 cpy = op + length; 1934 op[0] = match[0];
1248 if (unlikely((op-match)<8)) 1935 op[1] = match[1];
1249 { 1936 op[2] = match[2];
1250 const size_t dec64 = dec64table[op-match]; 1937 op[3] = match[3];
1251 op[0] = match[0]; 1938 match += inc32table[offset];
1252 op[1] = match[1]; 1939 memcpy(op+4, match, 4);
1253 op[2] = match[2]; 1940 match -= dec64table[offset];
1254 op[3] = match[3]; 1941 } else {
1255 match += dec32table[op-match]; 1942 memcpy(op, match, 8);
1256 LZ4_copy4(op+4, match); 1943 match += 8;
1257 op += 8; match -= dec64;
1258 } else { LZ4_copy8(op, match); op+=8; match+=8; }
1259
1260 if (unlikely(cpy>oend-12))
1261 {
1262 if (cpy > oend-LASTLITERALS) goto _output_error; /* Error : last LASTLITERALS bytes must be literals */
1263 if (op < oend-8)
1264 {
1265 LZ4_wildCopy(op, match, oend-8);
1266 match += (oend-8) - op;
1267 op = oend-8;
1268 } 1944 }
1269 while (op<cpy) *op++ = *match++; 1945 op += 8;
1946
1947 if (unlikely(cpy > oend-MATCH_SAFEGUARD_DISTANCE)) {
1948 BYTE* const oCopyLimit = oend - (WILDCOPYLENGTH-1);
1949 if (cpy > oend-LASTLITERALS) goto _output_error; /* Error : last LASTLITERALS bytes must be literals (uncompressed) */
1950 if (op < oCopyLimit) {
1951 LZ4_wildCopy8(op, match, oCopyLimit);
1952 match += oCopyLimit - op;
1953 op = oCopyLimit;
1954 }
1955 while (op < cpy) *op++ = *match++;
1956 } else {
1957 memcpy(op, match, 8);
1958 if (length > 16) LZ4_wildCopy8(op+8, match+8, cpy);
1959 }
1960 op = cpy; /* wildcopy correction */
1270 } 1961 }
1271 else
1272 LZ4_wildCopy(op, match, cpy);
1273 op=cpy; /* correction */
1274 }
1275 1962
1276 /* end of decoding */ 1963 /* end of decoding */
1277 if (endOnInput) 1964 if (endOnInput)
1278 return (int) (((char*)op)-dest); /* Nb of output bytes decoded */ 1965 return (int) (((char*)op)-dst); /* Nb of output bytes decoded */
1279 else 1966 else
1280 return (int) (((const char*)ip)-source); /* Nb of input bytes read */ 1967 return (int) (((const char*)ip)-src); /* Nb of input bytes read */
1281 1968
1282 /* Overflow error detected */ 1969 /* Overflow error detected */
1283_output_error: 1970 _output_error:
1284 return (int) (-(((const char*)ip)-source))-1; 1971 return (int) (-(((const char*)ip)-src))-1;
1972 }
1285} 1973}
1286 1974
1287 1975
1976/*===== Instantiate the API decoding functions. =====*/
1977
1978LZ4_FORCE_O2_GCC_PPC64LE
1288int LZ4_decompress_safe(const char* source, char* dest, int compressedSize, int maxDecompressedSize) 1979int LZ4_decompress_safe(const char* source, char* dest, int compressedSize, int maxDecompressedSize)
1289{ 1980{
1290 return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, endOnInputSize, full, 0, noDict, (BYTE*)dest, NULL, 0); 1981 return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize,
1982 endOnInputSize, decode_full_block, noDict,
1983 (BYTE*)dest, NULL, 0);
1291} 1984}
1292 1985
1293int LZ4_decompress_safe_partial(const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize) 1986LZ4_FORCE_O2_GCC_PPC64LE
1987int LZ4_decompress_safe_partial(const char* src, char* dst, int compressedSize, int targetOutputSize, int dstCapacity)
1294{ 1988{
1295 return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, endOnInputSize, partial, targetOutputSize, noDict, (BYTE*)dest, NULL, 0); 1989 dstCapacity = MIN(targetOutputSize, dstCapacity);
1990 return LZ4_decompress_generic(src, dst, compressedSize, dstCapacity,
1991 endOnInputSize, partial_decode,
1992 noDict, (BYTE*)dst, NULL, 0);
1296} 1993}
1297 1994
1995LZ4_FORCE_O2_GCC_PPC64LE
1298int LZ4_decompress_fast(const char* source, char* dest, int originalSize) 1996int LZ4_decompress_fast(const char* source, char* dest, int originalSize)
1299{ 1997{
1300 return LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, withPrefix64k, (BYTE*)(dest - 64 KB), NULL, 64 KB); 1998 return LZ4_decompress_generic(source, dest, 0, originalSize,
1999 endOnOutputSize, decode_full_block, withPrefix64k,
2000 (BYTE*)dest - 64 KB, NULL, 0);
1301} 2001}
1302 2002
2003/*===== Instantiate a few more decoding cases, used more than once. =====*/
1303 2004
1304/* streaming decompression functions */ 2005LZ4_FORCE_O2_GCC_PPC64LE /* Exported, an obsolete API function. */
2006int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int compressedSize, int maxOutputSize)
2007{
2008 return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize,
2009 endOnInputSize, decode_full_block, withPrefix64k,
2010 (BYTE*)dest - 64 KB, NULL, 0);
2011}
1305 2012
1306typedef struct 2013/* Another obsolete API function, paired with the previous one. */
2014int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int originalSize)
1307{ 2015{
1308 const BYTE* externalDict; 2016 /* LZ4_decompress_fast doesn't validate match offsets,
1309 size_t extDictSize; 2017 * and thus serves well with any prefixed dictionary. */
1310 const BYTE* prefixEnd; 2018 return LZ4_decompress_fast(source, dest, originalSize);
1311 size_t prefixSize; 2019}
1312} LZ4_streamDecode_t_internal;
1313 2020
1314/* 2021LZ4_FORCE_O2_GCC_PPC64LE
1315 * If you prefer dynamic allocation methods, 2022static int LZ4_decompress_safe_withSmallPrefix(const char* source, char* dest, int compressedSize, int maxOutputSize,
1316 * LZ4_createStreamDecode() 2023 size_t prefixSize)
1317 * provides a pointer (void*) towards an initialized LZ4_streamDecode_t structure. 2024{
2025 return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize,
2026 endOnInputSize, decode_full_block, noDict,
2027 (BYTE*)dest-prefixSize, NULL, 0);
2028}
2029
2030LZ4_FORCE_O2_GCC_PPC64LE
2031int LZ4_decompress_safe_forceExtDict(const char* source, char* dest,
2032 int compressedSize, int maxOutputSize,
2033 const void* dictStart, size_t dictSize)
2034{
2035 return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize,
2036 endOnInputSize, decode_full_block, usingExtDict,
2037 (BYTE*)dest, (const BYTE*)dictStart, dictSize);
2038}
2039
2040LZ4_FORCE_O2_GCC_PPC64LE
2041static int LZ4_decompress_fast_extDict(const char* source, char* dest, int originalSize,
2042 const void* dictStart, size_t dictSize)
2043{
2044 return LZ4_decompress_generic(source, dest, 0, originalSize,
2045 endOnOutputSize, decode_full_block, usingExtDict,
2046 (BYTE*)dest, (const BYTE*)dictStart, dictSize);
2047}
2048
2049/* The "double dictionary" mode, for use with e.g. ring buffers: the first part
2050 * of the dictionary is passed as prefix, and the second via dictStart + dictSize.
2051 * These routines are used only once, in LZ4_decompress_*_continue().
1318 */ 2052 */
2053LZ4_FORCE_INLINE
2054int LZ4_decompress_safe_doubleDict(const char* source, char* dest, int compressedSize, int maxOutputSize,
2055 size_t prefixSize, const void* dictStart, size_t dictSize)
2056{
2057 return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize,
2058 endOnInputSize, decode_full_block, usingExtDict,
2059 (BYTE*)dest-prefixSize, (const BYTE*)dictStart, dictSize);
2060}
2061
2062LZ4_FORCE_INLINE
2063int LZ4_decompress_fast_doubleDict(const char* source, char* dest, int originalSize,
2064 size_t prefixSize, const void* dictStart, size_t dictSize)
2065{
2066 return LZ4_decompress_generic(source, dest, 0, originalSize,
2067 endOnOutputSize, decode_full_block, usingExtDict,
2068 (BYTE*)dest-prefixSize, (const BYTE*)dictStart, dictSize);
2069}
2070
2071/*===== streaming decompression functions =====*/
2072
1319LZ4_streamDecode_t* LZ4_createStreamDecode(void) 2073LZ4_streamDecode_t* LZ4_createStreamDecode(void)
1320{ 2074{
1321 LZ4_streamDecode_t* lz4s = (LZ4_streamDecode_t*) ALLOCATOR(1, sizeof(LZ4_streamDecode_t)); 2075 LZ4_streamDecode_t* lz4s = (LZ4_streamDecode_t*) ALLOC_AND_ZERO(sizeof(LZ4_streamDecode_t));
2076 LZ4_STATIC_ASSERT(LZ4_STREAMDECODESIZE >= sizeof(LZ4_streamDecode_t_internal)); /* A compilation error here means LZ4_STREAMDECODESIZE is not large enough */
1322 return lz4s; 2077 return lz4s;
1323} 2078}
1324 2079
1325int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream) 2080int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream)
1326{ 2081{
2082 if (LZ4_stream == NULL) return 0; /* support free on NULL */
1327 FREEMEM(LZ4_stream); 2083 FREEMEM(LZ4_stream);
1328 return 0; 2084 return 0;
1329} 2085}
1330 2086
1331/* 2087/*! LZ4_setStreamDecode() :
1332 * LZ4_setStreamDecode 2088 * Use this function to instruct where to find the dictionary.
1333 * Use this function to instruct where to find the dictionary 2089 * This function is not necessary if previous data is still available where it was decoded.
1334 * This function is not necessary if previous data is still available where it was decoded. 2090 * Loading a size of 0 is allowed (same effect as no dictionary).
1335 * Loading a size of 0 is allowed (same effect as no dictionary). 2091 * @return : 1 if OK, 0 if error
1336 * Return : 1 if OK, 0 if error
1337 */ 2092 */
1338int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize) 2093int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize)
1339{ 2094{
1340 LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode; 2095 LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse;
1341 lz4sd->prefixSize = (size_t) dictSize; 2096 lz4sd->prefixSize = (size_t) dictSize;
1342 lz4sd->prefixEnd = (const BYTE*) dictionary + dictSize; 2097 lz4sd->prefixEnd = (const BYTE*) dictionary + dictSize;
1343 lz4sd->externalDict = NULL; 2098 lz4sd->externalDict = NULL;
@@ -1345,6 +2100,25 @@ int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dicti
1345 return 1; 2100 return 1;
1346} 2101}
1347 2102
2103/*! LZ4_decoderRingBufferSize() :
2104 * when setting a ring buffer for streaming decompression (optional scenario),
2105 * provides the minimum size of this ring buffer
2106 * to be compatible with any source respecting maxBlockSize condition.
2107 * Note : in a ring buffer scenario,
2108 * blocks are presumed decompressed next to each other.
2109 * When not enough space remains for next block (remainingSize < maxBlockSize),
2110 * decoding resumes from beginning of ring buffer.
2111 * @return : minimum ring buffer size,
2112 * or 0 if there is an error (invalid maxBlockSize).
2113 */
2114int LZ4_decoderRingBufferSize(int maxBlockSize)
2115{
2116 if (maxBlockSize < 0) return 0;
2117 if (maxBlockSize > LZ4_MAX_INPUT_SIZE) return 0;
2118 if (maxBlockSize < 16) maxBlockSize = 16;
2119 return LZ4_DECODER_RING_BUFFER_SIZE(maxBlockSize);
2120}
2121
1348/* 2122/*
1349*_continue() : 2123*_continue() :
1350 These decoding functions allow decompression of multiple blocks in "streaming" mode. 2124 These decoding functions allow decompression of multiple blocks in "streaming" mode.
@@ -1352,58 +2126,75 @@ int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dicti
1352 If it's not possible, save the relevant part of decoded data into a safe buffer, 2126 If it's not possible, save the relevant part of decoded data into a safe buffer,
1353 and indicate where it stands using LZ4_setStreamDecode() 2127 and indicate where it stands using LZ4_setStreamDecode()
1354*/ 2128*/
2129LZ4_FORCE_O2_GCC_PPC64LE
1355int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxOutputSize) 2130int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxOutputSize)
1356{ 2131{
1357 LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode; 2132 LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse;
1358 int result; 2133 int result;
1359 2134
1360 if (lz4sd->prefixEnd == (BYTE*)dest) 2135 if (lz4sd->prefixSize == 0) {
1361 { 2136 /* The first call, no dictionary yet. */
1362 result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, 2137 assert(lz4sd->extDictSize == 0);
1363 endOnInputSize, full, 0, 2138 result = LZ4_decompress_safe(source, dest, compressedSize, maxOutputSize);
1364 usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize);
1365 if (result <= 0) return result; 2139 if (result <= 0) return result;
1366 lz4sd->prefixSize += result; 2140 lz4sd->prefixSize = (size_t)result;
2141 lz4sd->prefixEnd = (BYTE*)dest + result;
2142 } else if (lz4sd->prefixEnd == (BYTE*)dest) {
2143 /* They're rolling the current segment. */
2144 if (lz4sd->prefixSize >= 64 KB - 1)
2145 result = LZ4_decompress_safe_withPrefix64k(source, dest, compressedSize, maxOutputSize);
2146 else if (lz4sd->extDictSize == 0)
2147 result = LZ4_decompress_safe_withSmallPrefix(source, dest, compressedSize, maxOutputSize,
2148 lz4sd->prefixSize);
2149 else
2150 result = LZ4_decompress_safe_doubleDict(source, dest, compressedSize, maxOutputSize,
2151 lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize);
2152 if (result <= 0) return result;
2153 lz4sd->prefixSize += (size_t)result;
1367 lz4sd->prefixEnd += result; 2154 lz4sd->prefixEnd += result;
1368 } 2155 } else {
1369 else 2156 /* The buffer wraps around, or they're switching to another buffer. */
1370 {
1371 lz4sd->extDictSize = lz4sd->prefixSize; 2157 lz4sd->extDictSize = lz4sd->prefixSize;
1372 lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize; 2158 lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize;
1373 result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, 2159 result = LZ4_decompress_safe_forceExtDict(source, dest, compressedSize, maxOutputSize,
1374 endOnInputSize, full, 0, 2160 lz4sd->externalDict, lz4sd->extDictSize);
1375 usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize);
1376 if (result <= 0) return result; 2161 if (result <= 0) return result;
1377 lz4sd->prefixSize = result; 2162 lz4sd->prefixSize = (size_t)result;
1378 lz4sd->prefixEnd = (BYTE*)dest + result; 2163 lz4sd->prefixEnd = (BYTE*)dest + result;
1379 } 2164 }
1380 2165
1381 return result; 2166 return result;
1382} 2167}
1383 2168
2169LZ4_FORCE_O2_GCC_PPC64LE
1384int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize) 2170int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize)
1385{ 2171{
1386 LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode; 2172 LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse;
1387 int result; 2173 int result;
2174 assert(originalSize >= 0);
1388 2175
1389 if (lz4sd->prefixEnd == (BYTE*)dest) 2176 if (lz4sd->prefixSize == 0) {
1390 { 2177 assert(lz4sd->extDictSize == 0);
1391 result = LZ4_decompress_generic(source, dest, 0, originalSize, 2178 result = LZ4_decompress_fast(source, dest, originalSize);
1392 endOnOutputSize, full, 0, 2179 if (result <= 0) return result;
1393 usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize); 2180 lz4sd->prefixSize = (size_t)originalSize;
2181 lz4sd->prefixEnd = (BYTE*)dest + originalSize;
2182 } else if (lz4sd->prefixEnd == (BYTE*)dest) {
2183 if (lz4sd->prefixSize >= 64 KB - 1 || lz4sd->extDictSize == 0)
2184 result = LZ4_decompress_fast(source, dest, originalSize);
2185 else
2186 result = LZ4_decompress_fast_doubleDict(source, dest, originalSize,
2187 lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize);
1394 if (result <= 0) return result; 2188 if (result <= 0) return result;
1395 lz4sd->prefixSize += originalSize; 2189 lz4sd->prefixSize += (size_t)originalSize;
1396 lz4sd->prefixEnd += originalSize; 2190 lz4sd->prefixEnd += originalSize;
1397 } 2191 } else {
1398 else
1399 {
1400 lz4sd->extDictSize = lz4sd->prefixSize; 2192 lz4sd->extDictSize = lz4sd->prefixSize;
1401 lz4sd->externalDict = (BYTE*)dest - lz4sd->extDictSize; 2193 lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize;
1402 result = LZ4_decompress_generic(source, dest, 0, originalSize, 2194 result = LZ4_decompress_fast_extDict(source, dest, originalSize,
1403 endOnOutputSize, full, 0, 2195 lz4sd->externalDict, lz4sd->extDictSize);
1404 usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize);
1405 if (result <= 0) return result; 2196 if (result <= 0) return result;
1406 lz4sd->prefixSize = originalSize; 2197 lz4sd->prefixSize = (size_t)originalSize;
1407 lz4sd->prefixEnd = (BYTE*)dest + originalSize; 2198 lz4sd->prefixEnd = (BYTE*)dest + originalSize;
1408 } 2199 }
1409 2200
@@ -1418,99 +2209,91 @@ Advanced decoding functions :
1418 the dictionary must be explicitly provided within parameters 2209 the dictionary must be explicitly provided within parameters
1419*/ 2210*/
1420 2211
1421FORCE_INLINE int LZ4_decompress_usingDict_generic(const char* source, char* dest, int compressedSize, int maxOutputSize, int safe, const char* dictStart, int dictSize) 2212int LZ4_decompress_safe_usingDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize)
1422{ 2213{
1423 if (dictSize==0) 2214 if (dictSize==0)
1424 return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest, NULL, 0); 2215 return LZ4_decompress_safe(source, dest, compressedSize, maxOutputSize);
1425 if (dictStart+dictSize == dest) 2216 if (dictStart+dictSize == dest) {
1426 { 2217 if (dictSize >= 64 KB - 1)
1427 if (dictSize >= (int)(64 KB - 1)) 2218 return LZ4_decompress_safe_withPrefix64k(source, dest, compressedSize, maxOutputSize);
1428 return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, withPrefix64k, (BYTE*)dest-64 KB, NULL, 0); 2219 return LZ4_decompress_safe_withSmallPrefix(source, dest, compressedSize, maxOutputSize, dictSize);
1429 return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest-dictSize, NULL, 0);
1430 } 2220 }
1431 return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, usingExtDict, (BYTE*)dest, (const BYTE*)dictStart, dictSize); 2221 return LZ4_decompress_safe_forceExtDict(source, dest, compressedSize, maxOutputSize, dictStart, dictSize);
1432}
1433
1434int LZ4_decompress_safe_usingDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize)
1435{
1436 return LZ4_decompress_usingDict_generic(source, dest, compressedSize, maxOutputSize, 1, dictStart, dictSize);
1437} 2222}
1438 2223
1439int LZ4_decompress_fast_usingDict(const char* source, char* dest, int originalSize, const char* dictStart, int dictSize) 2224int LZ4_decompress_fast_usingDict(const char* source, char* dest, int originalSize, const char* dictStart, int dictSize)
1440{ 2225{
1441 return LZ4_decompress_usingDict_generic(source, dest, 0, originalSize, 0, dictStart, dictSize); 2226 if (dictSize==0 || dictStart+dictSize == dest)
1442} 2227 return LZ4_decompress_fast(source, dest, originalSize);
1443 2228 return LZ4_decompress_fast_extDict(source, dest, originalSize, dictStart, dictSize);
1444/* debug function */
1445int LZ4_decompress_safe_forceExtDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize)
1446{
1447 return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, usingExtDict, (BYTE*)dest, (const BYTE*)dictStart, dictSize);
1448} 2229}
1449 2230
1450 2231
1451/*************************************************** 2232/*=*************************************************
1452* Obsolete Functions 2233* Obsolete Functions
1453***************************************************/ 2234***************************************************/
1454/* obsolete compression functions */ 2235/* obsolete compression functions */
1455int LZ4_compress_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize) { return LZ4_compress_default(source, dest, inputSize, maxOutputSize); } 2236int LZ4_compress_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize)
1456int LZ4_compress(const char* source, char* dest, int inputSize) { return LZ4_compress_default(source, dest, inputSize, LZ4_compressBound(inputSize)); } 2237{
1457int LZ4_compress_limitedOutput_withState (void* state, const char* src, char* dst, int srcSize, int dstSize) { return LZ4_compress_fast_extState(state, src, dst, srcSize, dstSize, 1); } 2238 return LZ4_compress_default(source, dest, inputSize, maxOutputSize);
1458int LZ4_compress_withState (void* state, const char* src, char* dst, int srcSize) { return LZ4_compress_fast_extState(state, src, dst, srcSize, LZ4_compressBound(srcSize), 1); } 2239}
1459int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_stream, const char* src, char* dst, int srcSize, int maxDstSize) { return LZ4_compress_fast_continue(LZ4_stream, src, dst, srcSize, maxDstSize, 1); } 2240int LZ4_compress(const char* source, char* dest, int inputSize)
1460int LZ4_compress_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize) { return LZ4_compress_fast_continue(LZ4_stream, source, dest, inputSize, LZ4_compressBound(inputSize), 1); } 2241{
2242 return LZ4_compress_default(source, dest, inputSize, LZ4_compressBound(inputSize));
2243}
2244int LZ4_compress_limitedOutput_withState (void* state, const char* src, char* dst, int srcSize, int dstSize)
2245{
2246 return LZ4_compress_fast_extState(state, src, dst, srcSize, dstSize, 1);
2247}
2248int LZ4_compress_withState (void* state, const char* src, char* dst, int srcSize)
2249{
2250 return LZ4_compress_fast_extState(state, src, dst, srcSize, LZ4_compressBound(srcSize), 1);
2251}
2252int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_stream, const char* src, char* dst, int srcSize, int dstCapacity)
2253{
2254 return LZ4_compress_fast_continue(LZ4_stream, src, dst, srcSize, dstCapacity, 1);
2255}
2256int LZ4_compress_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize)
2257{
2258 return LZ4_compress_fast_continue(LZ4_stream, source, dest, inputSize, LZ4_compressBound(inputSize), 1);
2259}
1461 2260
1462/* 2261/*
1463These function names are deprecated and should no longer be used. 2262These decompression functions are deprecated and should no longer be used.
1464They are only provided here for compatibility with older user programs. 2263They are only provided here for compatibility with older user programs.
1465- LZ4_uncompress is totally equivalent to LZ4_decompress_fast 2264- LZ4_uncompress is totally equivalent to LZ4_decompress_fast
1466- LZ4_uncompress_unknownOutputSize is totally equivalent to LZ4_decompress_safe 2265- LZ4_uncompress_unknownOutputSize is totally equivalent to LZ4_decompress_safe
1467*/ 2266*/
1468int LZ4_uncompress (const char* source, char* dest, int outputSize) { return LZ4_decompress_fast(source, dest, outputSize); } 2267int LZ4_uncompress (const char* source, char* dest, int outputSize)
1469int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize) { return LZ4_decompress_safe(source, dest, isize, maxOutputSize); } 2268{
1470 2269 return LZ4_decompress_fast(source, dest, outputSize);
2270}
2271int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize)
2272{
2273 return LZ4_decompress_safe(source, dest, isize, maxOutputSize);
2274}
1471 2275
1472/* Obsolete Streaming functions */ 2276/* Obsolete Streaming functions */
1473 2277
1474int LZ4_sizeofStreamState() { return LZ4_STREAMSIZE; } 2278int LZ4_sizeofStreamState() { return LZ4_STREAMSIZE; }
1475 2279
1476static void LZ4_init(LZ4_stream_t_internal* lz4ds, BYTE* base)
1477{
1478 MEM_INIT(lz4ds, 0, LZ4_STREAMSIZE);
1479 lz4ds->bufferStart = base;
1480}
1481
1482int LZ4_resetStreamState(void* state, char* inputBuffer) 2280int LZ4_resetStreamState(void* state, char* inputBuffer)
1483{ 2281{
1484 if ((((size_t)state) & 3) != 0) return 1; /* Error : pointer is not aligned on 4-bytes boundary */ 2282 (void)inputBuffer;
1485 LZ4_init((LZ4_stream_t_internal*)state, (BYTE*)inputBuffer); 2283 LZ4_resetStream((LZ4_stream_t*)state);
1486 return 0; 2284 return 0;
1487} 2285}
1488 2286
1489void* LZ4_create (char* inputBuffer) 2287void* LZ4_create (char* inputBuffer)
1490{ 2288{
1491 void* lz4ds = ALLOCATOR(8, LZ4_STREAMSIZE_U64); 2289 (void)inputBuffer;
1492 LZ4_init ((LZ4_stream_t_internal*)lz4ds, (BYTE*)inputBuffer); 2290 return LZ4_createStream();
1493 return lz4ds;
1494}
1495
1496char* LZ4_slideInputBuffer (void* LZ4_Data)
1497{
1498 LZ4_stream_t_internal* ctx = (LZ4_stream_t_internal*)LZ4_Data;
1499 int dictSize = LZ4_saveDict((LZ4_stream_t*)LZ4_Data, (char*)ctx->bufferStart, 64 KB);
1500 return (char*)(ctx->bufferStart + dictSize);
1501}
1502
1503/* Obsolete streaming decompression functions */
1504
1505int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int compressedSize, int maxOutputSize)
1506{
1507 return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB);
1508} 2291}
1509 2292
1510int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int originalSize) 2293char* LZ4_slideInputBuffer (void* state)
1511{ 2294{
1512 return LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB); 2295 /* avoid const char * -> char * conversion warning */
2296 return (char *)(uptrval)((LZ4_stream_t*)state)->internal_donotuse.dictionary;
1513} 2297}
1514 2298
1515#endif /* LZ4_COMMONDEFS_ONLY */ 2299#endif /* LZ4_COMMONDEFS_ONLY */
1516
diff --git a/src/static_libs/lz4/lz4.h b/src/static_libs/lz4/lz4.h
index 3e74002..a9c932c 100644
--- a/src/static_libs/lz4/lz4.h
+++ b/src/static_libs/lz4/lz4.h
@@ -1,7 +1,7 @@
1/* 1/*
2 LZ4 - Fast LZ compression algorithm 2 * LZ4 - Fast LZ compression algorithm
3 Header File 3 * Header File
4 Copyright (C) 2011-2015, Yann Collet. 4 * Copyright (C) 2011-present, Yann Collet.
5 5
6 BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 6 BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
7 7
@@ -29,291 +29,566 @@
29 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 30
31 You can contact the author at : 31 You can contact the author at :
32 - LZ4 source repository : https://github.com/Cyan4973/lz4 32 - LZ4 homepage : http://www.lz4.org
33 - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c 33 - LZ4 source repository : https://github.com/lz4/lz4
34*/ 34*/
35#pragma once
36
37#if defined (__cplusplus) 35#if defined (__cplusplus)
38extern "C" { 36extern "C" {
39#endif 37#endif
40 38
39#ifndef LZ4_H_2983827168210
40#define LZ4_H_2983827168210
41
42/* --- Dependency --- */
43#include <stddef.h> /* size_t */
44
45
46/**
47 Introduction
48
49 LZ4 is lossless compression algorithm, providing compression speed at 500 MB/s per core,
50 scalable with multi-cores CPU. It features an extremely fast decoder, with speed in
51 multiple GB/s per core, typically reaching RAM speed limits on multi-core systems.
52
53 The LZ4 compression library provides in-memory compression and decompression functions.
54 It gives full buffer control to user.
55 Compression can be done in:
56 - a single step (described as Simple Functions)
57 - a single step, reusing a context (described in Advanced Functions)
58 - unbounded multiple steps (described as Streaming compression)
59
60 lz4.h generates and decodes LZ4-compressed blocks (doc/lz4_Block_format.md).
61 Decompressing a block requires additional metadata, such as its compressed size.
62 Each application is free to encode and pass such metadata in whichever way it wants.
63
64 lz4.h only handle blocks, it can not generate Frames.
65
66 Blocks are different from Frames (doc/lz4_Frame_format.md).
67 Frames bundle both blocks and metadata in a specified manner.
68 This are required for compressed data to be self-contained and portable.
69 Frame format is delivered through a companion API, declared in lz4frame.h.
70 Note that the `lz4` CLI can only manage frames.
71*/
72
73/*^***************************************************************
74* Export parameters
75*****************************************************************/
41/* 76/*
42 * lz4.h provides block compression functions, and gives full buffer control to programmer. 77* LZ4_DLL_EXPORT :
43 * If you need to generate inter-operable compressed data (respecting LZ4 frame specification), 78* Enable exporting of functions when building a Windows DLL
44 * and can let the library handle its own memory, please use lz4frame.h instead. 79* LZ4LIB_VISIBILITY :
80* Control library symbols visibility.
45*/ 81*/
82#ifndef LZ4LIB_VISIBILITY
83# if defined(__GNUC__) && (__GNUC__ >= 4)
84# define LZ4LIB_VISIBILITY __attribute__ ((visibility ("default")))
85# else
86# define LZ4LIB_VISIBILITY
87# endif
88#endif
89#if defined(LZ4_DLL_EXPORT) && (LZ4_DLL_EXPORT==1)
90# define LZ4LIB_API __declspec(dllexport) LZ4LIB_VISIBILITY
91#elif defined(LZ4_DLL_IMPORT) && (LZ4_DLL_IMPORT==1)
92# define LZ4LIB_API __declspec(dllimport) LZ4LIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
93#else
94# define LZ4LIB_API LZ4LIB_VISIBILITY
95#endif
46 96
47/************************************** 97/*------ Version ------*/
48* Version
49**************************************/
50#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */ 98#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */
51#define LZ4_VERSION_MINOR 7 /* for new (non-breaking) interface capabilities */ 99#define LZ4_VERSION_MINOR 9 /* for new (non-breaking) interface capabilities */
52#define LZ4_VERSION_RELEASE 1 /* for tweaks, bug-fixes, or development */ 100#define LZ4_VERSION_RELEASE 1 /* for tweaks, bug-fixes, or development */
101
53#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE) 102#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE)
54int LZ4_versionNumber (void);
55 103
56/************************************** 104#define LZ4_LIB_VERSION LZ4_VERSION_MAJOR.LZ4_VERSION_MINOR.LZ4_VERSION_RELEASE
105#define LZ4_QUOTE(str) #str
106#define LZ4_EXPAND_AND_QUOTE(str) LZ4_QUOTE(str)
107#define LZ4_VERSION_STRING LZ4_EXPAND_AND_QUOTE(LZ4_LIB_VERSION)
108
109LZ4LIB_API int LZ4_versionNumber (void); /**< library version number; useful to check dll version */
110LZ4LIB_API const char* LZ4_versionString (void); /**< library version string; useful to check dll version */
111
112
113/*-************************************
57* Tuning parameter 114* Tuning parameter
58**************************************/ 115**************************************/
59/* 116/*!
60 * LZ4_MEMORY_USAGE : 117 * LZ4_MEMORY_USAGE :
61 * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) 118 * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
62 * Increasing memory usage improves compression ratio 119 * Increasing memory usage improves compression ratio.
63 * Reduced memory usage can improve speed, due to cache effect 120 * Reduced memory usage may improve speed, thanks to better cache locality.
64 * Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache 121 * Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache
65 */ 122 */
66#define LZ4_MEMORY_USAGE 14 123#ifndef LZ4_MEMORY_USAGE
124# define LZ4_MEMORY_USAGE 14
125#endif
67 126
68 127
69/************************************** 128/*-************************************
70* Simple Functions 129* Simple Functions
71**************************************/ 130**************************************/
72 131/*! LZ4_compress_default() :
73int LZ4_compress_default(const char* source, char* dest, int sourceSize, int maxDestSize); 132 Compresses 'srcSize' bytes from buffer 'src'
74int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize); 133 into already allocated 'dst' buffer of size 'dstCapacity'.
75 134 Compression is guaranteed to succeed if 'dstCapacity' >= LZ4_compressBound(srcSize).
76/*
77LZ4_compress_default() :
78 Compresses 'sourceSize' bytes from buffer 'source'
79 into already allocated 'dest' buffer of size 'maxDestSize'.
80 Compression is guaranteed to succeed if 'maxDestSize' >= LZ4_compressBound(sourceSize).
81 It also runs faster, so it's a recommended setting. 135 It also runs faster, so it's a recommended setting.
82 If the function cannot compress 'source' into a more limited 'dest' budget, 136 If the function cannot compress 'src' into a more limited 'dst' budget,
83 compression stops *immediately*, and the function result is zero. 137 compression stops *immediately*, and the function result is zero.
84 As a consequence, 'dest' content is not valid. 138 In which case, 'dst' content is undefined (invalid).
85 This function never writes outside 'dest' buffer, nor read outside 'source' buffer. 139 srcSize : max supported value is LZ4_MAX_INPUT_SIZE.
86 sourceSize : Max supported value is LZ4_MAX_INPUT_VALUE 140 dstCapacity : size of buffer 'dst' (which must be already allocated)
87 maxDestSize : full or partial size of buffer 'dest' (which must be already allocated) 141 @return : the number of bytes written into buffer 'dst' (necessarily <= dstCapacity)
88 return : the number of bytes written into buffer 'dest' (necessarily <= maxOutputSize) 142 or 0 if compression fails
89 or 0 if compression fails 143 Note : This function is protected against buffer overflow scenarios (never writes outside 'dst' buffer, nor read outside 'source' buffer).
90 144*/
91LZ4_decompress_safe() : 145LZ4LIB_API int LZ4_compress_default(const char* src, char* dst, int srcSize, int dstCapacity);
92 compressedSize : is the precise full size of the compressed block. 146
93 maxDecompressedSize : is the size of destination buffer, which must be already allocated. 147/*! LZ4_decompress_safe() :
94 return : the number of bytes decompressed into destination buffer (necessarily <= maxDecompressedSize) 148 compressedSize : is the exact complete size of the compressed block.
95 If destination buffer is not large enough, decoding will stop and output an error code (<0). 149 dstCapacity : is the size of destination buffer, which must be already allocated.
150 @return : the number of bytes decompressed into destination buffer (necessarily <= dstCapacity)
151 If destination buffer is not large enough, decoding will stop and output an error code (negative value).
96 If the source stream is detected malformed, the function will stop decoding and return a negative result. 152 If the source stream is detected malformed, the function will stop decoding and return a negative result.
97 This function is protected against buffer overflow exploits, including malicious data packets. 153 Note : This function is protected against malicious data packets (never writes outside 'dst' buffer, nor read outside 'source' buffer).
98 It never writes outside output buffer, nor reads outside input buffer.
99*/ 154*/
155LZ4LIB_API int LZ4_decompress_safe (const char* src, char* dst, int compressedSize, int dstCapacity);
100 156
101 157
102/************************************** 158/*-************************************
103* Advanced Functions 159* Advanced Functions
104**************************************/ 160**************************************/
105#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */ 161#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */
106#define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16) 162#define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16)
107 163
108/* 164/*! LZ4_compressBound() :
109LZ4_compressBound() :
110 Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible) 165 Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible)
111 This function is primarily useful for memory allocation purposes (destination buffer size). 166 This function is primarily useful for memory allocation purposes (destination buffer size).
112 Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example). 167 Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example).
113 Note that LZ4_compress_default() compress faster when dest buffer size is >= LZ4_compressBound(srcSize) 168 Note that LZ4_compress_default() compresses faster when dstCapacity is >= LZ4_compressBound(srcSize)
114 inputSize : max supported value is LZ4_MAX_INPUT_SIZE 169 inputSize : max supported value is LZ4_MAX_INPUT_SIZE
115 return : maximum output size in a "worst case" scenario 170 return : maximum output size in a "worst case" scenario
116 or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE) 171 or 0, if input size is incorrect (too large or negative)
117*/ 172*/
118int LZ4_compressBound(int inputSize); 173LZ4LIB_API int LZ4_compressBound(int inputSize);
119 174
120/* 175/*! LZ4_compress_fast() :
121LZ4_compress_fast() : 176 Same as LZ4_compress_default(), but allows selection of "acceleration" factor.
122 Same as LZ4_compress_default(), but allows to select an "acceleration" factor.
123 The larger the acceleration value, the faster the algorithm, but also the lesser the compression. 177 The larger the acceleration value, the faster the algorithm, but also the lesser the compression.
124 It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed. 178 It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed.
125 An acceleration value of "1" is the same as regular LZ4_compress_default() 179 An acceleration value of "1" is the same as regular LZ4_compress_default()
126 Values <= 0 will be replaced by ACCELERATION_DEFAULT (see lz4.c), which is 1. 180 Values <= 0 will be replaced by ACCELERATION_DEFAULT (currently == 1, see lz4.c).
127*/ 181*/
128int LZ4_compress_fast (const char* source, char* dest, int sourceSize, int maxDestSize, int acceleration); 182LZ4LIB_API int LZ4_compress_fast (const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
129 183
130 184
131/* 185/*! LZ4_compress_fast_extState() :
132LZ4_compress_fast_extState() : 186 * Same as LZ4_compress_fast(), using an externally allocated memory space for its state.
133 Same compression function, just using an externally allocated memory space to store compression state. 187 * Use LZ4_sizeofState() to know how much memory must be allocated,
134 Use LZ4_sizeofState() to know how much memory must be allocated, 188 * and allocate it on 8-bytes boundaries (using `malloc()` typically).
135 and allocate it on 8-bytes boundaries (using malloc() typically). 189 * Then, provide this buffer as `void* state` to compression function.
136 Then, provide it as 'void* state' to compression function. 190 */
137*/ 191LZ4LIB_API int LZ4_sizeofState(void);
138int LZ4_sizeofState(void); 192LZ4LIB_API int LZ4_compress_fast_extState (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration);
139int LZ4_compress_fast_extState (void* state, const char* source, char* dest, int inputSize, int maxDestSize, int acceleration);
140 193
141 194
142/* 195/*! LZ4_compress_destSize() :
143LZ4_compress_destSize() : 196 * Reverse the logic : compresses as much data as possible from 'src' buffer
144 Reverse the logic, by compressing as much data as possible from 'source' buffer 197 * into already allocated buffer 'dst', of size >= 'targetDestSize'.
145 into already allocated buffer 'dest' of size 'targetDestSize'. 198 * This function either compresses the entire 'src' content into 'dst' if it's large enough,
146 This function either compresses the entire 'source' content into 'dest' if it's large enough, 199 * or fill 'dst' buffer completely with as much data as possible from 'src'.
147 or fill 'dest' buffer completely with as much data as possible from 'source'. 200 * note: acceleration parameter is fixed to "default".
148 *sourceSizePtr : will be modified to indicate how many bytes where read from 'source' to fill 'dest'. 201 *
149 New value is necessarily <= old value. 202 * *srcSizePtr : will be modified to indicate how many bytes where read from 'src' to fill 'dst'.
150 return : Nb bytes written into 'dest' (necessarily <= targetDestSize) 203 * New value is necessarily <= input value.
151 or 0 if compression fails 204 * @return : Nb bytes written into 'dst' (necessarily <= targetDestSize)
205 * or 0 if compression fails.
152*/ 206*/
153int LZ4_compress_destSize (const char* source, char* dest, int* sourceSizePtr, int targetDestSize); 207LZ4LIB_API int LZ4_compress_destSize (const char* src, char* dst, int* srcSizePtr, int targetDstSize);
154
155 208
156/*
157LZ4_decompress_fast() :
158 originalSize : is the original and therefore uncompressed size
159 return : the number of bytes read from the source buffer (in other words, the compressed size)
160 If the source stream is detected malformed, the function will stop decoding and return a negative result.
161 Destination buffer must be already allocated. Its size must be a minimum of 'originalSize' bytes.
162 note : This function fully respect memory boundaries for properly formed compressed data.
163 It is a bit faster than LZ4_decompress_safe().
164 However, it does not provide any protection against intentionally modified data stream (malicious input).
165 Use this function in trusted environment only (data to decode comes from a trusted source).
166*/
167int LZ4_decompress_fast (const char* source, char* dest, int originalSize);
168 209
169/* 210/*! LZ4_decompress_safe_partial() :
170LZ4_decompress_safe_partial() : 211 * Decompress an LZ4 compressed block, of size 'srcSize' at position 'src',
171 This function decompress a compressed block of size 'compressedSize' at position 'source' 212 * into destination buffer 'dst' of size 'dstCapacity'.
172 into destination buffer 'dest' of size 'maxDecompressedSize'. 213 * Up to 'targetOutputSize' bytes will be decoded.
173 The function tries to stop decompressing operation as soon as 'targetOutputSize' has been reached, 214 * The function stops decoding on reaching this objective,
174 reducing decompression time. 215 * which can boost performance when only the beginning of a block is required.
175 return : the number of bytes decoded in the destination buffer (necessarily <= maxDecompressedSize) 216 *
176 Note : this number can be < 'targetOutputSize' should the compressed block to decode be smaller. 217 * @return : the number of bytes decoded in `dst` (necessarily <= dstCapacity)
177 Always control how many bytes were decoded. 218 * If source stream is detected malformed, function returns a negative result.
178 If the source stream is detected malformed, the function will stop decoding and return a negative result. 219 *
179 This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets 220 * Note : @return can be < targetOutputSize, if compressed block contains less data.
180*/ 221 *
181int LZ4_decompress_safe_partial (const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize); 222 * Note 2 : this function features 2 parameters, targetOutputSize and dstCapacity,
223 * and expects targetOutputSize <= dstCapacity.
224 * It effectively stops decoding on reaching targetOutputSize,
225 * so dstCapacity is kind of redundant.
226 * This is because in a previous version of this function,
227 * decoding operation would not "break" a sequence in the middle.
228 * As a consequence, there was no guarantee that decoding would stop at exactly targetOutputSize,
229 * it could write more bytes, though only up to dstCapacity.
230 * Some "margin" used to be required for this operation to work properly.
231 * This is no longer necessary.
232 * The function nonetheless keeps its signature, in an effort to not break API.
233 */
234LZ4LIB_API int LZ4_decompress_safe_partial (const char* src, char* dst, int srcSize, int targetOutputSize, int dstCapacity);
182 235
183 236
184/*********************************************** 237/*-*********************************************
185* Streaming Compression Functions 238* Streaming Compression Functions
186***********************************************/ 239***********************************************/
187#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4) 240typedef union LZ4_stream_u LZ4_stream_t; /* incomplete type (defined later) */
188#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(long long))
189/*
190 * LZ4_stream_t
191 * information structure to track an LZ4 stream.
192 * important : init this structure content before first use !
193 * note : only allocated directly the structure if you are statically linking LZ4
194 * If you are using liblz4 as a DLL, please use below construction methods instead.
195 */
196typedef struct { long long table[LZ4_STREAMSIZE_U64]; } LZ4_stream_t;
197 241
198/* 242LZ4LIB_API LZ4_stream_t* LZ4_createStream(void);
199 * LZ4_resetStream 243LZ4LIB_API int LZ4_freeStream (LZ4_stream_t* streamPtr);
200 * Use this function to init an allocated LZ4_stream_t structure
201 */
202void LZ4_resetStream (LZ4_stream_t* streamPtr);
203 244
204/* 245/*! LZ4_resetStream_fast() : v1.9.0+
205 * LZ4_createStream will allocate and initialize an LZ4_stream_t structure 246 * Use this to prepare an LZ4_stream_t for a new chain of dependent blocks
206 * LZ4_freeStream releases its memory. 247 * (e.g., LZ4_compress_fast_continue()).
207 * In the context of a DLL (liblz4), please use these methods rather than the static struct. 248 *
208 * They are more future proof, in case of a change of LZ4_stream_t size. 249 * An LZ4_stream_t must be initialized once before usage.
250 * This is automatically done when created by LZ4_createStream().
251 * However, should the LZ4_stream_t be simply declared on stack (for example),
252 * it's necessary to initialize it first, using LZ4_initStream().
253 *
254 * After init, start any new stream with LZ4_resetStream_fast().
255 * A same LZ4_stream_t can be re-used multiple times consecutively
256 * and compress multiple streams,
257 * provided that it starts each new stream with LZ4_resetStream_fast().
258 *
259 * LZ4_resetStream_fast() is much faster than LZ4_initStream(),
260 * but is not compatible with memory regions containing garbage data.
261 *
262 * Note: it's only useful to call LZ4_resetStream_fast()
263 * in the context of streaming compression.
264 * The *extState* functions perform their own resets.
265 * Invoking LZ4_resetStream_fast() before is redundant, and even counterproductive.
209 */ 266 */
210LZ4_stream_t* LZ4_createStream(void); 267LZ4LIB_API void LZ4_resetStream_fast (LZ4_stream_t* streamPtr);
211int LZ4_freeStream (LZ4_stream_t* streamPtr); 268
212 269/*! LZ4_loadDict() :
213/* 270 * Use this function to reference a static dictionary into LZ4_stream_t.
214 * LZ4_loadDict 271 * The dictionary must remain available during compression.
215 * Use this function to load a static dictionary into LZ4_stream. 272 * LZ4_loadDict() triggers a reset, so any previous data will be forgotten.
216 * Any previous data will be forgotten, only 'dictionary' will remain in memory. 273 * The same dictionary will have to be loaded on decompression side for successful decoding.
217 * Loading a size of 0 is allowed. 274 * Dictionary are useful for better compression of small data (KB range).
218 * Return : dictionary size, in bytes (necessarily <= 64 KB) 275 * While LZ4 accept any input as dictionary,
276 * results are generally better when using Zstandard's Dictionary Builder.
277 * Loading a size of 0 is allowed, and is the same as reset.
278 * @return : loaded dictionary size, in bytes (necessarily <= 64 KB)
219 */ 279 */
220int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize); 280LZ4LIB_API int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize);
221 281
222/* 282/*! LZ4_compress_fast_continue() :
223