1
0
mirror of https://github.com/soarqin/DSP_Mods_TO.git synced 2025-12-17 20:13:32 +08:00

update compression libraries, while formating codes

This commit is contained in:
2025-07-21 16:31:56 +08:00
parent 3cc1dfa750
commit 45a7552471
18 changed files with 1666 additions and 788 deletions

View File

@@ -1,6 +1,6 @@
/*
* LZ4 auto-framing library
* Copyright (C) 2011-2016, Yann Collet.
* Copyright (c) Yann Collet. All rights reserved.
*
* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
*
@@ -44,6 +44,7 @@
/*-************************************
* Compiler Options
**************************************/
#include <limits.h>
#ifdef _MSC_VER /* Visual Studio */
# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
#endif
@@ -125,8 +126,9 @@ static void* LZ4F_malloc(size_t s, LZ4F_CustomMem cmem)
static void LZ4F_free(void* p, LZ4F_CustomMem cmem)
{
/* custom malloc defined : use it */
if (p == NULL) return;
if (cmem.customFree != NULL) {
/* custom allocation defined : use it */
cmem.customFree(cmem.opaqueState, p);
return;
}
@@ -153,7 +155,7 @@ static void LZ4F_free(void* p, LZ4F_CustomMem cmem)
static int g_debuglog_enable = 1;
# define DEBUGLOG(l, ...) { \
if ((g_debuglog_enable) && (l<=LZ4_DEBUG)) { \
fprintf(stderr, __FILE__ ": "); \
fprintf(stderr, __FILE__ " %i: ", __LINE__ ); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, " \n"); \
} }
@@ -186,9 +188,9 @@ static U32 LZ4F_readLE32 (const void* src)
{
const BYTE* const srcPtr = (const BYTE*)src;
U32 value32 = srcPtr[0];
value32 += ((U32)srcPtr[1])<< 8;
value32 += ((U32)srcPtr[2])<<16;
value32 += ((U32)srcPtr[3])<<24;
value32 |= ((U32)srcPtr[1])<< 8;
value32 |= ((U32)srcPtr[2])<<16;
value32 |= ((U32)srcPtr[3])<<24;
return value32;
}
@@ -205,13 +207,13 @@ static U64 LZ4F_readLE64 (const void* src)
{
const BYTE* const srcPtr = (const BYTE*)src;
U64 value64 = srcPtr[0];
value64 += ((U64)srcPtr[1]<<8);
value64 += ((U64)srcPtr[2]<<16);
value64 += ((U64)srcPtr[3]<<24);
value64 += ((U64)srcPtr[4]<<32);
value64 += ((U64)srcPtr[5]<<40);
value64 += ((U64)srcPtr[6]<<48);
value64 += ((U64)srcPtr[7]<<56);
value64 |= ((U64)srcPtr[1]<<8);
value64 |= ((U64)srcPtr[2]<<16);
value64 |= ((U64)srcPtr[3]<<24);
value64 |= ((U64)srcPtr[4]<<32);
value64 |= ((U64)srcPtr[5]<<40);
value64 |= ((U64)srcPtr[6]<<48);
value64 |= ((U64)srcPtr[7]<<56);
return value64;
}
@@ -257,7 +259,8 @@ static const size_t BFSize = LZ4F_BLOCK_CHECKSUM_SIZE; /* block footer : checks
* Structures and local types
**************************************/
typedef enum { LZ4B_COMPRESSED, LZ4B_UNCOMPRESSED} LZ4F_blockCompression_t;
typedef enum { LZ4B_COMPRESSED, LZ4B_UNCOMPRESSED} LZ4F_BlockCompressMode_e;
typedef enum { ctxNone, ctxFast, ctxHC } LZ4F_CtxType_e;
typedef struct LZ4F_cctx_s
{
@@ -275,8 +278,8 @@ typedef struct LZ4F_cctx_s
XXH32_state_t xxh;
void* lz4CtxPtr;
U16 lz4CtxAlloc; /* sized for: 0 = none, 1 = lz4 ctx, 2 = lz4hc ctx */
U16 lz4CtxState; /* in use as: 0 = none, 1 = lz4 ctx, 2 = lz4hc ctx */
LZ4F_blockCompression_t blockCompression;
U16 lz4CtxType; /* in use as: 0 = none, 1 = lz4 ctx, 2 = lz4hc ctx */
LZ4F_BlockCompressMode_e blockCompressMode;
} LZ4F_cctx_t;
@@ -314,7 +317,12 @@ static LZ4F_errorCode_t LZ4F_returnErrorCode(LZ4F_errorCodes code)
#define RETURN_ERROR(e) return LZ4F_returnErrorCode(LZ4F_ERROR_ ## e)
#define RETURN_ERROR_IF(c,e) do { if (c) RETURN_ERROR(e); } while (0)
#define RETURN_ERROR_IF(c,e) do { \
if (c) { \
DEBUGLOG(3, "Error: " #c); \
RETURN_ERROR(e); \
} \
} while (0)
#define FORWARD_IF_ERROR(r) do { if (LZ4F_isError(r)) return (r); } while (0)
@@ -429,6 +437,7 @@ size_t LZ4F_compressFrame_usingCDict(LZ4F_cctx* cctx,
BYTE* dstPtr = dstStart;
BYTE* const dstEnd = dstStart + dstCapacity;
DEBUGLOG(4, "LZ4F_compressFrame_usingCDict (srcSize=%u)", (unsigned)srcSize);
if (preferencesPtr!=NULL)
prefs = *preferencesPtr;
else
@@ -494,7 +503,7 @@ size_t LZ4F_compressFrame(void* dstBuffer, size_t dstCapacity,
LZ4_initStream(&lz4ctx, sizeof(lz4ctx));
cctxPtr->lz4CtxPtr = &lz4ctx;
cctxPtr->lz4CtxAlloc = 1;
cctxPtr->lz4CtxState = 1;
cctxPtr->lz4CtxType = ctxFast;
}
#endif
DEBUGLOG(4, "LZ4F_compressFrame");
@@ -530,27 +539,35 @@ LZ4F_CDict*
LZ4F_createCDict_advanced(LZ4F_CustomMem cmem, const void* dictBuffer, size_t dictSize)
{
const char* dictStart = (const char*)dictBuffer;
LZ4F_CDict* const cdict = (LZ4F_CDict*)LZ4F_malloc(sizeof(*cdict), cmem);
LZ4F_CDict* cdict = NULL;
DEBUGLOG(4, "LZ4F_createCDict_advanced");
if (!cdict) return NULL;
if (!dictStart)
return NULL;
cdict = (LZ4F_CDict*)LZ4F_malloc(sizeof(*cdict), cmem);
if (!cdict)
return NULL;
cdict->cmem = cmem;
if (dictSize > 64 KB) {
dictStart += dictSize - 64 KB;
dictSize = 64 KB;
}
cdict->dictContent = LZ4F_malloc(dictSize, cmem);
/* note: using @cmem to allocate => can't use default create */
cdict->fastCtx = (LZ4_stream_t*)LZ4F_malloc(sizeof(LZ4_stream_t), cmem);
if (cdict->fastCtx)
LZ4_initStream(cdict->fastCtx, sizeof(LZ4_stream_t));
cdict->HCCtx = (LZ4_streamHC_t*)LZ4F_malloc(sizeof(LZ4_streamHC_t), cmem);
if (cdict->HCCtx)
LZ4_initStream(cdict->HCCtx, sizeof(LZ4_streamHC_t));
if (!cdict->dictContent || !cdict->fastCtx || !cdict->HCCtx) {
LZ4F_freeCDict(cdict);
return NULL;
}
memcpy(cdict->dictContent, dictStart, dictSize);
LZ4_loadDict (cdict->fastCtx, (const char*)cdict->dictContent, (int)dictSize);
LZ4_initStream(cdict->fastCtx, sizeof(LZ4_stream_t));
LZ4_loadDictSlow(cdict->fastCtx, (const char*)cdict->dictContent, (int)dictSize);
LZ4_initStreamHC(cdict->HCCtx, sizeof(LZ4_streamHC_t));
/* note: we don't know at this point which compression level is going to be used
* as a consequence, HCCtx is created for the more common HC mode */
LZ4_setCompressionLevel(cdict->HCCtx, LZ4HC_CLEVEL_DEFAULT);
LZ4_loadDictHC(cdict->HCCtx, (const char*)cdict->dictContent, (int)dictSize);
return cdict;
@@ -616,7 +633,6 @@ LZ4F_createCompressionContext(LZ4F_cctx** LZ4F_compressionContextPtr, unsigned v
return LZ4F_OK_NoError;
}
LZ4F_errorCode_t LZ4F_freeCompressionContext(LZ4F_cctx* cctxPtr)
{
if (cctxPtr != NULL) { /* support free on NULL */
@@ -641,7 +657,7 @@ static void LZ4F_initStream(void* ctx,
int level,
LZ4F_blockMode_t blockMode) {
if (level < LZ4HC_CLEVEL_MIN) {
if (cdict != NULL || blockMode == LZ4F_blockLinked) {
if (cdict || blockMode == LZ4F_blockLinked) {
/* In these cases, we will call LZ4_compress_fast_continue(),
* which needs an already reset context. Otherwise, we'll call a
* one-shot API. The non-continued APIs internally perform their own
@@ -649,11 +665,18 @@ static void LZ4F_initStream(void* ctx,
* tableType they need the context to be in. So in that case this
* would be misguided / wasted work. */
LZ4_resetStream_fast((LZ4_stream_t*)ctx);
if (cdict)
LZ4_attach_dictionary((LZ4_stream_t*)ctx, cdict->fastCtx);
}
LZ4_attach_dictionary((LZ4_stream_t *)ctx, cdict ? cdict->fastCtx : NULL);
/* In these cases, we'll call a one-shot API.
* The non-continued APIs internally perform their own resets
* at the beginning of their calls, where they know
* which tableType they need the context to be in.
* Therefore, a reset here would be wasted work. */
} else {
LZ4_resetStreamHC_fast((LZ4_streamHC_t*)ctx, level);
LZ4_attach_HC_dictionary((LZ4_streamHC_t *)ctx, cdict ? cdict->HCCtx : NULL);
if (cdict)
LZ4_attach_HC_dictionary((LZ4_streamHC_t*)ctx, cdict->HCCtx);
}
}
@@ -668,14 +691,19 @@ static int ctxTypeID_to_size(int ctxTypeID) {
}
}
/*! LZ4F_compressBegin_usingCDict() :
* init streaming compression AND writes frame header into @dstBuffer.
* @dstCapacity must be >= LZ4F_HEADER_SIZE_MAX bytes.
* @return : number of bytes written into @dstBuffer for the header
* or an error code (can be tested using LZ4F_isError())
size_t LZ4F_cctx_size(const LZ4F_cctx* cctx) {
if (cctx == NULL) {
return 0;
}
return sizeof(*cctx) + cctx->maxBufferSize + ctxTypeID_to_size(cctx->lz4CtxAlloc);
}
/* LZ4F_compressBegin_internal()
* Note: only accepts @cdict _or_ @dictBuffer as non NULL.
*/
size_t LZ4F_compressBegin_usingCDict(LZ4F_cctx* cctxPtr,
size_t LZ4F_compressBegin_internal(LZ4F_cctx* cctx,
void* dstBuffer, size_t dstCapacity,
const void* dictBuffer, size_t dictSize,
const LZ4F_CDict* cdict,
const LZ4F_preferences_t* preferencesPtr)
{
@@ -685,70 +713,85 @@ size_t LZ4F_compressBegin_usingCDict(LZ4F_cctx* cctxPtr,
RETURN_ERROR_IF(dstCapacity < maxFHSize, dstMaxSize_tooSmall);
if (preferencesPtr == NULL) preferencesPtr = &prefNull;
cctxPtr->prefs = *preferencesPtr;
cctx->prefs = *preferencesPtr;
DEBUGLOG(5, "LZ4F_compressBegin_internal: Independent_blocks=%u", cctx->prefs.frameInfo.blockMode);
/* cctx Management */
{ U16 const ctxTypeID = (cctxPtr->prefs.compressionLevel < LZ4HC_CLEVEL_MIN) ? 1 : 2;
{ U16 const ctxTypeID = (cctx->prefs.compressionLevel < LZ4HC_CLEVEL_MIN) ? 1 : 2;
int requiredSize = ctxTypeID_to_size(ctxTypeID);
int allocatedSize = ctxTypeID_to_size(cctxPtr->lz4CtxAlloc);
int allocatedSize = ctxTypeID_to_size(cctx->lz4CtxAlloc);
if (allocatedSize < requiredSize) {
/* not enough space allocated */
LZ4F_free(cctxPtr->lz4CtxPtr, cctxPtr->cmem);
if (cctxPtr->prefs.compressionLevel < LZ4HC_CLEVEL_MIN) {
LZ4F_free(cctx->lz4CtxPtr, cctx->cmem);
if (cctx->prefs.compressionLevel < LZ4HC_CLEVEL_MIN) {
/* must take ownership of memory allocation,
* in order to respect custom allocator contract */
cctxPtr->lz4CtxPtr = LZ4F_malloc(sizeof(LZ4_stream_t), cctxPtr->cmem);
if (cctxPtr->lz4CtxPtr)
LZ4_initStream(cctxPtr->lz4CtxPtr, sizeof(LZ4_stream_t));
cctx->lz4CtxPtr = LZ4F_malloc(sizeof(LZ4_stream_t), cctx->cmem);
if (cctx->lz4CtxPtr)
LZ4_initStream(cctx->lz4CtxPtr, sizeof(LZ4_stream_t));
} else {
cctxPtr->lz4CtxPtr = LZ4F_malloc(sizeof(LZ4_streamHC_t), cctxPtr->cmem);
if (cctxPtr->lz4CtxPtr)
LZ4_initStreamHC(cctxPtr->lz4CtxPtr, sizeof(LZ4_streamHC_t));
cctx->lz4CtxPtr = LZ4F_malloc(sizeof(LZ4_streamHC_t), cctx->cmem);
if (cctx->lz4CtxPtr)
LZ4_initStreamHC(cctx->lz4CtxPtr, sizeof(LZ4_streamHC_t));
}
RETURN_ERROR_IF(cctxPtr->lz4CtxPtr == NULL, allocation_failed);
cctxPtr->lz4CtxAlloc = ctxTypeID;
cctxPtr->lz4CtxState = ctxTypeID;
} else if (cctxPtr->lz4CtxState != ctxTypeID) {
RETURN_ERROR_IF(cctx->lz4CtxPtr == NULL, allocation_failed);
cctx->lz4CtxAlloc = ctxTypeID;
cctx->lz4CtxType = ctxTypeID;
} else if (cctx->lz4CtxType != ctxTypeID) {
/* otherwise, a sufficient buffer is already allocated,
* but we need to reset it to the correct context type */
if (cctxPtr->prefs.compressionLevel < LZ4HC_CLEVEL_MIN) {
LZ4_initStream((LZ4_stream_t*)cctxPtr->lz4CtxPtr, sizeof(LZ4_stream_t));
if (cctx->prefs.compressionLevel < LZ4HC_CLEVEL_MIN) {
LZ4_initStream((LZ4_stream_t*)cctx->lz4CtxPtr, sizeof(LZ4_stream_t));
} else {
LZ4_initStreamHC((LZ4_streamHC_t*)cctxPtr->lz4CtxPtr, sizeof(LZ4_streamHC_t));
LZ4_setCompressionLevel((LZ4_streamHC_t*)cctxPtr->lz4CtxPtr, cctxPtr->prefs.compressionLevel);
LZ4_initStreamHC((LZ4_streamHC_t*)cctx->lz4CtxPtr, sizeof(LZ4_streamHC_t));
LZ4_setCompressionLevel((LZ4_streamHC_t*)cctx->lz4CtxPtr, cctx->prefs.compressionLevel);
}
cctxPtr->lz4CtxState = ctxTypeID;
cctx->lz4CtxType = ctxTypeID;
} }
/* Buffer Management */
if (cctxPtr->prefs.frameInfo.blockSizeID == 0)
cctxPtr->prefs.frameInfo.blockSizeID = LZ4F_BLOCKSIZEID_DEFAULT;
cctxPtr->maxBlockSize = LZ4F_getBlockSize(cctxPtr->prefs.frameInfo.blockSizeID);
if (cctx->prefs.frameInfo.blockSizeID == 0)
cctx->prefs.frameInfo.blockSizeID = LZ4F_BLOCKSIZEID_DEFAULT;
cctx->maxBlockSize = LZ4F_getBlockSize(cctx->prefs.frameInfo.blockSizeID);
{ size_t const requiredBuffSize = preferencesPtr->autoFlush ?
((cctxPtr->prefs.frameInfo.blockMode == LZ4F_blockLinked) ? 64 KB : 0) : /* only needs past data up to window size */
cctxPtr->maxBlockSize + ((cctxPtr->prefs.frameInfo.blockMode == LZ4F_blockLinked) ? 128 KB : 0);
((cctx->prefs.frameInfo.blockMode == LZ4F_blockLinked) ? 64 KB : 0) : /* only needs past data up to window size */
cctx->maxBlockSize + ((cctx->prefs.frameInfo.blockMode == LZ4F_blockLinked) ? 128 KB : 0);
if (cctxPtr->maxBufferSize < requiredBuffSize) {
cctxPtr->maxBufferSize = 0;
LZ4F_free(cctxPtr->tmpBuff, cctxPtr->cmem);
cctxPtr->tmpBuff = (BYTE*)LZ4F_malloc(requiredBuffSize, cctxPtr->cmem);
RETURN_ERROR_IF(cctxPtr->tmpBuff == NULL, allocation_failed);
cctxPtr->maxBufferSize = requiredBuffSize;
if (cctx->maxBufferSize < requiredBuffSize) {
cctx->maxBufferSize = 0;
LZ4F_free(cctx->tmpBuff, cctx->cmem);
cctx->tmpBuff = (BYTE*)LZ4F_malloc(requiredBuffSize, cctx->cmem);
RETURN_ERROR_IF(cctx->tmpBuff == NULL, allocation_failed);
cctx->maxBufferSize = requiredBuffSize;
} }
cctxPtr->tmpIn = cctxPtr->tmpBuff;
cctxPtr->tmpInSize = 0;
(void)XXH32_reset(&(cctxPtr->xxh), 0);
cctx->tmpIn = cctx->tmpBuff;
cctx->tmpInSize = 0;
(void)XXH32_reset(&(cctx->xxh), 0);
/* context init */
cctxPtr->cdict = cdict;
if (cctxPtr->prefs.frameInfo.blockMode == LZ4F_blockLinked) {
cctx->cdict = cdict;
if (cctx->prefs.frameInfo.blockMode == LZ4F_blockLinked) {
/* frame init only for blockLinked : blockIndependent will be init at each block */
LZ4F_initStream(cctxPtr->lz4CtxPtr, cdict, cctxPtr->prefs.compressionLevel, LZ4F_blockLinked);
LZ4F_initStream(cctx->lz4CtxPtr, cdict, cctx->prefs.compressionLevel, LZ4F_blockLinked);
}
if (preferencesPtr->compressionLevel >= LZ4HC_CLEVEL_MIN) {
LZ4_favorDecompressionSpeed((LZ4_streamHC_t*)cctxPtr->lz4CtxPtr, (int)preferencesPtr->favorDecSpeed);
LZ4_favorDecompressionSpeed((LZ4_streamHC_t*)cctx->lz4CtxPtr, (int)preferencesPtr->favorDecSpeed);
}
if (dictBuffer) {
assert(cdict == NULL);
RETURN_ERROR_IF(dictSize > INT_MAX, parameter_invalid);
if (cctx->lz4CtxType == ctxFast) {
/* lz4 fast*/
LZ4_loadDict((LZ4_stream_t*)cctx->lz4CtxPtr, (const char*)dictBuffer, (int)dictSize);
} else {
/* lz4hc */
assert(cctx->lz4CtxType == ctxHC);
LZ4_loadDictHC((LZ4_streamHC_t*)cctx->lz4CtxPtr, (const char*)dictBuffer, (int)dictSize);
}
}
/* Stage 2 : Write Frame Header */
/* Magic Number */
LZ4F_writeLE32(dstPtr, LZ4F_MAGICNUMBER);
@@ -757,22 +800,22 @@ size_t LZ4F_compressBegin_usingCDict(LZ4F_cctx* cctxPtr,
/* FLG Byte */
*dstPtr++ = (BYTE)(((1 & _2BITS) << 6) /* Version('01') */
+ ((cctxPtr->prefs.frameInfo.blockMode & _1BIT ) << 5)
+ ((cctxPtr->prefs.frameInfo.blockChecksumFlag & _1BIT ) << 4)
+ ((unsigned)(cctxPtr->prefs.frameInfo.contentSize > 0) << 3)
+ ((cctxPtr->prefs.frameInfo.contentChecksumFlag & _1BIT ) << 2)
+ (cctxPtr->prefs.frameInfo.dictID > 0) );
+ ((cctx->prefs.frameInfo.blockMode & _1BIT ) << 5)
+ ((cctx->prefs.frameInfo.blockChecksumFlag & _1BIT ) << 4)
+ ((unsigned)(cctx->prefs.frameInfo.contentSize > 0) << 3)
+ ((cctx->prefs.frameInfo.contentChecksumFlag & _1BIT ) << 2)
+ (cctx->prefs.frameInfo.dictID > 0) );
/* BD Byte */
*dstPtr++ = (BYTE)((cctxPtr->prefs.frameInfo.blockSizeID & _3BITS) << 4);
*dstPtr++ = (BYTE)((cctx->prefs.frameInfo.blockSizeID & _3BITS) << 4);
/* Optional Frame content size field */
if (cctxPtr->prefs.frameInfo.contentSize) {
LZ4F_writeLE64(dstPtr, cctxPtr->prefs.frameInfo.contentSize);
if (cctx->prefs.frameInfo.contentSize) {
LZ4F_writeLE64(dstPtr, cctx->prefs.frameInfo.contentSize);
dstPtr += 8;
cctxPtr->totalInSize = 0;
cctx->totalInSize = 0;
}
/* Optional dictionary ID field */
if (cctxPtr->prefs.frameInfo.dictID) {
LZ4F_writeLE32(dstPtr, cctxPtr->prefs.frameInfo.dictID);
if (cctx->prefs.frameInfo.dictID) {
LZ4F_writeLE32(dstPtr, cctx->prefs.frameInfo.dictID);
dstPtr += 4;
}
/* Header CRC Byte */
@@ -780,24 +823,54 @@ size_t LZ4F_compressBegin_usingCDict(LZ4F_cctx* cctxPtr,
dstPtr++;
}
cctxPtr->cStage = 1; /* header written, now request input data block */
cctx->cStage = 1; /* header written, now request input data block */
return (size_t)(dstPtr - dstStart);
}
/*! LZ4F_compressBegin() :
* init streaming compression AND writes frame header into @dstBuffer.
* @dstCapacity must be >= LZ4F_HEADER_SIZE_MAX bytes.
* @preferencesPtr can be NULL, in which case default parameters are selected.
* @return : number of bytes written into dstBuffer for the header
* or an error code (can be tested using LZ4F_isError())
*/
size_t LZ4F_compressBegin(LZ4F_cctx* cctxPtr,
size_t LZ4F_compressBegin(LZ4F_cctx* cctx,
void* dstBuffer, size_t dstCapacity,
const LZ4F_preferences_t* preferencesPtr)
{
return LZ4F_compressBegin_usingCDict(cctxPtr, dstBuffer, dstCapacity,
NULL, preferencesPtr);
return LZ4F_compressBegin_internal(cctx, dstBuffer, dstCapacity,
NULL, 0,
NULL, preferencesPtr);
}
/* LZ4F_compressBegin_usingDictOnce:
* Hidden implementation,
* employed for multi-threaded compression
* when frame defines linked blocks */
size_t LZ4F_compressBegin_usingDictOnce(LZ4F_cctx* cctx,
void* dstBuffer, size_t dstCapacity,
const void* dict, size_t dictSize,
const LZ4F_preferences_t* preferencesPtr)
{
return LZ4F_compressBegin_internal(cctx, dstBuffer, dstCapacity,
dict, dictSize,
NULL, preferencesPtr);
}
size_t LZ4F_compressBegin_usingDict(LZ4F_cctx* cctx,
void* dstBuffer, size_t dstCapacity,
const void* dict, size_t dictSize,
const LZ4F_preferences_t* preferencesPtr)
{
/* note : incorrect implementation :
* this will only use the dictionary once,
* instead of once *per* block when frames defines independent blocks */
return LZ4F_compressBegin_usingDictOnce(cctx, dstBuffer, dstCapacity,
dict, dictSize,
preferencesPtr);
}
size_t LZ4F_compressBegin_usingCDict(LZ4F_cctx* cctx,
void* dstBuffer, size_t dstCapacity,
const LZ4F_CDict* cdict,
const LZ4F_preferences_t* preferencesPtr)
{
return LZ4F_compressBegin_internal(cctx, dstBuffer, dstCapacity,
NULL, 0,
cdict, preferencesPtr);
}
@@ -829,10 +902,11 @@ static size_t LZ4F_makeBlock(void* dst,
LZ4F_blockChecksum_t crcFlag)
{
BYTE* const cSizePtr = (BYTE*)dst;
int dstCapacity = (srcSize > 1) ? (int)srcSize - 1 : 1;
U32 cSize;
assert(compress != NULL);
cSize = (U32)compress(lz4ctx, (const char*)src, (char*)(cSizePtr+BHSize),
(int)(srcSize), (int)(srcSize-1),
(int)srcSize, dstCapacity,
level, cdict);
if (cSize == 0 || cSize >= srcSize) {
@@ -891,9 +965,10 @@ static int LZ4F_doNotCompressBlock(void* ctx, const char* src, char* dst, int sr
return 0;
}
static compressFunc_t LZ4F_selectCompression(LZ4F_blockMode_t blockMode, int level, LZ4F_blockCompression_t compressMode)
static compressFunc_t LZ4F_selectCompression(LZ4F_blockMode_t blockMode, int level, LZ4F_BlockCompressMode_e compressMode)
{
if (compressMode == LZ4B_UNCOMPRESSED) return LZ4F_doNotCompressBlock;
if (compressMode == LZ4B_UNCOMPRESSED)
return LZ4F_doNotCompressBlock;
if (level < LZ4HC_CLEVEL_MIN) {
if (blockMode == LZ4F_blockIndependent) return LZ4F_compressBlock;
return LZ4F_compressBlock_continue;
@@ -902,12 +977,13 @@ static compressFunc_t LZ4F_selectCompression(LZ4F_blockMode_t blockMode, int lev
return LZ4F_compressBlockHC_continue;
}
/* Save history (up to 64KB) into @tmpBuff */
static int LZ4F_localSaveDict(LZ4F_cctx_t* cctxPtr)
/* Save or shorten history (up to 64KB) into @tmpBuff */
static void LZ4F_localSaveDict(LZ4F_cctx_t* cctxPtr)
{
if (cctxPtr->prefs.compressionLevel < LZ4HC_CLEVEL_MIN)
return LZ4_saveDict ((LZ4_stream_t*)(cctxPtr->lz4CtxPtr), (char*)(cctxPtr->tmpBuff), 64 KB);
return LZ4_saveDictHC ((LZ4_streamHC_t*)(cctxPtr->lz4CtxPtr), (char*)(cctxPtr->tmpBuff), 64 KB);
int const dictSize = (cctxPtr->prefs.compressionLevel < LZ4HC_CLEVEL_MIN) ?
LZ4_saveDict ((LZ4_stream_t*)(cctxPtr->lz4CtxPtr), (char*)(cctxPtr->tmpBuff), 64 KB) :
LZ4_saveDictHC ((LZ4_streamHC_t*)(cctxPtr->lz4CtxPtr), (char*)(cctxPtr->tmpBuff), 64 KB);
cctxPtr->tmpIn = cctxPtr->tmpBuff + dictSize;
}
typedef enum { notDone, fromTmpBuffer, fromSrcBuffer } LZ4F_lastBlockStatus;
@@ -915,7 +991,7 @@ typedef enum { notDone, fromTmpBuffer, fromSrcBuffer } LZ4F_lastBlockStatus;
static const LZ4F_compressOptions_t k_cOptionsNull = { 0, { 0, 0, 0 } };
/*! LZ4F_compressUpdateImpl() :
/*! LZ4F_compressUpdateImpl() :
* LZ4F_compressUpdate() can be called repetitively to compress as much data as necessary.
* When successful, the function always entirely consumes @srcBuffer.
* src data is either buffered or compressed into @dstBuffer.
@@ -931,11 +1007,11 @@ static size_t LZ4F_compressUpdateImpl(LZ4F_cctx* cctxPtr,
void* dstBuffer, size_t dstCapacity,
const void* srcBuffer, size_t srcSize,
const LZ4F_compressOptions_t* compressOptionsPtr,
LZ4F_blockCompression_t blockCompression)
LZ4F_BlockCompressMode_e blockCompression)
{
size_t const blockSize = cctxPtr->maxBlockSize;
const BYTE* srcPtr = (const BYTE*)srcBuffer;
const BYTE* const srcEnd = srcPtr + srcSize;
const BYTE* const srcEnd = srcSize ? (assert(srcPtr!=NULL), srcPtr + srcSize) : srcPtr;
BYTE* const dstStart = (BYTE*)dstBuffer;
BYTE* dstPtr = dstStart;
LZ4F_lastBlockStatus lastBlockCompressed = notDone;
@@ -951,10 +1027,10 @@ static size_t LZ4F_compressUpdateImpl(LZ4F_cctx* cctxPtr,
RETURN_ERROR(dstMaxSize_tooSmall);
/* flush currently written block, to continue with new block compression */
if (cctxPtr->blockCompression != blockCompression) {
if (cctxPtr->blockCompressMode != blockCompression) {
bytesWritten = LZ4F_flush(cctxPtr, dstBuffer, dstCapacity, compressOptionsPtr);
dstPtr += bytesWritten;
cctxPtr->blockCompression = blockCompression;
cctxPtr->blockCompressMode = blockCompression;
}
if (compressOptionsPtr == NULL) compressOptionsPtr = &k_cOptionsNull;
@@ -1013,9 +1089,7 @@ static size_t LZ4F_compressUpdateImpl(LZ4F_cctx* cctxPtr,
if (compressOptionsPtr->stableSrc) {
cctxPtr->tmpIn = cctxPtr->tmpBuff; /* src is stable : dictionary remains in src across invocations */
} else {
int const realDictSize = LZ4F_localSaveDict(cctxPtr);
assert(0 <= realDictSize && realDictSize <= 64 KB);
cctxPtr->tmpIn = cctxPtr->tmpBuff + realDictSize;
LZ4F_localSaveDict(cctxPtr);
}
}
@@ -1025,8 +1099,7 @@ static size_t LZ4F_compressUpdateImpl(LZ4F_cctx* cctxPtr,
{
/* only preserve 64KB within internal buffer. Ensures there is enough room for next block.
* note: this situation necessarily implies lastBlockCompressed==fromTmpBuffer */
int const realDictSize = LZ4F_localSaveDict(cctxPtr);
cctxPtr->tmpIn = cctxPtr->tmpBuff + realDictSize;
LZ4F_localSaveDict(cctxPtr);
assert((cctxPtr->tmpIn + blockSize) <= (cctxPtr->tmpBuff + cctxPtr->maxBufferSize));
}
@@ -1068,13 +1141,9 @@ size_t LZ4F_compressUpdate(LZ4F_cctx* cctxPtr,
compressOptionsPtr, LZ4B_COMPRESSED);
}
/*! LZ4F_compressUpdate() :
* LZ4F_compressUpdate() can be called repetitively to compress as much data as necessary.
* When successful, the function always entirely consumes @srcBuffer.
* src data is either buffered or compressed into @dstBuffer.
* If previously an uncompressed block was written, buffered data is flushed
* before appending compressed data is continued.
* This is only supported when LZ4F_blockIndependent is used
/*! LZ4F_uncompressedUpdate() :
* Same as LZ4F_compressUpdate(), but requests blocks to be sent uncompressed.
* This symbol is only supported when LZ4F_blockIndependent is used
* @dstCapacity MUST be >= LZ4F_compressBound(srcSize, preferencesPtr).
* @compressOptionsPtr is optional : provide NULL to mean "default".
* @return : the number of bytes written into dstBuffer. It can be zero, meaning input data was just buffered.
@@ -1084,7 +1153,8 @@ size_t LZ4F_compressUpdate(LZ4F_cctx* cctxPtr,
size_t LZ4F_uncompressedUpdate(LZ4F_cctx* cctxPtr,
void* dstBuffer, size_t dstCapacity,
const void* srcBuffer, size_t srcSize,
const LZ4F_compressOptions_t* compressOptionsPtr) {
const LZ4F_compressOptions_t* compressOptionsPtr)
{
return LZ4F_compressUpdateImpl(cctxPtr,
dstBuffer, dstCapacity,
srcBuffer, srcSize,
@@ -1094,7 +1164,7 @@ size_t LZ4F_uncompressedUpdate(LZ4F_cctx* cctxPtr,
/*! LZ4F_flush() :
* When compressed data must be sent immediately, without waiting for a block to be filled,
* invoke LZ4_flush(), which will immediately compress any remaining data stored within LZ4F_cctx.
* invoke LZ4F_flush(), which will immediately compress any remaining data stored within LZ4F_cctx.
* 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 LZ4F_cctx.
* The function outputs an error code if it fails (can be tested using LZ4F_isError())
@@ -1108,13 +1178,15 @@ size_t LZ4F_flush(LZ4F_cctx* cctxPtr,
BYTE* dstPtr = dstStart;
compressFunc_t compress;
DEBUGLOG(5, "LZ4F_flush: %zu buffered bytes (saved dict size = %i) (dstCapacity=%u)",
cctxPtr->tmpInSize, (int)(cctxPtr->tmpIn - cctxPtr->tmpBuff), (unsigned)dstCapacity);
if (cctxPtr->tmpInSize == 0) return 0; /* nothing to flush */
RETURN_ERROR_IF(cctxPtr->cStage != 1, compressionState_uninitialized);
RETURN_ERROR_IF(dstCapacity < (cctxPtr->tmpInSize + BHSize + BFSize), dstMaxSize_tooSmall);
(void)compressOptionsPtr; /* not useful (yet) */
/* select compression function */
compress = LZ4F_selectCompression(cctxPtr->prefs.frameInfo.blockMode, cctxPtr->prefs.compressionLevel, cctxPtr->blockCompression);
compress = LZ4F_selectCompression(cctxPtr->prefs.frameInfo.blockMode, cctxPtr->prefs.compressionLevel, cctxPtr->blockCompressMode);
/* compress tmp buffer */
dstPtr += LZ4F_makeBlock(dstPtr,
@@ -1129,9 +1201,9 @@ size_t LZ4F_flush(LZ4F_cctx* cctxPtr,
cctxPtr->tmpInSize = 0;
/* keep tmpIn within limits */
if ((cctxPtr->tmpIn + cctxPtr->maxBlockSize) > (cctxPtr->tmpBuff + cctxPtr->maxBufferSize)) { /* necessarily LZ4F_blockLinked */
int const realDictSize = LZ4F_localSaveDict(cctxPtr);
cctxPtr->tmpIn = cctxPtr->tmpBuff + realDictSize;
if ((cctxPtr->tmpIn + cctxPtr->maxBlockSize) > (cctxPtr->tmpBuff + cctxPtr->maxBufferSize)) {
assert(cctxPtr->prefs.frameInfo.blockMode == LZ4F_blockLinked);
LZ4F_localSaveDict(cctxPtr);
}
return (size_t)(dstPtr - dstStart);
@@ -1169,7 +1241,7 @@ size_t LZ4F_compressEnd(LZ4F_cctx* cctxPtr,
if (cctxPtr->prefs.frameInfo.contentChecksumFlag == LZ4F_contentChecksumEnabled) {
U32 const xxh = XXH32_digest(&(cctxPtr->xxh));
RETURN_ERROR_IF(dstCapacity < 8, dstMaxSize_tooSmall);
DEBUGLOG(5,"Writing 32-bit content checksum");
DEBUGLOG(5,"Writing 32-bit content checksum (0x%0X)", xxh);
LZ4F_writeLE32(dstPtr, xxh);
dstPtr+=4; /* content Checksum */
}
@@ -1266,15 +1338,25 @@ LZ4F_errorCode_t LZ4F_freeDecompressionContext(LZ4F_dctx* dctx)
return result;
}
size_t LZ4F_dctx_size(const LZ4F_dctx* dctx) {
if (dctx == NULL) {
return 0;
}
return sizeof(*dctx)
+ (dctx->tmpIn != NULL ? dctx->maxBlockSize + BFSize : 0)
+ (dctx->tmpOutBuffer != NULL ? dctx->maxBufferSize : 0);
}
/*==--- Streaming Decompression operations ---==*/
void LZ4F_resetDecompressionContext(LZ4F_dctx* dctx)
{
DEBUGLOG(5, "LZ4F_resetDecompressionContext");
dctx->dStage = dstage_getFrameHeader;
dctx->dict = NULL;
dctx->dictSize = 0;
dctx->skipChecksum = 0;
dctx->frameRemainingSize = 0;
}
@@ -1331,6 +1413,7 @@ static size_t LZ4F_decodeHeader(LZ4F_dctx* dctx, const void* src, size_t srcSize
if (((FLG>>1)&_1BIT) != 0) RETURN_ERROR(reservedFlag_set); /* Reserved bit */
if (version != 1) RETURN_ERROR(headerVersion_wrong); /* Version Number, only supported value */
}
DEBUGLOG(6, "contentSizeFlag: %u", contentSizeFlag);
/* Frame Header Size */
frameHeaderSize = minFHSize + (contentSizeFlag?8:0) + (dictIDFlag?4:0);
@@ -1367,8 +1450,9 @@ static size_t LZ4F_decodeHeader(LZ4F_dctx* dctx, const void* src, size_t srcSize
dctx->frameInfo.contentChecksumFlag = (LZ4F_contentChecksum_t)contentChecksumFlag;
dctx->frameInfo.blockSizeID = (LZ4F_blockSizeID_t)blockSizeID;
dctx->maxBlockSize = LZ4F_getBlockSize((LZ4F_blockSizeID_t)blockSizeID);
if (contentSizeFlag)
if (contentSizeFlag) {
dctx->frameRemainingSize = dctx->frameInfo.contentSize = LZ4F_readLE64(srcPtr+6);
}
if (dictIDFlag)
dctx->frameInfo.dictID = LZ4F_readLE32(srcPtr + frameHeaderSize - 5);
@@ -1427,6 +1511,10 @@ LZ4F_errorCode_t LZ4F_getFrameInfo(LZ4F_dctx* dctx,
LZ4F_frameInfo_t* frameInfoPtr,
const void* srcBuffer, size_t* srcSizePtr)
{
assert(dctx != NULL);
RETURN_ERROR_IF(frameInfoPtr == NULL, parameter_null);
RETURN_ERROR_IF(srcSizePtr == NULL, parameter_null);
LZ4F_STATIC_ASSERT(dstage_getFrameHeader < dstage_storeFrameHeader);
if (dctx->dStage > dstage_storeFrameHeader) {
/* frameInfo already decoded */
@@ -1568,7 +1656,7 @@ size_t LZ4F_decompress(LZ4F_dctx* dctx,
size_t nextSrcSizeHint = 1;
DEBUGLOG(5, "LZ4F_decompress : %p,%u => %p,%u",
DEBUGLOG(5, "LZ4F_decompress: src[%p](%u) => dst[%p](%u)",
srcBuffer, (unsigned)*srcSizePtr, dstBuffer, (unsigned)*dstSizePtr);
if (dstBuffer == NULL) assert(*dstSizePtr == 0);
MEM_INIT(&optionsNull, 0, sizeof(optionsNull));
@@ -1957,6 +2045,7 @@ size_t LZ4F_decompress(LZ4F_dctx* dctx,
if (!dctx->skipChecksum) {
U32 const readCRC = LZ4F_readLE32(selectedIn);
U32 const resultCRC = XXH32_digest(&(dctx->xxh));
DEBUGLOG(4, "frame checksum: stored 0x%0X vs 0x%0X processed", readCRC, resultCRC);
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
RETURN_ERROR_IF(readCRC != resultCRC, contentChecksum_invalid);
#else