45 # pragma warning(disable : 4127)
53 #define ALLOCATOR(s) calloc(1,s)
56 #define MEM_INIT memset
71 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
79 typedef unsigned char BYTE;
80 typedef unsigned short U16;
81 typedef unsigned int U32;
82 typedef signed int S32;
83 typedef unsigned long long U64;
100 #define LZ4F_MAGIC_SKIPPABLE_START 0x184D2A50U
101 #define LZ4F_MAGICNUMBER 0x184D2204U
102 #define LZ4F_BLOCKUNCOMPRESSED_FLAG 0x80000000U
103 #define LZ4F_BLOCKSIZEID_DEFAULT LZ4F_max64KB
156 #define LZ4F_GENERATE_STRING(STRING) #STRING,
167 static const char* codeError =
"Unspecified error code";
178 static const size_t blockSizes[4] = { 64
KB, 256
KB, 1
MB, 4
MB };
182 if (blockSizeID > 3)
return (
size_t)-LZ4F_ERROR_maxBlockSize_invalid;
183 return blockSizes[blockSizeID];
190 U32 value32 = srcPtr[0];
191 value32 += (srcPtr[1]<<8);
192 value32 += (srcPtr[2]<<16);
193 value32 += ((
U32)srcPtr[3])<<24;
199 dstPtr[0] = (
BYTE)value32;
200 dstPtr[1] = (
BYTE)(value32 >> 8);
201 dstPtr[2] = (
BYTE)(value32 >> 16);
202 dstPtr[3] = (
BYTE)(value32 >> 24);
207 U64 value64 = srcPtr[0];
208 value64 += ((
U64)srcPtr[1]<<8);
209 value64 += ((
U64)srcPtr[2]<<16);
210 value64 += ((
U64)srcPtr[3]<<24);
211 value64 += ((
U64)srcPtr[4]<<32);
212 value64 += ((
U64)srcPtr[5]<<40);
213 value64 += ((
U64)srcPtr[6]<<48);
214 value64 += ((
U64)srcPtr[7]<<56);
220 dstPtr[0] = (
BYTE)value64;
221 dstPtr[1] = (
BYTE)(value64 >> 8);
222 dstPtr[2] = (
BYTE)(value64 >> 16);
223 dstPtr[3] = (
BYTE)(value64 >> 24);
224 dstPtr[4] = (
BYTE)(value64 >> 32);
225 dstPtr[5] = (
BYTE)(value64 >> 40);
226 dstPtr[6] = (
BYTE)(value64 >> 48);
227 dstPtr[7] = (
BYTE)(value64 >> 56);
234 return (
BYTE)(xxh >> 8);
244 size_t maxBlockSize = 64
KB;
245 while (requestedBSID > proposedBSID)
247 if (srcSize <= maxBlockSize)
252 return requestedBSID;
262 if (preferencesPtr!=NULL) prefs = *preferencesPtr;
263 else memset(&prefs, 0,
sizeof(prefs));
271 return headerSize + streamSize;
291 BYTE*
const dstStart = (
BYTE*) dstBuffer;
292 BYTE* dstPtr = dstStart;
293 BYTE*
const dstEnd = dstStart + dstMaxSize;
295 memset(&cctxI, 0,
sizeof(cctxI));
296 memset(&options, 0,
sizeof(options));
301 if (preferencesPtr!=NULL)
302 prefs = *preferencesPtr;
304 memset(&prefs, 0,
sizeof(prefs));
322 return (
size_t)-LZ4F_ERROR_dstMaxSize_tooSmall;
328 errorCode =
LZ4F_compressUpdate(&cctxI, dstPtr, dstEnd-dstPtr, srcBuffer, srcSize, &options);
339 return (dstPtr - dstStart);
360 if (cctxPtr==NULL)
return (
LZ4F_errorCode_t)(-LZ4F_ERROR_allocation_failed);
367 return LZ4F_OK_NoError;
379 FREEMEM(LZ4F_compressionContext);
382 return LZ4F_OK_NoError;
396 BYTE*
const dstStart = (
BYTE*)dstBuffer;
397 BYTE* dstPtr = dstStart;
399 size_t requiredBuffSize;
401 if (dstMaxSize <
maxFHSize)
return (
size_t)-LZ4F_ERROR_dstMaxSize_tooSmall;
402 if (cctxPtr->
cStage != 0)
return (
size_t)-LZ4F_ERROR_GENERIC;
403 memset(&prefNull, 0,
sizeof(prefNull));
404 if (preferencesPtr == NULL) preferencesPtr = &prefNull;
405 cctxPtr->
prefs = *preferencesPtr;
434 if (cctxPtr->
tmpBuff == NULL)
return (
size_t)-LZ4F_ERROR_allocation_failed;
447 headerStart = dstPtr;
469 return (dstPtr - dstStart);
480 memset(&prefsNull, 0,
sizeof(prefsNull));
483 const LZ4F_preferences_t* prefsPtr = (preferencesPtr==NULL) ? &prefsNull : preferencesPtr;
486 unsigned nbBlocks = (unsigned)(srcSize / blockSize) + 1;
487 size_t lastBlockSize = prefsPtr->
autoFlush ? srcSize % blockSize : blockSize;
488 size_t blockInfo = 4;
491 return (blockInfo * nbBlocks) + (blockSize * (nbBlocks-1)) + lastBlockSize + frameEnd;;
496 typedef int (*
compressFunc_t)(
void* ctx,
const char* src,
char*
dst,
int srcSize,
int dstSize,
int level);
503 cSize = (
U32)compress(lz4ctx, (
const char*)src, (
char*)(cSizePtr+4), (int)(srcSize), (int)(srcSize-1), level);
507 cSize = (
U32)srcSize;
509 memcpy(cSizePtr+4, src, srcSize);
567 const BYTE* srcPtr = (
const BYTE*)srcBuffer;
568 const BYTE*
const srcEnd = srcPtr + srcSize;
569 BYTE*
const dstStart = (
BYTE*)dstBuffer;
570 BYTE* dstPtr = dstStart;
575 if (cctxPtr->
cStage != 1)
return (
size_t)-LZ4F_ERROR_GENERIC;
576 if (dstMaxSize <
LZ4F_compressBound(srcSize, &(cctxPtr->
prefs)))
return (
size_t)-LZ4F_ERROR_dstMaxSize_tooSmall;
577 memset(&cOptionsNull, 0,
sizeof(cOptionsNull));
578 if (compressOptionsPtr == NULL) compressOptionsPtr = &cOptionsNull;
586 size_t sizeToCopy = blockSize - cctxPtr->
tmpInSize;
587 if (sizeToCopy > srcSize)
599 memcpy(cctxPtr->
tmpIn + cctxPtr->
tmpInSize, srcBuffer, sizeToCopy);
600 srcPtr += sizeToCopy;
609 while ((
size_t)(srcEnd - srcPtr) >= blockSize)
635 if (realDictSize==0)
return (
size_t)-LZ4F_ERROR_GENERIC;
652 size_t sizeToCopy = srcEnd - srcPtr;
653 memcpy(cctxPtr->
tmpIn, srcPtr, sizeToCopy);
661 return dstPtr - dstStart;
676 BYTE*
const dstStart = (
BYTE*)dstBuffer;
677 BYTE* dstPtr = dstStart;
682 if (cctxPtr->
cStage != 1)
return (
size_t)-LZ4F_ERROR_GENERIC;
683 if (dstMaxSize < (cctxPtr->
tmpInSize + 8))
return (
size_t)-LZ4F_ERROR_dstMaxSize_tooSmall;
684 (void)compressOptionsPtr;
701 return dstPtr - dstStart;
717 BYTE*
const dstStart = (
BYTE*)dstBuffer;
718 BYTE* dstPtr = dstStart;
721 errorCode =
LZ4F_flush(compressionContext, dstBuffer, dstMaxSize, compressOptionsPtr);
740 return (
size_t)-LZ4F_ERROR_frameSize_wrong;
743 return dstPtr - dstStart;
767 dctxPtr->
version = versionNumber;
769 return LZ4F_OK_NoError;
813 unsigned version, blockMode, blockChecksumFlag, contentSizeFlag, contentChecksumFlag, blockSizeID;
815 size_t frameHeaderSize;
816 const BYTE* srcPtr = (
const BYTE*)srcVoidPtr;
819 if (srcSize <
minFHSize)
return (
size_t)-LZ4F_ERROR_frameHeader_incomplete;
826 if (srcVoidPtr == (
void*)(dctxPtr->
header))
846 version = (FLG>>6) &
_2BITS;
847 blockMode = (FLG>>5) &
_1BIT;
848 blockChecksumFlag = (FLG>>4) &
_1BIT;
849 contentSizeFlag = (FLG>>3) &
_1BIT;
850 contentChecksumFlag = (FLG>>2) &
_1BIT;
855 if (srcSize < frameHeaderSize)
858 if (srcPtr != dctxPtr->
header)
859 memcpy(dctxPtr->
header, srcPtr, srcSize);
867 blockSizeID = (BD>>4) &
_3BITS;
870 if (version != 1)
return (
size_t)-LZ4F_ERROR_headerVersion_wrong;
871 if (blockChecksumFlag != 0)
return (
size_t)-LZ4F_ERROR_blockChecksum_unsupported;
872 if (((FLG>>0)&
_2BITS) != 0)
return (
size_t)-LZ4F_ERROR_reservedFlag_set;
873 if (((BD>>7)&
_1BIT) != 0)
return (
size_t)-LZ4F_ERROR_reservedFlag_set;
874 if (blockSizeID < 4)
return (
size_t)-LZ4F_ERROR_maxBlockSize_invalid;
875 if (((BD>>0)&
_4BITS) != 0)
return (
size_t)-LZ4F_ERROR_reservedFlag_set;
879 if (HC != srcPtr[frameHeaderSize-1])
return (
size_t)-LZ4F_ERROR_headerChecksum_invalid;
900 if (dctxPtr->
tmpIn == NULL)
return (
size_t)-LZ4F_ERROR_GENERIC;
902 if (dctxPtr->
tmpOutBuffer== NULL)
return (
size_t)-LZ4F_ERROR_GENERIC;
914 return frameHeaderSize;
929 const void* srcBuffer,
size_t* srcSizePtr)
944 size_t nextSrcSize =
LZ4F_decompress(dCtx, NULL, &o, srcBuffer, srcSizePtr, NULL);
946 return (
size_t)-LZ4F_ERROR_frameHeader_incomplete;
956 (void)dictStart; (void)dictSize;
964 dctxPtr->
dict = (
const BYTE*)dstPtr;
972 if (dstPtr - dstPtr0 + dstSize >= 64
KB)
974 dctxPtr->
dict = (
const BYTE*)dstPtr0;
975 dctxPtr->
dictSize = dstPtr - dstPtr0 + dstSize;
992 if (copySize > preserveSize) copySize = preserveSize;
994 memcpy(dctxPtr->
tmpOutBuffer + preserveSize - copySize, oldDictEnd - copySize, copySize);
1005 size_t preserveSize = 64
KB - dstSize;
1016 size_t preserveSize = 64
KB - dstSize;
1019 memcpy(dctxPtr->
tmpOutBuffer + preserveSize, dstPtr, dstSize);
1021 dctxPtr->
dictSize = preserveSize + dstSize;
1045 void* dstBuffer,
size_t* dstSizePtr,
1046 const void* srcBuffer,
size_t* srcSizePtr,
1051 const BYTE*
const srcStart = (
const BYTE*)srcBuffer;
1052 const BYTE*
const srcEnd = srcStart + *srcSizePtr;
1053 const BYTE* srcPtr = srcStart;
1054 BYTE*
const dstStart = (
BYTE*)dstBuffer;
1055 BYTE*
const dstEnd = dstStart + *dstSizePtr;
1056 BYTE* dstPtr = dstStart;
1057 const BYTE* selectedIn = NULL;
1058 unsigned doAnotherStage = 1;
1059 size_t nextSrcSizeHint = 1;
1062 memset(&optionsNull, 0,
sizeof(optionsNull));
1063 if (decompressOptionsPtr==NULL) decompressOptionsPtr = &optionsNull;
1070 if (srcStart != dctxPtr->
srcExpect)
return (
size_t)-LZ4F_ERROR_srcPtr_wrong;
1075 while (doAnotherStage)
1083 if ((
size_t)(srcEnd-srcPtr) >=
maxFHSize)
1087 srcPtr += errorCode;
1098 if (sizeToCopy > (
size_t)(srcEnd - srcPtr)) sizeToCopy = srcEnd - srcPtr;
1101 srcPtr += sizeToCopy;
1117 if ((
size_t)(srcEnd - srcPtr) >=
BHSize)
1119 selectedIn = srcPtr;
1134 if (sizeToCopy > (
size_t)(srcEnd - srcPtr)) sizeToCopy = srcEnd - srcPtr;
1136 srcPtr += sizeToCopy;
1144 selectedIn = dctxPtr->
tmpIn;
1149 size_t nextCBlockSize =
LZ4F_readLE32(selectedIn) & 0x7FFFFFFFU;
1150 if (nextCBlockSize==0)
1155 if (nextCBlockSize > dctxPtr->
maxBlockSize)
return (
size_t)-LZ4F_ERROR_GENERIC;
1165 nextSrcSizeHint = nextCBlockSize +
BHSize;
1174 if ((
size_t)(srcEnd-srcPtr) < sizeToCopy) sizeToCopy = srcEnd - srcPtr;
1175 if ((
size_t)(dstEnd-dstPtr) < sizeToCopy) sizeToCopy = dstEnd - dstPtr;
1176 memcpy(dstPtr, srcPtr, sizeToCopy);
1184 srcPtr += sizeToCopy;
1185 dstPtr += sizeToCopy;
1199 if ((
size_t)(srcEnd-srcPtr) < dctxPtr->
tmpInTarget)
1205 selectedIn = srcPtr;
1214 if (sizeToCopy > (
size_t)(srcEnd-srcPtr)) sizeToCopy = srcEnd-srcPtr;
1217 srcPtr += sizeToCopy;
1224 selectedIn = dctxPtr->
tmpIn;
1240 int (*decoder)(
const char*,
char*, int, int,
const char*, int);
1249 if (decodedSize < 0)
return (
size_t)-LZ4F_ERROR_GENERIC;
1257 dstPtr += decodedSize;
1265 int (*decoder)(
const char*,
char*, int, int,
const char*, int);
1287 size_t reservedDictSpace = dctxPtr->
dictSize;
1288 if (reservedDictSpace > 64
KB) reservedDictSpace = 64
KB;
1295 if (decodedSize < 0)
return (
size_t)-LZ4F_ERROR_decompressionFailed;
1307 if (sizeToCopy > (
size_t)(dstEnd-dstPtr)) sizeToCopy = dstEnd-dstPtr;
1315 dstPtr += sizeToCopy;
1323 nextSrcSizeHint =
BHSize;
1332 if (suffixSize == 0)
1334 nextSrcSizeHint = 0;
1339 if ((srcEnd - srcPtr) < 4)
1346 selectedIn = srcPtr;
1354 size_t sizeToCopy = 4 - dctxPtr->
tmpInSize;
1355 if (sizeToCopy > (
size_t)(srcEnd - srcPtr)) sizeToCopy = srcEnd - srcPtr;
1357 srcPtr += sizeToCopy;
1361 nextSrcSizeHint = 4 - dctxPtr->
tmpInSize;
1365 selectedIn = dctxPtr->
tmpIn;
1372 if (readCRC != resultCRC)
return (
size_t)-LZ4F_ERROR_contentChecksum_invalid;
1373 nextSrcSizeHint = 0;
1381 if ((srcEnd - srcPtr) >= 4)
1383 selectedIn = srcPtr;
1399 if (sizeToCopy > (
size_t)(srcEnd - srcPtr)) sizeToCopy = srcEnd - srcPtr;
1401 srcPtr += sizeToCopy;
1409 selectedIn = dctxPtr->
header + 4;
1424 if (skipSize > (
size_t)(srcEnd-srcPtr)) skipSize = srcEnd-srcPtr;
1429 if (nextSrcSizeHint)
break;
1449 if (copySize > preserveSize) copySize = preserveSize;
1451 memcpy(dctxPtr->
tmpOutBuffer + preserveSize - copySize, oldDictEnd - copySize, copySize);
1458 size_t newDictSize = dctxPtr->
dictSize;
1460 if ((newDictSize) > 64
KB) newDictSize = 64
KB;
1462 memcpy(dctxPtr->
tmpOutBuffer, oldDictEnd - newDictSize, newDictSize);
1476 *srcSizePtr = (srcPtr - srcStart);
1477 *dstSizePtr = (dstPtr - dstStart);
1478 return nextSrcSizeHint;
int LZ4_decompress_safe(const char *source, char *dest, int compressedSize, int maxDecompressedSize)
int LZ4_compress_limitedOutput_continue(LZ4_stream_t *LZ4_streamPtr, const char *source, char *dest, int inputSize, int maxOutputSize)
LZ4_stream_t * LZ4_createStream(void)
void LZ4_resetStream(LZ4_stream_t *streamPtr)
int LZ4_decompress_safe_usingDict(const char *source, char *dest, int compressedSize, int maxDecompressedSize, const char *dictStart, int dictSize)
int LZ4_saveDict(LZ4_stream_t *streamPtr, char *safeBuffer, int dictSize)
int LZ4_compress_limitedOutput_withState(void *state, const char *source, char *dest, int inputSize, int maxOutputSize)
struct LZ4F_cctx_s * LZ4F_compressionContext_t
struct LZ4F_dctx_s * LZ4F_decompressionContext_t
@ LZ4F_contentChecksumEnabled
#define LZ4F_LIST_ERRORS(ITEM)
void LZ4_resetStreamHC(LZ4_streamHC_t *streamHCPtr, int compressionLevel)
int LZ4_saveDictHC(LZ4_streamHC_t *streamHCPtr, char *safeBuffer, int maxDictSize)
int LZ4_compress_HC_extStateHC(void *state, const char *src, char *dst, int srcSize, int maxDstSize, int compressionLevel)
LZ4_streamHC_t * LZ4_createStreamHC(void)
int LZ4_compress_HC_continue(LZ4_streamHC_t *streamHCPtr, const char *src, char *dst, int srcSize, int maxDstSize)
unsigned int XXH32_digest(const XXH32_state_t *statePtr)
XXH_errorcode XXH32_update(XXH32_state_t *statePtr, const void *input, size_t length)
XXH_errorcode XXH32_reset(XXH32_state_t *statePtr, unsigned seed)
unsigned int XXH32(const void *input, size_t length, unsigned seed)
struct LZ4F_cctx_s LZ4F_cctx_t
static LZ4F_blockSizeID_t LZ4F_optimalBSID(const LZ4F_blockSizeID_t requestedBSID, const size_t srcSize)
LZ4F_errorCode_t LZ4F_freeDecompressionContext(LZ4F_decompressionContext_t LZ4F_decompressionContext)
@ dstage_decodeCBlock_intoDst
@ dstage_decodeCBlock_intoTmp
size_t LZ4F_compressEnd(LZ4F_compressionContext_t compressionContext, void *dstBuffer, size_t dstMaxSize, const LZ4F_compressOptions_t *compressOptionsPtr)
static int LZ4F_localLZ4_compress_limitedOutput_continue(void *ctx, const char *src, char *dst, int srcSize, int dstSize, int level)
LZ4F_errorCode_t LZ4F_createDecompressionContext(LZ4F_decompressionContext_t *LZ4F_decompressionContextPtr, unsigned versionNumber)
LZ4F_errorCode_t LZ4F_createCompressionContext(LZ4F_compressionContext_t *LZ4F_compressionContextPtr, unsigned version)
static int LZ4F_localLZ4_compressHC_limitedOutput_continue(void *ctx, const char *src, char *dst, int srcSize, int dstSize, int level)
size_t LZ4F_compressFrameBound(size_t srcSize, const LZ4F_preferences_t *preferencesPtr)
static const size_t minFHSize
size_t LZ4F_decompress(LZ4F_decompressionContext_t decompressionContext, void *dstBuffer, size_t *dstSizePtr, const void *srcBuffer, size_t *srcSizePtr, const LZ4F_decompressOptions_t *decompressOptionsPtr)
size_t LZ4F_compressUpdate(LZ4F_compressionContext_t compressionContext, void *dstBuffer, size_t dstMaxSize, const void *srcBuffer, size_t srcSize, const LZ4F_compressOptions_t *compressOptionsPtr)
static const size_t BHSize
static const size_t maxFHSize
#define LZ4F_MAGIC_SKIPPABLE_START
static size_t LZ4F_decodeHeader(LZ4F_dctx_t *dctxPtr, const void *srcVoidPtr, size_t srcSize)
#define LZ4F_BLOCKUNCOMPRESSED_FLAG
static compressFunc_t LZ4F_selectCompression(LZ4F_blockMode_t blockMode, int level)
size_t LZ4F_compressBound(size_t srcSize, const LZ4F_preferences_t *preferencesPtr)
static const char * LZ4F_errorStrings[]
static int LZ4F_localLZ4_compress_limitedOutput_withState(void *ctx, const char *src, char *dst, int srcSize, int dstSize, int level)
#define LZ4F_BLOCKSIZEID_DEFAULT
static void LZ4F_writeLE64(BYTE *dstPtr, U64 value64)
static size_t LZ4F_getBlockSize(unsigned blockSizeID)
unsigned LZ4F_isError(LZ4F_errorCode_t code)
LZ4F_errorCode_t LZ4F_getFrameInfo(LZ4F_decompressionContext_t dCtx, LZ4F_frameInfo_t *frameInfoPtr, const void *srcBuffer, size_t *srcSizePtr)
size_t LZ4F_compressFrame(void *dstBuffer, size_t dstMaxSize, const void *srcBuffer, size_t srcSize, const LZ4F_preferences_t *preferencesPtr)
struct LZ4F_dctx_s LZ4F_dctx_t
size_t LZ4F_flush(LZ4F_compressionContext_t compressionContext, void *dstBuffer, size_t dstMaxSize, const LZ4F_compressOptions_t *compressOptionsPtr)
static int LZ4F_localSaveDict(LZ4F_cctx_t *cctxPtr)
static BYTE LZ4F_headerChecksum(const void *header, size_t length)
static void LZ4F_updateDict(LZ4F_dctx_t *dctxPtr, const BYTE *dstPtr, size_t dstSize, const BYTE *dstPtr0, unsigned withinTmp)
static U32 LZ4F_readLE32(const BYTE *srcPtr)
size_t LZ4F_compressBegin(LZ4F_compressionContext_t compressionContext, void *dstBuffer, size_t dstMaxSize, const LZ4F_preferences_t *preferencesPtr)
LZ4F_errorCode_t LZ4F_freeCompressionContext(LZ4F_compressionContext_t LZ4F_compressionContext)
static void LZ4F_writeLE32(BYTE *dstPtr, U32 value32)
int(* compressFunc_t)(void *ctx, const char *src, char *dst, int srcSize, int dstSize, int level)
const char * LZ4F_getErrorName(LZ4F_errorCode_t code)
static int LZ4F_decompress_safe(const char *source, char *dest, int compressedSize, int maxDecompressedSize, const char *dictStart, int dictSize)
static U64 LZ4F_readLE64(const BYTE *srcPtr)
static size_t LZ4F_compressBlock(void *dst, const void *src, size_t srcSize, compressFunc_t compress, void *lz4ctx, int level)
static const int minHClevel
#define LZ4F_GENERATE_STRING(STRING)
LZ4F_frameInfo_t frameInfo
LZ4F_contentChecksum_t contentChecksumFlag
unsigned long long contentSize
LZ4F_frameType_t frameType
LZ4F_blockMode_t blockMode
LZ4F_blockSizeID_t blockSizeID
LZ4F_frameInfo_t frameInfo