• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2    LZ4 - Fast LZ compression algorithm
3    Copyright (C) 2011-2015, Yann Collet.
4    BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
5 
6    Redistribution and use in source and binary forms, with or without
7    modification, are permitted provided that the following conditions are
8    met:
9 
10        * Redistributions of source code must retain the above copyright
11    notice, this list of conditions and the following disclaimer.
12        * Redistributions in binary form must reproduce the above
13    copyright notice, this list of conditions and the following disclaimer
14    in the documentation and/or other materials provided with the
15    distribution.
16 
17    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29    You can contact the author at :
30    - LZ4 source repository : http://code.google.com/p/lz4
31    - LZ4 source mirror : https://github.com/Cyan4973/lz4
32    - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
33 */
34 
35 
36 /**************************************
37    Tuning parameters
38 **************************************/
39 /*
40  * 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 #define HEAPMODE 0
45 
46 /*
47  * CPU_HAS_EFFICIENT_UNALIGNED_MEMORY_ACCESS :
48  * By default, the source code expects the compiler to correctly optimize
49  * 4-bytes and 8-bytes read on architectures able to handle it efficiently.
50  * This is not always the case. In some circumstances (ARM notably),
51  * the compiler will issue cautious code even when target is able to correctly handle unaligned memory accesses.
52  *
53  * You can force the compiler to use unaligned memory access by uncommenting the line below.
54  * One of the below scenarios will happen :
55  * 1 - Your target CPU correctly handle unaligned access, and was not well optimized by compiler (good case).
56  *     You will witness large performance improvements (+50% and up).
57  *     Keep the line uncommented and send a word to upstream (https://groups.google.com/forum/#!forum/lz4c)
58  *     The goal is to automatically detect such situations by adding your target CPU within an exception list.
59  * 2 - Your target CPU correctly handle unaligned access, and was already already optimized by compiler
60  *     No change will be experienced.
61  * 3 - Your target CPU inefficiently handle unaligned access.
62  *     You will experience a performance loss. Comment back the line.
63  * 4 - Your target CPU does not handle unaligned access.
64  *     Program will crash.
65  * If uncommenting results in better performance (case 1)
66  * please report your configuration to upstream (https://groups.google.com/forum/#!forum/lz4c)
67  * An automatic detection macro will be added to match your case within future versions of the library.
68  */
69 /* #define CPU_HAS_EFFICIENT_UNALIGNED_MEMORY_ACCESS 1 */
70 
71 
72 /**************************************
73    CPU Feature Detection
74 **************************************/
75 /*
76  * Automated efficient unaligned memory access detection
77  * Based on known hardware architectures
78  * This list will be updated thanks to feedbacks
79  */
80 #if defined(CPU_HAS_EFFICIENT_UNALIGNED_MEMORY_ACCESS) \
81     || defined(__ARM_FEATURE_UNALIGNED) \
82     || defined(__i386__) || defined(__x86_64__) \
83     || defined(_M_IX86) || defined(_M_X64) \
84     || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_8__) \
85     || (defined(_M_ARM) && (_M_ARM >= 7))
86 #  define LZ4_UNALIGNED_ACCESS 1
87 #else
88 #  define LZ4_UNALIGNED_ACCESS 0
89 #endif
90 
91 /*
92  * LZ4_FORCE_SW_BITCOUNT
93  * Define this parameter if your target system or compiler does not support hardware bit count
94  */
95 #if defined(_MSC_VER) && defined(_WIN32_WCE)   /* Visual Studio for Windows CE does not support Hardware bit count */
96 #  define LZ4_FORCE_SW_BITCOUNT
97 #endif
98 
99 
100 /**************************************
101    Compiler Options
102 **************************************/
103 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)   /* C99 */
104 /* "restrict" is a known keyword */
105 #else
106 #  define restrict /* Disable restrict */
107 #endif
108 
109 #ifdef _MSC_VER    /* Visual Studio */
110 #  define FORCE_INLINE static __forceinline
111 #  include <intrin.h>
112 #  pragma warning(disable : 4127)        /* disable: C4127: conditional expression is constant */
113 #  pragma warning(disable : 4293)        /* disable: C4293: too large shift (32-bits) */
114 #else
115 #  if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)   /* C99 */
116 #    ifdef __GNUC__
117 #      define FORCE_INLINE static inline __attribute__((always_inline))
118 #    else
119 #      define FORCE_INLINE static inline
120 #    endif
121 #  else
122 #    define FORCE_INLINE static
123 #  endif   /* __STDC_VERSION__ */
124 #endif  /* _MSC_VER */
125 
126 #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
127 
128 #if (GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__)
129 #  define expect(expr,value)    (__builtin_expect ((expr),(value)) )
130 #else
131 #  define expect(expr,value)    (expr)
132 #endif
133 
134 #define likely(expr)     expect((expr) != 0, 1)
135 #define unlikely(expr)   expect((expr) != 0, 0)
136 
137 
138 /**************************************
139    Memory routines
140 **************************************/
141 #include <stdlib.h>   /* malloc, calloc, free */
142 #define ALLOCATOR(n,s) calloc(n,s)
143 #define FREEMEM        free
144 #include <string.h>   /* memset, memcpy */
145 #define MEM_INIT       memset
146 
147 
148 /**************************************
149    Includes
150 **************************************/
151 #include "lz4.h"
152 
153 
154 /**************************************
155    Basic Types
156 **************************************/
157 #if defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)   /* C99 */
158 # include <stdint.h>
159   typedef  uint8_t BYTE;
160   typedef uint16_t U16;
161   typedef uint32_t U32;
162   typedef  int32_t S32;
163   typedef uint64_t U64;
164 #else
165   typedef unsigned char       BYTE;
166   typedef unsigned short      U16;
167   typedef unsigned int        U32;
168   typedef   signed int        S32;
169   typedef unsigned long long  U64;
170 #endif
171 
172 
173 /**************************************
174    Reading and writing into memory
175 **************************************/
176 #define STEPSIZE sizeof(size_t)
177 
LZ4_64bits(void)178 static unsigned LZ4_64bits(void) { return sizeof(void*)==8; }
179 
LZ4_isLittleEndian(void)180 static unsigned LZ4_isLittleEndian(void)
181 {
182     const union { U32 i; BYTE c[4]; } one = { 1 };   /* don't use static : performance detrimental  */
183     return one.c[0];
184 }
185 
186 
LZ4_readLE16(const void * memPtr)187 static U16 LZ4_readLE16(const void* memPtr)
188 {
189     if ((LZ4_UNALIGNED_ACCESS) && (LZ4_isLittleEndian()))
190         return *(U16*)memPtr;
191     else
192     {
193         const BYTE* p = memPtr;
194         return (U16)((U16)p[0] + (p[1]<<8));
195     }
196 }
197 
LZ4_writeLE16(void * memPtr,U16 value)198 static void LZ4_writeLE16(void* memPtr, U16 value)
199 {
200     if ((LZ4_UNALIGNED_ACCESS) && (LZ4_isLittleEndian()))
201     {
202         *(U16*)memPtr = value;
203         return;
204     }
205     else
206     {
207         BYTE* p = memPtr;
208         p[0] = (BYTE) value;
209         p[1] = (BYTE)(value>>8);
210     }
211 }
212 
213 
LZ4_read16(const void * memPtr)214 static U16 LZ4_read16(const void* memPtr)
215 {
216     if (LZ4_UNALIGNED_ACCESS)
217         return *(U16*)memPtr;
218     else
219     {
220         U16 val16;
221         memcpy(&val16, memPtr, 2);
222         return val16;
223     }
224 }
225 
LZ4_read32(const void * memPtr)226 static U32 LZ4_read32(const void* memPtr)
227 {
228     if (LZ4_UNALIGNED_ACCESS)
229         return *(U32*)memPtr;
230     else
231     {
232         U32 val32;
233         memcpy(&val32, memPtr, 4);
234         return val32;
235     }
236 }
237 
LZ4_read64(const void * memPtr)238 static U64 LZ4_read64(const void* memPtr)
239 {
240     if (LZ4_UNALIGNED_ACCESS)
241         return *(U64*)memPtr;
242     else
243     {
244         U64 val64;
245         memcpy(&val64, memPtr, 8);
246         return val64;
247     }
248 }
249 
LZ4_read_ARCH(const void * p)250 static size_t LZ4_read_ARCH(const void* p)
251 {
252     if (LZ4_64bits())
253         return (size_t)LZ4_read64(p);
254     else
255         return (size_t)LZ4_read32(p);
256 }
257 
258 
LZ4_copy4(void * dstPtr,const void * srcPtr)259 static void LZ4_copy4(void* dstPtr, const void* srcPtr)
260 {
261     if (LZ4_UNALIGNED_ACCESS)
262     {
263         *(U32*)dstPtr = *(U32*)srcPtr;
264         return;
265     }
266     memcpy(dstPtr, srcPtr, 4);
267 }
268 
LZ4_copy8(void * dstPtr,const void * srcPtr)269 static void LZ4_copy8(void* dstPtr, const void* srcPtr)
270 {
271 #if GCC_VERSION!=409  /* disabled on GCC 4.9, as it generates invalid opcode (crash) */
272     if (LZ4_UNALIGNED_ACCESS)
273     {
274         if (LZ4_64bits())
275             *(U64*)dstPtr = *(U64*)srcPtr;
276         else
277             ((U32*)dstPtr)[0] = ((U32*)srcPtr)[0],
278             ((U32*)dstPtr)[1] = ((U32*)srcPtr)[1];
279         return;
280     }
281 #endif
282     memcpy(dstPtr, srcPtr, 8);
283 }
284 
285 /* customized version of memcpy, which may overwrite up to 7 bytes beyond dstEnd */
LZ4_wildCopy(void * dstPtr,const void * srcPtr,void * dstEnd)286 static void LZ4_wildCopy(void* dstPtr, const void* srcPtr, void* dstEnd)
287 {
288     BYTE* d = dstPtr;
289     const BYTE* s = srcPtr;
290     BYTE* e = dstEnd;
291     do { LZ4_copy8(d,s); d+=8; s+=8; } while (d<e);
292 }
293 
294 
295 /**************************************
296    Common Constants
297 **************************************/
298 #define MINMATCH 4
299 
300 #define COPYLENGTH 8
301 #define LASTLITERALS 5
302 #define MFLIMIT (COPYLENGTH+MINMATCH)
303 static const int LZ4_minLength = (MFLIMIT+1);
304 
305 #define KB *(1 <<10)
306 #define MB *(1 <<20)
307 #define GB *(1U<<30)
308 
309 #define MAXD_LOG 16
310 #define MAX_DISTANCE ((1 << MAXD_LOG) - 1)
311 
312 #define ML_BITS  4
313 #define ML_MASK  ((1U<<ML_BITS)-1)
314 #define RUN_BITS (8-ML_BITS)
315 #define RUN_MASK ((1U<<RUN_BITS)-1)
316 
317 
318 /**************************************
319    Common Utils
320 **************************************/
321 #define LZ4_STATIC_ASSERT(c)    { enum { LZ4_static_assert = 1/(int)(!!(c)) }; }   /* use only *after* variable declarations */
322 
323 
324 /********************************
325    Common functions
326 ********************************/
LZ4_NbCommonBytes(register size_t val)327 static unsigned LZ4_NbCommonBytes (register size_t val)
328 {
329     if (LZ4_isLittleEndian())
330     {
331         if (LZ4_64bits())
332         {
333 #       if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT)
334             unsigned long r = 0;
335             _BitScanForward64( &r, (U64)val );
336             return (int)(r>>3);
337 #       elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
338             return (__builtin_ctzll((U64)val) >> 3);
339 #       else
340             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 };
341             return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];
342 #       endif
343         }
344         else /* 32 bits */
345         {
346 #       if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
347             unsigned long r;
348             _BitScanForward( &r, (U32)val );
349             return (int)(r>>3);
350 #       elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
351             return (__builtin_ctz((U32)val) >> 3);
352 #       else
353             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 };
354             return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
355 #       endif
356         }
357     }
358     else   /* Big Endian CPU */
359     {
360         if (LZ4_64bits())
361         {
362 #       if defined(_MSC_VER) && defined(_WIN64) && !defined(LZ4_FORCE_SW_BITCOUNT)
363             unsigned long r = 0;
364             _BitScanReverse64( &r, val );
365             return (unsigned)(r>>3);
366 #       elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
367             return (__builtin_clzll(val) >> 3);
368 #       else
369             unsigned r;
370             if (!(val>>32)) { r=4; } else { r=0; val>>=32; }
371             if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
372             r += (!val);
373             return r;
374 #       endif
375         }
376         else /* 32 bits */
377         {
378 #       if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
379             unsigned long r = 0;
380             _BitScanReverse( &r, (unsigned long)val );
381             return (unsigned)(r>>3);
382 #       elif defined(__GNUC__) && (GCC_VERSION >= 304) && !defined(LZ4_FORCE_SW_BITCOUNT)
383             return (__builtin_clz(val) >> 3);
384 #       else
385             unsigned r;
386             if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
387             r += (!val);
388             return r;
389 #       endif
390         }
391     }
392 }
393 
LZ4_count(const BYTE * pIn,const BYTE * pMatch,const BYTE * pInLimit)394 static unsigned LZ4_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* pInLimit)
395 {
396     const BYTE* const pStart = pIn;
397 
398     while (likely(pIn<pInLimit-(STEPSIZE-1)))
399     {
400         size_t diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn);
401         if (!diff) { pIn+=STEPSIZE; pMatch+=STEPSIZE; continue; }
402         pIn += LZ4_NbCommonBytes(diff);
403         return (unsigned)(pIn - pStart);
404     }
405 
406     if (LZ4_64bits()) if ((pIn<(pInLimit-3)) && (LZ4_read32(pMatch) == LZ4_read32(pIn))) { pIn+=4; pMatch+=4; }
407     if ((pIn<(pInLimit-1)) && (LZ4_read16(pMatch) == LZ4_read16(pIn))) { pIn+=2; pMatch+=2; }
408     if ((pIn<pInLimit) && (*pMatch == *pIn)) pIn++;
409     return (unsigned)(pIn - pStart);
410 }
411 
412 
413 #ifndef LZ4_COMMONDEFS_ONLY
414 /**************************************
415    Local Constants
416 **************************************/
417 #define LZ4_HASHLOG   (LZ4_MEMORY_USAGE-2)
418 #define HASHTABLESIZE (1 << LZ4_MEMORY_USAGE)
419 #define HASH_SIZE_U32 (1 << LZ4_HASHLOG)       /* required as macro for static allocation */
420 
421 static const int LZ4_64Klimit = ((64 KB) + (MFLIMIT-1));
422 static const U32 LZ4_skipTrigger = 6;  /* Increase this value ==> compression run slower on incompressible data */
423 
424 
425 /**************************************
426    Local Utils
427 **************************************/
LZ4_versionNumber(void)428 int LZ4_versionNumber (void) { return LZ4_VERSION_NUMBER; }
LZ4_compressBound(int isize)429 int LZ4_compressBound(int isize)  { return LZ4_COMPRESSBOUND(isize); }
430 
431 
432 /**************************************
433    Local Structures and types
434 **************************************/
435 typedef struct {
436     U32 hashTable[HASH_SIZE_U32];
437     U32 currentOffset;
438     U32 initCheck;
439     const BYTE* dictionary;
440     const BYTE* bufferStart;
441     U32 dictSize;
442 } LZ4_stream_t_internal;
443 
444 typedef enum { notLimited = 0, limitedOutput = 1 } limitedOutput_directive;
445 typedef enum { byPtr, byU32, byU16 } tableType_t;
446 
447 typedef enum { noDict = 0, withPrefix64k, usingExtDict } dict_directive;
448 typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive;
449 
450 typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive;
451 typedef enum { full = 0, partial = 1 } earlyEnd_directive;
452 
453 
454 
455 /********************************
456    Compression functions
457 ********************************/
458 
LZ4_hashSequence(U32 sequence,tableType_t tableType)459 static U32 LZ4_hashSequence(U32 sequence, tableType_t tableType)
460 {
461     if (tableType == byU16)
462         return (((sequence) * 2654435761U) >> ((MINMATCH*8)-(LZ4_HASHLOG+1)));
463     else
464         return (((sequence) * 2654435761U) >> ((MINMATCH*8)-LZ4_HASHLOG));
465 }
466 
LZ4_hashPosition(const BYTE * p,tableType_t tableType)467 static U32 LZ4_hashPosition(const BYTE* p, tableType_t tableType) { return LZ4_hashSequence(LZ4_read32(p), tableType); }
468 
LZ4_putPositionOnHash(const BYTE * p,U32 h,void * tableBase,tableType_t tableType,const BYTE * srcBase)469 static void LZ4_putPositionOnHash(const BYTE* p, U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase)
470 {
471     switch (tableType)
472     {
473     case byPtr: { const BYTE** hashTable = (const BYTE**)tableBase; hashTable[h] = p; return; }
474     case byU32: { U32* hashTable = (U32*) tableBase; hashTable[h] = (U32)(p-srcBase); return; }
475     case byU16: { U16* hashTable = (U16*) tableBase; hashTable[h] = (U16)(p-srcBase); return; }
476     }
477 }
478 
LZ4_putPosition(const BYTE * p,void * tableBase,tableType_t tableType,const BYTE * srcBase)479 static void LZ4_putPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase)
480 {
481     U32 h = LZ4_hashPosition(p, tableType);
482     LZ4_putPositionOnHash(p, h, tableBase, tableType, srcBase);
483 }
484 
LZ4_getPositionOnHash(U32 h,void * tableBase,tableType_t tableType,const BYTE * srcBase)485 static const BYTE* LZ4_getPositionOnHash(U32 h, void* tableBase, tableType_t tableType, const BYTE* srcBase)
486 {
487     if (tableType == byPtr) { const BYTE** hashTable = (const BYTE**) tableBase; return hashTable[h]; }
488     if (tableType == byU32) { U32* hashTable = (U32*) tableBase; return hashTable[h] + srcBase; }
489     { U16* hashTable = (U16*) tableBase; return hashTable[h] + srcBase; }   /* default, to ensure a return */
490 }
491 
LZ4_getPosition(const BYTE * p,void * tableBase,tableType_t tableType,const BYTE * srcBase)492 static const BYTE* LZ4_getPosition(const BYTE* p, void* tableBase, tableType_t tableType, const BYTE* srcBase)
493 {
494     U32 h = LZ4_hashPosition(p, tableType);
495     return LZ4_getPositionOnHash(h, tableBase, tableType, srcBase);
496 }
497 
LZ4_compress_generic(void * ctx,const char * source,char * dest,int inputSize,int maxOutputSize,limitedOutput_directive outputLimited,tableType_t tableType,dict_directive dict,dictIssue_directive dictIssue)498 static int LZ4_compress_generic(
499                  void* ctx,
500                  const char* source,
501                  char* dest,
502                  int inputSize,
503                  int maxOutputSize,
504                  limitedOutput_directive outputLimited,
505                  tableType_t tableType,
506                  dict_directive dict,
507                  dictIssue_directive dictIssue)
508 {
509     LZ4_stream_t_internal* const dictPtr = (LZ4_stream_t_internal*)ctx;
510 
511     const BYTE* ip = (const BYTE*) source;
512     const BYTE* base;
513     const BYTE* lowLimit;
514     const BYTE* const lowRefLimit = ip - dictPtr->dictSize;
515     const BYTE* const dictionary = dictPtr->dictionary;
516     const BYTE* const dictEnd = dictionary + dictPtr->dictSize;
517     const size_t dictDelta = dictEnd - (const BYTE*)source;
518     const BYTE* anchor = (const BYTE*) source;
519     const BYTE* const iend = ip + inputSize;
520     const BYTE* const mflimit = iend - MFLIMIT;
521     const BYTE* const matchlimit = iend - LASTLITERALS;
522 
523     BYTE* op = (BYTE*) dest;
524     BYTE* const olimit = op + maxOutputSize;
525 
526     U32 forwardH;
527     size_t refDelta=0;
528 
529     /* Init conditions */
530     if ((U32)inputSize > (U32)LZ4_MAX_INPUT_SIZE) return 0;          /* Unsupported input size, too large (or negative) */
531     switch(dict)
532     {
533     case noDict:
534     default:
535         base = (const BYTE*)source;
536         lowLimit = (const BYTE*)source;
537         break;
538     case withPrefix64k:
539         base = (const BYTE*)source - dictPtr->currentOffset;
540         lowLimit = (const BYTE*)source - dictPtr->dictSize;
541         break;
542     case usingExtDict:
543         base = (const BYTE*)source - dictPtr->currentOffset;
544         lowLimit = (const BYTE*)source;
545         break;
546     }
547     if ((tableType == byU16) && (inputSize>=LZ4_64Klimit)) return 0;   /* Size too large (not within 64K limit) */
548     if (inputSize<LZ4_minLength) goto _last_literals;                  /* Input too small, no compression (all literals) */
549 
550     /* First Byte */
551     LZ4_putPosition(ip, ctx, tableType, base);
552     ip++; forwardH = LZ4_hashPosition(ip, tableType);
553 
554     /* Main Loop */
555     for ( ; ; )
556     {
557         const BYTE* match;
558         BYTE* token;
559         {
560             const BYTE* forwardIp = ip;
561             unsigned step=1;
562             unsigned searchMatchNb = (1U << LZ4_skipTrigger);
563 
564             /* Find a match */
565             do {
566                 U32 h = forwardH;
567                 ip = forwardIp;
568                 forwardIp += step;
569                 step = searchMatchNb++ >> LZ4_skipTrigger;
570 
571                 if (unlikely(forwardIp > mflimit)) goto _last_literals;
572 
573                 match = LZ4_getPositionOnHash(h, ctx, tableType, base);
574                 if (dict==usingExtDict)
575                 {
576                     if (match<(const BYTE*)source)
577                     {
578                         refDelta = dictDelta;
579                         lowLimit = dictionary;
580                     }
581                     else
582                     {
583                         refDelta = 0;
584                         lowLimit = (const BYTE*)source;
585                     }
586                 }
587                 forwardH = LZ4_hashPosition(forwardIp, tableType);
588                 LZ4_putPositionOnHash(ip, h, ctx, tableType, base);
589 
590             } while ( ((dictIssue==dictSmall) ? (match < lowRefLimit) : 0)
591                 || ((tableType==byU16) ? 0 : (match + MAX_DISTANCE < ip))
592                 || (LZ4_read32(match+refDelta) != LZ4_read32(ip)) );
593         }
594 
595         /* Catch up */
596         while ((ip>anchor) && (match+refDelta > lowLimit) && (unlikely(ip[-1]==match[refDelta-1]))) { ip--; match--; }
597 
598         {
599             /* Encode Literal length */
600             unsigned litLength = (unsigned)(ip - anchor);
601             token = op++;
602             if ((outputLimited) && (unlikely(op + litLength + (2 + 1 + LASTLITERALS) + (litLength/255) > olimit)))
603                 return 0;   /* Check output limit */
604             if (litLength>=RUN_MASK)
605             {
606                 int len = (int)litLength-RUN_MASK;
607                 *token=(RUN_MASK<<ML_BITS);
608                 for(; len >= 255 ; len-=255) *op++ = 255;
609                 *op++ = (BYTE)len;
610             }
611             else *token = (BYTE)(litLength<<ML_BITS);
612 
613             /* Copy Literals */
614             LZ4_wildCopy(op, anchor, op+litLength);
615             op+=litLength;
616         }
617 
618 _next_match:
619         /* Encode Offset */
620         LZ4_writeLE16(op, (U16)(ip-match)); op+=2;
621 
622         /* Encode MatchLength */
623         {
624             unsigned matchLength;
625 
626             if ((dict==usingExtDict) && (lowLimit==dictionary))
627             {
628                 const BYTE* limit;
629                 match += refDelta;
630                 limit = ip + (dictEnd-match);
631                 if (limit > matchlimit) limit = matchlimit;
632                 matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, limit);
633                 ip += MINMATCH + matchLength;
634                 if (ip==limit)
635                 {
636                     unsigned more = LZ4_count(ip, (const BYTE*)source, matchlimit);
637                     matchLength += more;
638                     ip += more;
639                 }
640             }
641             else
642             {
643                 matchLength = LZ4_count(ip+MINMATCH, match+MINMATCH, matchlimit);
644                 ip += MINMATCH + matchLength;
645             }
646 
647             if ((outputLimited) && (unlikely(op + (1 + LASTLITERALS) + (matchLength>>8) > olimit)))
648                 return 0;    /* Check output limit */
649             if (matchLength>=ML_MASK)
650             {
651                 *token += ML_MASK;
652                 matchLength -= ML_MASK;
653                 for (; matchLength >= 510 ; matchLength-=510) { *op++ = 255; *op++ = 255; }
654                 if (matchLength >= 255) { matchLength-=255; *op++ = 255; }
655                 *op++ = (BYTE)matchLength;
656             }
657             else *token += (BYTE)(matchLength);
658         }
659 
660         anchor = ip;
661 
662         /* Test end of chunk */
663         if (ip > mflimit) break;
664 
665         /* Fill table */
666         LZ4_putPosition(ip-2, ctx, tableType, base);
667 
668         /* Test next position */
669         match = LZ4_getPosition(ip, ctx, tableType, base);
670         if (dict==usingExtDict)
671         {
672             if (match<(const BYTE*)source)
673             {
674                 refDelta = dictDelta;
675                 lowLimit = dictionary;
676             }
677             else
678             {
679                 refDelta = 0;
680                 lowLimit = (const BYTE*)source;
681             }
682         }
683         LZ4_putPosition(ip, ctx, tableType, base);
684         if ( ((dictIssue==dictSmall) ? (match>=lowRefLimit) : 1)
685             && (match+MAX_DISTANCE>=ip)
686             && (LZ4_read32(match+refDelta)==LZ4_read32(ip)) )
687         { token=op++; *token=0; goto _next_match; }
688 
689         /* Prepare next loop */
690         forwardH = LZ4_hashPosition(++ip, tableType);
691     }
692 
693 _last_literals:
694     /* Encode Last Literals */
695     {
696         int lastRun = (int)(iend - anchor);
697         if ((outputLimited) && (((char*)op - dest) + lastRun + 1 + ((lastRun+255-RUN_MASK)/255) > (U32)maxOutputSize))
698             return 0;   /* Check output limit */
699         if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun >= 255 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; }
700         else *op++ = (BYTE)(lastRun<<ML_BITS);
701         memcpy(op, anchor, iend - anchor);
702         op += iend-anchor;
703     }
704 
705     /* End */
706     return (int) (((char*)op)-dest);
707 }
708 
709 
LZ4_compress(const char * source,char * dest,int inputSize)710 int LZ4_compress(const char* source, char* dest, int inputSize)
711 {
712 #if (HEAPMODE)
713     void* ctx = ALLOCATOR(LZ4_STREAMSIZE_U64, 8);   /* Aligned on 8-bytes boundaries */
714 #else
715     U64 ctx[LZ4_STREAMSIZE_U64] = {0};      /* Ensure data is aligned on 8-bytes boundaries */
716 #endif
717     int result;
718 
719     if (inputSize < LZ4_64Klimit)
720         result = LZ4_compress_generic((void*)ctx, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue);
721     else
722         result = LZ4_compress_generic((void*)ctx, source, dest, inputSize, 0, notLimited, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue);
723 
724 #if (HEAPMODE)
725     FREEMEM(ctx);
726 #endif
727     return result;
728 }
729 
LZ4_compress_limitedOutput(const char * source,char * dest,int inputSize,int maxOutputSize)730 int LZ4_compress_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize)
731 {
732 #if (HEAPMODE)
733     void* ctx = ALLOCATOR(LZ4_STREAMSIZE_U64, 8);   /* Aligned on 8-bytes boundaries */
734 #else
735     U64 ctx[LZ4_STREAMSIZE_U64] = {0};      /* Ensure data is aligned on 8-bytes boundaries */
736 #endif
737     int result;
738 
739     if (inputSize < LZ4_64Klimit)
740         result = LZ4_compress_generic((void*)ctx, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue);
741     else
742         result = LZ4_compress_generic((void*)ctx, source, dest, inputSize, maxOutputSize, limitedOutput, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue);
743 
744 #if (HEAPMODE)
745     FREEMEM(ctx);
746 #endif
747     return result;
748 }
749 
750 
751 /*****************************************
752    Experimental : Streaming functions
753 *****************************************/
754 
755 /*
756  * LZ4_initStream
757  * Use this function once, to init a newly allocated LZ4_stream_t structure
758  * Return : 1 if OK, 0 if error
759  */
LZ4_resetStream(LZ4_stream_t * LZ4_stream)760 void LZ4_resetStream (LZ4_stream_t* LZ4_stream)
761 {
762     MEM_INIT(LZ4_stream, 0, sizeof(LZ4_stream_t));
763 }
764 
LZ4_createStream(void)765 LZ4_stream_t* LZ4_createStream(void)
766 {
767     LZ4_stream_t* lz4s = (LZ4_stream_t*)ALLOCATOR(8, LZ4_STREAMSIZE_U64);
768     LZ4_STATIC_ASSERT(LZ4_STREAMSIZE >= sizeof(LZ4_stream_t_internal));    /* A compilation error here means LZ4_STREAMSIZE is not large enough */
769     LZ4_resetStream(lz4s);
770     return lz4s;
771 }
772 
LZ4_freeStream(LZ4_stream_t * LZ4_stream)773 int LZ4_freeStream (LZ4_stream_t* LZ4_stream)
774 {
775     FREEMEM(LZ4_stream);
776     return (0);
777 }
778 
779 
LZ4_loadDict(LZ4_stream_t * LZ4_dict,const char * dictionary,int dictSize)780 int LZ4_loadDict (LZ4_stream_t* LZ4_dict, const char* dictionary, int dictSize)
781 {
782     LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict;
783     const BYTE* p = (const BYTE*)dictionary;
784     const BYTE* const dictEnd = p + dictSize;
785     const BYTE* base;
786 
787     if (dict->initCheck) LZ4_resetStream(LZ4_dict);                         /* Uninitialized structure detected */
788 
789     if (dictSize < MINMATCH)
790     {
791         dict->dictionary = NULL;
792         dict->dictSize = 0;
793         return 0;
794     }
795 
796     if (p <= dictEnd - 64 KB) p = dictEnd - 64 KB;
797     base = p - dict->currentOffset;
798     dict->dictionary = p;
799     dict->dictSize = (U32)(dictEnd - p);
800     dict->currentOffset += dict->dictSize;
801 
802     while (p <= dictEnd-MINMATCH)
803     {
804         LZ4_putPosition(p, dict, byU32, base);
805         p+=3;
806     }
807 
808     return dict->dictSize;
809 }
810 
811 
LZ4_renormDictT(LZ4_stream_t_internal * LZ4_dict,const BYTE * src)812 static void LZ4_renormDictT(LZ4_stream_t_internal* LZ4_dict, const BYTE* src)
813 {
814     if ((LZ4_dict->currentOffset > 0x80000000) ||
815         ((size_t)LZ4_dict->currentOffset > (size_t)src))   /* address space overflow */
816     {
817         /* rescale hash table */
818         U32 delta = LZ4_dict->currentOffset - 64 KB;
819         const BYTE* dictEnd = LZ4_dict->dictionary + LZ4_dict->dictSize;
820         int i;
821         for (i=0; i<HASH_SIZE_U32; i++)
822         {
823             if (LZ4_dict->hashTable[i] < delta) LZ4_dict->hashTable[i]=0;
824             else LZ4_dict->hashTable[i] -= delta;
825         }
826         LZ4_dict->currentOffset = 64 KB;
827         if (LZ4_dict->dictSize > 64 KB) LZ4_dict->dictSize = 64 KB;
828         LZ4_dict->dictionary = dictEnd - LZ4_dict->dictSize;
829     }
830 }
831 
832 
LZ4_compress_continue_generic(void * LZ4_stream,const char * source,char * dest,int inputSize,int maxOutputSize,limitedOutput_directive limit)833 FORCE_INLINE int LZ4_compress_continue_generic (void* LZ4_stream, const char* source, char* dest, int inputSize,
834                                                 int maxOutputSize, limitedOutput_directive limit)
835 {
836     LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_stream;
837     const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize;
838 
839     const BYTE* smallest = (const BYTE*) source;
840     if (streamPtr->initCheck) return 0;   /* Uninitialized structure detected */
841     if ((streamPtr->dictSize>0) && (smallest>dictEnd)) smallest = dictEnd;
842     LZ4_renormDictT(streamPtr, smallest);
843 
844     /* Check overlapping input/dictionary space */
845     {
846         const BYTE* sourceEnd = (const BYTE*) source + inputSize;
847         if ((sourceEnd > streamPtr->dictionary) && (sourceEnd < dictEnd))
848         {
849             streamPtr->dictSize = (U32)(dictEnd - sourceEnd);
850             if (streamPtr->dictSize > 64 KB) streamPtr->dictSize = 64 KB;
851             if (streamPtr->dictSize < 4) streamPtr->dictSize = 0;
852             streamPtr->dictionary = dictEnd - streamPtr->dictSize;
853         }
854     }
855 
856     /* prefix mode : source data follows dictionary */
857     if (dictEnd == (const BYTE*)source)
858     {
859         int result;
860         if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset))
861             result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, withPrefix64k, dictSmall);
862         else
863             result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, withPrefix64k, noDictIssue);
864         streamPtr->dictSize += (U32)inputSize;
865         streamPtr->currentOffset += (U32)inputSize;
866         return result;
867     }
868 
869     /* external dictionary mode */
870     {
871         int result;
872         if ((streamPtr->dictSize < 64 KB) && (streamPtr->dictSize < streamPtr->currentOffset))
873             result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, usingExtDict, dictSmall);
874         else
875             result = LZ4_compress_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limit, byU32, usingExtDict, noDictIssue);
876         streamPtr->dictionary = (const BYTE*)source;
877         streamPtr->dictSize = (U32)inputSize;
878         streamPtr->currentOffset += (U32)inputSize;
879         return result;
880     }
881 }
882 
LZ4_compress_continue(LZ4_stream_t * LZ4_stream,const char * source,char * dest,int inputSize)883 int LZ4_compress_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize)
884 {
885     return LZ4_compress_continue_generic(LZ4_stream, source, dest, inputSize, 0, notLimited);
886 }
887 
LZ4_compress_limitedOutput_continue(LZ4_stream_t * LZ4_stream,const char * source,char * dest,int inputSize,int maxOutputSize)888 int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_stream, const char* source, char* dest, int inputSize, int maxOutputSize)
889 {
890     return LZ4_compress_continue_generic(LZ4_stream, source, dest, inputSize, maxOutputSize, limitedOutput);
891 }
892 
893 
894 /* Hidden debug function, to force separate dictionary mode */
LZ4_compress_forceExtDict(LZ4_stream_t * LZ4_dict,const char * source,char * dest,int inputSize)895 int LZ4_compress_forceExtDict (LZ4_stream_t* LZ4_dict, const char* source, char* dest, int inputSize)
896 {
897     LZ4_stream_t_internal* streamPtr = (LZ4_stream_t_internal*)LZ4_dict;
898     int result;
899     const BYTE* const dictEnd = streamPtr->dictionary + streamPtr->dictSize;
900 
901     const BYTE* smallest = dictEnd;
902     if (smallest > (const BYTE*) source) smallest = (const BYTE*) source;
903     LZ4_renormDictT((LZ4_stream_t_internal*)LZ4_dict, smallest);
904 
905     result = LZ4_compress_generic(LZ4_dict, source, dest, inputSize, 0, notLimited, byU32, usingExtDict, noDictIssue);
906 
907     streamPtr->dictionary = (const BYTE*)source;
908     streamPtr->dictSize = (U32)inputSize;
909     streamPtr->currentOffset += (U32)inputSize;
910 
911     return result;
912 }
913 
914 
LZ4_saveDict(LZ4_stream_t * LZ4_dict,char * safeBuffer,int dictSize)915 int LZ4_saveDict (LZ4_stream_t* LZ4_dict, char* safeBuffer, int dictSize)
916 {
917     LZ4_stream_t_internal* dict = (LZ4_stream_t_internal*) LZ4_dict;
918     const BYTE* previousDictEnd = dict->dictionary + dict->dictSize;
919 
920     if ((U32)dictSize > 64 KB) dictSize = 64 KB;   /* useless to define a dictionary > 64 KB */
921     if ((U32)dictSize > dict->dictSize) dictSize = dict->dictSize;
922 
923     memmove(safeBuffer, previousDictEnd - dictSize, dictSize);
924 
925     dict->dictionary = (const BYTE*)safeBuffer;
926     dict->dictSize = (U32)dictSize;
927 
928     return dictSize;
929 }
930 
931 
932 
933 /****************************
934    Decompression functions
935 ****************************/
936 /*
937  * This generic decompression function cover all use cases.
938  * It shall be instantiated several times, using different sets of directives
939  * Note that it is essential this generic function is really inlined,
940  * in order to remove useless branches during compilation optimization.
941  */
LZ4_decompress_generic(const char * const source,char * const dest,int inputSize,int outputSize,int endOnInput,int partialDecoding,int targetOutputSize,int dict,const BYTE * const lowPrefix,const BYTE * const dictStart,const size_t dictSize)942 FORCE_INLINE int LZ4_decompress_generic(
943                  const char* const source,
944                  char* const dest,
945                  int inputSize,
946                  int outputSize,         /* If endOnInput==endOnInputSize, this value is the max size of Output Buffer. */
947 
948                  int endOnInput,         /* endOnOutputSize, endOnInputSize */
949                  int partialDecoding,    /* full, partial */
950                  int targetOutputSize,   /* only used if partialDecoding==partial */
951                  int dict,               /* noDict, withPrefix64k, usingExtDict */
952                  const BYTE* const lowPrefix,  /* == dest if dict == noDict */
953                  const BYTE* const dictStart,  /* only if dict==usingExtDict */
954                  const size_t dictSize         /* note : = 0 if noDict */
955                  )
956 {
957     /* Local Variables */
958     const BYTE* restrict ip = (const BYTE*) source;
959     const BYTE* const iend = ip + inputSize;
960 
961     BYTE* op = (BYTE*) dest;
962     BYTE* const oend = op + outputSize;
963     BYTE* cpy;
964     BYTE* oexit = op + targetOutputSize;
965     const BYTE* const lowLimit = lowPrefix - dictSize;
966 
967     const BYTE* const dictEnd = (const BYTE*)dictStart + dictSize;
968     const size_t dec32table[] = {4, 1, 2, 1, 4, 4, 4, 4};
969     const size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3};
970 
971     const int safeDecode = (endOnInput==endOnInputSize);
972     const int checkOffset = ((safeDecode) && (dictSize < (int)(64 KB)));
973 
974 
975     /* Special cases */
976     if ((partialDecoding) && (oexit> oend-MFLIMIT)) oexit = oend-MFLIMIT;                         /* targetOutputSize too high => decode everything */
977     if ((endOnInput) && (unlikely(outputSize==0))) return ((inputSize==1) && (*ip==0)) ? 0 : -1;  /* Empty output buffer */
978     if ((!endOnInput) && (unlikely(outputSize==0))) return (*ip==0?1:-1);
979 
980 
981     /* Main Loop */
982     while (1)
983     {
984         unsigned token;
985         size_t length;
986         const BYTE* match;
987 
988         /* get literal length */
989         token = *ip++;
990         if ((length=(token>>ML_BITS)) == RUN_MASK)
991         {
992             unsigned s;
993             do
994             {
995                 s = *ip++;
996                 length += s;
997             }
998             while (likely((endOnInput)?ip<iend-RUN_MASK:1) && (s==255));
999             if ((safeDecode) && unlikely((size_t)(op+length)<(size_t)(op))) goto _output_error;   /* overflow detection */
1000             if ((safeDecode) && unlikely((size_t)(ip+length)<(size_t)(ip))) goto _output_error;   /* overflow detection */
1001         }
1002 
1003         /* copy literals */
1004         cpy = op+length;
1005         if (((endOnInput) && ((cpy>(partialDecoding?oexit:oend-MFLIMIT)) || (ip+length>iend-(2+1+LASTLITERALS))) )
1006             || ((!endOnInput) && (cpy>oend-COPYLENGTH)))
1007         {
1008             if (partialDecoding)
1009             {
1010                 if (cpy > oend) goto _output_error;                           /* Error : write attempt beyond end of output buffer */
1011                 if ((endOnInput) && (ip+length > iend)) goto _output_error;   /* Error : read attempt beyond end of input buffer */
1012             }
1013             else
1014             {
1015                 if ((!endOnInput) && (cpy != oend)) goto _output_error;       /* Error : block decoding must stop exactly there */
1016                 if ((endOnInput) && ((ip+length != iend) || (cpy > oend))) goto _output_error;   /* Error : input must be consumed */
1017             }
1018             memcpy(op, ip, length);
1019             ip += length;
1020             op += length;
1021             break;     /* Necessarily EOF, due to parsing restrictions */
1022         }
1023         LZ4_wildCopy(op, ip, cpy);
1024         ip += length; op = cpy;
1025 
1026         /* get offset */
1027         match = cpy - LZ4_readLE16(ip); ip+=2;
1028         if ((checkOffset) && (unlikely(match < lowLimit))) goto _output_error;   /* Error : offset outside destination buffer */
1029 
1030         /* get matchlength */
1031         length = token & ML_MASK;
1032         if (length == ML_MASK)
1033         {
1034             unsigned s;
1035             do
1036             {
1037                 if ((endOnInput) && (ip > iend-LASTLITERALS)) goto _output_error;
1038                 s = *ip++;
1039                 length += s;
1040             } while (s==255);
1041             if ((safeDecode) && unlikely((size_t)(op+length)<(size_t)op)) goto _output_error;   /* overflow detection */
1042         }
1043         length += MINMATCH;
1044 
1045         /* check external dictionary */
1046         if ((dict==usingExtDict) && (match < lowPrefix))
1047         {
1048             if (unlikely(op+length > oend-LASTLITERALS)) goto _output_error;   /* doesn't respect parsing restriction */
1049 
1050             if (length <= (size_t)(lowPrefix-match))
1051             {
1052                 /* match can be copied as a single segment from external dictionary */
1053                 match = dictEnd - (lowPrefix-match);
1054                 memcpy(op, match, length);
1055                 op += length;
1056             }
1057             else
1058             {
1059                 /* match encompass external dictionary and current segment */
1060                 size_t copySize = (size_t)(lowPrefix-match);
1061                 memcpy(op, dictEnd - copySize, copySize);
1062                 op += copySize;
1063                 copySize = length - copySize;
1064                 if (copySize > (size_t)(op-lowPrefix))   /* overlap within current segment */
1065                 {
1066                     BYTE* const endOfMatch = op + copySize;
1067                     const BYTE* copyFrom = lowPrefix;
1068                     while (op < endOfMatch) *op++ = *copyFrom++;
1069                 }
1070                 else
1071                 {
1072                     memcpy(op, lowPrefix, copySize);
1073                     op += copySize;
1074                 }
1075             }
1076             continue;
1077         }
1078 
1079         /* copy repeated sequence */
1080         cpy = op + length;
1081         if (unlikely((op-match)<8))
1082         {
1083             const size_t dec64 = dec64table[op-match];
1084             op[0] = match[0];
1085             op[1] = match[1];
1086             op[2] = match[2];
1087             op[3] = match[3];
1088             match += dec32table[op-match];
1089             LZ4_copy4(op+4, match);
1090             op += 8; match -= dec64;
1091         } else { LZ4_copy8(op, match); op+=8; match+=8; }
1092 
1093         if (unlikely(cpy>oend-12))
1094         {
1095             if (cpy > oend-LASTLITERALS) goto _output_error;    /* Error : last LASTLITERALS bytes must be literals */
1096             if (op < oend-8)
1097             {
1098                 LZ4_wildCopy(op, match, oend-8);
1099                 match += (oend-8) - op;
1100                 op = oend-8;
1101             }
1102             while (op<cpy) *op++ = *match++;
1103         }
1104         else
1105             LZ4_wildCopy(op, match, cpy);
1106         op=cpy;   /* correction */
1107     }
1108 
1109     /* end of decoding */
1110     if (endOnInput)
1111        return (int) (((char*)op)-dest);     /* Nb of output bytes decoded */
1112     else
1113        return (int) (((char*)ip)-source);   /* Nb of input bytes read */
1114 
1115     /* Overflow error detected */
1116 _output_error:
1117     return (int) (-(((char*)ip)-source))-1;
1118 }
1119 
1120 
LZ4_decompress_safe(const char * source,char * dest,int compressedSize,int maxDecompressedSize)1121 int LZ4_decompress_safe(const char* source, char* dest, int compressedSize, int maxDecompressedSize)
1122 {
1123     return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, endOnInputSize, full, 0, noDict, (BYTE*)dest, NULL, 0);
1124 }
1125 
LZ4_decompress_safe_partial(const char * source,char * dest,int compressedSize,int targetOutputSize,int maxDecompressedSize)1126 int LZ4_decompress_safe_partial(const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize)
1127 {
1128     return LZ4_decompress_generic(source, dest, compressedSize, maxDecompressedSize, endOnInputSize, partial, targetOutputSize, noDict, (BYTE*)dest, NULL, 0);
1129 }
1130 
LZ4_decompress_fast(const char * source,char * dest,int originalSize)1131 int LZ4_decompress_fast(const char* source, char* dest, int originalSize)
1132 {
1133     return LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, withPrefix64k, (BYTE*)(dest - 64 KB), NULL, 64 KB);
1134 }
1135 
1136 
1137 /* streaming decompression functions */
1138 
1139 typedef struct
1140 {
1141     BYTE* externalDict;
1142     size_t extDictSize;
1143     BYTE* prefixEnd;
1144     size_t prefixSize;
1145 } LZ4_streamDecode_t_internal;
1146 
1147 /*
1148  * If you prefer dynamic allocation methods,
1149  * LZ4_createStreamDecode()
1150  * provides a pointer (void*) towards an initialized LZ4_streamDecode_t structure.
1151  */
LZ4_createStreamDecode(void)1152 LZ4_streamDecode_t* LZ4_createStreamDecode(void)
1153 {
1154     LZ4_streamDecode_t* lz4s = (LZ4_streamDecode_t*) ALLOCATOR(sizeof(U64), LZ4_STREAMDECODESIZE_U64);
1155     return lz4s;
1156 }
1157 
LZ4_freeStreamDecode(LZ4_streamDecode_t * LZ4_stream)1158 int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream)
1159 {
1160     FREEMEM(LZ4_stream);
1161     return 0;
1162 }
1163 
1164 /*
1165  * LZ4_setStreamDecode
1166  * Use this function to instruct where to find the dictionary
1167  * This function is not necessary if previous data is still available where it was decoded.
1168  * Loading a size of 0 is allowed (same effect as no dictionary).
1169  * Return : 1 if OK, 0 if error
1170  */
LZ4_setStreamDecode(LZ4_streamDecode_t * LZ4_streamDecode,const char * dictionary,int dictSize)1171 int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize)
1172 {
1173     LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode;
1174     lz4sd->prefixSize = (size_t) dictSize;
1175     lz4sd->prefixEnd = (BYTE*) dictionary + dictSize;
1176     lz4sd->externalDict = NULL;
1177     lz4sd->extDictSize  = 0;
1178     return 1;
1179 }
1180 
1181 /*
1182 *_continue() :
1183     These decoding functions allow decompression of multiple blocks in "streaming" mode.
1184     Previously decoded blocks must still be available at the memory position where they were decoded.
1185     If it's not possible, save the relevant part of decoded data into a safe buffer,
1186     and indicate where it stands using LZ4_setStreamDecode()
1187 */
LZ4_decompress_safe_continue(LZ4_streamDecode_t * LZ4_streamDecode,const char * source,char * dest,int compressedSize,int maxOutputSize)1188 int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxOutputSize)
1189 {
1190     LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode;
1191     int result;
1192 
1193     if (lz4sd->prefixEnd == (BYTE*)dest)
1194     {
1195         result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize,
1196                                         endOnInputSize, full, 0,
1197                                         usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize);
1198         if (result <= 0) return result;
1199         lz4sd->prefixSize += result;
1200         lz4sd->prefixEnd  += result;
1201     }
1202     else
1203     {
1204         lz4sd->extDictSize = lz4sd->prefixSize;
1205         lz4sd->externalDict = lz4sd->prefixEnd - lz4sd->extDictSize;
1206         result = LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize,
1207                                         endOnInputSize, full, 0,
1208                                         usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize);
1209         if (result <= 0) return result;
1210         lz4sd->prefixSize = result;
1211         lz4sd->prefixEnd  = (BYTE*)dest + result;
1212     }
1213 
1214     return result;
1215 }
1216 
LZ4_decompress_fast_continue(LZ4_streamDecode_t * LZ4_streamDecode,const char * source,char * dest,int originalSize)1217 int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize)
1218 {
1219     LZ4_streamDecode_t_internal* lz4sd = (LZ4_streamDecode_t_internal*) LZ4_streamDecode;
1220     int result;
1221 
1222     if (lz4sd->prefixEnd == (BYTE*)dest)
1223     {
1224         result = LZ4_decompress_generic(source, dest, 0, originalSize,
1225                                         endOnOutputSize, full, 0,
1226                                         usingExtDict, lz4sd->prefixEnd - lz4sd->prefixSize, lz4sd->externalDict, lz4sd->extDictSize);
1227         if (result <= 0) return result;
1228         lz4sd->prefixSize += originalSize;
1229         lz4sd->prefixEnd  += originalSize;
1230     }
1231     else
1232     {
1233         lz4sd->extDictSize = lz4sd->prefixSize;
1234         lz4sd->externalDict = (BYTE*)dest - lz4sd->extDictSize;
1235         result = LZ4_decompress_generic(source, dest, 0, originalSize,
1236                                         endOnOutputSize, full, 0,
1237                                         usingExtDict, (BYTE*)dest, lz4sd->externalDict, lz4sd->extDictSize);
1238         if (result <= 0) return result;
1239         lz4sd->prefixSize = originalSize;
1240         lz4sd->prefixEnd  = (BYTE*)dest + originalSize;
1241     }
1242 
1243     return result;
1244 }
1245 
1246 
1247 /*
1248 Advanced decoding functions :
1249 *_usingDict() :
1250     These decoding functions work the same as "_continue" ones,
1251     the dictionary must be explicitly provided within parameters
1252 */
1253 
LZ4_decompress_usingDict_generic(const char * source,char * dest,int compressedSize,int maxOutputSize,int safe,const char * dictStart,int dictSize)1254 FORCE_INLINE int LZ4_decompress_usingDict_generic(const char* source, char* dest, int compressedSize, int maxOutputSize, int safe, const char* dictStart, int dictSize)
1255 {
1256     if (dictSize==0)
1257         return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest, NULL, 0);
1258     if (dictStart+dictSize == dest)
1259     {
1260         if (dictSize >= (int)(64 KB - 1))
1261             return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, withPrefix64k, (BYTE*)dest-64 KB, NULL, 0);
1262         return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, noDict, (BYTE*)dest-dictSize, NULL, 0);
1263     }
1264     return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, safe, full, 0, usingExtDict, (BYTE*)dest, (BYTE*)dictStart, dictSize);
1265 }
1266 
LZ4_decompress_safe_usingDict(const char * source,char * dest,int compressedSize,int maxOutputSize,const char * dictStart,int dictSize)1267 int LZ4_decompress_safe_usingDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize)
1268 {
1269     return LZ4_decompress_usingDict_generic(source, dest, compressedSize, maxOutputSize, 1, dictStart, dictSize);
1270 }
1271 
LZ4_decompress_fast_usingDict(const char * source,char * dest,int originalSize,const char * dictStart,int dictSize)1272 int LZ4_decompress_fast_usingDict(const char* source, char* dest, int originalSize, const char* dictStart, int dictSize)
1273 {
1274     return LZ4_decompress_usingDict_generic(source, dest, 0, originalSize, 0, dictStart, dictSize);
1275 }
1276 
1277 /* debug function */
LZ4_decompress_safe_forceExtDict(const char * source,char * dest,int compressedSize,int maxOutputSize,const char * dictStart,int dictSize)1278 int LZ4_decompress_safe_forceExtDict(const char* source, char* dest, int compressedSize, int maxOutputSize, const char* dictStart, int dictSize)
1279 {
1280     return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, usingExtDict, (BYTE*)dest, (BYTE*)dictStart, dictSize);
1281 }
1282 
1283 
1284 /***************************************************
1285     Obsolete Functions
1286 ***************************************************/
1287 /*
1288 These function names are deprecated and should no longer be used.
1289 They are only provided here for compatibility with older user programs.
1290 - LZ4_uncompress is totally equivalent to LZ4_decompress_fast
1291 - LZ4_uncompress_unknownOutputSize is totally equivalent to LZ4_decompress_safe
1292 */
LZ4_uncompress(const char * source,char * dest,int outputSize)1293 int LZ4_uncompress (const char* source, char* dest, int outputSize) { return LZ4_decompress_fast(source, dest, outputSize); }
LZ4_uncompress_unknownOutputSize(const char * source,char * dest,int isize,int maxOutputSize)1294 int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize) { return LZ4_decompress_safe(source, dest, isize, maxOutputSize); }
1295 
1296 
1297 /* Obsolete Streaming functions */
1298 
LZ4_sizeofStreamState()1299 int LZ4_sizeofStreamState() { return LZ4_STREAMSIZE; }
1300 
LZ4_init(LZ4_stream_t_internal * lz4ds,const BYTE * base)1301 static void LZ4_init(LZ4_stream_t_internal* lz4ds, const BYTE* base)
1302 {
1303     MEM_INIT(lz4ds, 0, LZ4_STREAMSIZE);
1304     lz4ds->bufferStart = base;
1305 }
1306 
LZ4_resetStreamState(void * state,const char * inputBuffer)1307 int LZ4_resetStreamState(void* state, const char* inputBuffer)
1308 {
1309     if ((((size_t)state) & 3) != 0) return 1;   /* Error : pointer is not aligned on 4-bytes boundary */
1310     LZ4_init((LZ4_stream_t_internal*)state, (const BYTE*)inputBuffer);
1311     return 0;
1312 }
1313 
LZ4_create(const char * inputBuffer)1314 void* LZ4_create (const char* inputBuffer)
1315 {
1316     void* lz4ds = ALLOCATOR(8, LZ4_STREAMSIZE_U64);
1317     LZ4_init ((LZ4_stream_t_internal*)lz4ds, (const BYTE*)inputBuffer);
1318     return lz4ds;
1319 }
1320 
LZ4_slideInputBuffer(void * LZ4_Data)1321 char* LZ4_slideInputBuffer (void* LZ4_Data)
1322 {
1323     LZ4_stream_t_internal* ctx = (LZ4_stream_t_internal*)LZ4_Data;
1324     int dictSize = LZ4_saveDict((LZ4_stream_t*)ctx, (char*)ctx->bufferStart, 64 KB);
1325     return (char*)(ctx->bufferStart + dictSize);
1326 }
1327 
1328 /*  Obsolete compresson functions using User-allocated state */
1329 
LZ4_sizeofState()1330 int LZ4_sizeofState() { return LZ4_STREAMSIZE; }
1331 
LZ4_compress_withState(void * state,const char * source,char * dest,int inputSize)1332 int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize)
1333 {
1334     if (((size_t)(state)&3) != 0) return 0;   /* Error : state is not aligned on 4-bytes boundary */
1335     MEM_INIT(state, 0, LZ4_STREAMSIZE);
1336 
1337     if (inputSize < LZ4_64Klimit)
1338         return LZ4_compress_generic(state, source, dest, inputSize, 0, notLimited, byU16, noDict, noDictIssue);
1339     else
1340         return LZ4_compress_generic(state, source, dest, inputSize, 0, notLimited, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue);
1341 }
1342 
LZ4_compress_limitedOutput_withState(void * state,const char * source,char * dest,int inputSize,int maxOutputSize)1343 int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize)
1344 {
1345     if (((size_t)(state)&3) != 0) return 0;   /* Error : state is not aligned on 4-bytes boundary */
1346     MEM_INIT(state, 0, LZ4_STREAMSIZE);
1347 
1348     if (inputSize < LZ4_64Klimit)
1349         return LZ4_compress_generic(state, source, dest, inputSize, maxOutputSize, limitedOutput, byU16, noDict, noDictIssue);
1350     else
1351         return LZ4_compress_generic(state, source, dest, inputSize, maxOutputSize, limitedOutput, LZ4_64bits() ? byU32 : byPtr, noDict, noDictIssue);
1352 }
1353 
1354 /* Obsolete streaming decompression functions */
1355 
LZ4_decompress_safe_withPrefix64k(const char * source,char * dest,int compressedSize,int maxOutputSize)1356 int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int compressedSize, int maxOutputSize)
1357 {
1358     return LZ4_decompress_generic(source, dest, compressedSize, maxOutputSize, endOnInputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB);
1359 }
1360 
LZ4_decompress_fast_withPrefix64k(const char * source,char * dest,int originalSize)1361 int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int originalSize)
1362 {
1363     return LZ4_decompress_generic(source, dest, 0, originalSize, endOnOutputSize, full, 0, withPrefix64k, (BYTE*)dest - 64 KB, NULL, 64 KB);
1364 }
1365 
1366 #endif   /* LZ4_COMMONDEFS_ONLY */
1367 
1368