summaryrefslogtreecommitdiffstats
path: root/lz4.c
diff options
context:
space:
mode:
Diffstat (limited to 'lz4.c')
-rw-r--r--lz4.c69
1 files changed, 33 insertions, 36 deletions
diff --git a/lz4.c b/lz4.c
index b2156cb..0ae0c7e 100644
--- a/lz4.c
+++ b/lz4.c
@@ -41,20 +41,13 @@
// Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache
#define MEMORY_USAGE 14
-// NOTCOMPRESSIBLE_CONFIRMATION :
+// NOTCOMPRESSIBLE_DETECTIONLEVEL :
// Decreasing this value will make the algorithm skip faster data segments considered "incompressible"
// This may decrease compression ratio dramatically, but will be faster on incompressible data
// Increasing this value will make the algorithm search more before declaring a segment "incompressible"
// This could improve compression a bit, but will be slower on incompressible data
// The default value (6) is recommended
-#define NOTCOMPRESSIBLE_CONFIRMATION 6
-
-// LZ4_COMPRESSMIN :
-// Compression function will *fail* if it is not successful at compressing input by at least LZ4_COMPRESSMIN bytes
-// Since the compression function stops working prematurely, it results in a speed gain
-// The output however is unusable. Compression function result will be zero.
-// Default : 0 = disabled
-#define LZ4_COMPRESSMIN 0
+#define NOTCOMPRESSIBLE_DETECTIONLEVEL 6
// BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE :
// This will provide a small boost to performance for big endian cpu, but the resulting compressed stream will be incompatible with little-endian CPU.
@@ -185,7 +178,7 @@ typedef struct _U64_S { U64 v; } U64_S;
#define HASHTABLESIZE (1 << HASH_LOG)
#define HASH_MASK (HASHTABLESIZE - 1)
-#define SKIPSTRENGTH (NOTCOMPRESSIBLE_CONFIRMATION>2?NOTCOMPRESSIBLE_CONFIRMATION:2)
+#define SKIPSTRENGTH (NOTCOMPRESSIBLE_DETECTIONLEVEL>2?NOTCOMPRESSIBLE_DETECTIONLEVEL:2)
#define STACKLIMIT 13
#define HEAPMODE (HASH_LOG>STACKLIMIT) // Defines if memory is allocated into the stack (local variable), or into the heap (malloc()).
#define COPYLENGTH 8
@@ -257,7 +250,7 @@ struct refTables
//****************************
#if LZ4_ARCH64
-inline static int LZ4_NbCommonBytes (register U64 val)
+inline int LZ4_NbCommonBytes (register U64 val)
{
#if defined(LZ4_BIG_ENDIAN)
#if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
@@ -289,7 +282,7 @@ inline static int LZ4_NbCommonBytes (register U64 val)
#else
-inline static int LZ4_NbCommonBytes (register U32 val)
+inline int LZ4_NbCommonBytes (register U32 val)
{
#if defined(LZ4_BIG_ENDIAN)
#if defined(_MSC_VER) && !defined(LZ4_FORCE_SW_BITCOUNT)
@@ -321,25 +314,16 @@ inline static int LZ4_NbCommonBytes (register U32 val)
#endif
-//****************************
-// Public functions
-//****************************
-
-int LZ4_compressBound(int isize)
-{
- return (isize + (isize/255) + 16);
-}
-
-
//******************************
// Compression functions
//******************************
-int LZ4_compressCtx(void** ctx,
+inline int LZ4_compressCtx(void** ctx,
const char* source,
char* dest,
- int isize)
+ int isize,
+ int maxOutputSize)
{
#if HEAPMODE
struct refTables *srt = (struct refTables *) (*ctx);
@@ -356,6 +340,7 @@ int LZ4_compressCtx(void** ctx,
#define matchlimit (iend - LASTLITERALS)
BYTE* op = (BYTE*) dest;
+ BYTE* const oend = op + maxOutputSize;
int len, length;
const int skipStrength = SKIPSTRENGTH;
@@ -410,6 +395,7 @@ int LZ4_compressCtx(void** ctx,
// Encode Literal length
length = ip - anchor;
token = op++;
+ if unlikely(op + length + (2 + 1 + LASTLITERALS) + (length>>8) >= oend) return 0; // Check output limit
if (length>=(int)RUN_MASK) { *token=(RUN_MASK<<ML_BITS); len = length-RUN_MASK; for(; len > 254 ; len-=255) *op++ = 255; *op++ = (BYTE)len; }
else *token = (length<<ML_BITS);
@@ -460,7 +446,7 @@ _last_literals:
// Encode Last Literals
{
int lastRun = iend - anchor;
- if ((LZ4_COMPRESSMIN>0) && (((op - (BYTE*)dest) + lastRun + 1 + ((lastRun-15)/255)) > isize - LZ4_COMPRESSMIN)) return 0;
+ if (op + lastRun + 1 + ((lastRun-15)/255) >= oend) return 0;
if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; }
else *op++ = (lastRun<<ML_BITS);
memcpy(op, anchor, iend - anchor);
@@ -479,10 +465,11 @@ _last_literals:
#define HASH64KTABLESIZE (1U<<HASHLOG64K)
#define LZ4_HASH64K_FUNCTION(i) (((i) * 2654435761U) >> ((MINMATCH*8)-HASHLOG64K))
#define LZ4_HASH64K_VALUE(p) LZ4_HASH64K_FUNCTION(A32(p))
-int LZ4_compress64kCtx(void** ctx,
+inline int LZ4_compress64kCtx(void** ctx,
const char* source,
char* dest,
- int isize)
+ int isize,
+ int maxOutputSize)
{
#if HEAPMODE
struct refTables *srt = (struct refTables *) (*ctx);
@@ -499,6 +486,7 @@ int LZ4_compress64kCtx(void** ctx,
#define matchlimit (iend - LASTLITERALS)
BYTE* op = (BYTE*) dest;
+ BYTE* const oend = op + maxOutputSize;
int len, length;
const int skipStrength = SKIPSTRENGTH;
@@ -552,6 +540,7 @@ int LZ4_compress64kCtx(void** ctx,
// Encode Literal length
length = ip - anchor;
token = op++;
+ if unlikely(op + length + (2 + 1 + LASTLITERALS) + (length>>8) >= oend) return 0; // Check output limit
if (length>=(int)RUN_MASK) { *token=(RUN_MASK<<ML_BITS); len = length-RUN_MASK; for(; len > 254 ; len-=255) *op++ = 255; *op++ = (BYTE)len; }
else *token = (length<<ML_BITS);
@@ -602,7 +591,7 @@ _last_literals:
// Encode Last Literals
{
int lastRun = iend - anchor;
- if ((LZ4_COMPRESSMIN>0) && (((op - (BYTE*)dest) + lastRun + 1 + ((lastRun-15)/255)) > isize - LZ4_COMPRESSMIN)) return 0;
+ if (op + lastRun + 1 + ((lastRun-15)/255) >= oend) return 0;
if (lastRun>=(int)RUN_MASK) { *op++=(RUN_MASK<<ML_BITS); lastRun-=RUN_MASK; for(; lastRun > 254 ; lastRun-=255) *op++ = 255; *op++ = (BYTE) lastRun; }
else *op++ = (lastRun<<ML_BITS);
memcpy(op, anchor, iend - anchor);
@@ -614,26 +603,34 @@ _last_literals:
}
-
-int LZ4_compress(const char* source,
- char* dest,
- int isize)
+int LZ4_compress_limitedOutput(const char* source,
+ char* dest,
+ int isize,
+ int maxOutputSize)
{
#if HEAPMODE
void* ctx = malloc(sizeof(struct refTables));
int result;
if (isize < LZ4_64KLIMIT)
- result = LZ4_compress64kCtx(&ctx, source, dest, isize);
- else result = LZ4_compressCtx(&ctx, source, dest, isize);
+ result = LZ4_compress64kCtx(&ctx, source, dest, isize, maxOutputSize);
+ else result = LZ4_compressCtx(&ctx, source, dest, isize, maxOutputSize);
free(ctx);
return result;
#else
- if (isize < (int)LZ4_64KLIMIT) return LZ4_compress64kCtx(NULL, source, dest, isize);
- return LZ4_compressCtx(NULL, source, dest, isize);
+ if (isize < (int)LZ4_64KLIMIT) return LZ4_compress64kCtx(NULL, source, dest, isize, maxOutputSize);
+ return LZ4_compressCtx(NULL, source, dest, isize, maxOutputSize);
#endif
}
+int LZ4_compress(const char* source,
+ char* dest,
+ int isize)
+{
+ return LZ4_compress_limitedOutput(source, dest, isize, LZ4_compressBound(isize));
+}
+
+
//****************************