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