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