46 #ifndef LZ4HC_HEAPMODE
47 # define LZ4HC_HEAPMODE 1
52 #define LZ4_HC_STATIC_LINKING_ONLY
58 # pragma GCC diagnostic ignored "-Wunused-function"
60 #if defined (__clang__)
61 # pragma clang diagnostic ignored "-Wunused-function"
64 #define LZ4_COMMONDEFS_ONLY
65 #ifndef LZ4_SRC_INCLUDED
75 #define OPTIMAL_ML (int)((ML_MASK-1)+MINMATCH)
76 #define LZ4_OPT_NUM (1<<12)
80 #define MIN(a,b) ( (a) < (b) ? (a) : (b) )
81 #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
82 #define HASH_FUNCTION(i) (((i) * 2654435761U) >> ((MINMATCH*8)-LZ4HC_HASH_LOG))
83 #define DELTANEXTMAXD(p) chainTable[(p) & LZ4HC_MAXD_MASK]
84 #define DELTANEXTU16(table, pos) table[(U16)(pos)]
86 #define UPDATABLE(ip, op, anchor) &ip, &op, &anchor
103 size_t newStartingOffset = bufferSize + hc4->
dictLimit;
104 assert(newStartingOffset >= bufferSize);
105 if (newStartingOffset > 1
GB) {
107 newStartingOffset = 0;
109 newStartingOffset += 64
KB;
126 U32 const target = (
U32)(
ip - prefixPtr) + prefixIdx;
129 assert(target >= prefixIdx);
131 while (idx < target) {
133 size_t delta = idx - hashTable[h];
134 if (delta>LZ4_DISTANCE_MAX) delta = LZ4_DISTANCE_MAX;
147 const BYTE*
const iMin,
const BYTE*
const mMin)
155 && (
ip[back-1] ==
match[back-1]) )
160 #if defined(_MSC_VER)
161 # define LZ4HC_rotl32(x,r) _rotl(x,r)
163 # define LZ4HC_rotl32(x,r) ((x << r) | (x >> (32 - r)))
169 size_t const bitsToRotate = (rotate & (
sizeof(pattern) - 1)) << 3;
170 if (bitsToRotate == 0)
return pattern;
179 const BYTE*
const iStart =
ip;
180 reg_t const pattern = (
sizeof(pattern)==8) ?
181 (
reg_t)pattern32 + (((
reg_t)pattern32) << (
sizeof(pattern)*4)) : pattern32;
183 while (
likely(
ip < iEnd-(
sizeof(pattern)-1))) {
185 if (!diff) {
ip+=
sizeof(pattern);
continue; }
187 return (
unsigned)(
ip - iStart);
191 reg_t patternByte = pattern;
192 while ((
ip<iEnd) && (*
ip == (
BYTE)patternByte)) {
193 ip++; patternByte >>= 8;
196 U32 bitOffset = (
sizeof(pattern)*8) - 8;
198 BYTE const byte = (
BYTE)(pattern >> bitOffset);
199 if (*
ip !=
byte)
break;
200 ip ++; bitOffset -= 8;
203 return (
unsigned)(
ip - iStart);
212 const BYTE*
const iStart =
ip;
218 {
const BYTE* bytePtr = (
const BYTE*)(&pattern) + 3;
220 if (
ip[-1] != *bytePtr)
break;
223 return (
unsigned)(iStart -
ip);
233 return ((
U32)((dictLimit - 1) - matchIndex) >= 3);
243 const BYTE*
const iLowLimit,
const BYTE*
const iHighLimit,
245 const BYTE** matchpos,
246 const BYTE** startpos,
247 const int maxNbAttempts,
248 const int patternAnalysis,
const int chainSwap,
257 const U32 ipIndex = (
U32)(
ip - prefixPtr) + prefixIdx;
258 const int withinStartDistance = (hc4->
lowLimit + (LZ4_DISTANCE_MAX + 1) > ipIndex);
259 const U32 lowestMatchIndex = (withinStartDistance) ? hc4->
lowLimit : ipIndex - LZ4_DISTANCE_MAX;
262 const BYTE*
const dictEnd = dictStart + prefixIdx - dictIdx;
263 int const lookBackLength = (
int)(
ip-iLowLimit);
264 int nbAttempts = maxNbAttempts;
265 U32 matchChainPos = 0;
269 size_t srcPatternLength = 0;
271 DEBUGLOG(7,
"LZ4HC_InsertAndGetWiderMatch");
275 DEBUGLOG(7,
"First match at index %u / %u (lowestMatchIndex)",
276 matchIndex, lowestMatchIndex);
278 while ((matchIndex>=lowestMatchIndex) && (nbAttempts>0)) {
281 assert(matchIndex < ipIndex);
282 if (favorDecSpeed && (ipIndex - matchIndex < 8)) {
284 }
else if (matchIndex >= prefixIdx) {
285 const BYTE*
const matchPtr = prefixPtr + matchIndex - prefixIdx;
288 if (
LZ4_read16(iLowLimit + longest - 1) ==
LZ4_read16(matchPtr - lookBackLength + longest - 1)) {
290 int const back = lookBackLength ?
LZ4HC_countBack(
ip, matchPtr, iLowLimit, prefixPtr) : 0;
293 if (matchLength > longest) {
294 longest = matchLength;
295 *matchpos = matchPtr + back;
296 *startpos =
ip + back;
299 const BYTE*
const matchPtr = dictStart + (matchIndex - dictIdx);
300 assert(matchIndex >= dictIdx);
301 if (
likely(matchIndex <= prefixIdx - 4)
304 const BYTE* vLimit =
ip + (prefixIdx - matchIndex);
305 if (vLimit > iHighLimit) vLimit = iHighLimit;
307 if ((
ip+matchLength == vLimit) && (vLimit < iHighLimit))
308 matchLength +=
LZ4_count(
ip+matchLength, prefixPtr, iHighLimit);
311 if (matchLength > longest) {
312 longest = matchLength;
313 *matchpos = prefixPtr - prefixIdx + matchIndex + back;
314 *startpos =
ip + back;
317 if (chainSwap && matchLength==longest) {
318 assert(lookBackLength==0);
319 if (matchIndex + (
U32)longest <= ipIndex) {
320 int const kTrigger = 4;
321 U32 distanceToNextMatch = 1;
322 int const end = longest -
MINMATCH + 1;
324 int accel = 1 << kTrigger;
326 for (pos = 0; pos < end; pos += step) {
328 step = (accel++ >> kTrigger);
329 if (candidateDist > distanceToNextMatch) {
330 distanceToNextMatch = candidateDist;
331 matchChainPos = (
U32)pos;
332 accel = 1 << kTrigger;
334 if (distanceToNextMatch > 1) {
335 if (distanceToNextMatch > matchIndex)
break;
336 matchIndex -= distanceToNextMatch;
341 if (patternAnalysis && distNextMatch==1 && matchChainPos==0) {
342 U32 const matchCandidateIdx = matchIndex-1;
345 if ( ((pattern & 0xFFFF) == (pattern >> 16))
346 & ((pattern & 0xFF) == (pattern >> 24)) ) {
348 srcPatternLength =
LZ4HC_countPattern(
ip+
sizeof(pattern), iHighLimit, pattern) +
sizeof(pattern);
352 if ( (repeat ==
rep_confirmed) && (matchCandidateIdx >= lowestMatchIndex)
354 const int extDict = matchCandidateIdx < prefixIdx;
355 const BYTE*
const matchPtr = (extDict ? dictStart - dictIdx : prefixPtr - prefixIdx) + matchCandidateIdx;
357 const BYTE*
const iLimit = extDict ? dictEnd : iHighLimit;
358 size_t forwardPatternLength =
LZ4HC_countPattern(matchPtr+
sizeof(pattern), iLimit, pattern) +
sizeof(pattern);
359 if (extDict && matchPtr + forwardPatternLength == iLimit) {
363 {
const BYTE*
const lowestMatchPtr = extDict ? dictStart : prefixPtr;
365 size_t currentSegmentLength;
367 && matchPtr - backLength == prefixPtr
368 && dictIdx < prefixIdx) {
373 backLength = matchCandidateIdx -
MAX(matchCandidateIdx - (
U32)backLength, lowestMatchIndex);
374 assert(matchCandidateIdx - backLength >= lowestMatchIndex);
375 currentSegmentLength = backLength + forwardPatternLength;
377 if ( (currentSegmentLength >= srcPatternLength)
378 && (forwardPatternLength <= srcPatternLength) ) {
379 U32 const newMatchIndex = matchCandidateIdx + (
U32)forwardPatternLength - (
U32)srcPatternLength;
381 matchIndex = newMatchIndex;
384 assert(newMatchIndex >= prefixIdx - 3 && newMatchIndex < prefixIdx && !extDict);
385 matchIndex = prefixIdx;
388 U32 const newMatchIndex = matchCandidateIdx - (
U32)backLength;
390 assert(newMatchIndex >= prefixIdx - 3 && newMatchIndex < prefixIdx && !extDict);
391 matchIndex = prefixIdx;
393 matchIndex = newMatchIndex;
394 if (lookBackLength==0) {
395 size_t const maxML =
MIN(currentSegmentLength, srcPatternLength);
396 if ((
size_t)longest < maxML) {
397 assert(prefixPtr - prefixIdx + matchIndex !=
ip);
398 if ((
size_t)(
ip - prefixPtr) + prefixIdx - matchIndex > LZ4_DISTANCE_MAX)
break;
400 longest = (
int)maxML;
401 *matchpos = prefixPtr - prefixIdx + matchIndex;
405 if (distToNextPattern > matchIndex)
break;
406 matchIndex -= distToNextPattern;
413 matchIndex -=
DELTANEXTU16(chainTable, matchIndex + matchChainPos);
419 && ipIndex - lowestMatchIndex < LZ4_DISTANCE_MAX) {
423 matchIndex = dictMatchIndex + lowestMatchIndex - (
U32)dictEndOffset;
424 while (ipIndex - matchIndex <= LZ4_DISTANCE_MAX && nbAttempts--) {
430 const BYTE* vLimit =
ip + (dictEndOffset - dictMatchIndex);
431 if (vLimit > iHighLimit) vLimit = iHighLimit;
437 *matchpos = prefixPtr - prefixIdx + matchIndex + back;
438 *startpos =
ip + back;
442 dictMatchIndex -= nextOffset;
443 matchIndex -= nextOffset;
451 const BYTE*
const ip,
const BYTE*
const iLimit,
452 const BYTE** matchpos,
453 const int maxNbAttempts,
454 const int patternAnalysis,
457 const BYTE* uselessPtr =
ip;
461 return LZ4HC_InsertAndGetWiderMatch(hc4,
ip,
ip, iLimit,
MINMATCH-1, matchpos, &uselessPtr, maxNbAttempts, patternAnalysis, 0 , dict,
favorCompressionRatio);
470 const BYTE** _anchor,
478 #define anchor (*_anchor)
483 #if defined(LZ4_DEBUG) && (LZ4_DEBUG >= 6)
485 static U32 totalCost = 0;
488 U32 const llAdd = (ll>=15) ? ((ll-15) / 255) + 1 : 0;
489 U32 const mlAdd = (matchLength>=19) ? ((matchLength-19) / 255) + 1 : 0;
490 U32 const cost = 1 + llAdd + ll + 2 + mlAdd;
493 DEBUGLOG(6,
"pos:%7u -- literals:%4u, match:%4i, offset:%5u, cost:%4u + %5u",
504 if (limit && ((
op + (length / 255) + length + (2 + 1 +
LASTLITERALS)) > oend)) {
505 DEBUGLOG(6,
"Not enough room to write %i literals (%i bytes remaining)",
506 (
int)length, (
int)(oend -
op));
512 for(; len >= 255 ; len -= 255) *
op++ = 255;
530 DEBUGLOG(6,
"Not enough room to write match length");
536 for(; length >= 510 ; length -= 510) { *
op++ = 255; *
op++ = 255; }
537 if (length >= 255) { length -= 255; *
op++ = 255; }
540 *token += (
BYTE)(length);
565 const int patternAnalysis = (maxNbAttempts > 128);
577 int ml0, ml, ml2, ml3;
580 const BYTE* ref = NULL;
581 const BYTE* start2 = NULL;
582 const BYTE* ref2 = NULL;
583 const BYTE* start3 = NULL;
584 const BYTE* ref3 = NULL;
592 while (
ip <= mflimit) {
597 start0 =
ip; ref0 = ref; ml0 = ml;
600 if (
ip+ml <= mflimit) {
602 ip + ml - 2,
ip + 0, matchlimit, ml, &ref2, &start2,
615 if (start2 <
ip + ml0) {
616 ip = start0; ref = ref0; ml = ml0;
620 if ((start2 -
ip) < 3) {
636 correction = new_ml - (
int)(start2 -
ip);
637 if (correction > 0) {
638 start2 += correction;
645 if (start2 + ml2 <= mflimit) {
647 start2 + ml2 - 3, start2, matchlimit, ml2, &ref3, &start3,
655 if (start2 <
ip+ml) ml = (
int)(start2 -
ip);
669 if (start3 <
ip+ml+3) {
670 if (start3 >= (
ip+ml)) {
671 if (start2 <
ip+ml) {
672 int correction = (
int)(
ip+ml - start2);
673 start2 += correction;
706 if (start2 <
ip+ml) {
711 correction = ml - (
int)(start2 -
ip);
712 if (correction > 0) {
713 start2 += correction;
718 ml = (
int)(start2 -
ip);
725 ip = start2; ref = ref2; ml = ml2;
728 start2 = start3; ref2 = ref3; ml2 = ml3;
737 size_t llAdd = (lastRunSize + 255 -
RUN_MASK) / 255;
738 size_t const totalSize = 1 + llAdd + lastRunSize;
740 if (limit && (
op + totalSize > oend)) {
743 lastRunSize = (
size_t)(oend -
op) - 1 ;
744 llAdd = (lastRunSize + 256 -
RUN_MASK) / 256;
745 lastRunSize -= llAdd;
747 DEBUGLOG(6,
"Final literal run : %i literals", (
int)lastRunSize);
751 size_t accumulator = lastRunSize -
RUN_MASK;
753 for(; accumulator >= 255 ; accumulator -= 255) *
op++ = 255;
754 *
op++ = (
BYTE) accumulator;
764 return (
int) (((
char*)
op)-
dest);
770 size_t const ll_addbytes = (ll + 240) / 255;
771 size_t const ll_totalCost = 1 + ll_addbytes + ll;
772 BYTE*
const maxLitPos = oend - 3;
773 DEBUGLOG(6,
"Last sequence overflowing");
775 if (
op + ll_totalCost <= maxLitPos) {
777 size_t const bytesLeftForMl = (
size_t)(maxLitPos - (
op+ll_totalCost));
778 size_t const maxMlSize =
MINMATCH + (
ML_MASK-1) + (bytesLeftForMl * 255);
780 if ((
size_t)ml > maxMlSize) ml = (
int)maxMlSize;
793 int* srcSizePtr,
int dstCapacity,
794 int const nbSearches,
size_t sufficient_len,
802 const char*
const src,
804 int*
const srcSizePtr,
805 int const dstCapacity,
811 typedef enum { lz4hc, lz4opt } lz4hc_strat_e;
833 DEBUGLOG(4,
"LZ4HC_compress_generic(ctx=%p, src=%p, srcSize=%d, limit=%d)",
834 ctx, src, *srcSizePtr, limit);
836 if (limit ==
fillOutput && dstCapacity < 1)
return 0;
839 ctx->
end += *srcSizePtr;
842 { cParams_t
const cParam = clTable[cLevel];
846 if (cParam.strat == lz4hc) {
848 src,
dst, srcSizePtr, dstCapacity,
849 cParam.nbSearches, limit, dict);
851 assert(cParam.strat == lz4opt);
853 src,
dst, srcSizePtr, dstCapacity,
854 cParam.nbSearches, cParam.targetLength, limit,
858 if (result <= 0) ctx->
dirty = 1;
868 const char*
const src,
870 int*
const srcSizePtr,
871 int const dstCapacity,
883 const char*
const src,
885 int*
const srcSizePtr,
886 int const dstCapacity,
893 if (position >= 64
KB) {
896 }
else if (position == 0 && *srcSizePtr > 4
KB) {
909 const char*
const src,
911 int*
const srcSizePtr,
912 int const dstCapacity,
954 if (ctx==NULL)
return 0;
961 #if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1
963 if (statePtr==NULL)
return 0;
969 #if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1
979 if (ctx==NULL)
return 0;
991 #if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION)
996 if (
state == NULL)
return NULL;
1003 DEBUGLOG(4,
"LZ4_freeStreamHC(%p)", LZ4_streamHCPtr);
1004 if (!LZ4_streamHCPtr)
return 0;
1014 DEBUGLOG(4,
"LZ4_initStreamHC(%p, %u)", buffer, (
unsigned)
size);
1016 if (buffer == NULL)
return NULL;
1021 MEM_INIT(hcstate, 0,
sizeof(*hcstate)); }
1023 return LZ4_streamHCPtr;
1067 const char* dictionary,
int dictSize)
1070 DEBUGLOG(4,
"LZ4_loadDictHC(ctx:%p, dict:%p, dictSize:%d)", LZ4_streamHCPtr, dictionary, dictSize);
1071 assert(LZ4_streamHCPtr != NULL);
1072 if (dictSize > 64
KB) {
1073 dictionary += (
size_t)dictSize - 64
KB;
1082 ctxPtr->
end = (
const BYTE*)dictionary + dictSize;
1095 DEBUGLOG(4,
"LZ4HC_setExternalDict(%p, %p)", ctxPtr, newBlock);
1104 ctxPtr->
end = newBlock;
1113 const char* src,
char*
dst,
1114 int* srcSizePtr,
int dstCapacity,
1118 DEBUGLOG(5,
"LZ4_compressHC_continue_generic(ctx=%p, src=%p, srcSize=%d, limit=%d)",
1119 LZ4_streamHCPtr, src, *srcSizePtr, limit);
1127 if (dictSize > 64
KB) dictSize = 64
KB;
1128 LZ4_loadDictHC(LZ4_streamHCPtr, (
const char*)(ctxPtr->
end) - dictSize, (
int)dictSize);
1132 if ((
const BYTE*)src != ctxPtr->
end)
1136 {
const BYTE* sourceEnd = (
const BYTE*) src + *srcSizePtr;
1139 if ((sourceEnd > dictBegin) && ((
const BYTE*)src < dictEnd)) {
1140 if (sourceEnd > dictEnd) sourceEnd = dictEnd;
1175 DEBUGLOG(5,
"LZ4_saveDictHC(%p, %p, %d)", LZ4_streamHCPtr, safeBuffer, dictSize);
1177 if (dictSize > 64
KB) dictSize = 64
KB;
1178 if (dictSize < 4) dictSize = 0;
1179 if (dictSize > prefixSize) dictSize = prefixSize;
1180 if (safeBuffer == NULL)
assert(dictSize == 0);
1184 streamPtr->
end = (
const BYTE*)safeBuffer + dictSize;
1210 int LZ4_compressHC2_limitedOutput_withStateHC (
void*
state,
const char* src,
char*
dst,
int srcSize,
int maxDstSize,
int cLevel) {
return LZ4_compress_HC_extStateHC(
state, src,
dst,
srcSize,
maxDstSize, cLevel); }
1223 if (hc4 == NULL)
return 1;
1228 #if !defined(LZ4_STATIC_LINKING_ONLY_DISABLE_MEMORY_ALLOCATION)
1232 if (hc4 == NULL)
return NULL;
1239 if (!LZ4HC_Data)
return 0;
1261 return (
char*)(
uptrval)bufferStart;
1309 const BYTE*
ip,
const BYTE*
const iHighLimit,
1310 int minLen,
int nbSearches,
1315 const BYTE* matchPtr = NULL;
1319 int matchLength =
LZ4HC_InsertAndGetWiderMatch(ctx,
ip,
ip, iHighLimit, minLen, &matchPtr, &
ip, nbSearches, 1 , 1 , dict, favorDecSpeed);
1320 if (matchLength <= minLen)
return match;
1321 if (favorDecSpeed) {
1322 if ((matchLength>18) & (matchLength<=36)) matchLength=18;
1324 match.len = matchLength;
1331 const char*
const source,
1335 int const nbSearches,
1336 size_t sufficient_len,
1338 int const fullUpdate,
1343 #define TRAILING_LITERALS 3
1344 #if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1
1352 const BYTE*
const iend =
ip + *srcSizePtr;
1357 BYTE* oend =
op + dstCapacity;
1359 const BYTE* ovref = NULL;
1362 #if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1
1363 if (opt == NULL)
goto _return_label;
1365 DEBUGLOG(5,
"LZ4HC_compress_optimal(dst=%p, dstCapa=%u)",
dst, (
unsigned)dstCapacity);
1371 while (
ip <= mflimit) {
1373 int best_mlen, best_off;
1374 int cur, last_match_pos = 0;
1377 if (firstMatch.
len==0) {
ip++;
continue; }
1379 if ((
size_t)firstMatch.
len > sufficient_len) {
1381 int const firstML = firstMatch.
len;
1382 const BYTE*
const matchPos =
ip - firstMatch.
off;
1387 goto _dest_overflow;
1394 for (rPos = 0 ; rPos <
MINMATCH ; rPos++) {
1398 opt[rPos].
litlen = llen + rPos;
1399 opt[rPos].
price = cost;
1400 DEBUGLOG(7,
"rPos:%3i => price:%3i (litlen=%i) -- initial setup",
1401 rPos, cost, opt[rPos].litlen);
1405 int const matchML = firstMatch.
len;
1406 int const offset = firstMatch.
off;
1408 for ( ; mlen <= matchML ; mlen++) {
1410 opt[mlen].
mlen = mlen;
1411 opt[mlen].
off = offset;
1413 opt[mlen].
price = cost;
1414 DEBUGLOG(7,
"rPos:%3i => price:%3i (matchlen=%i) -- initial setup",
1417 last_match_pos = firstMatch.
len;
1420 opt[last_match_pos+addLit].
mlen = 1;
1421 opt[last_match_pos+addLit].
off = 0;
1422 opt[last_match_pos+addLit].
litlen = addLit;
1424 DEBUGLOG(7,
"rPos:%3i => price:%3i (litlen=%i) -- initial setup",
1425 last_match_pos+addLit, opt[last_match_pos+addLit].price, addLit);
1429 for (cur = 1; cur < last_match_pos; cur++) {
1430 const BYTE*
const curPtr =
ip + cur;
1433 if (curPtr > mflimit)
break;
1434 DEBUGLOG(7,
"rPos:%u[%u] vs [%u]%u",
1435 cur, opt[cur].price, opt[cur+1].price, cur+1);
1438 if ( (opt[cur+1].price <= opt[cur].price)
1440 && (opt[cur+
MINMATCH].price < opt[cur].price + 3) )
1444 if (opt[cur+1].price <= opt[cur].price)
continue;
1447 DEBUGLOG(7,
"search at rPos:%u", cur);
1452 newMatch =
LZ4HC_FindLongerMatch(ctx, curPtr, matchlimit, last_match_pos - cur, nbSearches, dict, favorDecSpeed);
1453 if (!newMatch.
len)
continue;
1455 if ( ((
size_t)newMatch.
len > sufficient_len)
1458 best_mlen = newMatch.
len;
1459 best_off = newMatch.
off;
1460 last_match_pos = cur + 1;
1465 {
int const baseLitlen = opt[cur].
litlen;
1467 for (litlen = 1; litlen <
MINMATCH; litlen++) {
1469 int const pos = cur + litlen;
1470 if (price < opt[pos].price) {
1473 opt[pos].
litlen = baseLitlen+litlen;
1474 opt[pos].
price = price;
1475 DEBUGLOG(7,
"rPos:%3i => price:%3i (litlen=%i)",
1476 pos, price, opt[pos].litlen);
1480 {
int const matchML = newMatch.
len;
1484 for ( ; ml <= matchML ; ml++) {
1485 int const pos = cur + ml;
1486 int const offset = newMatch.
off;
1489 DEBUGLOG(7,
"testing price rPos %i (last_match_pos=%i)",
1490 pos, last_match_pos);
1491 if (opt[cur].mlen == 1) {
1493 price = ((cur > ll) ? opt[cur - ll].price : 0)
1502 || price <= opt[pos].price - (
int)favorDecSpeed) {
1503 DEBUGLOG(7,
"rPos:%3i => price:%3i (matchlen=%i)",
1506 if ( (ml == matchML)
1507 && (last_match_pos < pos) )
1508 last_match_pos = pos;
1510 opt[pos].
off = offset;
1512 opt[pos].
price = price;
1517 opt[last_match_pos+addLit].
mlen = 1;
1518 opt[last_match_pos+addLit].
off = 0;
1519 opt[last_match_pos+addLit].
litlen = addLit;
1521 DEBUGLOG(7,
"rPos:%3i => price:%3i (litlen=%i)", last_match_pos+addLit, opt[last_match_pos+addLit].price, addLit);
1526 best_mlen = opt[last_match_pos].
mlen;
1527 best_off = opt[last_match_pos].
off;
1528 cur = last_match_pos - best_mlen;
1532 assert(last_match_pos >= 1);
1533 DEBUGLOG(6,
"reverse traversal, looking for shortest path (last_match_pos=%i)", last_match_pos);
1534 {
int candidate_pos = cur;
1535 int selected_matchLength = best_mlen;
1536 int selected_offset = best_off;
1538 int const next_matchLength = opt[candidate_pos].
mlen;
1539 int const next_offset = opt[candidate_pos].
off;
1540 DEBUGLOG(7,
"pos %i: sequence length %i", candidate_pos, selected_matchLength);
1541 opt[candidate_pos].
mlen = selected_matchLength;
1542 opt[candidate_pos].
off = selected_offset;
1543 selected_matchLength = next_matchLength;
1544 selected_offset = next_offset;
1545 if (next_matchLength > candidate_pos)
break;
1546 assert(next_matchLength > 0);
1547 candidate_pos -= next_matchLength;
1552 while (rPos < last_match_pos) {
1553 int const ml = opt[rPos].
mlen;
1554 int const offset = opt[rPos].
off;
1555 if (ml == 1) {
ip++; rPos++;
continue; }
1558 assert((offset >= 1) && (offset <= LZ4_DISTANCE_MAX));
1562 ovref =
ip - offset;
1563 goto _dest_overflow;
1570 size_t llAdd = (lastRunSize + 255 -
RUN_MASK) / 255;
1571 size_t const totalSize = 1 + llAdd + lastRunSize;
1573 if (limit && (
op + totalSize > oend)) {
1579 lastRunSize = (
size_t)(oend -
op) - 1 ;
1580 llAdd = (lastRunSize + 256 -
RUN_MASK) / 256;
1581 lastRunSize -= llAdd;
1583 DEBUGLOG(6,
"Final literal run : %i literals", (
int)lastRunSize);
1587 size_t accumulator = lastRunSize -
RUN_MASK;
1589 for(; accumulator >= 255 ; accumulator -= 255) *
op++ = 255;
1590 *
op++ = (
BYTE) accumulator;
1607 size_t const ll_addbytes = (ll + 240) / 255;
1608 size_t const ll_totalCost = 1 + ll_addbytes + ll;
1609 BYTE*
const maxLitPos = oend - 3;
1610 DEBUGLOG(6,
"Last sequence overflowing (only %i bytes remaining)", (
int)(oend-1-opSaved));
1612 if (
op + ll_totalCost <= maxLitPos) {
1614 size_t const bytesLeftForMl = (
size_t)(maxLitPos - (
op+ll_totalCost));
1615 size_t const maxMlSize =
MINMATCH + (
ML_MASK-1) + (bytesLeftForMl * 255);
1617 if ((
size_t)ovml > maxMlSize) ovml = (
int)maxMlSize;
1619 DEBUGLOG(6,
"Space to end : %i + ml (%i)", (
int)((oend +
LASTLITERALS) - (
op + ll_totalCost + 2) - 1), ovml);
1624 goto _last_literals;
1627 #if defined(LZ4HC_HEAPMODE) && LZ4HC_HEAPMODE==1