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 */