44 # pragma warning(disable : 4127)
47 #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
49 # pragma GCC diagnostic ignored "-Wmissing-braces"
50 # pragma GCC diagnostic ignored "-Wmissing-field-initializers"
58 #define ALLOCATOR(s) calloc(1,s)
61 #define MEM_INIT memset
76 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
84 typedef unsigned char BYTE;
85 typedef unsigned short U16;
86 typedef unsigned int U32;
87 typedef signed int S32;
88 typedef unsigned long long U64;
105 #define LZ4F_MAGICNUMBER 0x184D2204U
106 #define LZ4F_BLOCKUNCOMPRESSED_FLAG 0x80000000U
107 #define LZ4F_MAXHEADERFRAME_SIZE 7
108 #define LZ4F_BLOCKSIZEID_DEFAULT max64KB
110 static const U32 minHClevel = 3;
160 #define LZ4F_GENERATE_STRING(STRING) #STRING,
171 static const char* codeError =
"Unspecified error code";
172 if (
LZ4F_isError(code))
return LZ4F_errorStrings[-(int)(code)];
180 static size_t LZ4F_getBlockSize(
unsigned blockSizeID)
182 static const size_t blockSizes[4] = { 64
KB, 256
KB, 1
MB, 4 MB };
186 if (blockSizeID > 3)
return (
size_t)-ERROR_maxBlockSize_invalid;
187 return blockSizes[blockSizeID];
192 static void LZ4F_writeLE32 (
BYTE* dstPtr,
U32 value32)
194 dstPtr[0] = (
BYTE)value32;
195 dstPtr[1] = (
BYTE)(value32 >> 8);
196 dstPtr[2] = (
BYTE)(value32 >> 16);
197 dstPtr[3] = (
BYTE)(value32 >> 24);
200 static U32 LZ4F_readLE32 (
const BYTE* srcPtr)
202 U32 value32 = srcPtr[0];
203 value32 += (srcPtr[1]<<8);
204 value32 += (srcPtr[2]<<16);
205 value32 += (srcPtr[3]<<24);
213 return (
BYTE)(xxh >> 8);
226 if (preferencesPtr!=NULL) prefs = *preferencesPtr;
229 size_t maxBlockSize = 64
KB;
232 if (srcSize <= maxBlockSize)
246 return headerSize + streamSize;
265 BYTE*
const dstStart = (
BYTE*) dstBuffer;
266 BYTE* dstPtr = dstStart;
267 BYTE*
const dstEnd = dstStart + dstMaxSize;
273 if (preferencesPtr!=NULL) prefs = *preferencesPtr;
276 size_t maxBlockSize = 64
KB;
279 if (srcSize <= maxBlockSize)
295 return (
size_t)-ERROR_dstMaxSize_tooSmall;
301 dstMaxSize -= errorCode;
312 return (dstPtr - dstStart);
350 FREEMEM(LZ4F_compressionContext);
366 BYTE*
const dstStart = (
BYTE*)dstBuffer;
367 BYTE* dstPtr = dstStart;
369 size_t requiredBuffSize;
372 if (cctxPtr->
cStage != 0)
return (
size_t)-ERROR_GENERIC;
373 if (preferencesPtr == NULL) preferencesPtr = &prefNull;
374 cctxPtr->
prefs = *preferencesPtr;
403 if (cctxPtr->
tmpBuff == NULL)
return (
size_t)-ERROR_allocation_failed;
416 headerStart = dstPtr;
419 *dstPtr++ = ((1 &
_2BITS) << 6)
425 *dstPtr++ = LZ4F_headerChecksum(headerStart, 2);
429 return (dstPtr - dstStart);
440 const LZ4F_preferences_t* prefsPtr = (preferencesPtr==NULL) ? &prefsNull : preferencesPtr;
442 size_t blockSize = LZ4F_getBlockSize(bid);
443 unsigned nbBlocks = (unsigned)(srcSize / blockSize) + 1;
444 size_t lastBlockSize = prefsPtr->
autoFlush ? srcSize % blockSize : blockSize;
445 size_t blockInfo = 4;
447 size_t result = (blockInfo * nbBlocks) + (blockSize * (nbBlocks-1)) + lastBlockSize + frameEnd;
453 typedef int (*
compressFunc_t)(
void* ctx,
const char* src,
char* dst,
int srcSize,
int dstSize,
int level);
455 static size_t LZ4F_compressBlock(
void* dst,
const void* src,
size_t srcSize,
compressFunc_t compress,
void* lz4ctx,
int level)
460 cSize = (
U32)
compress(lz4ctx, (
const char*)src, (
char*)(cSizePtr+4), (int)(srcSize), (int)(srcSize-1), level);
461 LZ4F_writeLE32(cSizePtr, cSize);
464 cSize = (
U32)srcSize;
466 memcpy(cSizePtr+4, src, srcSize);
472 static int LZ4F_localLZ4_compress_limitedOutput_withState(
void* ctx,
const char* src,
char* dst,
int srcSize,
int dstSize,
int level)
478 static int LZ4F_localLZ4_compress_limitedOutput_continue(
void* ctx,
const char* src,
char* dst,
int srcSize,
int dstSize,
int level)
484 static int LZ4F_localLZ4_compressHC_limitedOutput_continue(
void* ctx,
const char* src,
char* dst,
int srcSize,
int dstSize,
int level)
492 if (level < minHClevel)
494 if (blockMode ==
blockIndependent)
return LZ4F_localLZ4_compress_limitedOutput_withState;
495 return LZ4F_localLZ4_compress_limitedOutput_continue;
498 return LZ4F_localLZ4_compressHC_limitedOutput_continue;
524 const BYTE* srcPtr = (
const BYTE*)srcBuffer;
525 const BYTE*
const srcEnd = srcPtr + srcSize;
526 BYTE*
const dstStart = (
BYTE*)dstBuffer;
527 BYTE* dstPtr = dstStart;
532 if (cctxPtr->
cStage != 1)
return (
size_t)-ERROR_GENERIC;
534 if (compressOptionsPtr == NULL) compressOptionsPtr = &cOptionsNull;
542 size_t sizeToCopy = blockSize - cctxPtr->
tmpInSize;
543 if (sizeToCopy > srcSize)
555 memcpy(cctxPtr->
tmpIn + cctxPtr->
tmpInSize, srcBuffer, sizeToCopy);
556 srcPtr += sizeToCopy;
565 while ((
size_t)(srcEnd - srcPtr) >= blockSize)
590 int realDictSize = LZ4F_localSaveDict(cctxPtr);
591 if (realDictSize==0)
return (
size_t)-ERROR_GENERIC;
600 LZ4F_localSaveDict(cctxPtr);
608 size_t sizeToCopy = srcEnd - srcPtr;
609 memcpy(cctxPtr->
tmpIn, srcPtr, sizeToCopy);
616 return dstPtr - dstStart;
632 BYTE*
const dstStart = (
BYTE*)dstBuffer;
633 BYTE* dstPtr = dstStart;
638 if (cctxPtr->
cStage != 1)
return (
size_t)-ERROR_GENERIC;
639 if (dstMaxSize < (cctxPtr->
tmpInSize + 16))
return (
size_t)-ERROR_dstMaxSize_tooSmall;
640 if (compressOptionsPtr == NULL) compressOptionsPtr = &cOptionsNull;
641 (void)compressOptionsPtr;
654 LZ4F_localSaveDict(cctxPtr);
658 return dstPtr - dstStart;
674 BYTE*
const dstStart = (
BYTE*)dstBuffer;
675 BYTE* dstPtr = dstStart;
678 errorCode =
LZ4F_flush(compressionContext, dstBuffer, dstMaxSize, compressOptionsPtr);
682 LZ4F_writeLE32(dstPtr, 0);
688 LZ4F_writeLE32(dstPtr, xxh);
694 return dstPtr - dstStart;
718 dctxPtr->
version = versionNumber;
738 unsigned version, blockMode, blockChecksumFlag, contentSizeFlag, contentChecksumFlag, dictFlag, blockSizeID;
742 if (srcSize < 7)
return (
size_t)-ERROR_GENERIC;
745 if (LZ4F_readLE32(srcPtr) !=
LZ4F_MAGICNUMBER)
return (
size_t)-ERROR_GENERIC;
750 version = (FLG>>6)&
_2BITS;
751 blockMode = (FLG>>5) &
_1BIT;
752 blockChecksumFlag = (FLG>>4) &
_1BIT;
753 contentSizeFlag = (FLG>>3) &
_1BIT;
754 contentChecksumFlag = (FLG>>2) &
_1BIT;
755 dictFlag = (FLG>>0) &
_1BIT;
757 blockSizeID = (BD>>4) &
_3BITS;
760 HC = LZ4F_headerChecksum(srcPtr, 2);
761 if (HC != srcPtr[2])
return (
size_t)-ERROR_GENERIC;
764 if (version != 1)
return (
size_t)-ERROR_GENERIC;
765 if (blockChecksumFlag != 0)
return (
size_t)-ERROR_GENERIC;
766 if (contentSizeFlag != 0)
return (
size_t)-ERROR_GENERIC;
767 if (((FLG>>1)&
_1BIT) != 0)
return (
size_t)-ERROR_GENERIC;
768 if (dictFlag != 0)
return (
size_t)-ERROR_GENERIC;
769 if (((BD>>7)&
_1BIT) != 0)
return (
size_t)-ERROR_GENERIC;
770 if (blockSizeID < 4)
return (
size_t)-ERROR_GENERIC;
771 if (((BD>>0)&
_4BITS) != 0)
return (
size_t)-ERROR_GENERIC;
790 if (dctxPtr->
tmpIn == NULL)
return (
size_t)-ERROR_GENERIC;
792 if (dctxPtr->
tmpOutBuffer== NULL)
return (
size_t)-ERROR_GENERIC;
831 LZ4F_errorCode_t errorCode = LZ4F_decodeHeader(dctxPtr, srcBuffer, *srcSizePtr);
833 *srcSizePtr = errorCode;
847 static int LZ4F_decompress_safe (
const char* source,
char* dest,
int compressedSize,
int maxDecompressedSize,
const char* dictStart,
int dictSize)
867 if (dstPtr - dstPtr0 + dstSize >= 64
KB)
870 dctxPtr->
dictSize = dstPtr - dstPtr0 + dstSize;
896 if (copySize > preserveSize) copySize = preserveSize;
898 memcpy(dctxPtr->
tmpOutBuffer + preserveSize - copySize, oldDictEnd - copySize, copySize);
910 size_t preserveSize = 64
KB - dstSize;
911 memcpy(dctxPtr->
dict, dctxPtr->
dict + dctxPtr->
dictSize - preserveSize, preserveSize);
914 memcpy(dctxPtr->
dict + dctxPtr->
dictSize, dstPtr, dstSize);
921 size_t preserveSize = 64
KB - dstSize;
924 memcpy(dctxPtr->
tmpOutBuffer + preserveSize, dstPtr, dstSize);
926 dctxPtr->
dictSize = preserveSize + dstSize;
950 void* dstBuffer,
size_t* dstSizePtr,
951 const void* srcBuffer,
size_t* srcSizePtr,
956 const BYTE*
const srcStart = (
const BYTE*)srcBuffer;
957 const BYTE*
const srcEnd = srcStart + *srcSizePtr;
958 const BYTE* srcPtr = srcStart;
959 BYTE*
const dstStart = (
BYTE*)dstBuffer;
960 BYTE*
const dstEnd = dstStart + *dstSizePtr;
961 BYTE* dstPtr = dstStart;
962 const BYTE* selectedIn=NULL;
963 unsigned doAnotherStage = 1;
964 size_t nextSrcSizeHint = 1;
967 if (decompressOptionsPtr==NULL) decompressOptionsPtr = &optionsNull;
974 if (srcStart != dctxPtr->
srcExpect)
return (
size_t)-ERROR_GENERIC;
979 while (doAnotherStage)
987 if (srcEnd-srcPtr >= 7)
1001 size_t sizeToCopy = 7 - dctxPtr->
tmpInSize;
1002 if (sizeToCopy > (
size_t)(srcEnd - srcPtr)) sizeToCopy = srcEnd - srcPtr;
1005 srcPtr += sizeToCopy;
1008 nextSrcSizeHint = (7 - dctxPtr->
tmpInSize) + 4;
1012 selectedIn = dctxPtr->
header;
1027 if ((srcEnd - srcPtr) >= 4)
1029 selectedIn = srcPtr;
1042 size_t sizeToCopy = 4 - dctxPtr->
tmpInSize;
1043 if (sizeToCopy > (
size_t)(srcEnd - srcPtr)) sizeToCopy = srcEnd - srcPtr;
1045 srcPtr += sizeToCopy;
1049 nextSrcSizeHint = 4 - dctxPtr->
tmpInSize;
1053 selectedIn = dctxPtr->
tmpIn;
1060 size_t nextCBlockSize = LZ4F_readLE32(selectedIn) & 0x7FFFFFFFU;
1061 if (nextCBlockSize==0)
1066 if (nextCBlockSize > dctxPtr->
maxBlockSize)
return (
size_t)-ERROR_GENERIC;
1076 nextSrcSizeHint = nextCBlockSize + 4;
1085 if ((
size_t)(srcEnd-srcPtr) < sizeToCopy) sizeToCopy = srcEnd - srcPtr;
1086 if ((
size_t)(dstEnd-dstPtr) < sizeToCopy) sizeToCopy = dstEnd - dstPtr;
1087 memcpy(dstPtr, srcPtr, sizeToCopy);
1092 LZ4F_updateDict(dctxPtr, dstPtr, sizeToCopy, dstStart, 0);
1094 srcPtr += sizeToCopy;
1095 dstPtr += sizeToCopy;
1109 if ((
size_t)(srcEnd-srcPtr) < dctxPtr->
tmpInTarget)
1115 selectedIn = srcPtr;
1124 if (sizeToCopy > (
size_t)(srcEnd-srcPtr)) sizeToCopy = srcEnd-srcPtr;
1127 srcPtr += sizeToCopy;
1134 selectedIn = dctxPtr->
tmpIn;
1150 int (*decoder)(
const char*,
char*, int, int,
const char*, int);
1156 decoder = LZ4F_decompress_safe;
1159 if (decodedSize < 0)
return (
size_t)-ERROR_GENERIC;
1164 LZ4F_updateDict(dctxPtr, dstPtr, decodedSize, dstStart, 0);
1166 dstPtr += decodedSize;
1174 int (*decoder)(
const char*,
char*, int, int,
const char*, int);
1180 decoder = LZ4F_decompress_safe;
1196 size_t reservedDictSpace = dctxPtr->
dictSize;
1197 if (reservedDictSpace > 64
KB) reservedDictSpace = 64
KB;
1204 if (decodedSize < 0)
return (
size_t)-ERROR_decompressionFailed;
1215 if (sizeToCopy > (
size_t)(dstEnd-dstPtr)) sizeToCopy = dstEnd-dstPtr;
1220 LZ4F_updateDict(dctxPtr, dstPtr, sizeToCopy, dstStart, 1);
1223 dstPtr += sizeToCopy;
1231 nextSrcSizeHint = 4;
1239 if (suffixSize == 0)
1241 nextSrcSizeHint = 0;
1246 if ((srcEnd - srcPtr) >= 4)
1248 selectedIn = srcPtr;
1260 size_t sizeToCopy = 4 - dctxPtr->
tmpInSize;
1261 if (sizeToCopy > (
size_t)(srcEnd - srcPtr)) sizeToCopy = srcEnd - srcPtr;
1263 srcPtr += sizeToCopy;
1267 nextSrcSizeHint = 4 - dctxPtr->
tmpInSize;
1271 selectedIn = dctxPtr->
tmpIn;
1278 U32 readCRC = LZ4F_readLE32(selectedIn);
1280 if (readCRC != resultCRC)
return (
size_t)-ERROR_checksum_invalid;
1281 nextSrcSizeHint = 0;
1302 if (copySize > preserveSize) copySize = preserveSize;
1304 memcpy(dctxPtr->
tmpOutBuffer + preserveSize - copySize, oldDictEnd - copySize, copySize);
1311 size_t newDictSize = dctxPtr->
dictSize;
1313 if ((newDictSize) > 64
KB) newDictSize = 64
KB;
1315 memcpy(dctxPtr->
tmpOutBuffer, oldDictEnd - newDictSize, newDictSize);
1327 *srcSizePtr = (srcPtr - srcStart);
1328 *dstSizePtr = (dstPtr - dstStart);
1329 return nextSrcSizeHint;