File Coverage

lz4.c
Criterion Covered Total %
statement 238 571 41.6
branch 196 2548 7.6
condition n/a
subroutine n/a
pod n/a
total 434 3119 13.9


line stmt bran cond sub pod time code
1             /*
2             LZ4 - Fast LZ compression algorithm
3             Copyright (C) 2011-2017, 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             /*-************************************
37             * Tuning parameters
38             **************************************/
39             /*
40             * LZ4_HEAPMODE :
41             * Select how default compression functions will allocate memory for their hash table,
42             * in memory stack (0:default, fastest), or in memory heap (1:requires malloc()).
43             */
44             #ifndef LZ4_HEAPMODE
45             # define LZ4_HEAPMODE 0
46             #endif
47              
48             /*
49             * ACCELERATION_DEFAULT :
50             * Select "acceleration" for LZ4_compress_fast() when parameter value <= 0
51             */
52             #define ACCELERATION_DEFAULT 1
53              
54              
55             /*-************************************
56             * CPU Feature Detection
57             **************************************/
58             /* LZ4_FORCE_MEMORY_ACCESS
59             * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.
60             * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.
61             * The below switch allow to select different access method for improved performance.
62             * Method 0 (default) : use `memcpy()`. Safe and portable.
63             * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable).
64             * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.
65             * Method 2 : direct access. This method is portable but violate C standard.
66             * It can generate buggy code on targets which assembly generation depends on alignment.
67             * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6)
68             * See https://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details.
69             * Prefer these methods in priority order (0 > 1 > 2)
70             */
71             #ifndef LZ4_FORCE_MEMORY_ACCESS /* can be defined externally */
72             # if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )
73             # define LZ4_FORCE_MEMORY_ACCESS 2
74             # elif defined(__INTEL_COMPILER) || defined(__GNUC__)
75             # define LZ4_FORCE_MEMORY_ACCESS 1
76             # endif
77             #endif
78              
79             /*
80             * LZ4_FORCE_SW_BITCOUNT
81             * Define this parameter if your target system or compiler does not support hardware bit count
82             */
83             #if defined(_MSC_VER) && defined(_WIN32_WCE) /* Visual Studio for Windows CE does not support Hardware bit count */
84             # define LZ4_FORCE_SW_BITCOUNT
85             #endif
86              
87              
88             /*-************************************
89             * Dependency
90             **************************************/
91             #include "lz4.h"
92             /* see also "memory routines" below */
93              
94              
95             /*-************************************
96             * Compiler Options
97             **************************************/
98             #ifdef _MSC_VER /* Visual Studio */
99             # include
100             # pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
101             # pragma warning(disable : 4293) /* disable: C4293: too large shift (32-bits) */
102             #endif /* _MSC_VER */
103              
104             #ifndef LZ4_FORCE_INLINE
105             # ifdef _MSC_VER /* Visual Studio */
106             # define LZ4_FORCE_INLINE static __forceinline
107             # else
108             # if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
109             # ifdef __GNUC__
110             # define LZ4_FORCE_INLINE static inline __attribute__((always_inline))
111             # else
112             # define LZ4_FORCE_INLINE static inline
113             # endif
114             # else
115             # define LZ4_FORCE_INLINE static
116             # endif /* __STDC_VERSION__ */
117             # endif /* _MSC_VER */
118             #endif /* LZ4_FORCE_INLINE */
119              
120             #if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__)
121             # define expect(expr,value) (__builtin_expect ((expr),(value)) )
122             #else
123             # define expect(expr,value) (expr)
124             #endif
125              
126             #define likely(expr) expect((expr) != 0, 1)
127             #define unlikely(expr) expect((expr) != 0, 0)
128              
129              
130             /*-************************************
131             * Memory routines
132             **************************************/
133             #include /* malloc, calloc, free */
134             #define ALLOCATOR(n,s) calloc(n,s)
135             #define FREEMEM free
136             #include /* memset, memcpy */
137             #define MEM_INIT memset
138              
139              
140             /*-************************************
141             * Basic Types
142             **************************************/
143             #if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
144             # include
145             typedef uint8_t BYTE;
146             typedef uint16_t U16;
147             typedef uint32_t U32;
148             typedef int32_t S32;
149             typedef uint64_t U64;
150             typedef uintptr_t uptrval;
151             #else
152             typedef unsigned char BYTE;
153             typedef unsigned short U16;
154             typedef unsigned int U32;
155             typedef signed int S32;
156             typedef unsigned long long U64;
157             typedef size_t uptrval; /* generally true, except OpenVMS-64 */
158             #endif
159              
160             #if defined(__x86_64__)
161             typedef U64 reg_t; /* 64-bits in x32 mode */
162             #else
163             typedef size_t reg_t; /* 32-bits in x32 mode */
164             #endif
165              
166             /*-************************************
167             * Reading and writing into memory
168             **************************************/
169 942987           static unsigned LZ4_isLittleEndian(void)
170             {
171 942987           const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */
172 942987           return one.c[0];
173             }
174              
175              
176             #if defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS==2)
177             /* lie to the compiler about data alignment; use with caution */
178              
179             static U16 LZ4_read16(const void* memPtr) { return *(const U16*) memPtr; }
180             static U32 LZ4_read32(const void* memPtr) { return *(const U32*) memPtr; }
181             static reg_t LZ4_read_ARCH(const void* memPtr) { return *(const reg_t*) memPtr; }
182              
183             static void LZ4_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; }
184             static void LZ4_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; }
185              
186             #elif defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS==1)
187              
188             /* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
189             /* currently only defined for gcc and icc */
190             typedef union { U16 u16; U32 u32; reg_t uArch; } __attribute__((packed)) unalign;
191              
192 307352           static U16 LZ4_read16(const void* ptr) { return ((const unalign*)ptr)->u16; }
193 2157588           static U32 LZ4_read32(const void* ptr) { return ((const unalign*)ptr)->u32; }
194 1578622           static reg_t LZ4_read_ARCH(const void* ptr) { return ((const unalign*)ptr)->uArch; }
195              
196 49980           static void LZ4_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u16 = value; }
197 153676           static void LZ4_write32(void* memPtr, U32 value) { ((unalign*)memPtr)->u32 = value; }
198              
199             #else /* safe and portable access through memcpy() */
200              
201             static U16 LZ4_read16(const void* memPtr)
202             {
203             U16 val; memcpy(&val, memPtr, sizeof(val)); return val;
204             }
205              
206             static U32 LZ4_read32(const void* memPtr)
207             {
208             U32 val; memcpy(&val, memPtr, sizeof(val)); return val;
209             }
210              
211             static reg_t LZ4_read_ARCH(const void* memPtr)
212             {
213             reg_t val; memcpy(&val, memPtr, sizeof(val)); return val;
214             }
215              
216             static void LZ4_write16(void* memPtr, U16 value)
217             {
218             memcpy(memPtr, &value, sizeof(value));
219             }
220              
221             static void LZ4_write32(void* memPtr, U32 value)
222             {
223             memcpy(memPtr, &value, sizeof(value));
224             }
225              
226             #endif /* LZ4_FORCE_MEMORY_ACCESS */
227              
228              
229 153676           static U16 LZ4_readLE16(const void* memPtr)
230             {
231 153676 50         if (LZ4_isLittleEndian()) {
232 153676           return LZ4_read16(memPtr);
233             } else {
234 0           const BYTE* p = (const BYTE*)memPtr;
235 0           return (U16)((U16)p[0] + (p[1]<<8));
236             }
237             }
238              
239 49980           static void LZ4_writeLE16(void* memPtr, U16 value)
240             {
241 49980 50         if (LZ4_isLittleEndian()) {
242 49980           LZ4_write16(memPtr, value);
243             } else {
244 0           BYTE* p = (BYTE*)memPtr;
245 0           p[0] = (BYTE) value;
246 0           p[1] = (BYTE)(value>>8);
247             }
248 49980           }
249              
250 716477           static void LZ4_copy8(void* dst, const void* src)
251             {
252 716477           memcpy(dst,src,8);
253 716477           }
254              
255             /* customized variant of memcpy, which can overwrite up to 8 bytes beyond dstEnd */
256 203666           static void LZ4_wildCopy(void* dstPtr, const void* srcPtr, void* dstEnd)
257             {
258 203666           BYTE* d = (BYTE*)dstPtr;
259 203666           const BYTE* s = (const BYTE*)srcPtr;
260 203666           BYTE* const e = (BYTE*)dstEnd;
261              
262 409485 100         do { LZ4_copy8(d,s); d+=8; s+=8; } while (d
263 203666           }
264              
265              
266             /*-************************************
267             * Common Constants
268             **************************************/
269             #define MINMATCH 4
270              
271             #define WILDCOPYLENGTH 8
272             #define LASTLITERALS 5
273             #define MFLIMIT (WILDCOPYLENGTH+MINMATCH)
274             static const int LZ4_minLength = (MFLIMIT+1);
275              
276             #define KB *(1 <<10)
277             #define MB *(1 <<20)
278             #define GB *(1U<<30)
279              
280             #define MAXD_LOG 16
281             #define MAX_DISTANCE ((1 << MAXD_LOG) - 1)
282              
283             #define ML_BITS 4
284             #define ML_MASK ((1U<
285             #define RUN_BITS (8-ML_BITS)
286             #define RUN_MASK ((1U<
287              
288              
289             /*-************************************
290             * Error detection
291             **************************************/
292             #define LZ4_STATIC_ASSERT(c) { enum { LZ4_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
293              
294             #if defined(LZ4_DEBUG) && (LZ4_DEBUG>=2)
295             # include
296             # define DEBUGLOG(l, ...) { \
297             if (l<=LZ4_DEBUG) { \
298             fprintf(stderr, __FILE__ ": "); \
299             fprintf(stderr, __VA_ARGS__); \
300             fprintf(stderr, " \n"); \
301             } }
302             #else
303             # define DEBUGLOG(l, ...) {} /* disabled */
304             #endif
305              
306              
307             /*-************************************
308             * Common functions
309             **************************************/
310 49980           static unsigned LZ4_NbCommonBytes (register reg_t val)
311             {
312 49980 50         if (LZ4_isLittleEndian()) {
313             if (sizeof(val)==8) {
314             # if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT)
315             unsigned long r = 0;
316             _BitScanForward64( &r, (U64)val );
317             return (int)(r>>3);
318             # elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT)
319 49980           return (__builtin_ctzll((U64)val) >> 3);
320             # else
321             static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2, 0, 3, 1, 3, 1, 4, 2, 7, 0, 2, 3, 6, 1, 5, 3, 5, 1, 3, 4, 4, 2, 5, 6, 7, 7, 0, 1, 2, 3, 3, 4, 6, 2, 6, 5, 5, 3, 4, 5, 6, 7, 1, 2, 4, 6, 4, 4, 5, 7, 2, 6, 5, 7, 6, 7, 7 };
322             return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];
323             # endif
324             } else /* 32 bits */ {
325             # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
326             unsigned long r;
327             _BitScanForward( &r, (U32)val );
328             return (int)(r>>3);
329             # elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT)
330             return (__builtin_ctz((U32)val) >> 3);
331             # else
332             static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0, 3, 2, 2, 1, 3, 2, 0, 1, 3, 3, 1, 2, 2, 2, 2, 0, 3, 1, 2, 0, 1, 0, 1, 1 };
333             return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
334             # endif
335             }
336             } else /* Big Endian CPU */ {
337             if (sizeof(val)==8) {
338             # if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT)
339             unsigned long r = 0;
340             _BitScanReverse64( &r, val );
341             return (unsigned)(r>>3);
342             # elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT)
343 0           return (__builtin_clzll((U64)val) >> 3);
344             # else
345             unsigned r;
346             if (!(val>>32)) { r=4; } else { r=0; val>>=32; }
347             if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
348             r += (!val);
349             return r;
350             # endif
351             } else /* 32 bits */ {
352             # if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
353             unsigned long r = 0;
354             _BitScanReverse( &r, (unsigned long)val );
355             return (unsigned)(r>>3);
356             # elif (defined(__clang__) || (defined(__GNUC__) && (__GNUC__>=3))) && !defined(LZ4_FORCE_SW_BITCOUNT)
357             return (__builtin_clz((U32)val) >> 3);
358             # else
359             unsigned r;
360             if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
361             r += (!val);
362             return r;
363             # endif
364             }
365             }
366             }
367              
368             #define STEPSIZE sizeof(reg_t)
369 49980           static unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLimit)
370             {
371 49980           const BYTE* const pStart = pIn;
372              
373 49980 50         while (likely(pIn
374 49980           reg_t const diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn);
375 49980 50         if (!diff) { pIn+=STEPSIZE; pMatch+=STEPSIZE; continue; }
376 49980           pIn += LZ4_NbCommonBytes(diff);
377 49980           return (unsigned)(pIn - pStart);
378             }
379              
380 0 0         if ((STEPSIZE==8) && (pIn<(pInLimit-3)) && (LZ4_read32(pMatch) == LZ4_read32(pIn))) { pIn+=4; pMatch+=4; }
    0          
381 0 0         if ((pIn<(pInLimit-1)) && (LZ4_read16(pMatch) == LZ4_read16(pIn))) { pIn+=2; pMatch+=2; }
    0          
382 0 0         if ((pIn
    0          
383 0           return (unsigned)(pIn - pStart);
384             }
385              
386              
387             #ifndef LZ4_COMMONDEFS_ONLY
388             /*-************************************
389             * Local Constants
390             **************************************/
391             static const int LZ4_64Klimit = ((64 KB) + (MFLIMIT-1));
392             static const U32 LZ4_skipTrigger = 6; /* Increase this value ==> compression run slower on incompressible data */
393              
394              
395             /*-************************************
396             * Local Structures and types
397             **************************************/
398             typedef enum { notLimited = 0, limitedOutput = 1 } limitedOutput_directive;
399             typedef enum { byPtr, byU32, byU16 } tableType_t;
400              
401             typedef enum { noDict = 0, withPrefix64k, usingExtDict } dict_directive;
402             typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive;
403              
404             typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive;
405             typedef enum { full = 0, partial = 1 } earlyEnd_directive;
406              
407              
408             /*-************************************
409             * Local Utils
410             **************************************/
411 0           int LZ4_versionNumber (void) { return LZ4_VERSION_NUMBER; }
412 0           const char* LZ4_versionString(void) { return LZ4_VERSION_STRING; }
413 0 0         int LZ4_compressBound(int isize) { return LZ4_COMPRESSBOUND(isize); }
414 0           int LZ4_sizeofState() { return LZ4_STREAMSIZE; }
415              
416              
417             /*-******************************
418             * Compression functions
419             ********************************/
420 0           static U32 LZ4_hash4(U32 sequence, tableType_t const tableType)
421             {
422 0 0         if (tableType == byU16)
423 0           return ((sequence * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1)));
424             else
425 0           return ((sequence * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG));
426             }
427              
428 689351           static U32 LZ4_hash5(U64 sequence, tableType_t const tableType)
429             {
430             static const U64 prime5bytes = 889523592379ULL;
431             static const U64 prime8bytes = 11400714785074694791ULL;
432 689351 50         const U32 hashLog = (tableType == byU16) ? LZ4_HASHLOG+1 : LZ4_HASHLOG;
433 689351 50         if (LZ4_isLittleEndian())
434 689351           return (U32)(((sequence << 24) * prime5bytes) >> (64 - hashLog));
435             else
436 0           return (U32)(((sequence >> 24) * prime8bytes) >> (64 - hashLog));
437             }
438              
439             LZ4_FORCE_INLINE U32 LZ4_hashPosition(const void* const p, tableType_t const tableType)
440             {
441 689351 0         if ((sizeof(reg_t)==8) && (tableType != byU16)) return LZ4_hash5(LZ4_read_ARCH(p), tableType);
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
442 0           return LZ4_hash4(LZ4_read32(p), tableType);
443             }
444              
445 589399           static void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableType_t const tableType, const BYTE* srcBase)
446             {
447 589399           switch (tableType)
448             {
449 0           case byPtr: { const BYTE** hashTable = (const BYTE**)tableBase; hashTable[h] = p; return; }
450 589399           case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = (U32)(p-srcBase); return; }
451 0           case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = (U16)(p-srcBase); return; }
452             }
453             }
454              
455             LZ4_FORCE_INLINE void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase)
456             {
457 99965           U32 const h = LZ4_hashPosition(p, tableType);
458 99965           LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase);
459             }
460              
461 539410           static const BYTE* LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase)
462             {
463 539410 50         if (tableType == byPtr) { const BYTE** hashTable = (const BYTE**) tableBase; return hashTable[h]; }
464 539410 50         if (tableType == byU32) { const U32* const hashTable = (U32*) tableBase; return hashTable[h] + srcBase; }
465 0           { const U16* const hashTable = (U16*) tableBase; return hashTable[h] + srcBase; } /* default, to ensure a return */
466             }
467              
468             LZ4_FORCE_INLINE const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase)
469             {
470 49976           U32 const h = LZ4_hashPosition(p, tableType);
471 49976           return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase);
472             }
473              
474              
475             /** LZ4_compress_generic() :
476             inlined, to ensure branches are decided at compilation time */
477             LZ4_FORCE_INLINE int LZ4_compress_generic(
478             LZ4_stream_t_internal* const cctx,
479             const char* const source,
480             char* const dest,
481             const int inputSize,
482             const int maxOutputSize,
483             const limitedOutput_directive outputLimited,
484             const tableType_t tableType,
485             const dict_directive dict,
486             const dictIssue_directive dictIssue,
487             const U32 acceleration)
488             {
489 13           const BYTE* ip = (const BYTE*) source;
490             const BYTE* base;
491             const BYTE* lowLimit;
492 13           const BYTE* const lowRefLimit = ip - cctx->dictSize;
493 13           const BYTE* const dictionary = cctx->dictionary;
494 13           const BYTE* const dictEnd = dictionary + cctx->dictSize;
495 13           const ptrdiff_t dictDelta = dictEnd - (const BYTE*)source;
496 13           const BYTE* anchor = (const BYTE*) source;
497 13           const BYTE* const iend = ip + inputSize;
498 13           const BYTE* const mflimit = iend - MFLIMIT;
499 13           const BYTE* const matchlimit = iend - LASTLITERALS;
500              
501 13           BYTE* op = (BYTE*) dest;
502 13           BYTE* const olimit = op + maxOutputSize;
503              
504             U32 forwardH;
505              
506             /* Init conditions */
507 13 0         if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported inputSize, too large (or negative) */
    0          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
508             switch(dict)
509             {
510             case noDict:
511             default:
512 0           base = (const BYTE*)source;
513 0           lowLimit = (const BYTE*)source;
514             break;
515             case withPrefix64k:
516 12           base = (const BYTE*)source - cctx->currentOffset;
517 12           lowLimit = (const BYTE*)source - cctx->dictSize;
518             break;
519             case usingExtDict:
520 1           base = (const BYTE*)source - cctx->currentOffset;
521 1           lowLimit = (const BYTE*)source;
522             break;
523             }
524 0 0         if ((tableType == byU16) && (inputSize>=LZ4_64Klimit)) return 0; /* Size too large (not within 64K limit) */
    0          
    0          
525 13 0         if (inputSize
    0          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
526              
527             /* First Byte */
528 13           LZ4_putPosition(ip, cctx->hashTable, tableType, base);
529 13           ip++; forwardH = LZ4_hashPosition(ip, tableType);
530              
531             /* Main Loop */
532             for ( ; ; ) {
533 49976           ptrdiff_t refDelta = 0;
534             const BYTE* match;
535             BYTE* token;
536              
537             /* Find a match */
538 49976           { const BYTE* forwardIp = ip;
539 49976           unsigned step = 1;
540 49976           unsigned searchMatchNb = acceleration << LZ4_skipTrigger;
541             do {
542 489443           U32 const h = forwardH;
543 489443           ip = forwardIp;
544 489443           forwardIp += step;
545 489443           step = (searchMatchNb++ >> LZ4_skipTrigger);
546              
547 489443 0         if (unlikely(forwardIp > mflimit)) goto _last_literals;
    0          
    100          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
548              
549 489434           match = LZ4_getPositionOnHash(h, cctx->hashTable, tableType, base);
550             if (dict==usingExtDict) {
551 37399           if (match < (const BYTE*)source) {
552 0           refDelta = dictDelta;
553 0           lowLimit = dictionary;
554             } else {
555 37399           refDelta = 0;
556 37399           lowLimit = (const BYTE*)source;
557             } }
558 489434           forwardH = LZ4_hashPosition(forwardIp, tableType);
559 489434           LZ4_putPositionOnHash(ip, h, cctx->hashTable, tableType, base);
560              
561             } while ( ((dictIssue==dictSmall) ? (match < lowRefLimit) : 0)
562 489434           || ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip))
563 489421 0         || (LZ4_read32(match+refDelta) != LZ4_read32(ip)) );
    0          
    100          
    0          
    100          
    0          
    0          
    0          
    0          
    0          
    0          
564             }
565              
566             /* Catch up */
567 50041 0         while (((ip>anchor) & (match+refDelta > lowLimit)) && (unlikely(ip[-1]==match[refDelta-1]))) { ip--; match--; }
    0          
    0          
    0          
    50          
    100          
    0          
    0          
    100          
    100          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
568              
569             /* Encode Literals */
570 49967           { unsigned const litLength = (unsigned)(ip - anchor);
571 49967           token = op++;
572 49967 0         if ((outputLimited) && /* Check output buffer overflow */
    50          
    0          
    50          
    0          
    0          
    0          
    0          
573 49967           (unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit)))
574 0           return 0;
575 49967 0         if (litLength >= RUN_MASK) {
    0          
    100          
    0          
    100          
    0          
    0          
    0          
    0          
    0          
    0          
576 99           int len = (int)litLength-RUN_MASK;
577 99           *token = (RUN_MASK<
578 99 0         for(; len >= 255 ; len-=255) *op++ = 255;
    0          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
579 99           *op++ = (BYTE)len;
580             }
581 49868           else *token = (BYTE)(litLength<
582              
583             /* Copy Literals */
584 49967           LZ4_wildCopy(op, anchor, op+litLength);
585 49967           op+=litLength;
586             }
587              
588             _next_match:
589             /* Encode Offset */
590 49980           LZ4_writeLE16(op, (U16)(ip-match)); op+=2;
591              
592             /* Encode MatchLength */
593             { unsigned matchCode;
594              
595 4093           if ((dict==usingExtDict) && (lowLimit==dictionary)) {
596             const BYTE* limit;
597 0           match += refDelta;
598 0           limit = ip + (dictEnd-match);
599 0 0         if (limit > matchlimit) limit = matchlimit;
    0          
    0          
600 0           matchCode = LZ4_count(ip+MINMATCH, match+MINMATCH, limit);
601 0           ip += MINMATCH + matchCode;
602 0           if (ip==limit) {
603 0           unsigned const more = LZ4_count(ip, (const BYTE*)source, matchlimit);
604 0           matchCode += more;
605 0           ip += more;
606             }
607             } else {
608 49980           matchCode = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit);
609 4093           ip += MINMATCH + matchCode;
610             }
611              
612 49980 0         if ( outputLimited && /* Check output buffer overflow */
613 49980           (unlikely(op + (1 + LASTLITERALS) + (matchCode>>8) > olimit)) )
614 0           return 0;
615 49980 0         if (matchCode >= ML_MASK) {
    0          
    50          
    0          
    50          
    0          
    0          
    0          
616 0           *token += ML_MASK;
617 0           matchCode -= ML_MASK;
618 0           LZ4_write32(op, 0xFFFFFFFF);
619 0 0         while (matchCode >= 4*255) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
620 0           op+=4;
621 0           LZ4_write32(op, 0xFFFFFFFF);
622 0           matchCode -= 4*255;
623             }
624 0           op += matchCode / 255;
625 0           *op++ = (BYTE)(matchCode % 255);
626             } else
627 49980           *token += (BYTE)(matchCode);
628             }
629              
630 49980           anchor = ip;
631              
632             /* Test end of chunk */
633 49980 0         if (ip > mflimit) break;
    0          
    100          
    0          
    100          
    0          
    0          
    0          
    0          
    0          
    0          
