diff options
author | yann.collet.73@gmail.com <yann.collet.73@gmail.com@650e7d94-2a16-8b24-b05c-7c0b3f6821cd> | 2012-07-28 13:32:30 (GMT) |
---|---|---|
committer | yann.collet.73@gmail.com <yann.collet.73@gmail.com@650e7d94-2a16-8b24-b05c-7c0b3f6821cd> | 2012-07-28 13:32:30 (GMT) |
commit | 84004b90159468e4d4984fcd6ee1dbb5ea53c982 (patch) | |
tree | 6417fbde6862175811e3db54c97c1a0d1bbed3d9 | |
parent | cfbace25d7bb8bbc25ab29e0c308e61a529dfc70 (diff) | |
download | lz4-84004b90159468e4d4984fcd6ee1dbb5ea53c982.zip lz4-84004b90159468e4d4984fcd6ee1dbb5ea53c982.tar.gz lz4-84004b90159468e4d4984fcd6ee1dbb5ea53c982.tar.bz2 |
Added : function LZ4_compress_limitedOutput()
Removed : functions with explicit *ctx management (LZ4_compressCtx & LZ4_compress64kCtx). Functions are still present in the .c
Changed : LZ4_compressBound() now a macro
git-svn-id: https://lz4.googlecode.com/svn/trunk@71 650e7d94-2a16-8b24-b05c-7c0b3f6821cd
-rw-r--r-- | lz4.c | 69 | ||||
-rw-r--r-- | lz4.h | 51 |
2 files changed, 57 insertions, 63 deletions
@@ -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));
+}
+
+
//****************************
@@ -47,19 +47,22 @@ int LZ4_uncompress (const char* source, char* dest, int osize); /*
LZ4_compress() :
+ Compresses 'isize' bytes from 'source' into 'dest'.
+ Destination buffer must be already allocated,
+ and must be sized to handle worst cases situations (input data not compressible)
+ Worst case size evaluation is provided by macro LZ4_compressBound()
+
isize : is the input size. Max supported value is ~1.9GB
return : the number of bytes written in buffer dest
- or 0 if the compression fails (if LZ4_COMPRESSMIN is set)
- note : destination buffer must be already allocated.
- destination buffer must be sized to handle worst cases situations (input data not compressible)
- worst case size evaluation is provided by function LZ4_compressBound()
+
LZ4_uncompress() :
osize : is the output size, therefore the original size
return : the number of bytes read in the source buffer
If the source stream is malformed, the function will stop decoding and return a negative result, indicating the byte position of the faulty instruction
This function never writes beyond dest + osize, and is therefore protected against malicious data packets
- note : destination buffer must be already allocated
+ note : destination buffer must be already allocated.
+ its size must be a minimum of 'osize' bytes.
*/
@@ -67,7 +70,7 @@ LZ4_uncompress() : // Advanced Functions
//****************************
-int LZ4_compressBound(int isize);
+#define LZ4_compressBound(isize) (isize + (isize/255) + 16)
/*
LZ4_compressBound() :
@@ -80,6 +83,21 @@ LZ4_compressBound() : */
+int LZ4_compress_limitedOutput (const char* source, char* dest, int isize, int maxOutputSize);
+
+/*
+LZ4_compress_limitedOutput() :
+ Compress 'isize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'.
+ If it cannot achieve it, compression will stop, and result of the function will be zero.
+ This function never writes outside of provided output buffer.
+
+ isize : is the input size. Max supported value is ~1.9GB
+ maxOutputSize : is the size of the destination buffer (which must be already allocated)
+ return : the number of bytes written in buffer dest
+ or 0 if the compression fails
+*/
+
+
int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize);
/*
@@ -94,27 +112,6 @@ LZ4_uncompress_unknownOutputSize() : */
-int LZ4_compressCtx(void** ctx, const char* source, char* dest, int isize);
-int LZ4_compress64kCtx(void** ctx, const char* source, char* dest, int isize);
-
-/*
-LZ4_compressCtx() :
- This function explicitly handles the CTX memory structure.
- It avoids allocating/deallocating memory between each call, improving performance when malloc is heavily invoked.
- This function is only useful when memory is allocated into the heap (HASH_LOG value beyond STACK_LIMIT)
- Performance difference will be noticeable only when repetitively calling the compression function over many small segments.
- Note : by default, memory is allocated into the stack, therefore "malloc" is not invoked.
-LZ4_compress64kCtx() :
- Same as LZ4_compressCtx(), but specific to small inputs (<64KB).
- isize *Must* be <64KB, otherwise the output will be corrupted.
-
- On first call : provide a *ctx=NULL; It will be automatically allocated.
- On next calls : reuse the same ctx pointer.
- Use different pointers for different threads when doing multi-threading.
-
-*/
-
-
#if defined (__cplusplus)
}
#endif
|