39 static const int LZ4HC_compressionLevel_default = 8;
52 # pragma GCC diagnostic ignored "-Wunused-function"
55 #if defined (__clang__)
56 # pragma clang diagnostic ignored "-Wunused-function"
63 #define LZ4_COMMONDEFS_ONLY
70 #define DICTIONARY_LOGSIZE 16
71 #define MAXD (1<<DICTIONARY_LOGSIZE)
72 #define MAXD_MASK ((U32)(MAXD - 1))
74 #define HASH_LOG (DICTIONARY_LOGSIZE-1)
75 #define HASHTABLESIZE (1 << HASH_LOG)
76 #define HASH_MASK (HASHTABLESIZE - 1)
78 #define OPTIMAL_ML (int)((ML_MASK-1)+MINMATCH)
80 static const int g_maxCompressionLevel = 16;
104 #define HASH_FUNCTION(i) (((i) * 2654435761U) >> ((MINMATCH*8)-HASH_LOG))
105 #define DELTANEXT(p) chainTable[(size_t)(p) & MAXD_MASK]
106 #define GETNEXT(p) ((p) - (size_t)DELTANEXT(p))
108 static U32 LZ4HC_hashPtr(
const void* ptr) {
return HASH_FUNCTION(LZ4_read32(ptr)); }
120 hc4->
base = start - 64
KB;
135 const U32 target = (
U32)(ip - base);
140 U32 h = LZ4HC_hashPtr(base+idx);
141 size_t delta = idx - HashTable[h];
143 chainTable[idx & 0xFFFF] = (
U16)delta;
153 const BYTE* ip,
const BYTE*
const iLimit,
154 const BYTE** matchpos,
155 const int maxNbAttempts)
165 int nbAttempts=maxNbAttempts;
170 matchIndex = HashTable[LZ4HC_hashPtr(ip)];
172 while ((matchIndex>=lowLimit) && (nbAttempts))
175 if (matchIndex >= dictLimit)
177 match = base + matchIndex;
178 if (*(match+ml) == *(ip+ml)
179 && (LZ4_read32(match) == LZ4_read32(ip)))
182 if (mlt > ml) { ml = mlt; *matchpos =
match; }
187 match = dictBase + matchIndex;
188 if (LZ4_read32(match) == LZ4_read32(ip))
191 const BYTE* vLimit = ip + (dictLimit - matchIndex);
192 if (vLimit > iLimit) vLimit = iLimit;
194 if ((ip+mlt == vLimit) && (vLimit < iLimit))
195 mlt += LZ4_count(ip+mlt, base+dictLimit, iLimit);
196 if (mlt > ml) { ml = mlt; *matchpos = base + matchIndex; }
199 matchIndex -= chainTable[matchIndex & 0xFFFF];
209 const BYTE* iLowLimit,
210 const BYTE* iHighLimit,
212 const BYTE** matchpos,
213 const BYTE** startpos,
214 const int maxNbAttempts)
224 int nbAttempts = maxNbAttempts;
225 int delta = (int)(ip-iLowLimit);
230 matchIndex = HashTable[LZ4HC_hashPtr(ip)];
232 while ((matchIndex>=lowLimit) && (nbAttempts))
235 if (matchIndex >= dictLimit)
237 match = base + matchIndex;
238 if (*(iLowLimit + longest) == *(match - delta + longest))
239 if (LZ4_read32(match) == LZ4_read32(ip))
241 const BYTE* startt = ip;
245 while ((startt>iLowLimit) && (tmpMatch > iLowLimit) && (startt[-1] == tmpMatch[-1])) {startt--; tmpMatch--;}
247 if ((matchEnd-startt) > longest)
249 longest = (int)(matchEnd-startt);
250 *matchpos = tmpMatch;
257 match = dictBase + matchIndex;
258 if (LZ4_read32(match) == LZ4_read32(ip))
262 const BYTE* vLimit = ip + (dictLimit - matchIndex);
263 if (vLimit > iHighLimit) vLimit = iHighLimit;
265 if ((ip+mlt == vLimit) && (vLimit < iHighLimit))
266 mlt += LZ4_count(ip+mlt, base+dictLimit, iHighLimit);
267 while ((ip+back > iLowLimit) && (matchIndex+back > lowLimit) && (ip[back-1] == match[back-1])) back--;
269 if ((
int)mlt > longest) { longest = (int)mlt; *matchpos = base + matchIndex + back; *startpos = ip+back; }
272 matchIndex -= chainTable[matchIndex & 0xFFFF];
281 #define LZ4HC_DEBUG 0
283 static unsigned debug = 0;
299 if (debug) printf(
"literal : %u -- match : %u -- offset : %u\n", (
U32)(*ip - *anchor), (
U32)matchLength, (
U32)(*ip-match));
303 length = (int)(*ip - *anchor);
305 if ((limitedOutputBuffer) && ((*op + (length>>8) + length + (2 + 1 +
LASTLITERALS)) > oend))
return 1;
310 LZ4_wildCopy(*op, *anchor, (*op) + length);
314 LZ4_writeLE16(*op, (
U16)(*ip-match)); *op += 2;
317 length = (int)(matchLength-
MINMATCH);
318 if ((limitedOutputBuffer) && (*op + (length>>8) + (1 +
LASTLITERALS) > oend))
return 1;
319 if (length>=(
int)
ML_MASK) { *token+=
ML_MASK; length-=
ML_MASK;
for(; length > 509 ; length-=510) { *(*op)++ = 255; *(*op)++ = 255; }
if (length > 254) { length-=255; *(*op)++ = 255; } *(*op)++ = (
BYTE)length; }
320 else *token += (
BYTE)(length);
330 static int LZ4HC_compress_generic (
336 int compressionLevel,
341 const BYTE* ip = (
const BYTE*) source;
342 const BYTE* anchor = ip;
343 const BYTE*
const iend = ip + inputSize;
348 BYTE*
const oend = op + maxOutputSize;
350 unsigned maxNbAttempts;
351 int ml, ml2, ml3, ml0;
352 const BYTE* ref=NULL;
353 const BYTE* start2=NULL;
354 const BYTE* ref2=NULL;
355 const BYTE* start3=NULL;
356 const BYTE* ref3=NULL;
362 if (compressionLevel > g_maxCompressionLevel) compressionLevel = g_maxCompressionLevel;
363 if (compressionLevel < 1) compressionLevel = LZ4HC_compressionLevel_default;
364 maxNbAttempts = 1 << (compressionLevel-1);
365 ctx->
end += inputSize;
373 if (!ml) { ip++;
continue; }
393 if (start2 < ip + ml0)
402 if ((start2 - ip) < 3)
421 if (ip+new_ml > start2 + ml2 -
MINMATCH) new_ml = (int)(start2 - ip) + ml2 -
MINMATCH;
422 correction = new_ml - (int)(start2 - ip);
425 start2 += correction;
432 if (start2 + ml2 < mflimit)
439 if (start2 < ip+ml) ml = (int)(start2 - ip);
447 if (start3 < ip+ml+3)
449 if (start3 >= (ip+ml))
453 int correction = (int)(ip+ml - start2);
454 start2 += correction;
488 if ((start2 - ip) < (int)
ML_MASK)
492 if (ip + ml > start2 + ml2 - MINMATCH) ml = (int)(start2 - ip) + ml2 -
MINMATCH;
493 correction = ml - (int)(start2 - ip);
496 start2 += correction;
503 ml = (int)(start2 - ip);
521 int lastRun = (int)(iend - anchor);
522 if ((limit) && (((
char*)op - dest) + lastRun + 1 + ((lastRun+255-
RUN_MASK)/255) > (
U32)maxOutputSize))
return 0;
525 memcpy(op, anchor, iend - anchor);
530 return (
int) (((
char*)op)-dest);
534 int LZ4_compressHC2(
const char* source,
char* dest,
int inputSize,
int compressionLevel)
537 LZ4HC_init(&ctx, (
const BYTE*)source);
538 return LZ4HC_compress_generic (&ctx, source, dest, inputSize, 0, compressionLevel,
noLimit);
546 LZ4HC_init(&ctx, (
const BYTE*)source);
547 return LZ4HC_compress_generic (&ctx, source, dest, inputSize, maxOutputSize, compressionLevel,
limitedOutput);
564 if (((
size_t)(state)&(
sizeof(
void*)-1)) != 0)
return 0;
566 return LZ4HC_compress_generic (state, source, dest, inputSize, 0, compressionLevel,
noLimit);
575 if (((
size_t)(state)&(
sizeof(
void*)-1)) != 0)
return 0;
577 return LZ4HC_compress_generic (state, source, dest, inputSize, maxOutputSize, compressionLevel,
limitedOutput);
604 if (dictSize > 64
KB)
606 dictionary += dictSize - 64
KB;
609 LZ4HC_init (ctxPtr, (
const BYTE*)dictionary);
610 if (dictSize >= 4)
LZ4HC_Insert (ctxPtr, (
const BYTE*)dictionary +(dictSize-3));
611 ctxPtr->
end = (
const BYTE*)dictionary + dictSize;
620 if (ctxPtr->
end >= ctxPtr->
base + 4)
627 ctxPtr->
end = newBlock;
632 const char* source,
char* dest,
636 if (ctxPtr->
base == NULL)
637 LZ4HC_init (ctxPtr, (
const BYTE*) source);
640 if ((
size_t)(ctxPtr->
end - ctxPtr->
base) > 2
GB)
643 if (dictSize > 64
KB) dictSize = 64
KB;
649 if ((
const BYTE*)source != ctxPtr->
end) LZ4HC_setExternalDict(ctxPtr, (
const BYTE*)source);
653 const BYTE* sourceEnd = (
const BYTE*) source + inputSize;
656 if ((sourceEnd > dictBegin) && ((
BYTE*)source < dictEnd))
658 if (sourceEnd > dictEnd) sourceEnd = dictEnd;
664 return LZ4HC_compress_generic (ctxPtr, source, dest, inputSize, maxOutputSize, ctxPtr->
compressionLevel, limit);
683 int prefixSize = (int)(streamPtr->
end - (streamPtr->
base + streamPtr->
dictLimit));
684 if (dictSize > 64
KB) dictSize = 64
KB;
685 if (dictSize < 4) dictSize = 0;
686 if (dictSize > prefixSize) dictSize = prefixSize;
687 memcpy(safeBuffer, streamPtr->
end - dictSize, dictSize);
690 streamPtr->
end = (
const BYTE*)safeBuffer + dictSize;
691 streamPtr->
base = streamPtr->
end - endIndex;
692 streamPtr->
dictLimit = endIndex - dictSize;
693 streamPtr->
lowLimit = endIndex - dictSize;
707 if ((((
size_t)state) & (
sizeof(
void*)-1)) != 0)
return 1;
738 return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, 0, compressionLevel,
noLimit);
743 return LZ4HC_compress_generic (LZ4HC_Data, source, dest, inputSize, maxOutputSize, compressionLevel,
limitedOutput);