634              
635             /* Fill table */
636 49976           LZ4_putPosition(ip-2, cctx->hashTable, tableType, base);
637              
638             /* Test next position */
639 99952           match = LZ4_getPosition(ip, cctx->hashTable, tableType, base);
640             if (dict==usingExtDict) {
641 4092           if (match < (const BYTE*)source) {
642 0           refDelta = dictDelta;
643 0           lowLimit = dictionary;
644             } else {
645 4092           refDelta = 0;
646 4092           lowLimit = (const BYTE*)source;
647             } }
648 49976           LZ4_putPosition(ip, cctx->hashTable, tableType, base);
649             if ( ((dictIssue==dictSmall) ? (match>=lowRefLimit) : 1)
650 49976           && (match+MAX_DISTANCE>=ip)
651 49976 0         && (LZ4_read32(match+refDelta)==LZ4_read32(ip)) )
    0          
    100          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
652 13           { token=op++; *token=0; goto _next_match; }
653              
654             /* Prepare next loop */
655 49963           forwardH = LZ4_hashPosition(++ip, tableType);
656             }
657              
658             _last_literals:
659             /* Encode Last Literals */
660 13           { size_t const lastRun = (size_t)(iend - anchor);
661 13 0         if ( (outputLimited) && /* Check output buffer overflow */
    50          
    0          
    50          
    0          
    0          
    0          
    0          
662 13           ((op - (BYTE*)dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize) )
663 0           return 0;
664 13 0         if (lastRun >= RUN_MASK) {
    0          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
665 0           size_t accumulator = lastRun - RUN_MASK;
666 0           *op++ = RUN_MASK << ML_BITS;
667 0 0         for(; accumulator >= 255 ; accumulator-=255) *op++ = 255;
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
668 0           *op++ = (BYTE) accumulator;
669             } else {
670 13           *op++ = (BYTE)(lastRun<
671             }
672 13           memcpy(op, anchor, lastRun);
673 13           op += lastRun;
674             }
675              
676             /* End */
677 13           return (int) (((char*)op)-dest);
678             }
679              
680              
681 0           int LZ4_compress_fast_extState(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
682             {
683 0           LZ4_stream_t_internal* ctx = &((LZ4_stream_t*)state)->internal_donotuse;
684 0           LZ4_resetStream((LZ4_stream_t*)state);
685 0 0         if (acceleration < 1) acceleration = ACCELERATION_DEFAULT;
686              
687 0 0         if (maxOutputSize >= LZ4_compressBound(inputSize)) {
688 0 0         if (inputSize < LZ4_64Klimit)
689 0           return LZ4_compress_generic(ctx, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue, acceleration);
690             else
691 0           return LZ4_compress_generic(ctx, source, dest, inputSize, 0, notLimited, (sizeof(void*)==8) ? byU32 : byPtr, noDict, noDictIssue, acceleration);
692             } else {
693 0 0         if (inputSize < LZ4_64Klimit)
694 0           return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration);
695             else
696 0           return LZ4_compress_generic(ctx, source, dest, inputSize, maxOutputSize, limitedOutput, (sizeof(void*)==8) ? byU32 : byPtr, noDict, noDictIssue, acceleration);
697             }
698             }
699              
700              
701 0           int LZ4_compress_fast(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
702             {
703             #if (LZ4_HEAPMODE)
704             void* ctxPtr = ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */
705             #else
706             LZ4_stream_t ctx;
707 0           void* const ctxPtr = &ctx;
708             #endif
709              
710 0           int const result = LZ4_compress_fast_extState(ctxPtr, source, dest, inputSize, maxOutputSize, acceleration);
711              
712             #if (LZ4_HEAPMODE)
713             FREEMEM(ctxPtr);
714             #endif
715 0           return result;
716             }
717              
718              
719 0           int LZ4_compress_default(const char* source, char* dest, int inputSize, int maxOutputSize)
720             {
721 0           return LZ4_compress_fast(source, dest, inputSize, maxOutputSize, 1);
722             }
723              
724              
725             /* hidden debug function */
726             /* strangely enough, gcc generates faster code when this function is uncommented, even if unused */
727 0           int LZ4_compress_fast_force(const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
728             {
729             LZ4_stream_t ctx;
730 0           LZ4_resetStream(&ctx);
731              
732 0 0         if (inputSize < LZ4_64Klimit)
733 0           return LZ4_compress_generic(&ctx.internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue, acceleration);
734             else
735 0           return LZ4_compress_generic(&ctx.internal_donotuse, source, dest, inputSize, maxOutputSize, limitedOutput, sizeof(void*)==8 ? byU32 : byPtr, noDict, noDictIssue, acceleration);
736             }
737              
738              
739             /*-******************************
740             * *_destSize() variant
741             ********************************/
742              
743 0           static int LZ4_compress_destSize_generic(
744             LZ4_stream_t_internal* const ctx,
745             const char* const src,
746             char* const dst,
747             int* const srcSizePtr,
748             const int targetDstSize,
749             const tableType_t tableType)
750             {
751 0           const BYTE* ip = (const BYTE*) src;
752 0           const BYTE* base = (const BYTE*) src;
753 0           const BYTE* lowLimit = (const BYTE*) src;
754 0           const BYTE* anchor = ip;
755 0           const BYTE* const iend = ip + *srcSizePtr;
756 0           const BYTE* const mflimit = iend - MFLIMIT;
757 0           const BYTE* const matchlimit = iend - LASTLITERALS;
758              
759 0           BYTE* op = (BYTE*) dst;
760 0           BYTE* const oend = op + targetDstSize;
761 0           BYTE* const oMaxLit = op + targetDstSize - 2 /* offset */ - 8 /* because 8+MINMATCH==MFLIMIT */ - 1 /* token */;
762 0           BYTE* const oMaxMatch = op + targetDstSize - (LASTLITERALS + 1 /* token */);
763 0           BYTE* const oMaxSeq = oMaxLit - 1 /* token */;
764              
765             U32 forwardH;
766              
767              
768             /* Init conditions */
769 0 0         if (targetDstSize < 1) return 0; /* Impossible to store anything */
770 0 0         if ((U32)*srcSizePtr > (U32)LZ4_MAX_INPUT_SIZE) return 0; /* Unsupported input size, too large (or negative) */
771 0 0         if ((tableType == byU16) && (*srcSizePtr>=LZ4_64Klimit)) return 0; /* Size too large (not within 64K limit) */
    0          
772 0 0         if (*srcSizePtr
773              
774             /* First Byte */
775 0           *srcSizePtr = 0;
776 0           LZ4_putPosition(ip, ctx->hashTable, tableType, base);
777 0           ip++; forwardH = LZ4_hashPosition(ip, tableType);
778              
779             /* Main Loop */
780             for ( ; ; ) {
781             const BYTE* match;
782             BYTE* token;
783              
784             /* Find a match */
785 0           { const BYTE* forwardIp = ip;
786 0           unsigned step = 1;
787 0           unsigned searchMatchNb = 1 << LZ4_skipTrigger;
788              
789             do {
790 0           U32 h = forwardH;
791 0           ip = forwardIp;
792 0           forwardIp += step;
793 0           step = (searchMatchNb++ >> LZ4_skipTrigger);
794              
795 0 0         if (unlikely(forwardIp > mflimit)) goto _last_literals;
796              
797 0           match = LZ4_getPositionOnHash(h, ctx->hashTable, tableType, base);
798 0           forwardH = LZ4_hashPosition(forwardIp, tableType);
799 0           LZ4_putPositionOnHash(ip, h, ctx->hashTable, tableType, base);
800              
801 0           } while ( ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip))
802 0 0         || (LZ4_read32(match) != LZ4_read32(ip)) );
    0          
    0          
803             }
804              
805             /* Catch up */
806 0 0         while ((ip>anchor) && (match > lowLimit) && (unlikely(ip[-1]==match[-1]))) { ip--; match--; }
    0          
    0          
807              
808             /* Encode Literal length */
809 0           { unsigned litLength = (unsigned)(ip - anchor);
810 0           token = op++;
811 0 0         if (op + ((litLength+240)/255) + litLength > oMaxLit) {
812             /* Not enough space for a last match */
813 0           op--;
814 0           goto _last_literals;
815             }
816 0 0         if (litLength>=RUN_MASK) {
817 0           unsigned len = litLength - RUN_MASK;
818 0           *token=(RUN_MASK<
819 0 0         for(; len >= 255 ; len-=255) *op++ = 255;
820 0           *op++ = (BYTE)len;
821             }
822 0           else *token = (BYTE)(litLength<
823              
824             /* Copy Literals */
825 0           LZ4_wildCopy(op, anchor, op+litLength);
826 0           op += litLength;
827             }
828              
829             _next_match:
830             /* Encode Offset */
831 0           LZ4_writeLE16(op, (U16)(ip-match)); op+=2;
832              
833             /* Encode MatchLength */
834 0           { size_t matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit);
835              
836 0 0         if (op + ((matchLength+240)/255) > oMaxMatch) {
837             /* Match description too long : reduce it */
838 0           matchLength = (15-1) + (oMaxMatch-op) * 255;
839             }
840 0           ip += MINMATCH + matchLength;
841              
842 0 0         if (matchLength>=ML_MASK) {
843 0           *token += ML_MASK;
844 0           matchLength -= ML_MASK;
845 0 0         while (matchLength >= 255) { matchLength-=255; *op++ = 255; }
846 0           *op++ = (BYTE)matchLength;
847             }
848 0           else *token += (BYTE)(matchLength);
849             }
850              
851 0           anchor = ip;
852              
853             /* Test end of block */
854 0 0         if (ip > mflimit) break;
855 0 0         if (op > oMaxSeq) break;
856              
857             /* Fill table */
858 0           LZ4_putPosition(ip-2, ctx->hashTable, tableType, base);
859              
860             /* Test next position */
861 0           match = LZ4_getPosition(ip, ctx->hashTable, tableType, base);
862 0           LZ4_putPosition(ip, ctx->hashTable, tableType, base);
863 0 0         if ( (match+MAX_DISTANCE>=ip)
864 0 0         && (LZ4_read32(match)==LZ4_read32(ip)) )
865 0           { token=op++; *token=0; goto _next_match; }
866              
867             /* Prepare next loop */
868 0           forwardH = LZ4_hashPosition(++ip, tableType);
869 0           }
870              
871             _last_literals:
872             /* Encode Last Literals */
873 0           { size_t lastRunSize = (size_t)(iend - anchor);
874 0 0         if (op + 1 /* token */ + ((lastRunSize+240)/255) /* litLength */ + lastRunSize /* literals */ > oend) {
875             /* adapt lastRunSize to fill 'dst' */
876 0           lastRunSize = (oend-op) - 1;
877 0           lastRunSize -= (lastRunSize+240)/255;
878             }
879 0           ip = anchor + lastRunSize;
880              
881 0 0         if (lastRunSize >= RUN_MASK) {
882 0           size_t accumulator = lastRunSize - RUN_MASK;
883 0           *op++ = RUN_MASK << ML_BITS;
884 0 0         for(; accumulator >= 255 ; accumulator-=255) *op++ = 255;
885 0           *op++ = (BYTE) accumulator;
886             } else {
887 0           *op++ = (BYTE)(lastRunSize<
888             }
889 0           memcpy(op, anchor, lastRunSize);
890 0           op += lastRunSize;
891             }
892              
893             /* End */
894 0           *srcSizePtr = (int) (((const char*)ip)-src);
895 0           return (int) (((char*)op)-dst);
896             }
897              
898              
899 0           static int LZ4_compress_destSize_extState (LZ4_stream_t* state, const char* src, char* dst, int* srcSizePtr, int targetDstSize)
900             {
901 0           LZ4_resetStream(state);
902              
903 0 0         if (targetDstSize >= LZ4_compressBound(*srcSizePtr)) { /* compression success is guaranteed */
904 0           return LZ4_compress_fast_extState(state, src, dst, *srcSizePtr, targetDstSize, 1);
905             } else {
906 0 0         if (*srcSizePtr < LZ4_64Klimit)
907 0           return LZ4_compress_destSize_generic(&state->internal_donotuse, src, dst, srcSizePtr, targetDstSize, byU16);
908             else
909 0           return LZ4_compress_destSize_generic(&state->internal_donotuse, src, dst, srcSizePtr, targetDstSize, sizeof(void*)==8 ? byU32 : byPtr);
910             }
911             }
912              
913              
914 0           int LZ4_compress_destSize(const char* src, char* dst, int* srcSizePtr, int targetDstSize)
915             {
916             #if (LZ4_HEAPMODE)
917             LZ4_stream_t* ctx = (LZ4_stream_t*)ALLOCATOR(1, sizeof(LZ4_stream_t)); /* malloc-calloc always properly aligned */
918             #else
919             LZ4_stream_t ctxBody;
920 0           LZ4_stream_t* ctx = &ctxBody;
921             #endif
922              
923 0           int result = LZ4_compress_destSize_extState(ctx, src, dst, srcSizePtr, targetDstSize);
924              
925             #if (LZ4_HEAPMODE)
926             FREEMEM(ctx);
927             #endif
928 0           return result;
929             }
930              
931              
932              
933             /*-******************************
934             * Streaming functions
935             ********************************/
936              
937 0           LZ4_stream_t* LZ4_createStream(void)
938             {
939 0           LZ4_stream_t* lz4s = (LZ4_stream_t*)ALLOCATOR(8, LZ4_STREAMSIZE_U64);
940             LZ4_STATIC_ASSERT(LZ4_STREAMSIZE >= sizeof(LZ4_stream_t_internal)); /* A compilation error here means LZ4_STREAMSIZE is not large enough */
941 0           LZ4_resetStream(lz4s);
942 0           return lz4s;
943             }
944              
945 1           void LZ4_resetStream (LZ4_stream_t* LZ4_stream)
946             {
947 1           MEM_INIT(LZ4_stream, 0, sizeof(LZ4_stream_t));
948 1           }
949              
950 0           int LZ4_freeStream (LZ4_stream_t* LZ4_stream)
951             {
952 0 0         if (!LZ4_stream) return 0; /* support free on NULL */
953 0           FREEMEM(LZ4_stream);
954 0           return (0);
955             }
956              
957              
958             #define HASH_UNIT sizeof(reg_t)
959 0           int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize)
960             {
961 0           LZ4_stream_t_internal* dict = &LZ4_dict->internal_donotuse;
962 0           const BYTE* p = (const BYTE*)dictionary;
963 0           const BYTE* const dictEnd = p + dictSize;
964             const BYTE* base;
965              
966 0 0         if ((dict->initCheck) || (dict->currentOffset > 1 GB)) /* Uninitialized structure, or reuse overflow */
    0          
967 0           LZ4_resetStream(LZ4_dict);
968              
969 0 0         if (dictSize < (int)HASH_UNIT) {
970 0           dict->dictionary = NULL;
971 0           dict->dictSize = 0;
972 0           return 0;
973             }
974              
975 0 0         if ((dictEnd - p) > 64 KB) p = dictEnd - 64 KB;
976 0           dict->currentOffset += 64 KB;
977 0           base = p - dict->currentOffset;
978 0           dict->dictionary = p;
979 0           dict->dictSize = (U32)(dictEnd - p);
980 0           dict->currentOffset += dict->dictSize;
981              
982 0 0         while (p <= dictEnd-HASH_UNIT) {
983 0           LZ4_putPosition(p, dict->hashTable, byU32, base);
984 0           p+=3;
985             }
986              
987 0           return dict->dictSize;
988             }
989              
990              
991 13           static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, const BYTE* src)
992             {
993 13 50         if ((LZ4_dict->currentOffset > 0x80000000) ||
    50          
994 13           ((uptrval)LZ4_dict->currentOffset > (uptrval)src)) { /* address space overflow */
995             /* rescale hash table */
996 0           U32 const delta = LZ4_dict->currentOffset - 64 KB;
997 0           const BYTE* dictEnd = LZ4_dict->dictionary + LZ4_dict->dictSize;
998             int i;
999 0 0         for (i=0; i
1000 0 0         if (LZ4_dict->hashTable[i] < delta) LZ4_dict->hashTable[i]=0;
1001 0           else LZ4_dict->hashTable[i] -= delta;
1002             }
1003 0           LZ4_dict->currentOffset = 64 KB;
1004 0 0         if (LZ4_dict->dictSize > 64 KB) LZ4_dict->dictSize = 64 KB;
1005 0           LZ4_dict->dictionary = dictEnd - LZ4_dict->dictSize;
1006             }
1007 13           }
1008              
1009              
1010 13           int LZ4_compress_fast_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize, int maxOutputSize, int acceleration)
1011             {
1012 13           LZ4_stream_t_internal* streamPtr = &LZ4_stream->internal_donotuse;
1013 13           const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize;
1014              
1015 13           const BYTE* smallest = (const BYTE*) source;
1016 13 50         if (streamPtr->initCheck) return 0; /* Uninitialized structure detected */
1017 13 100         if ((streamPtr->dictSize>0) && (smallest>dictEnd)) smallest = dictEnd;
    50          
1018 13           LZ4_renormDictT(streamPtr, smallest);
1019 13 50         if (acceleration < 1) acceleration = ACCELERATION_DEFAULT;
1020              
1021             /* Check overlapping input/dictionary space */
1022 13           { const BYTE* sourceEnd = (const BYTE*) source + inputSize;
1023 13 50         if ((sourceEnd > streamPtr->dictionary) && (sourceEnd < dictEnd)) {
    50          
1024 0           streamPtr->dictSize = (U32)(dictEnd - sourceEnd);
1025 0 0         if (streamPtr->dictSize > 64 KB) streamPtr->dictSize = 64 KB;
1026 0 0         if (streamPtr->dictSize < 4) streamPtr->dictSize = 0;
1027 0           streamPtr->dictionary = dictEnd - streamPtr->dictSize;
1028             }
1029             }
1030              
1031             /* prefix mode : source data follows dictionary */
1032 13 100         if (dictEnd == (const BYTE*)source) {
1033             int result;
1034 12 50         if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset))
    0          
1035 0           result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, dictSmall, acceleration);
1036             else
1037 12           result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, withPrefix64k, noDictIssue, acceleration);
1038 12           streamPtr->dictSize += (U32)inputSize;
1039 12           streamPtr->currentOffset += (U32)inputSize;
1040 12           return result;
1041             }
1042              
1043             /* external dictionary mode */
1044             { int result;
1045 1 50         if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset))
    50          
