summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/lz4frame.c75
-rw-r--r--lib/lz4frame_static.h2
-rw-r--r--programs/lz4io.c2
-rw-r--r--tests/framebench.c2
-rw-r--r--tests/frametest.c19
5 files changed, 69 insertions, 31 deletions
diff --git a/lib/lz4frame.c b/lib/lz4frame.c
index 9ff7766..e77fd35 100644
--- a/lib/lz4frame.c
+++ b/lib/lz4frame.c
@@ -47,6 +47,19 @@ You can contact the author at :
/*-************************************
+* Tuning parameters
+**************************************/
+/*
+ * LZ4_HEAPMODE :
+ * Select how default compression functions will allocate memory for their hash table,
+ * in memory stack (0:default, fastest), or in memory heap (1:requires malloc()).
+ */
+#ifndef LZ4_HEAPMODE
+# define LZ4_HEAPMODE 0
+#endif
+
+
+/*-************************************
* Memory routines
**************************************/
#include <stdlib.h> /* malloc, calloc, free */
@@ -332,23 +345,18 @@ size_t LZ4F_compressFrameBound(size_t srcSize, const LZ4F_preferences_t* prefere
* @return : number of bytes written into dstBuffer,
* or an error code if it fails (can be tested using LZ4F_isError())
*/
-size_t LZ4F_compressFrame_usingCDict(void* dstBuffer, size_t dstCapacity,
+size_t LZ4F_compressFrame_usingCDict(LZ4F_cctx* cctx,
+ void* dstBuffer, size_t dstCapacity,
const void* srcBuffer, size_t srcSize,
const LZ4F_CDict* cdict,
const LZ4F_preferences_t* preferencesPtr)
{
- LZ4F_cctx_t cctxI;
- LZ4_stream_t lz4ctx; /* pretty large on stack */
LZ4F_preferences_t prefs;
LZ4F_compressOptions_t options;
BYTE* const dstStart = (BYTE*) dstBuffer;
BYTE* dstPtr = dstStart;
BYTE* const dstEnd = dstStart + dstCapacity;
- memset(&cctxI, 0, sizeof(cctxI));
- cctxI.version = LZ4F_VERSION;
- cctxI.maxBufferSize = 5 MB; /* mess with real buffer size to prevent dynamic allocation; works only because autoflush==1 & stableSrc==1 */
-
if (preferencesPtr!=NULL)
prefs = *preferencesPtr;
else
@@ -361,33 +369,24 @@ size_t LZ4F_compressFrame_usingCDict(void* dstBuffer, size_t dstCapacity,
if (srcSize <= LZ4F_getBlockSize(prefs.frameInfo.blockSizeID))
prefs.frameInfo.blockMode = LZ4F_blockIndependent; /* only one block => no need for inter-block link */
- if (prefs.compressionLevel < LZ4HC_CLEVEL_MIN) {
- LZ4_resetStream(&lz4ctx);
- cctxI.lz4CtxPtr = &lz4ctx;
- cctxI.lz4CtxLevel = 2;
- } /* fast compression context pre-created on stack */
-
memset(&options, 0, sizeof(options));
options.stableSrc = 1;
if (dstCapacity < LZ4F_compressFrameBound(srcSize, &prefs)) /* condition to guarantee success */
return err0r(LZ4F_ERROR_dstMaxSize_tooSmall);
- { size_t const headerSize = LZ4F_compressBegin_usingCDict(&cctxI, dstBuffer, dstCapacity, cdict, &prefs); /* write header */
+ { size_t const headerSize = LZ4F_compressBegin_usingCDict(cctx, dstBuffer, dstCapacity, cdict, &prefs); /* write header */
if (LZ4F_isError(headerSize)) return headerSize;
dstPtr += headerSize; /* header size */ }
- { size_t const cSize = LZ4F_compressUpdate(&cctxI, dstPtr, dstEnd-dstPtr, srcBuffer, srcSize, &options);
+ { size_t const cSize = LZ4F_compressUpdate(cctx, dstPtr, dstEnd-dstPtr, srcBuffer, srcSize, &options);
if (LZ4F_isError(cSize)) return cSize;
dstPtr += cSize; }
- { size_t const tailSize = LZ4F_compressEnd(&cctxI, dstPtr, dstEnd-dstPtr, &options); /* flush last block, and generate suffix */
+ { size_t const tailSize = LZ4F_compressEnd(cctx, dstPtr, dstEnd-dstPtr, &options); /* flush last block, and generate suffix */
if (LZ4F_isError(tailSize)) return tailSize;
dstPtr += tailSize; }
- if (prefs.compressionLevel >= LZ4HC_CLEVEL_MIN) /* Ctx allocation only for lz4hc */
- FREEMEM(cctxI.lz4CtxPtr);
-
return (dstPtr - dstStart);
}
@@ -403,9 +402,41 @@ size_t LZ4F_compressFrame(void* dstBuffer, size_t dstCapacity,
const void* srcBuffer, size_t srcSize,
const LZ4F_preferences_t* preferencesPtr)
{
- return LZ4F_compressFrame_usingCDict(dstBuffer, dstCapacity,
- srcBuffer, srcSize,
- NULL, preferencesPtr);
+ size_t result;
+#if (LZ4_HEAPMODE)
+ LZ4F_cctx_t *cctxPtr;
+ LZ4F_createCompressionContext(&cctxPtr, LZ4F_VERSION);
+#else
+ LZ4F_cctx_t cctx;
+ LZ4_stream_t lz4ctx;
+ LZ4F_cctx_t *cctxPtr = &cctx;
+
+ MEM_INIT(&cctx, 0, sizeof(cctx));
+ cctx.version = LZ4F_VERSION;
+ cctx.maxBufferSize = 5 MB; /* mess with real buffer size to prevent dynamic allocation; works only because autoflush==1 & stableSrc==1 */
+ if (preferencesPtr == NULL ||
+ preferencesPtr->compressionLevel < LZ4HC_CLEVEL_MIN
+ ) {
+ LZ4_resetStream(&lz4ctx);
+ cctxPtr->lz4CtxPtr = &lz4ctx;
+ cctxPtr->lz4CtxLevel = 2;
+ }
+#endif
+
+ result = LZ4F_compressFrame_usingCDict(cctxPtr, dstBuffer, dstCapacity,
+ srcBuffer, srcSize,
+ NULL, preferencesPtr);
+
+#if (LZ4_HEAPMODE)
+ LZ4F_freeCompressionContext(cctxPtr);
+#else
+ if (preferencesPtr != NULL &&
+ preferencesPtr->compressionLevel >= LZ4HC_CLEVEL_MIN
+ ) {
+ FREEMEM(cctxPtr->lz4CtxPtr);
+ }
+#endif
+ return result;
}
diff --git a/lib/lz4frame_static.h b/lib/lz4frame_static.h
index a59b94b..be587e6 100644
--- a/lib/lz4frame_static.h
+++ b/lib/lz4frame_static.h
@@ -107,6 +107,7 @@ LZ4FLIB_STATIC_API void LZ4F_freeCDict(LZ4F_CDict* CDict);
/*! LZ4_compressFrame_usingCDict() :
* Compress an entire srcBuffer into a valid LZ4 frame using a digested Dictionary.
+ * cctx must point to a context created by LZ4F_createCompressionContext().
* If cdict==NULL, compress without a dictionary.
* dstBuffer MUST be >= LZ4F_compressFrameBound(srcSize, preferencesPtr).
* If this condition is not respected, function will fail (@return an errorCode).
@@ -115,6 +116,7 @@ LZ4FLIB_STATIC_API void LZ4F_freeCDict(LZ4F_CDict* CDict);
* @return : number of bytes written into dstBuffer.
* or an error code if it fails (can be tested using LZ4F_isError()) */
LZ4FLIB_STATIC_API size_t LZ4F_compressFrame_usingCDict(
+ LZ4F_cctx* cctx,
void* dst, size_t dstCapacity,
const void* src, size_t srcSize,
const LZ4F_CDict* cdict,
diff --git a/programs/lz4io.c b/programs/lz4io.c
index c712fe1..ca13316 100644
--- a/programs/lz4io.c
+++ b/programs/lz4io.c
@@ -560,7 +560,7 @@ static int LZ4IO_compressFilename_extRess(cRess_t ress, const char* srcFileName,
/* single-block file */
if (readSize < blockSize) {
/* Compress in single pass */
- size_t cSize = LZ4F_compressFrame_usingCDict(dstBuffer, dstBufferSize, srcBuffer, readSize, ress.cdict, &prefs);
+ size_t cSize = LZ4F_compressFrame_usingCDict(ctx, dstBuffer, dstBufferSize, srcBuffer, readSize, ress.cdict, &prefs);
if (LZ4F_isError(cSize)) EXM_THROW(31, "Compression failed : %s", LZ4F_getErrorName(cSize));
compressedfilesize = cSize;
DISPLAYUPDATE(2, "\rRead : %u MB ==> %.2f%% ",
diff --git a/tests/framebench.c b/tests/framebench.c
index 21c3704..a7a270b 100644
--- a/tests/framebench.c
+++ b/tests/framebench.c
@@ -30,6 +30,7 @@ typedef struct {
size_t compress_frame(bench_params_t *p) {
size_t iter = p->iter;
+ LZ4F_cctx *cctx = p->cctx;
char *obuf = p->obuf;
size_t osize = p->osize;
const char* ibuf = p->ibuf;
@@ -43,6 +44,7 @@ size_t compress_frame(bench_params_t *p) {
prefs->frameInfo.contentSize = isize;
oused = LZ4F_compressFrame_usingCDict(
+ cctx,
obuf,
osize,
ibuf + ((iter * 2654435761U) % num_ibuf) * isize,
diff --git a/tests/frametest.c b/tests/frametest.c
index 986a16d..74d9c88 100644
--- a/tests/frametest.c
+++ b/tests/frametest.c
@@ -164,7 +164,7 @@ static unsigned FUZ_highbit(U32 v32)
/*-*******************************************************
* Tests
*********************************************************/
-#define CHECK_V(v,f) v = f; if (LZ4F_isError(v)) goto _output_error
+#define CHECK_V(v,f) v = f; if (LZ4F_isError(v)) { fprintf(stderr, "%s\n", LZ4F_getErrorName(v)); goto _output_error; }
#define CHECK(f) { LZ4F_errorCode_t const CHECK_V(err_ , f); }
int basicTests(U32 seed, double compressibility)
@@ -509,23 +509,25 @@ int basicTests(U32 seed, double compressibility)
CHECK( LZ4F_freeCompressionContext(cctx) ); cctx = NULL;
}
-
/* Dictionary compression test */
{ size_t const dictSize = 63 KB;
size_t const dstCapacity = LZ4F_compressFrameBound(dictSize, NULL);
size_t cSizeNoDict, cSizeWithDict;
LZ4F_CDict* const cdict = LZ4F_createCDict(CNBuffer, dictSize);
if (cdict == NULL) goto _output_error;
+ CHECK( LZ4F_createCompressionContext(&cctx, LZ4F_VERSION) );
DISPLAYLEVEL(3, "LZ4F_compressFrame_usingCDict, with NULL dict : ");
CHECK_V(cSizeNoDict,
- LZ4F_compressFrame_usingCDict(compressedBuffer, dstCapacity,
+ LZ4F_compressFrame_usingCDict(cctx, compressedBuffer, dstCapacity,
CNBuffer, dictSize,
NULL, NULL) );
DISPLAYLEVEL(3, "%u bytes \n", (unsigned)cSizeNoDict);
+ CHECK( LZ4F_freeCompressionContext(cctx) );
+ CHECK( LZ4F_createCompressionContext(&cctx, LZ4F_VERSION) );
DISPLAYLEVEL(3, "LZ4F_compressFrame_usingCDict, with dict : ");
CHECK_V(cSizeWithDict,
- LZ4F_compressFrame_usingCDict(compressedBuffer, dstCapacity,
+ LZ4F_compressFrame_usingCDict(cctx, compressedBuffer, dstCapacity,
CNBuffer, dictSize,
cdict, NULL) );
DISPLAYLEVEL(3, "compressed %u bytes into %u bytes \n",
@@ -557,7 +559,7 @@ int basicTests(U32 seed, double compressibility)
memset(&cParams, 0, sizeof(cParams));
cParams.compressionLevel = -3;
CHECK_V(cSizeLevelMax,
- LZ4F_compressFrame_usingCDict(compressedBuffer, dstCapacity,
+ LZ4F_compressFrame_usingCDict(cctx, compressedBuffer, dstCapacity,
CNBuffer, dictSize,
cdict, &cParams) );
DISPLAYLEVEL(3, "%u bytes \n", (unsigned)cSizeLevelMax);
@@ -569,7 +571,7 @@ int basicTests(U32 seed, double compressibility)
memset(&cParams, 0, sizeof(cParams));
cParams.compressionLevel = LZ4F_compressionLevel_max();
CHECK_V(cSizeLevelMax,
- LZ4F_compressFrame_usingCDict(compressedBuffer, dstCapacity,
+ LZ4F_compressFrame_usingCDict(cctx, compressedBuffer, dstCapacity,
CNBuffer, dictSize,
cdict, &cParams) );
DISPLAYLEVEL(3, "%u bytes \n", (unsigned)cSizeLevelMax);
@@ -584,7 +586,7 @@ int basicTests(U32 seed, double compressibility)
cParams.frameInfo.blockMode = LZ4F_blockLinked;
cParams.frameInfo.blockSizeID = LZ4F_max64KB;
CHECK_V(cSizeContiguous,
- LZ4F_compressFrame_usingCDict(compressedBuffer, outCapacity,
+ LZ4F_compressFrame_usingCDict(cctx, compressedBuffer, outCapacity,
CNBuffer, inSize,
cdict, &cParams) );
DISPLAYLEVEL(3, "compressed %u bytes into %u bytes \n",
@@ -620,7 +622,7 @@ int basicTests(U32 seed, double compressibility)
cParams.frameInfo.blockMode = LZ4F_blockIndependent;
cParams.frameInfo.blockSizeID = LZ4F_max64KB;
CHECK_V(cSizeIndep,
- LZ4F_compressFrame_usingCDict(compressedBuffer, outCapacity,
+ LZ4F_compressFrame_usingCDict(cctx, compressedBuffer, outCapacity,
CNBuffer, inSize,
cdict, &cParams) );
DISPLAYLEVEL(3, "compressed %u bytes into %u bytes \n",
@@ -647,6 +649,7 @@ int basicTests(U32 seed, double compressibility)
}
LZ4F_freeCDict(cdict);
+ CHECK( LZ4F_freeCompressionContext(cctx) ); cctx = NULL;
}