48 # pragma warning(disable : 4127)
61 # define LZ4F_HEAPMODE 0
68 #define LZ4F_STATIC_LINKING_ONLY
70 #define LZ4_STATIC_LINKING_ONLY
72 #define LZ4_HC_STATIC_LINKING_ONLY
74 #define XXH_STATIC_LINKING_ONLY
89 #ifndef LZ4_SRC_INCLUDED
90 # define MEM_INIT(p,v,s) memset((p),(v),(s))
93 #ifndef LZ4_SRC_INCLUDED
95 # define ALLOC(s) malloc(s)
96 # define ALLOC_AND_ZERO(s) calloc(1,(s))
97 # define FREEMEM(p) free(p)
103 if (cmem.customCalloc != NULL) {
104 return cmem.customCalloc(cmem.opaqueState,
s);
107 if (cmem.customAlloc == NULL) {
111 {
void*
const p = cmem.customAlloc(cmem.opaqueState,
s);
119 if (cmem.customAlloc != NULL) {
120 return cmem.customAlloc(cmem.opaqueState,
s);
129 if (cmem.customFree != NULL) {
130 cmem.customFree(cmem.opaqueState, p);
141 #if defined(LZ4_DEBUG) && (LZ4_DEBUG>=1)
145 # define assert(condition) ((void)0)
149 #define LZ4F_STATIC_ASSERT(c) { enum { LZ4F_static_assert = 1/(int)(!!(c)) }; }
151 #if defined(LZ4_DEBUG) && (LZ4_DEBUG>=2) && !defined(DEBUGLOG)
153 static int g_debuglog_enable = 1;
154 # define DEBUGLOG(l, ...) { \
155 if ((g_debuglog_enable) && (l<=LZ4_DEBUG)) { \
156 fprintf(stderr, __FILE__ ": "); \
157 fprintf(stderr, __VA_ARGS__); \
158 fprintf(stderr, " \n"); \
161 # define DEBUGLOG(l, ...) {}
168 #if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) ) )
170 typedef uint8_t
BYTE;
171 typedef uint16_t
U16;
172 typedef uint32_t
U32;
174 typedef uint64_t
U64;
177 typedef unsigned short U16;
180 typedef unsigned long long U64;
187 const BYTE*
const srcPtr = (
const BYTE*)src;
188 U32 value32 = srcPtr[0];
189 value32 += ((
U32)srcPtr[1])<< 8;
190 value32 += ((
U32)srcPtr[2])<<16;
191 value32 += ((
U32)srcPtr[3])<<24;
198 dstPtr[0] = (
BYTE)value32;
199 dstPtr[1] = (
BYTE)(value32 >> 8);
200 dstPtr[2] = (
BYTE)(value32 >> 16);
201 dstPtr[3] = (
BYTE)(value32 >> 24);
206 const BYTE*
const srcPtr = (
const BYTE*)src;
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);
221 dstPtr[0] = (
BYTE)value64;
222 dstPtr[1] = (
BYTE)(value64 >> 8);
223 dstPtr[2] = (
BYTE)(value64 >> 16);
224 dstPtr[3] = (
BYTE)(value64 >> 24);
225 dstPtr[4] = (
BYTE)(value64 >> 32);
226 dstPtr[5] = (
BYTE)(value64 >> 40);
227 dstPtr[6] = (
BYTE)(value64 >> 48);
228 dstPtr[7] = (
BYTE)(value64 >> 56);
235 #ifndef LZ4_SRC_INCLUDED
247 #define LZ4F_BLOCKUNCOMPRESSED_FLAG 0x80000000U
248 #define LZ4F_BLOCKSIZEID_DEFAULT LZ4F_max64KB
286 #define LZ4F_GENERATE_STRING(STRING) #STRING,
297 static const char* codeError =
"Unspecified error code";
304 if (!
LZ4F_isError(functionResult))
return LZ4F_OK_NoError;
305 return (LZ4F_errorCodes)(-(ptrdiff_t)functionResult);
315 #define RETURN_ERROR(e) return LZ4F_returnErrorCode(LZ4F_ERROR_ ## e)
317 #define RETURN_ERROR_IF(c,e) if (c) RETURN_ERROR(e)
319 #define FORWARD_IF_ERROR(r) if (LZ4F_isError(r)) return (r)
327 static const size_t blockSizes[4] = { 64
KB, 256
KB, 1
MB, 4
MB };
330 if (blockSizeID < LZ4F_max64KB || blockSizeID >
LZ4F_max4MB)
333 return blockSizes[blockSizeIdx];
339 #define MIN(a,b) ( (a) < (b) ? (a) : (b) )
344 return (
BYTE)(xxh >> 8);
355 size_t maxBlockSize = 64
KB;
356 while (requestedBSID > proposedBSID) {
362 return requestedBSID;
373 size_t alreadyBuffered)
378 {
const LZ4F_preferences_t*
const prefsPtr = (preferencesPtr==NULL) ? &prefsNull : preferencesPtr;
382 size_t const maxBuffered = blockSize - 1;
383 size_t const bufferedSize =
MIN(alreadyBuffered, maxBuffered);
384 size_t const maxSrcSize =
srcSize + bufferedSize;
385 unsigned const nbFullBlocks = (unsigned)(maxSrcSize / blockSize);
386 size_t const partialBlockSize = maxSrcSize & (blockSize-1);
387 size_t const lastBlockSize = flush ? partialBlockSize : 0;
388 unsigned const nbBlocks = nbFullBlocks + (lastBlockSize>0);
393 return ((
BHSize + blockCRCSize) * nbBlocks) +
394 (blockSize * nbFullBlocks) + lastBlockSize + frameEnd;
403 if (preferencesPtr!=NULL) prefs = *preferencesPtr;
404 else MEM_INIT(&prefs, 0,
sizeof(prefs));
421 void* dstBuffer,
size_t dstCapacity,
422 const void* srcBuffer,
size_t srcSize,
423 const LZ4F_CDict* cdict,
428 BYTE*
const dstStart = (
BYTE*) dstBuffer;
429 BYTE* dstPtr = dstStart;
430 BYTE*
const dstEnd = dstStart + dstCapacity;
432 if (preferencesPtr!=NULL)
433 prefs = *preferencesPtr;
444 MEM_INIT(&options, 0,
sizeof(options));
451 dstPtr += headerSize; }
459 {
size_t const tailSize =
LZ4F_compressEnd(cctx, dstPtr, (
size_t)(dstEnd-dstPtr), &options);
461 dstPtr += tailSize; }
463 assert(dstEnd >= dstStart);
464 return (
size_t)(dstPtr - dstStart);
476 const void* srcBuffer,
size_t srcSize,
492 if ( preferencesPtr == NULL
504 NULL, preferencesPtr);
509 if ( preferencesPtr != NULL
532 const char* dictStart = (
const char*)dictBuffer;
533 LZ4F_CDict*
const cdict = (LZ4F_CDict*)
LZ4F_malloc(
sizeof(*cdict), cmem);
534 DEBUGLOG(4,
"LZ4F_createCDict_advanced");
535 if (!cdict)
return NULL;
537 if (dictSize > 64
KB) {
538 dictStart += dictSize - 64
KB;
548 if (!cdict->dictContent || !cdict->fastCtx || !cdict->HCCtx) {
552 memcpy(cdict->dictContent, dictStart, dictSize);
553 LZ4_loadDict (cdict->fastCtx, (
const char*)cdict->dictContent, (
int)dictSize);
555 LZ4_loadDictHC(cdict->HCCtx, (
const char*)cdict->dictContent, (
int)dictSize);
573 if (cdict==NULL)
return;
574 LZ4F_free(cdict->dictContent, cdict->cmem);
590 if (cctxPtr==NULL)
return NULL;
592 cctxPtr->
cmem = customMem;
610 assert(LZ4F_compressionContextPtr != NULL);
616 return LZ4F_OK_NoError;
622 if (cctxPtr != NULL) {
627 return LZ4F_OK_NoError;
640 const LZ4F_CDict* cdict,
678 void* dstBuffer,
size_t dstCapacity,
679 const LZ4F_CDict* cdict,
683 BYTE*
const dstStart = (
BYTE*)dstBuffer;
684 BYTE* dstPtr = dstStart;
687 if (preferencesPtr == NULL) preferencesPtr = &prefNull;
688 cctxPtr->
prefs = *preferencesPtr;
694 if (allocatedSize < requiredSize) {
728 {
size_t const requiredBuffSize = preferencesPtr->
autoFlush ?
744 cctxPtr->
cdict = cdict;
756 {
BYTE*
const headerStart = dstPtr;
784 return (
size_t)(dstPtr - dstStart);
796 void* dstBuffer,
size_t dstCapacity,
800 NULL, preferencesPtr);
811 if (preferencesPtr && preferencesPtr->
autoFlush) {
826 const void* src,
size_t srcSize,
828 const LZ4F_CDict* cdict,
834 cSize = (
U32)compress(lz4ctx, (
const char*)src, (
char*)(cSizePtr+
BHSize),
838 if (cSize == 0 || cSize >=
srcSize) {
855 int const acceleration = (level < 0) ? -level + 1 : 1;
867 int const acceleration = (level < 0) ? -level + 1 : 1;
931 void* dstBuffer,
size_t dstCapacity,
932 const void* srcBuffer,
size_t srcSize,
937 const BYTE* srcPtr = (
const BYTE*)srcBuffer;
939 BYTE*
const dstStart = (
BYTE*)dstBuffer;
940 BYTE* dstPtr = dstStart;
955 bytesWritten =
LZ4F_flush(cctxPtr, dstBuffer, dstCapacity, compressOptionsPtr);
956 dstPtr += bytesWritten;
960 if (compressOptionsPtr == NULL) compressOptionsPtr = &
k_cOptionsNull;
964 size_t const sizeToCopy = blockSize - cctxPtr->
tmpInSize;
975 memcpy(cctxPtr->
tmpIn + cctxPtr->
tmpInSize, srcBuffer, sizeToCopy);
976 srcPtr += sizeToCopy;
979 cctxPtr->
tmpIn, blockSize,
987 while ((
size_t)(srcEnd - srcPtr) >= blockSize) {
1002 srcPtr, (
size_t)(srcEnd - srcPtr),
1017 assert(0 <= realDictSize && realDictSize <= 64
KB);
1034 if (srcPtr < srcEnd) {
1036 size_t const sizeToCopy = (
size_t)(srcEnd - srcPtr);
1037 memcpy(cctxPtr->
tmpIn, srcPtr, sizeToCopy);
1045 return (
size_t)(dstPtr - dstStart);
1061 void* dstBuffer,
size_t dstCapacity,
1062 const void* srcBuffer,
size_t srcSize,
1066 dstBuffer, dstCapacity,
1085 void* dstBuffer,
size_t dstCapacity,
1086 const void* srcBuffer,
size_t srcSize,
1090 dstBuffer, dstCapacity,
1105 void* dstBuffer,
size_t dstCapacity,
1108 BYTE*
const dstStart = (
BYTE*)dstBuffer;
1109 BYTE* dstPtr = dstStart;
1115 (
void)compressOptionsPtr;
1126 assert(((
void)
"flush overflows dstBuffer!", (
size_t)(dstPtr - dstStart) <= dstCapacity));
1138 return (
size_t)(dstPtr - dstStart);
1152 void* dstBuffer,
size_t dstCapacity,
1155 BYTE*
const dstStart = (
BYTE*)dstBuffer;
1156 BYTE* dstPtr = dstStart;
1158 size_t const flushSize =
LZ4F_flush(cctxPtr, dstBuffer, dstCapacity, compressOptionsPtr);
1159 DEBUGLOG(5,
"LZ4F_compressEnd: dstCapacity=%u", (
unsigned)dstCapacity);
1161 dstPtr += flushSize;
1163 assert(flushSize <= dstCapacity);
1164 dstCapacity -= flushSize;
1173 DEBUGLOG(5,
"Writing 32-bit content checksum");
1186 return (
size_t)(dstPtr - dstStart);
1233 if (dctx == NULL)
return NULL;
1235 dctx->
cmem = customMem;
1249 assert(LZ4F_decompressionContextPtr != NULL);
1250 RETURN_ERROR_IF(LZ4F_decompressionContextPtr == NULL, parameter_null);
1253 if (*LZ4F_decompressionContextPtr == NULL) {
1256 return LZ4F_OK_NoError;
1293 unsigned blockMode, blockChecksumFlag, contentSizeFlag, contentChecksumFlag, dictIDFlag, blockSizeID;
1294 size_t frameHeaderSize;
1295 const BYTE* srcPtr = (
const BYTE*)src;
1305 if (src == (
void*)(dctx->
header)) {
1316 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1318 DEBUGLOG(4,
"frame header error : unknown magic number");
1325 {
U32 const FLG = srcPtr[4];
1327 blockChecksumFlag = (FLG>>4) &
_1BIT;
1328 blockMode = (FLG>>5) &
_1BIT;
1329 contentSizeFlag = (FLG>>3) &
_1BIT;
1330 contentChecksumFlag = (FLG>>2) &
_1BIT;
1331 dictIDFlag = FLG &
_1BIT;
1338 frameHeaderSize =
minFHSize + (contentSizeFlag?8:0) + (dictIDFlag?4:0);
1340 if (
srcSize < frameHeaderSize) {
1342 if (srcPtr != dctx->
header)
1350 {
U32 const BD = srcPtr[5];
1351 blockSizeID = (BD>>4) &
_3BITS;
1354 if (blockSizeID < 4)
RETURN_ERROR(maxBlockSize_invalid);
1359 assert(frameHeaderSize > 5);
1360 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1362 RETURN_ERROR_IF(HC != srcPtr[frameHeaderSize-1], headerChecksum_invalid);
1372 if (contentSizeFlag)
1379 return frameHeaderSize;
1400 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1406 {
BYTE const FLG = ((
const BYTE*)src)[4];
1407 U32 const contentSizeFlag = (FLG>>3) &
_1BIT;
1408 U32 const dictIDFlag = FLG &
_1BIT;
1409 return minFHSize + (contentSizeFlag?8:0) + (dictIDFlag?4:0);
1430 const void* srcBuffer,
size_t* srcSizePtr)
1447 if (
LZ4F_isError(hSize)) { *srcSizePtr=0;
return hSize; }
1448 if (*srcSizePtr < hSize) {
1457 *srcSizePtr = decodeResult;
1461 return decodeResult;
1471 const BYTE* dstPtr,
size_t dstSize,
const BYTE* dstBufferStart,
1483 assert(dstPtr >= dstBufferStart);
1484 if ((
size_t)(dstPtr - dstBufferStart) + dstSize >= 64
KB) {
1485 dctx->
dict = (
const BYTE*)dstBufferStart;
1507 if (copySize > preserveSize) copySize = preserveSize;
1509 memcpy(dctx->
tmpOutBuffer + preserveSize - copySize, oldDictEnd - copySize, copySize);
1518 size_t const preserveSize = 64
KB - dstSize;
1528 {
size_t preserveSize = 64
KB - dstSize;
1531 memcpy(dctx->
tmpOutBuffer + preserveSize, dstPtr, dstSize);
1533 dctx->
dictSize = preserveSize + dstSize;
1557 void* dstBuffer,
size_t* dstSizePtr,
1558 const void* srcBuffer,
size_t* srcSizePtr,
1562 const BYTE*
const srcStart = (
const BYTE*)srcBuffer;
1563 const BYTE*
const srcEnd = srcStart + *srcSizePtr;
1564 const BYTE* srcPtr = srcStart;
1565 BYTE*
const dstStart = (
BYTE*)dstBuffer;
1566 BYTE*
const dstEnd = dstStart ? dstStart + *dstSizePtr : NULL;
1567 BYTE* dstPtr = dstStart;
1568 const BYTE* selectedIn = NULL;
1569 unsigned doAnotherStage = 1;
1570 size_t nextSrcSizeHint = 1;
1573 DEBUGLOG(5,
"LZ4F_decompress : %p,%u => %p,%u",
1574 srcBuffer, (
unsigned)*srcSizePtr, dstBuffer, (
unsigned)*dstSizePtr);
1575 if (dstBuffer == NULL)
assert(*dstSizePtr == 0);
1576 MEM_INIT(&optionsNull, 0,
sizeof(optionsNull));
1577 if (decompressOptionsPtr==NULL) decompressOptionsPtr = &optionsNull;
1585 while (doAnotherStage) {
1591 DEBUGLOG(6,
"dstage_getFrameHeader");
1592 if ((
size_t)(srcEnd-srcPtr) >=
maxFHSize) {
1599 if (srcEnd-srcPtr == 0)
return minFHSize;
1605 DEBUGLOG(6,
"dstage_storeFrameHeader");
1609 srcPtr += sizeToCopy;
1645 if ((
size_t)(srcEnd - srcPtr) >=
BHSize) {
1646 selectedIn = srcPtr;
1656 {
size_t const remainingInput = (
size_t)(srcEnd - srcPtr);
1658 size_t const sizeToCopy =
MIN(wantedData, remainingInput);
1660 srcPtr += sizeToCopy;
1668 selectedIn = dctx->
tmpIn;
1673 size_t const nextCBlockSize = blockHeader & 0x7FFFFFFFU;
1675 if (blockHeader==0) {
1686 DEBUGLOG(5,
"next block is uncompressed (size %u)", (
U32)nextCBlockSize);
1696 if (dstPtr==dstEnd || srcPtr==srcEnd) {
1697 nextSrcSizeHint =
BHSize + nextCBlockSize + crcSize;
1705 {
size_t sizeToCopy;
1706 if (dstPtr == NULL) {
1709 size_t const minBuffSize =
MIN((
size_t)(srcEnd-srcPtr), (
size_t)(dstEnd-dstPtr));
1711 memcpy(dstPtr, srcPtr, sizeToCopy);
1727 srcPtr += sizeToCopy;
1728 dstPtr += sizeToCopy;
1747 DEBUGLOG(6,
"dstage_getBlockChecksum");
1748 {
const void* crcSrc;
1749 if ((srcEnd-srcPtr >= 4) && (dctx->
tmpInSize==0)) {
1753 size_t const stillToCopy = 4 - dctx->
tmpInSize;
1754 size_t const sizeToCopy =
MIN(stillToCopy, (
size_t)(srcEnd-srcPtr));
1757 srcPtr += sizeToCopy;
1767 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1768 DEBUGLOG(6,
"compare block checksum");
1769 if (readCRC != calcCRC) {
1770 DEBUGLOG(4,
"incorrect block checksum: %08X != %08X",
1784 if ((
size_t)(srcEnd-srcPtr) < dctx->
tmpInTarget) {
1790 selectedIn = srcPtr;
1796 size_t const inputLeft = (
size_t)(srcEnd-srcPtr);
1797 size_t const sizeToCopy =
MIN(wantedData, inputLeft);
1800 srcPtr += sizeToCopy;
1808 selectedIn = dctx->
tmpIn;
1817 assert(selectedIn != NULL);
1820 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1835 const char* dict = (
const char*)dctx->
dict;
1839 if (dict && dictSize > 1
GB) {
1841 dict += dictSize - 64
KB;
1845 (
const char*)selectedIn, (
char*)dstPtr,
1847 dict, (
int)dictSize);
1859 dstPtr += decodedSize;
1876 size_t const reservedDictSpace =
MIN(dctx->
dictSize, 64
KB);
1881 {
const char* dict = (
const char*)dctx->
dict;
1884 if (dict && dictSize > 1
GB) {
1886 dict += dictSize - 64
KB;
1890 (
const char*)selectedIn, (
char*)dctx->
tmpOut,
1892 dict, (
int)dictSize);
1906 if (dstPtr != NULL) {
1915 dstPtr += sizeToCopy;
1923 nextSrcSizeHint =
BHSize;
1929 nextSrcSizeHint = 0;
1934 if ((srcEnd - srcPtr) < 4) {
1938 selectedIn = srcPtr;
1944 {
size_t const remainingInput = (
size_t)(srcEnd - srcPtr);
1945 size_t const wantedData = 4 - dctx->
tmpInSize;
1946 size_t const sizeToCopy =
MIN(wantedData, remainingInput);
1948 srcPtr += sizeToCopy;
1955 selectedIn = dctx->
tmpIn;
1962 #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
1969 nextSrcSizeHint = 0;
1975 if ((srcEnd - srcPtr) >= 4) {
1976 selectedIn = srcPtr;
1988 (
size_t)(srcEnd - srcPtr) );
1990 srcPtr += sizeToCopy;
1998 selectedIn = dctx->
header + 4;
2010 {
size_t const skipSize =
MIN(dctx->
tmpInTarget, (
size_t)(srcEnd-srcPtr));
2015 if (nextSrcSizeHint)
break;
2027 && (dctx->
dict != NULL)
2036 if (copySize > preserveSize) copySize = preserveSize;
2039 memcpy(dctx->
tmpOutBuffer + preserveSize - copySize, oldDictEnd - copySize, copySize);
2047 memcpy(dctx->
tmpOutBuffer, oldDictEnd - newDictSize, newDictSize);
2055 *srcSizePtr = (
size_t)(srcPtr - srcStart);
2056 *dstSizePtr = (
size_t)(dstPtr - dstStart);
2057 return nextSrcSizeHint;
2066 void* dstBuffer,
size_t* dstSizePtr,
2067 const void* srcBuffer,
size_t* srcSizePtr,
2068 const void* dict,
size_t dictSize,
2076 srcBuffer, srcSizePtr,
2077 decompressOptionsPtr);