1046 0           result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, dictSmall, acceleration);
1047             else
1048 1           result = LZ4_compress_generic(streamPtr, source, dest, inputSize, maxOutputSize, limitedOutput, byU32, usingExtDict, noDictIssue, acceleration);
1049 1           streamPtr->dictionary = (const BYTE*)source;
1050 1           streamPtr->dictSize = (U32)inputSize;
1051 1           streamPtr->currentOffset += (U32)inputSize;
1052 1           return result;
1053             }
1054             }
1055              
1056              
1057             /* Hidden debug function, to force external dictionary mode */
1058 0           int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* dest, int inputSize)
1059             {
1060 0           LZ4_stream_t_internal* streamPtr = &LZ4_dict->internal_donotuse;
1061             int result;
1062 0           const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize;
1063              
1064 0           const BYTE* smallest = dictEnd;
1065 0 0         if (smallest > (const BYTE*) source) smallest = (const BYTE*) source;
1066 0           LZ4_renormDictT(streamPtr, smallest);
1067              
1068 0           result = LZ4_compress_generic(streamPtr, source, dest, inputSize, 0, notLimited, byU32, usingExtDict, noDictIssue, 1);
1069              
1070 0           streamPtr->dictionary = (const BYTE*)source;
1071 0           streamPtr->dictSize = (U32)inputSize;
1072 0           streamPtr->currentOffset += (U32)inputSize;
1073              
1074 0           return result;
1075             }
1076              
1077              
1078             /*! LZ4_saveDict() :
1079             * If previously compressed data block is not guaranteed to remain available at its memory location,
1080             * save it into a safer place (char* safeBuffer).
1081             * Note : you don't need to call LZ4_loadDict() afterwards,
1082             * dictionary is immediately usable, you can therefore call LZ4_compress_fast_continue().
1083             * Return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error.
1084             */
1085 0           int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize)
1086             {
1087 0           LZ4_stream_t_internal* const dict = &LZ4_dict->internal_donotuse;
1088 0           const BYTE* const previousDictEnd = dict->dictionary + dict->dictSize;
1089              
1090 0 0         if ((U32)dictSize > 64 KB) dictSize = 64 KB; /* useless to define a dictionary > 64 KB */
1091 0 0         if ((U32)dictSize > dict->dictSize) dictSize = dict->dictSize;
1092              
1093 0           memmove(safeBuffer, previousDictEnd - dictSize, dictSize);
1094              
1095 0           dict->dictionary = (const BYTE*)safeBuffer;
1096 0           dict->dictSize = (U32)dictSize;
1097              
1098 0           return dictSize;
1099             }
1100              
1101              
1102              
1103             /*-*****************************
1104             * Decompression functions
1105             *******************************/
1106             /*! LZ4_decompress_generic() :
1107             * This generic decompression function covers all use cases.
1108             * It shall be instantiated several times, using different sets of directives.
1109             * Note that it is important for performance that this function really get inlined,
1110             * in order to remove useless branches during compilation optimization.
1111             */
1112             LZ4_FORCE_INLINE int LZ4_decompress_generic(
1113             const char* const src,
1114             char* const dst,
1115             int srcSize,
1116             int outputSize, /* If endOnInput==endOnInputSize, this value is `dstCapacity` */
1117              
1118             int endOnInput, /* endOnOutputSize, endOnInputSize */
1119             int partialDecoding, /* full, partial */
1120             int targetOutputSize, /* only used if partialDecoding==partial */
1121             int dict, /* noDict, withPrefix64k, usingExtDict */
1122             const BYTE* const lowPrefix, /* == dst when no prefix */
1123             const BYTE* const dictStart, /* only if dict==usingExtDict */
1124             const size_t dictSize /* note : = 0 if noDict */
1125             )
1126             {
1127 42           const BYTE* ip = (const BYTE*) src;
1128 42           const BYTE* const iend = ip + srcSize;
1129              
1130 42           BYTE* op = (BYTE*) dst;
1131 42           BYTE* const oend = op + outputSize;
1132             BYTE* cpy;
1133 42           BYTE* oexit = op + targetOutputSize;
1134              
1135 42           const BYTE* const dictEnd = (const BYTE*)dictStart + dictSize;
1136 42           const unsigned dec32table[] = {0, 1, 2, 1, 4, 4, 4, 4};
1137 42           const int dec64table[] = {0, 0, 0, -1, 0, 1, 2, 3};
1138              
1139 42           const int safeDecode = (endOnInput==endOnInputSize);
1140 42 0         const int checkOffset = ((safeDecode) && (dictSize < (int)(64 KB)));
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1141              
1142              
1143             /* Special cases */
1144 42 0         if ((partialDecoding) && (oexit > oend-MFLIMIT)) oexit = oend-MFLIMIT; /* targetOutputSize too high => decode everything */
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    0          
    50          
    0          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1145 42 0         if ((endOnInput) && (unlikely(outputSize==0))) return ((srcSize==1) && (*ip==0)) ? 0 : -1; /* Empty output buffer */
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    0          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1146 42 0         if ((!endOnInput) && (unlikely(outputSize==0))) return (*ip==0?1:-1);
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1147              
1148             /* Main Loop : decode sequences */
1149             while (1) {
1150             size_t length;
1151             const BYTE* match;
1152             size_t offset;
1153              
1154             /* get literal length */
1155 153718           unsigned const token = *ip++;
1156 153718 0         if ((length=(token>>ML_BITS)) == RUN_MASK) {
    0          
    0          
    0          
    0          
    0          
    0          
    100          
    100          
    0          
    100          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1157             unsigned s;
1158             do {
1159 305           s = *ip++;
1160 305           length += s;
1161 305 0         } while ( likely(endOnInput ? ip
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1162 305 0         if ((safeDecode) && unlikely((uptrval)(op)+length<(uptrval)(op))) goto _output_error; /* overflow detection */
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1163 305 0         if ((safeDecode) && unlikely((uptrval)(ip)+length<(uptrval)(ip))) goto _output_error; /* overflow detection */
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    0          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1164             }
1165              
1166             /* copy literals */
1167 153718           cpy = op+length;
1168 153718 0         if ( ((endOnInput) && ((cpy>(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) )
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    100          
    100          
    50          
    50          
    100          
    50          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    100          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1169 153676 0         || ((!endOnInput) && (cpy>oend-WILDCOPYLENGTH)) )
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    0          
    50          
    0          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1170             {
1171 42 0         if (partialDecoding) {
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1172 0 0         if (cpy > oend) goto _output_error; /* Error : write attempt beyond end of output buffer */
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1173 0 0         if ((endOnInput) && (ip+length > iend)) goto _output_error; /* Error : read attempt beyond end of input buffer */
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1174             } else {
1175 42 0         if ((!endOnInput) && (cpy != oend)) goto _output_error; /* Error : block decoding must stop exactly there */
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    0          
    50          
    0          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1176 42 0         if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) goto _output_error; /* Error : input must be consumed */
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    50          
    50          
    50          
    50          
    0          
    0          
    0          
    50          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1177             }
1178 42           memcpy(op, ip, length);
1179 42           ip += length;
1180 42           op += length;
1181             break; /* Necessarily EOF, due to parsing restrictions */
1182             }
1183 153676           LZ4_wildCopy(op, ip, cpy);
1184 153676           ip += length; op = cpy;
1185              
1186             /* get offset */
1187 153676           offset = LZ4_readLE16(ip); ip+=2;
1188 153676           match = op - offset;
1189 153676 0         if ((checkOffset) && (unlikely(match + dictSize < lowPrefix))) goto _output_error; /* Error : offset outside buffers */
    0          
1190 153676           LZ4_write32(op, (U32)offset); /* costs ~1%; silence an msan warning when offset==0 */
1191              
1192             /* get matchlength */
1193 153676           length = token & ML_MASK;
1194 153676           if (length == ML_MASK) {
1195             unsigned s;
1196             do {
1197 269           s = *ip++;
1198 269 0         if ((endOnInput) && (ip > iend-LASTLITERALS)) goto _output_error;
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1199 269           length += s;
1200 269 0         } while (s==255);
    0          
    0          
    0          
    0          
    0          
    0          
    100          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1201 5 0         if ((safeDecode) && unlikely((uptrval)(op)+length<(uptrval)op)) goto _output_error; /* overflow detection */
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1202             }
1203 153676           length += MINMATCH;
1204              
1205             /* check external dictionary */
1206 153676 0         if ((dict==usingExtDict) && (match < lowPrefix)) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    0          
    50          
    0          
    0          
    0          
    50          
    100          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1207 162 0         if (unlikely(op+length > oend-LASTLITERALS)) goto _output_error; /* doesn't respect parsing restriction */
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1208              
1209 162 0         if (length <= (size_t)(lowPrefix-match)) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1210             /* match can be copied as a single segment from external dictionary */
1211 162           memmove(op, dictEnd - (lowPrefix-match), length);
1212 162           op += length;
1213             } else {
1214             /* match encompass external dictionary and current block */
1215 0           size_t const copySize = (size_t)(lowPrefix-match);
1216 0           size_t const restSize = length - copySize;
1217 0           memcpy(op, dictEnd - copySize, copySize);
1218 0           op += copySize;
1219 0 0         if (restSize > (size_t)(op-lowPrefix)) { /* overlap copy */
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1220 0           BYTE* const endOfMatch = op + restSize;
1221 0           const BYTE* copyFrom = lowPrefix;
1222 0 0         while (op < endOfMatch) *op++ = *copyFrom++;
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1223             } else {
1224 0           memcpy(op, lowPrefix, restSize);
1225 0           op += restSize;
1226             } }
1227 162           continue;
1228             }
1229              
1230             /* copy match within block */
1231 153514           cpy = op + length;
1232 153514 0         if (unlikely(offset<8)) {
    0          
    0          
    0          
    0          
    0          
    0          
    100          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1233 23           const int dec64 = dec64table[offset];
1234 23           op[0] = match[0];
1235 23           op[1] = match[1];
1236 23           op[2] = match[2];
1237 23           op[3] = match[3];
1238 23           match += dec32table[offset];
1239 23           memcpy(op+4, match, 4);
1240 23           match -= dec64;
1241 153491           } else { LZ4_copy8(op, match); match+=8; }
1242 153514           op += 8;
1243              
1244 153514 0         if (unlikely(cpy>oend-12)) {
    0          
    0          
    0          
    0          
    0          
    0          
    100          
    100          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1245 13           BYTE* const oCopyLimit = oend-(WILDCOPYLENGTH-1);
1246 13 0         if (cpy > oend-LASTLITERALS) goto _output_error; /* Error : last LASTLITERALS bytes must be literals (uncompressed) */
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1247 13 0         if (op < oCopyLimit) {
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1248 13           LZ4_wildCopy(op, match, oCopyLimit);
1249 13           match += oCopyLimit - op;
1250 13           op = oCopyLimit;
1251             }
1252 15 0         while (op
    0          
    0          
    0          
    0          
    0          
    0          
    100          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1253             } else {
1254 153501           LZ4_copy8(op, match);
1255 153501 0         if (length>16) LZ4_wildCopy(op+8, match+8, cpy);
    0          
    0          
    0          
    0          
    0          
    0          
    100          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1256             }
1257 153676           op=cpy; /* correction */
1258             }
1259              
1260             /* end of decoding */
1261 42 0         if (endOnInput)
    0          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
1262 42           return (int) (((char*)op)-dst); /* Nb of output bytes decoded */
1263             else
1264 0           return (int) (((const char*)ip)-src); /* Nb of input bytes read */
1265              
1266             /* Overflow error detected */
1267             _output_error:
1268 42           return (int) (-(((const char*)ip)-src))-1;
1269             }
1270              
1271              
1272 0           int LZ4_decompress_safe(const char* source, char* dest, int compressedSize, int maxDecompressedSize)
1273             {
1274 0           return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, endOnInputSize, full, 0, noDict, (BYTE*)dest, NULL, 0);
1275             }
1276              
1277 0           int LZ4_decompress_safe_partial(const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize)
1278             {
1279 0           return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, endOnInputSize, partial, targetOutputSize, noDict, (BYTE*)dest, NULL, 0);
1280             }
1281              
1282 0           int LZ4_decompress_fast(const char* source, char* dest, int originalSize)
1283             {
1284 0           return LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, withPrefix64k, (BYTE*)(dest - 64 KB), NULL, 64 KB);
1285             }
1286              
1287              
1288             /*===== streaming decompression functions =====*/
1289              
1290 0           LZ4_streamDecode_t* LZ4_createStreamDecode(void)
1291             {
1292 0           LZ4_streamDecode_t* lz4s = (LZ4_streamDecode_t*) ALLOCATOR(1, sizeof(LZ4_streamDecode_t));
1293 0           return lz4s;
1294             }
1295              
1296 0           int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream)
1297             {
1298 0 0         if (!LZ4_stream) return 0; /* support free on NULL */
1299 0           FREEMEM(LZ4_stream);
1300 0           return 0;
1301             }
1302              
1303             /*!
1304             * LZ4_setStreamDecode() :
1305             * Use this function to instruct where to find the dictionary.
1306             * This function is not necessary if previous data is still available where it was decoded.
1307             * Loading a size of 0 is allowed (same effect as no dictionary).
1308             * Return : 1 if OK, 0 if error
1309             */
1310 0           int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize)
1311             {
1312 0           LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse;
1313 0           lz4sd->prefixSize = (size_t) dictSize;
1314 0           lz4sd->prefixEnd = (const BYTE*) dictionary + dictSize;
1315 0           lz4sd->externalDict = NULL;
1316 0           lz4sd->extDictSize = 0;
1317 0           return 1;
1318             }
1319              
1320             /*
1321             *_continue() :
1322             These decoding functions allow decompression of multiple blocks in "streaming" mode.
1323             Previously decoded blocks must still be available at the memory position where they were decoded.
1324             If it's not possible, save the relevant part of decoded data into a safe buffer,
1325             and indicate where it stands using LZ4_setStreamDecode()
1326             */
1327 0           int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxOutputSize)
1328             {
1329 0           LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse;
1330             int result;
1331              
1332 0 0         if (lz4sd->prefixEnd == (BYTE*)dest) {
1333 0           result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize,
1334             endOnInputSize, full, 0,
1335 0           usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize);
1336 0 0         if (result <= 0) return result;
1337 0           lz4sd->prefixSize += result;
1338 0           lz4sd->prefixEnd += result;
1339             } else {
1340 0           lz4sd->extDictSize = lz4sd->prefixSize;
1341 0           lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize;
1342 0           result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize,
1343             endOnInputSize, full, 0,
1344 0           usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize);
1345 0 0         if (result <= 0) return result;
1346 0           lz4sd->prefixSize = result;
1347 0           lz4sd->prefixEnd = (BYTE*)dest + result;
1348             }
1349              
1350 0           return result;
1351             }
1352              
1353 0           int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize)
1354             {
1355 0           LZ4_streamDecode_t_internal* lz4sd = &LZ4_streamDecode->internal_donotuse;
1356             int result;
1357              
1358 0 0         if (lz4sd->prefixEnd == (BYTE*)dest) {
1359 0           result = LZ4_decompress_generic(source, dest, 0, originalSize,
1360             endOnOutputSize, full, 0,
1361 0           usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize);
1362 0 0         if (result <= 0) return result;
1363 0           lz4sd->prefixSize += originalSize;
1364 0           lz4sd->prefixEnd += originalSize;
1365             } else {
1366 0           lz4sd->extDictSize = lz4sd->prefixSize;
1367 0           lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize;
1368 0           result = LZ4_decompress_generic(source, dest, 0, originalSize,
1369             endOnOutputSize, full, 0,
1370 0           usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize);
1371 0 0         if (result <= 0) return result;
1372 0           lz4sd->prefixSize = originalSize;
1373 0           lz4sd->prefixEnd = (BYTE*)dest + originalSize;
1374             }
1375              
1376 0           return result;
1377             }
1378              
1379              
1380             /*
1381             Advanced decoding functions :
1382             *_usingDict() :
1383             These decoding functions work the same as "_continue" ones,
1384             the dictionary must be explicitly provided within parameters
1385             */
1386              
1387             LZ4_FORCE_INLINE int LZ4_decompress_usingDict_generic(const char* source, char* dest, int compressedSize, int maxOutputSize, int safe, const char* dictStart, int dictSize)
1388             {
1389 42 0         if (dictSize==0)
    100          
1390 6           return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest, NULL, 0);
1391 36 0         if (dictStart+dictSize == dest) {
    100          
1392 33 0         if (dictSize >= (int)(64 KB - 1))
    50          
1393 33           return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, withPrefix64k, (BYTE*)dest-64 KB, NULL, 0);
1394 0           return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest-dictSize, NULL, 0);
1395             }
1396 3           return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, usingExtDict, (BYTE*)dest, (const BYTE*)dictStart, dictSize);
1397             }
1398              
1399 42           int LZ4_decompress_safe_usingDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize)
1400             {
1401 42           return LZ4_decompress_usingDict_generic(source, dest, compressedSize, maxOutputSize, 1, dictStart, dictSize);
1402             }
1403              
1404 0           int LZ4_decompress_fast_usingDict(const char* source, char* dest, int originalSize, const char* dictStart, int dictSize)
1405             {
1406 0           return LZ4_decompress_usingDict_generic(source, dest, 0, originalSize, 0, dictStart, dictSize);
1407             }
1408              
1409             /* debug function */
1410 0           int LZ4_decompress_safe_forceExtDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize)
1411             {
1412 0           return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, usingExtDict, (BYTE*)dest, (const BYTE*)dictStart, dictSize);
1413             }
1414              
1415              
1416             /*=*************************************************
1417             * Obsolete Functions
1418             ***************************************************/
1419             /* obsolete compression functions */
1420 0           int LZ4_compress_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize) { return LZ4_compress_default(source, dest, inputSize, maxOutputSize); }
1421 0           int LZ4_compress(const char* source, char* dest, int inputSize) { return LZ4_compress_default(source, dest, inputSize, LZ4_compressBound(inputSize)); }
1422 0           int LZ4_compress_limitedOutput_withState (void* state, const char* src, char* dst, int srcSize, int dstSize) { return LZ4_compress_fast_extState(state, src, dst, srcSize, dstSize, 1); }
1423 0           int LZ4_compress_withState (void* state, const char* src, char* dst, int srcSize) { return LZ4_compress_fast_extState(state, src, dst, srcSize, LZ4_compressBound(srcSize), 1); }
1424 0           int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_stream, const char* src, char* dst, int srcSize, int maxDstSize) { return LZ4_compress_fast_continue(LZ4_stream, src, dst, srcSize, maxDstSize, 1); }
1425 0           int LZ4_compress_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize) { return LZ4_compress_fast_continue(LZ4_stream, source, dest, inputSize, LZ4_compressBound(inputSize), 1); }
1426              
1427             /*
1428             These function names are deprecated and should no longer be used.
1429             They are only provided here for compatibility with older user programs.
1430             - LZ4_uncompress is totally equivalent to LZ4_decompress_fast
1431             - LZ4_uncompress_unknownOutputSize is totally equivalent to LZ4_decompress_safe
1432             */
1433 0           int LZ4_uncompress (const char* source, char* dest, int outputSize) { return LZ4_decompress_fast(source, dest, outputSize); }
1434 0           int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize) { return LZ4_decompress_safe(source, dest, isize, maxOutputSize); }
1435              
1436              
1437             /* Obsolete Streaming functions */
1438              
1439 0           int LZ4_sizeofStreamState() { return LZ4_STREAMSIZE; }
1440              
1441 0           static void LZ4_init(LZ4_stream_t* lz4ds, BYTE* base)
1442             {
1443 0           MEM_INIT(lz4ds, 0, sizeof(LZ4_stream_t));
1444 0           lz4ds->internal_donotuse.bufferStart = base;
1445 0           }
1446              
1447 0           int LZ4_resetStreamState(void* state, char* inputBuffer)
1448             {
1449 0 0         if ((((uptrval)state) & 3) != 0) return 1; /* Error : pointer is not aligned on 4-bytes boundary */
1450 0           LZ4_init((LZ4_stream_t*)state, (BYTE*)inputBuffer);
1451 0           return 0;
1452             }
1453              
1454 0           void* LZ4_create (char* inputBuffer)
1455             {
1456 0           LZ4_stream_t* lz4ds = (LZ4_stream_t*)ALLOCATOR(8, sizeof(LZ4_stream_t));
1457 0           LZ4_init (lz4ds, (BYTE*)inputBuffer);
1458 0           return lz4ds;
1459             }
1460              
1461 0           char* LZ4_slideInputBuffer (void* LZ4_Data)
1462             {
1463 0           LZ4_stream_t_internal* ctx = &((LZ4_stream_t*)LZ4_Data)->internal_donotuse;
1464 0           int dictSize = LZ4_saveDict((LZ4_stream_t*)LZ4_Data, (char*)ctx->bufferStart, 64 KB);
1465 0           return (char*)(ctx->bufferStart + dictSize);
1466             }
1467              
1468             /* Obsolete streaming decompression functions */
1469              
1470 0           int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int compressedSize, int maxOutputSize)
1471             {
1472 0           return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB);
1473             }
1474              
1475 0           int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int originalSize)
1476             {
1477 0           return LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB);
1478             }
1479              
1480             #endif /* LZ4_COMMONDEFS_ONLY */