LzmaEnc.c (p7zip_15.14.1_src_all) | : | LzmaEnc.c (p7zip_16.02_src_all) | ||
---|---|---|---|---|
/* LzmaEnc.c -- LZMA Encoder | /* LzmaEnc.c -- LZMA Encoder | |||
2015-11-08 : Igor Pavlov : Public domain */ | 2016-05-16 : Igor Pavlov : Public domain */ | |||
#include "Precomp.h" | #include "Precomp.h" | |||
#include <string.h> | #include <string.h> | |||
/* #define SHOW_STAT */ | /* #define SHOW_STAT */ | |||
/* #define SHOW_STAT2 */ | /* #define SHOW_STAT2 */ | |||
#if defined(SHOW_STAT) || defined(SHOW_STAT2) | #if defined(SHOW_STAT) || defined(SHOW_STAT2) | |||
#include <stdio.h> | #include <stdio.h> | |||
skipping to change at line 111 | skipping to change at line 111 | |||
#if (_MSC_VER >= 1400) | #if (_MSC_VER >= 1400) | |||
/* BSR code is fast for some new CPUs */ | /* BSR code is fast for some new CPUs */ | |||
/* #define LZMA_LOG_BSR */ | /* #define LZMA_LOG_BSR */ | |||
#endif | #endif | |||
#ifdef LZMA_LOG_BSR | #ifdef LZMA_LOG_BSR | |||
#define kDicLogSizeMaxCompress 32 | #define kDicLogSizeMaxCompress 32 | |||
#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } | #define BSR2_RET(pos, res) { unsigned long zz; _BitScanReverse(&zz, (pos)); res = (zz + zz) + ((pos >> (zz - 1)) & 1); } | |||
static UInt32 GetPosSlot1(UInt32 pos) | static UInt32 GetPosSlot1(UInt32 pos) | |||
{ | { | |||
UInt32 res; | UInt32 res; | |||
BSR2_RET(pos, res); | BSR2_RET(pos, res); | |||
return res; | return res; | |||
} | } | |||
#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } | #define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } | |||
#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); } | #define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); } | |||
skipping to change at line 148 | skipping to change at line 148 | |||
size_t k = ((size_t)1 << ((slot >> 1) - 1)); | size_t k = ((size_t)1 << ((slot >> 1) - 1)); | |||
size_t j; | size_t j; | |||
for (j = 0; j < k; j++) | for (j = 0; j < k; j++) | |||
g_FastPos[j] = (Byte)slot; | g_FastPos[j] = (Byte)slot; | |||
g_FastPos += k; | g_FastPos += k; | |||
} | } | |||
} | } | |||
/* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */ | /* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */ | |||
/* | /* | |||
#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ | #define BSR2_RET(pos, res) { UInt32 zz = 6 + ((kNumLogBits - 1) & \ | |||
(0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ | (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ | |||
res = p->g_FastPos[pos >> i] + (i * 2); } | res = p->g_FastPos[pos >> zz] + (zz * 2); } | |||
*/ | */ | |||
/* | /* | |||
#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ | #define BSR2_RET(pos, res) { UInt32 zz = 6 + ((kNumLogBits - 1) & \ | |||
(0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \ | (0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \ | |||
res = p->g_FastPos[pos >> i] + (i * 2); } | res = p->g_FastPos[pos >> zz] + (zz * 2); } | |||
*/ | */ | |||
#define BSR2_RET(pos, res) { UInt32 i = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 | #define BSR2_RET(pos, res) { UInt32 zz = (pos < (1 << (kNumLogBits + 6))) ? 6 : | |||
+ kNumLogBits - 1; \ | 6 + kNumLogBits - 1; \ | |||
res = p->g_FastPos[pos >> i] + (i * 2); } | res = p->g_FastPos[pos >> zz] + (zz * 2); } | |||
/* | /* | |||
#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ | #define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ | |||
p->g_FastPos[pos >> 6] + 12 : \ | p->g_FastPos[pos >> 6] + 12 : \ | |||
p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; } | p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; } | |||
*/ | */ | |||
#define GetPosSlot1(pos) p->g_FastPos[pos] | #define GetPosSlot1(pos) p->g_FastPos[pos] | |||
#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } | #define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } | |||
#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[p os]; else BSR2_RET(pos, res); } | #define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[p os]; else BSR2_RET(pos, res); } | |||
skipping to change at line 970 | skipping to change at line 970 | |||
while (cur != 0); | while (cur != 0); | |||
*backRes = p->opt[0].backPrev; | *backRes = p->opt[0].backPrev; | |||
p->optimumCurrentIndex = p->opt[0].posPrev; | p->optimumCurrentIndex = p->opt[0].posPrev; | |||
return p->optimumCurrentIndex; | return p->optimumCurrentIndex; | |||
} | } | |||
#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * (UInt32)0x300) | #define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * (UInt32)0x300) | |||
static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) | static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) | |||
{ | { | |||
UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur | UInt32 lenEnd, cur; | |||
; | ||||
UInt32 matchPrice, repMatchPrice, normalMatchPrice; | ||||
UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS]; | UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS]; | |||
UInt32 *matches; | UInt32 *matches; | |||
{ | ||||
UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, len; | ||||
UInt32 matchPrice, repMatchPrice, normalMatchPrice; | ||||
const Byte *data; | const Byte *data; | |||
Byte curByte, matchByte; | Byte curByte, matchByte; | |||
if (p->optimumEndIndex != p->optimumCurrentIndex) | if (p->optimumEndIndex != p->optimumCurrentIndex) | |||
{ | { | |||
const COptimal *opt = &p->opt[p->optimumCurrentIndex]; | const COptimal *opt = &p->opt[p->optimumCurrentIndex]; | |||
UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex; | UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex; | |||
*backRes = opt->backPrev; | *backRes = opt->backPrev; | |||
p->optimumCurrentIndex = opt->posPrev; | p->optimumCurrentIndex = opt->posPrev; | |||
return lenRes; | return lenRes; | |||
} | } | |||
p->optimumCurrentIndex = p->optimumEndIndex = 0; | p->optimumCurrentIndex = p->optimumEndIndex = 0; | |||
skipping to change at line 1163 | skipping to change at line 1168 | |||
#ifdef SHOW_STAT2 | #ifdef SHOW_STAT2 | |||
/* if (position >= 0) */ | /* if (position >= 0) */ | |||
{ | { | |||
unsigned i; | unsigned i; | |||
printf("\n pos = %4X", position); | printf("\n pos = %4X", position); | |||
for (i = cur; i <= lenEnd; i++) | for (i = cur; i <= lenEnd; i++) | |||
printf("\nprice[%4X] = %u", position - cur + i, p->opt[i].price); | printf("\nprice[%4X] = %u", position - cur + i, p->opt[i].price); | |||
} | } | |||
#endif | #endif | |||
} | ||||
for (;;) | for (;;) | |||
{ | { | |||
UInt32 numAvail; | ||||
UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen; | UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen; | |||
UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice; | UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice; | |||
Bool nextIsChar; | Bool nextIsChar; | |||
Byte curByte, matchByte; | Byte curByte, matchByte; | |||
const Byte *data; | const Byte *data; | |||
COptimal *curOpt; | COptimal *curOpt; | |||
COptimal *nextOpt; | COptimal *nextOpt; | |||
cur++; | cur++; | |||
if (cur == lenEnd) | if (cur == lenEnd) | |||
skipping to change at line 1452 | skipping to change at line 1460 | |||
p->opt[++lenEnd].price = kInfinityPrice; | p->opt[++lenEnd].price = kInfinityPrice; | |||
offs = 0; | offs = 0; | |||
while (startLen > matches[offs]) | while (startLen > matches[offs]) | |||
offs += 2; | offs += 2; | |||
curBack = matches[offs + 1]; | curBack = matches[offs + 1]; | |||
GetPosSlot2(curBack, posSlot); | GetPosSlot2(curBack, posSlot); | |||
for (lenTest = /*2*/ startLen; ; lenTest++) | for (lenTest = /*2*/ startLen; ; lenTest++) | |||
{ | { | |||
UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][le nTest - LZMA_MATCH_LEN_MIN]; | UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][le nTest - LZMA_MATCH_LEN_MIN]; | |||
{ | ||||
UInt32 lenToPosState = GetLenToPosState(lenTest); | UInt32 lenToPosState = GetLenToPosState(lenTest); | |||
COptimal *opt; | COptimal *opt; | |||
if (curBack < kNumFullDistances) | if (curBack < kNumFullDistances) | |||
curAndLenPrice += p->distancesPrices[lenToPosState][curBack]; | curAndLenPrice += p->distancesPrices[lenToPosState][curBack]; | |||
else | else | |||
curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignP rices[curBack & kAlignMask]; | curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignP rices[curBack & kAlignMask]; | |||
opt = &p->opt[cur + lenTest]; | opt = &p->opt[cur + lenTest]; | |||
if (curAndLenPrice < opt->price) | if (curAndLenPrice < opt->price) | |||
{ | { | |||
opt->price = curAndLenPrice; | opt->price = curAndLenPrice; | |||
opt->posPrev = cur; | opt->posPrev = cur; | |||
opt->backPrev = curBack + LZMA_NUM_REPS; | opt->backPrev = curBack + LZMA_NUM_REPS; | |||
opt->prev1IsChar = False; | opt->prev1IsChar = False; | |||
} | } | |||
} | ||||
if (/*_maxMode && */lenTest == matches[offs]) | if (/*_maxMode && */lenTest == matches[offs]) | |||
{ | { | |||
/* Try Match + Literal + Rep0 */ | /* Try Match + Literal + Rep0 */ | |||
const Byte *data2 = data - curBack - 1; | const Byte *data2 = data - curBack - 1; | |||
UInt32 lenTest2 = lenTest + 1; | UInt32 lenTest2 = lenTest + 1; | |||
UInt32 limit = lenTest2 + p->numFastBytes; | UInt32 limit = lenTest2 + p->numFastBytes; | |||
if (limit > numAvailFull) | if (limit > numAvailFull) | |||
limit = numAvailFull; | limit = numAvailFull; | |||
for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2 ++); | for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2 ++); | |||
skipping to change at line 1496 | skipping to change at line 1506 | |||
data[lenTest], data2[lenTest], p->ProbPrices); | data[lenTest], data2[lenTest], p->ProbPrices); | |||
state2 = kLiteralNextStates[state2]; | state2 = kLiteralNextStates[state2]; | |||
posStateNext = (posStateNext + 1) & p->pbMask; | posStateNext = (posStateNext + 1) & p->pbMask; | |||
nextRepMatchPrice = curAndLenCharPrice + | nextRepMatchPrice = curAndLenCharPrice + | |||
GET_PRICE_1(p->isMatch[state2][posStateNext]) + | GET_PRICE_1(p->isMatch[state2][posStateNext]) + | |||
GET_PRICE_1(p->isRep[state2]); | GET_PRICE_1(p->isRep[state2]); | |||
/* for (; lenTest2 >= 2; lenTest2--) */ | /* for (; lenTest2 >= 2; lenTest2--) */ | |||
{ | { | |||
UInt32 offset = cur + lenTest + 1 + lenTest2; | UInt32 offset = cur + lenTest + 1 + lenTest2; | |||
UInt32 curAndLenPrice; | UInt32 curAndLenPrice2; | |||
COptimal *opt; | COptimal *opt; | |||
while (lenEnd < offset) | while (lenEnd < offset) | |||
p->opt[++lenEnd].price = kInfinityPrice; | p->opt[++lenEnd].price = kInfinityPrice; | |||
curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, s tate2, posStateNext); | curAndLenPrice2 = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); | |||
opt = &p->opt[offset]; | opt = &p->opt[offset]; | |||
if (curAndLenPrice < opt->price) | if (curAndLenPrice2 < opt->price) | |||
{ | { | |||
opt->price = curAndLenPrice; | opt->price = curAndLenPrice2; | |||
opt->posPrev = cur + lenTest + 1; | opt->posPrev = cur + lenTest + 1; | |||
opt->backPrev = 0; | opt->backPrev = 0; | |||
opt->prev1IsChar = True; | opt->prev1IsChar = True; | |||
opt->prev2 = True; | opt->prev2 = True; | |||
opt->posPrev2 = cur; | opt->posPrev2 = cur; | |||
opt->backPrev2 = curBack + LZMA_NUM_REPS; | opt->backPrev2 = curBack + LZMA_NUM_REPS; | |||
} | } | |||
} | } | |||
} | } | |||
offs += 2; | offs += 2; | |||
skipping to change at line 1705 | skipping to change at line 1715 | |||
UInt32 posSlot; | UInt32 posSlot; | |||
const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState]; | const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState]; | |||
UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState]; | UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState]; | |||
for (posSlot = 0; posSlot < p->distTableSize; posSlot++) | for (posSlot = 0; posSlot < p->distTableSize; posSlot++) | |||
posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot , p->ProbPrices); | posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot , p->ProbPrices); | |||
for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++) | for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++) | |||
posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumB itPriceShiftBits); | posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumB itPriceShiftBits); | |||
{ | { | |||
UInt32 *distancesPrices = p->distancesPrices[lenToPosState]; | UInt32 *distancesPrices = p->distancesPrices[lenToPosState]; | |||
UInt32 i; | ||||
for (i = 0; i < kStartPosModelIndex; i++) | for (i = 0; i < kStartPosModelIndex; i++) | |||
distancesPrices[i] = posSlotPrices[i]; | distancesPrices[i] = posSlotPrices[i]; | |||
for (; i < kNumFullDistances; i++) | for (; i < kNumFullDistances; i++) | |||
distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i]; | distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i]; | |||
} | } | |||
} | } | |||
p->matchPriceCount = 0; | p->matchPriceCount = 0; | |||
} | } | |||
void LzmaEnc_Construct(CLzmaEnc *p) | void LzmaEnc_Construct(CLzmaEnc *p) | |||
End of changes. 19 change blocks. | ||||
17 lines changed or deleted | 25 lines changed or added |