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