API change : compressionContext more easily reusable
authorYann Collet <yann.collet.73@gmail.com>
Sun, 7 Sep 2014 11:57:09 +0000 (12:57 +0100)
committerYann Collet <yann.collet.73@gmail.com>
Sun, 7 Sep 2014 11:57:09 +0000 (12:57 +0100)
lz4frame.c
lz4frame.h
programs/frametest.c

index 19b228c..eaa8408 100644 (file)
@@ -117,6 +117,7 @@ typedef struct {
        unsigned version;
        unsigned cStage;
        size_t maxBlockSize;
+       size_t maxBufferSize;
        XXH32_stateSpace_t xxh;
        BYTE* tmpIn;
        size_t tmpInSize;
@@ -254,10 +255,10 @@ size_t LZ4F_compressFrame(void* dstBuffer, size_t dstMaxSize, const void* srcBuf
        if (dstMaxSize < LZ4F_compressFrameBound(srcSize, frameInfoPtr))
                return -ERROR_dstMaxSize_tooSmall;
 
-       errorCode = LZ4F_createCompressionContext(&cctx, LZ4F_VERSION, preferencesPtr);
+       errorCode = LZ4F_createCompressionContext(&cctx, LZ4F_VERSION);
        if (LZ4F_isError(errorCode)) return errorCode;
 
-       errorCode = LZ4F_compressBegin(cctx, dstBuffer, dstMaxSize);  /* write header */
+       errorCode = LZ4F_compressBegin(cctx, dstBuffer, dstMaxSize, preferencesPtr);  /* write header */
        if (LZ4F_isError(errorCode)) return errorCode;
        dstPtr += errorCode;   /* header size */
 
@@ -297,30 +298,19 @@ size_t LZ4F_compressFrame(void* dstBuffer, size_t dstMaxSize, const void* srcBuf
  * The first thing to do is to create a compressionContext object, which will be used in all compression operations.
  * This is achieved using LZ4F_createCompressionContext(), which takes as argument a version and an LZ4F_preferences_t structure.
  * The version provided MUST be LZ4F_VERSION. It is intended to track potential version differences between different binaries.
- * The LZ4F_preferences_t structure is optional : you can provide NULL as argument, all preferences will then be set to default.
- * The function will provide a pointer to a fully allocated LZ4F_compressionContext_t object.
- * If the result LZ4F_errorCode_t is not zero, there was an error during context creation.
+ * The function will provide a pointer to an allocated LZ4F_compressionContext_t object.
+ * If the result LZ4F_errorCode_t is not OK_NoError, there was an error during context creation.
  * Object can release its memory using LZ4F_freeCompressionContext();
  */
-LZ4F_errorCode_t LZ4F_createCompressionContext(LZ4F_compressionContext_t* LZ4F_compressionContextPtr, int version, const LZ4F_preferences_t* preferencesPtr)
+LZ4F_errorCode_t LZ4F_createCompressionContext(LZ4F_compressionContext_t* LZ4F_compressionContextPtr, unsigned version)
 {
-       const LZ4F_preferences_t prefNull = { 0 };
        LZ4F_cctx_internal_t* cctxPtr;
 
-       if (preferencesPtr == NULL) preferencesPtr = &prefNull;
-
        cctxPtr = ALLOCATOR(sizeof(LZ4F_cctx_internal_t));
        if (cctxPtr==NULL) return -ERROR_allocation_failed;
 
-       cctxPtr->prefs = *preferencesPtr;   /* equivalent to memcpy() */
        cctxPtr->version = version;
        cctxPtr->cStage = 0;   /* Next stage : write header */
-       if (cctxPtr->prefs.frameInfo.blockSizeID == 0) cctxPtr->prefs.frameInfo.blockSizeID = LZ4F_BLOCKSIZEID_DEFAULT;
-       cctxPtr->maxBlockSize = LZ4F_getBlockSize(cctxPtr->prefs.frameInfo.blockSizeID);
-       cctxPtr->tmpIn = ALLOCATOR(cctxPtr->maxBlockSize);
-       if (cctxPtr->tmpIn == NULL) return -ERROR_allocation_failed;
-       cctxPtr->tmpInSize = 0;
-       XXH32_resetState(&(cctxPtr->xxh), 0);
 
        *LZ4F_compressionContextPtr = (LZ4F_compressionContext_t)cctxPtr;
 
@@ -345,8 +335,9 @@ LZ4F_errorCode_t LZ4F_freeCompressionContext(LZ4F_compressionContext_t LZ4F_comp
  * The result of the function is the number of bytes written into dstBuffer for the header
  * or an error code (can be tested using LZ4F_isError())
  */
-size_t LZ4F_compressBegin(LZ4F_compressionContext_t compressionContext, void* dstBuffer, size_t dstMaxSize)
+size_t LZ4F_compressBegin(LZ4F_compressionContext_t compressionContext, void* dstBuffer, size_t dstMaxSize, const LZ4F_preferences_t* preferencesPtr)
 {
+    LZ4F_preferences_t prefNull = { 0 };
        LZ4F_cctx_internal_t* cctxPtr = (LZ4F_cctx_internal_t*)compressionContext;
        BYTE* const dstStart = (BYTE*)dstBuffer;
        BYTE* dstPtr = dstStart;
@@ -354,6 +345,20 @@ size_t LZ4F_compressBegin(LZ4F_compressionContext_t compressionContext, void* ds
 
        if (dstMaxSize < LZ4F_MAXHEADERFRAME_SIZE) return -ERROR_dstMaxSize_tooSmall;
        if (cctxPtr->cStage != 0) return -ERROR_GENERIC;
+       if (preferencesPtr == NULL) preferencesPtr = &prefNull;
+
+       /* Buffer Management */
+       cctxPtr->prefs = *preferencesPtr;
+       if (cctxPtr->prefs.frameInfo.blockSizeID == 0) cctxPtr->prefs.frameInfo.blockSizeID = LZ4F_BLOCKSIZEID_DEFAULT;
+       cctxPtr->maxBlockSize = LZ4F_getBlockSize(cctxPtr->prefs.frameInfo.blockSizeID);
+       if (cctxPtr->maxBufferSize < cctxPtr->maxBlockSize)
+    {
+        cctxPtr->maxBufferSize = cctxPtr->maxBlockSize;
+        cctxPtr->tmpIn = ALLOCATOR(cctxPtr->maxBlockSize);
+        if (cctxPtr->tmpIn == NULL) return -ERROR_allocation_failed;
+    }
+    cctxPtr->tmpInSize = 0;
+       XXH32_resetState(&(cctxPtr->xxh), 0);
 
        /* Magic Number */
        LZ4F_writeLE32(dstPtr, LZ4F_MAGICNUMBER);
index b4a067e..179271a 100644 (file)
@@ -124,13 +124,12 @@ typedef struct {
 /* Resource Management */
 
 #define LZ4F_VERSION 100
-LZ4F_errorCode_t LZ4F_createCompressionContext(LZ4F_compressionContext_t* LZ4F_compressionContextPtr, int version, const LZ4F_preferences_t* preferencesPtr);
+LZ4F_errorCode_t LZ4F_createCompressionContext(LZ4F_compressionContext_t* LZ4F_compressionContextPtr, unsigned version);
 LZ4F_errorCode_t LZ4F_freeCompressionContext(LZ4F_compressionContext_t LZ4F_compressionContext);
 /* LZ4F_createCompressionContext() :
  * The first thing to do is to create a compressionContext object, which will be used in all compression operations.
  * This is achieved using LZ4F_createCompressionContext(), which takes as argument a version and an LZ4F_preferences_t structure.
  * The version provided MUST be LZ4F_VERSION. It is intended to track potential version differences between different binaries.
- * The LZ4F_preferences_t structure is optional : you can provide NULL as argument, all preferences will then be set to default.
  * The function will provide a pointer to a fully allocated LZ4F_compressionContext_t object.
  * If the result LZ4F_errorCode_t is not zero, there was an error during context creation.
  * Object can release its memory using LZ4F_freeCompressionContext();
@@ -139,10 +138,11 @@ LZ4F_errorCode_t LZ4F_freeCompressionContext(LZ4F_compressionContext_t LZ4F_comp
 
 /* Compression */
 
-size_t LZ4F_compressBegin(LZ4F_compressionContext_t compressionContext, void* dstBuffer, size_t dstMaxSize);
+size_t LZ4F_compressBegin(LZ4F_compressionContext_t compressionContext, void* dstBuffer, size_t dstMaxSize, const LZ4F_preferences_t* preferencesPtr);
 /* LZ4F_compressBegin() :
  * will write the frame header into dstBuffer.
- * dstBuffer must be large enough to accomodate a header (dstMaxSize). Maximum header size is 19 bytes.
+ * dstBuffer must be large enough to accommodate a header (dstMaxSize). Maximum header size is 19 bytes.
+ * The LZ4F_preferences_t structure is optional : you can provide NULL as argument, all preferences will then be set to default.
  * The result of the function is the number of bytes written into dstBuffer for the header
  * or an error code (can be tested using LZ4F_isError())
  */
@@ -163,7 +163,7 @@ size_t LZ4F_compress(LZ4F_compressionContext_t compressionContext, void* dstBuff
  * Conversely, given a fixed dstMaxSize value, you can know the maximum srcSize authorized using LZ4F_getMaxSrcSize()
  * If this condition is not respected, LZ4F_compress() will fail (result is an errorCode)
  * The LZ4F_compressOptions_t structure is optional : you can provide NULL as argument.
- * The result of the function is the number of bytes written into dstBuffer (it can be zero, meaning input data is just stored within compressionContext for a future block to complete)
+ * The result of the function is the number of bytes written into dstBuffer : it can be zero, meaning input data was just stored within compressionContext
  * The function outputs an error code if it fails (can be tested using LZ4F_isError())
  */
 
@@ -171,10 +171,10 @@ size_t LZ4F_flush(LZ4F_compressionContext_t compressionContext, void* dstBuffer,
 /* LZ4F_flush()
  * Should you need to create compressed data immediately, without waiting for a block to be filled,
  * you can call LZ4_flush(), which will immediately compress any remaining data stored within compressionContext.
+ * The LZ4F_compressOptions_t structure is optional : you can provide NULL as argument.
  * The result of the function is the number of bytes written into dstBuffer
  * (it can be zero, this means there was no data left within compressionContext)
  * The function outputs an error code if it fails (can be tested using LZ4F_isError())
- * The LZ4F_compressOptions_t structure is optional : you can provide NULL as argument.
  */
 
 size_t LZ4F_compressEnd(LZ4F_compressionContext_t compressionContext, void* dstBuffer, size_t dstMaxSize, const LZ4F_compressOptions_t* compressOptionsPtr);
@@ -202,7 +202,7 @@ typedef struct {
 
 /* Resource management */
 
-LZ4F_errorCode_t LZ4F_createDecompressionContext(LZ4F_compressionContext_t* LZ4F_decompressionContextPtr, unsigned versionNumber);
+LZ4F_errorCode_t LZ4F_createDecompressionContext(LZ4F_compressionContext_t* LZ4F_decompressionContextPtr, unsigned version);
 LZ4F_errorCode_t LZ4F_freeDecompressionContext(LZ4F_compressionContext_t LZ4F_decompressionContext);
 /* LZ4F_createDecompressionContext() :
  * The first thing to do is to create a decompressionContext object, which will be used in all decompression operations.
index 6807f4c..c33e1ac 100644 (file)
@@ -363,20 +363,27 @@ int fuzzerTests(U32 seed, unsigned nbTests, unsigned startTest, double compressi
 {
        unsigned testResult = 0;
        unsigned testNb = 0;
-       void* srcBuffer;
-       void* compressedBuffer;
-       void* decodedBuffer;
+       void* srcBuffer = NULL;
+       void* compressedBuffer = NULL;
+       void* decodedBuffer = NULL;
        U32 coreRand = seed;
        LZ4F_decompressionContext_t dCtx;
+       LZ4F_compressionContext_t cCtx;
+    size_t result;
 #   define CHECK(cond, ...) if (cond) { DISPLAY("Error => "); DISPLAY(__VA_ARGS__); \
                             DISPLAY(" (seed %u, test nb %i)  \n", seed, testNb); goto _output_error; }
 
-       (void)startTest;
-       // Create compressible test buffer
-       LZ4F_createDecompressionContext(&dCtx, LZ4F_VERSION);
+       // Create buffers
+       result = LZ4F_createDecompressionContext(&dCtx, LZ4F_VERSION);
+    CHECK(LZ4F_isError(result), "Allocation failed (error %i)", (int)result);
+       result = LZ4F_createCompressionContext(&cCtx, LZ4F_VERSION);
+    CHECK(LZ4F_isError(result), "Allocation failed (error %i)", (int)result);
        srcBuffer = malloc(srcDataLength);
+    CHECK(srcBuffer==NULL, "srcBuffer Allocation failed");
        compressedBuffer = malloc(LZ4F_compressFrameBound(srcDataLength, NULL));
+    CHECK(compressedBuffer==NULL, "compressedBuffer Allocation failed");
        decodedBuffer = malloc(srcDataLength);
+    CHECK(decodedBuffer==NULL, "decodedBuffer Allocation failed");
        FUZ_fillCompressibleNoiseBuffer(srcBuffer, srcDataLength, compressibility, &coreRand);
 
     // jump to requested testNb
@@ -394,7 +401,6 @@ int fuzzerTests(U32 seed, unsigned nbTests, unsigned startTest, double compressi
         size_t srcStart = FUZ_rand(&randState) % (srcDataLength - srcSize);
         size_t cSize;
         U64 crcOrig, crcDecoded;
-        size_t result;
 
         DISPLAYUPDATE(2, "\r%5i   ", testNb);
         crcOrig = XXH64(srcBuffer+srcStart, srcSize, 1);
@@ -405,10 +411,7 @@ int fuzzerTests(U32 seed, unsigned nbTests, unsigned startTest, double compressi
             BYTE* op = compressedBuffer;
             BYTE* const oend = op + LZ4F_compressFrameBound(srcDataLength, NULL);
             unsigned maxBits = FUZ_highbit(srcSize);
-            LZ4F_compressionContext_t cctx;
-            result = LZ4F_createCompressionContext(&cctx, LZ4F_VERSION, &prefs);
-            CHECK(LZ4F_isError(result), "Allocation for compression failed (error %i)", (int)result);
-            result = LZ4F_compressBegin(cctx, op, oend-op);
+            result = LZ4F_compressBegin(cCtx, op, oend-op, &prefs);
             CHECK(LZ4F_isError(result), "Compression header failed (error %i)", (int)result);
             op += result;
             while (ip < iend)
@@ -417,16 +420,14 @@ int fuzzerTests(U32 seed, unsigned nbTests, unsigned startTest, double compressi
                 size_t iSize = (FUZ_rand(&randState) & ((1<<nbBitsSeg)-1)) + 1;
                 size_t oSize = oend-op;
                 if (iSize > (size_t)(iend-ip)) iSize = iend-ip;
-                result = LZ4F_compress(cctx, op, oSize, ip, iSize, NULL);
+                result = LZ4F_compress(cCtx, op, oSize, ip, iSize, NULL);
                 CHECK(LZ4F_isError(result), "Compression failed (error %i)", (int)result);
                 op += result;
                 ip += iSize;
             }
-            result = LZ4F_compressEnd(cctx, op, oend-op, NULL);
+            result = LZ4F_compressEnd(cCtx, op, oend-op, NULL);
             CHECK(LZ4F_isError(result), "Compression completion failed (error %i)", (int)result);
             op += result;
-            result = LZ4F_freeCompressionContext(cctx);
-            CHECK(LZ4F_isError(result), "deallocation failed (error %i)", (int)result);
             cSize = op-(BYTE*)compressedBuffer;
         }
 
@@ -461,6 +462,7 @@ int fuzzerTests(U32 seed, unsigned nbTests, unsigned startTest, double compressi
 
 _end:
     LZ4F_freeDecompressionContext(dCtx);
+    LZ4F_freeCompressionContext(cCtx);
        free(srcBuffer);
        free(compressedBuffer);
        free(decodedBuffer);