Index: third_party/lzma_sdk/LzmaEnc.c |
diff --git a/third_party/lzma_sdk/LzmaEnc.c b/third_party/lzma_sdk/LzmaEnc.c |
index cf131388a448f23cd50f27d7d75d0693de41839b..9c164e6f0412ca116932d5bc136aa7889c7a9651 100644 |
--- a/third_party/lzma_sdk/LzmaEnc.c |
+++ b/third_party/lzma_sdk/LzmaEnc.c |
@@ -1,5 +1,7 @@ |
/* LzmaEnc.c -- LZMA Encoder |
-2010-04-16 : Igor Pavlov : Public domain */ |
+2015-11-08 : Igor Pavlov : Public domain */ |
+ |
+#include "Precomp.h" |
#include <string.h> |
@@ -18,9 +20,12 @@ |
#endif |
#ifdef SHOW_STAT |
-static int ttt = 0; |
+static unsigned g_STAT_OFFSET = 0; |
#endif |
+#define kMaxHistorySize ((UInt32)3 << 29) |
+/* #define kMaxHistorySize ((UInt32)7 << 29) */ |
+ |
#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1) |
#define kBlockSize (9 << 10) |
@@ -46,6 +51,7 @@ void LzmaEncProps_Init(CLzmaEncProps *p) |
{ |
p->level = 5; |
p->dictSize = p->mc = 0; |
+ p->reduceSize = (UInt64)(Int64)-1; |
p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; |
p->writeEndMark = 0; |
} |
@@ -55,15 +61,28 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p) |
int level = p->level; |
if (level < 0) level = 5; |
p->level = level; |
+ |
if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); |
+ if (p->dictSize > p->reduceSize) |
+ { |
+ unsigned i; |
+ for (i = 11; i <= 30; i++) |
+ { |
+ if ((UInt32)p->reduceSize <= ((UInt32)2 << i)) { p->dictSize = ((UInt32)2 << i); break; } |
+ if ((UInt32)p->reduceSize <= ((UInt32)3 << i)) { p->dictSize = ((UInt32)3 << i); break; } |
+ } |
+ } |
+ |
if (p->lc < 0) p->lc = 3; |
if (p->lp < 0) p->lp = 0; |
if (p->pb < 0) p->pb = 2; |
+ |
if (p->algo < 0) p->algo = (level < 5 ? 0 : 1); |
if (p->fb < 0) p->fb = (level < 7 ? 32 : 64); |
if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); |
if (p->numHashBytes < 0) p->numHashBytes = 4; |
- if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1); |
+ if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1); |
+ |
if (p->numThreads < 0) |
p->numThreads = |
#ifndef _7ZIP_ST |
@@ -80,17 +99,18 @@ UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) |
return props.dictSize; |
} |
+#if (_MSC_VER >= 1400) |
+/* BSR code is fast for some new CPUs */ |
/* #define LZMA_LOG_BSR */ |
-/* Define it for Intel's CPU */ |
- |
+#endif |
#ifdef LZMA_LOG_BSR |
-#define kDicLogSizeMaxCompress 30 |
+#define kDicLogSizeMaxCompress 32 |
#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); } |
-UInt32 GetPosSlot1(UInt32 pos) |
+static UInt32 GetPosSlot1(UInt32 pos) |
{ |
UInt32 res; |
BSR2_RET(pos, res); |
@@ -101,27 +121,44 @@ UInt32 GetPosSlot1(UInt32 pos) |
#else |
-#define kNumLogBits (9 + (int)sizeof(size_t) / 2) |
+#define kNumLogBits (9 + sizeof(size_t) / 2) |
+/* #define kNumLogBits (11 + sizeof(size_t) / 8 * 3) */ |
+ |
#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) |
-void LzmaEnc_FastPosInit(Byte *g_FastPos) |
+static void LzmaEnc_FastPosInit(Byte *g_FastPos) |
{ |
- int c = 2, slotFast; |
+ unsigned slot; |
g_FastPos[0] = 0; |
g_FastPos[1] = 1; |
+ g_FastPos += 2; |
- for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++) |
+ for (slot = 2; slot < kNumLogBits * 2; slot++) |
{ |
- UInt32 k = (1 << ((slotFast >> 1) - 1)); |
- UInt32 j; |
- for (j = 0; j < k; j++, c++) |
- g_FastPos[c] = (Byte)slotFast; |
+ size_t k = ((size_t)1 << ((slot >> 1) - 1)); |
+ size_t j; |
+ for (j = 0; j < k; j++) |
+ g_FastPos[j] = (Byte)slot; |
+ g_FastPos += k; |
} |
} |
+/* we can use ((limit - pos) >> 31) only if (pos < ((UInt32)1 << 31)) */ |
+/* |
#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ |
(0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ |
res = p->g_FastPos[pos >> i] + (i * 2); } |
+*/ |
+ |
+/* |
+#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ |
+ (0 - (((((UInt32)1 << (kNumLogBits)) - 1) - (pos >> 6)) >> 31))); \ |
+ res = p->g_FastPos[pos >> i] + (i * 2); } |
+*/ |
+ |
+#define BSR2_RET(pos, res) { UInt32 i = (pos < (1 << (kNumLogBits + 6))) ? 6 : 6 + kNumLogBits - 1; \ |
+ res = p->g_FastPos[pos >> i] + (i * 2); } |
+ |
/* |
#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ |
p->g_FastPos[pos >> 6] + 12 : \ |
@@ -201,6 +238,7 @@ typedef struct |
#define kNumStates 12 |
+ |
typedef struct |
{ |
CLzmaProb choice; |
@@ -210,14 +248,16 @@ typedef struct |
CLzmaProb high[kLenNumHighSymbols]; |
} CLenEnc; |
+ |
typedef struct |
{ |
CLenEnc p; |
- UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal]; |
UInt32 tableSize; |
+ UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal]; |
UInt32 counters[LZMA_NUM_PB_STATES_MAX]; |
} CLenPriceEnc; |
+ |
typedef struct |
{ |
UInt32 range; |
@@ -232,10 +272,14 @@ typedef struct |
SRes res; |
} CRangeEnc; |
+ |
typedef struct |
{ |
CLzmaProb *litProbs; |
+ UInt32 state; |
+ UInt32 reps[LZMA_NUM_REPS]; |
+ |
CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; |
CLzmaProb isRep[kNumStates]; |
CLzmaProb isRepG0[kNumStates]; |
@@ -249,15 +293,49 @@ typedef struct |
CLenPriceEnc lenEnc; |
CLenPriceEnc repLenEnc; |
- |
- UInt32 reps[LZMA_NUM_REPS]; |
- UInt32 state; |
} CSaveState; |
+ |
typedef struct |
{ |
- IMatchFinder matchFinder; |
void *matchFinderObj; |
+ IMatchFinder matchFinder; |
+ |
+ UInt32 optimumEndIndex; |
+ UInt32 optimumCurrentIndex; |
+ |
+ UInt32 longestMatchLength; |
+ UInt32 numPairs; |
+ UInt32 numAvail; |
+ |
+ UInt32 numFastBytes; |
+ UInt32 additionalOffset; |
+ UInt32 reps[LZMA_NUM_REPS]; |
+ UInt32 state; |
+ |
+ unsigned lc, lp, pb; |
+ unsigned lpMask, pbMask; |
+ unsigned lclp; |
+ |
+ CLzmaProb *litProbs; |
+ |
+ Bool fastMode; |
+ Bool writeEndMark; |
+ Bool finished; |
+ Bool multiThread; |
+ Bool needInit; |
+ |
+ UInt64 nowPos64; |
+ |
+ UInt32 matchPriceCount; |
+ UInt32 alignPriceCount; |
+ |
+ UInt32 distTableSize; |
+ |
+ UInt32 dictSize; |
+ SRes result; |
+ |
+ CRangeEnc rc; |
#ifndef _7ZIP_ST |
Bool mtMode; |
@@ -270,12 +348,6 @@ typedef struct |
Byte pad[128]; |
#endif |
- UInt32 optimumEndIndex; |
- UInt32 optimumCurrentIndex; |
- |
- UInt32 longestMatchLength; |
- UInt32 numPairs; |
- UInt32 numAvail; |
COptimal opt[kNumOpts]; |
#ifndef LZMA_LOG_BSR |
@@ -284,22 +356,10 @@ typedef struct |
UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; |
UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1]; |
- UInt32 numFastBytes; |
- UInt32 additionalOffset; |
- UInt32 reps[LZMA_NUM_REPS]; |
- UInt32 state; |
UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; |
UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; |
UInt32 alignPrices[kAlignTableSize]; |
- UInt32 alignPriceCount; |
- |
- UInt32 distTableSize; |
- |
- unsigned lc, lp, pb; |
- unsigned lpMask, pbMask; |
- |
- CLzmaProb *litProbs; |
CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; |
CLzmaProb isRep[kNumStates]; |
@@ -315,27 +375,14 @@ typedef struct |
CLenPriceEnc lenEnc; |
CLenPriceEnc repLenEnc; |
- unsigned lclp; |
- |
- Bool fastMode; |
- |
- CRangeEnc rc; |
- |
- Bool writeEndMark; |
- UInt64 nowPos64; |
- UInt32 matchPriceCount; |
- Bool finished; |
- Bool multiThread; |
- |
- SRes result; |
- UInt32 dictSize; |
- UInt32 matchFinderCycles; |
- |
- int needInit; |
- |
CSaveState saveState; |
+ |
+ #ifndef _7ZIP_ST |
+ Byte pad2[128]; |
+ #endif |
} CLzmaEnc; |
+ |
void LzmaEnc_SaveState(CLzmaEncHandle pp) |
{ |
CLzmaEnc *p = (CLzmaEnc *)pp; |
@@ -359,7 +406,7 @@ void LzmaEnc_SaveState(CLzmaEncHandle pp) |
memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); |
memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); |
memcpy(dest->reps, p->reps, sizeof(p->reps)); |
- memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb)); |
+ memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << p->lclp) * sizeof(CLzmaProb)); |
} |
void LzmaEnc_RestoreState(CLzmaEncHandle pp) |
@@ -385,7 +432,7 @@ void LzmaEnc_RestoreState(CLzmaEncHandle pp) |
memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); |
memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); |
memcpy(dest->reps, p->reps, sizeof(p->reps)); |
- memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb)); |
+ memcpy(dest->litProbs, p->litProbs, ((UInt32)0x300 << dest->lclp) * sizeof(CLzmaProb)); |
} |
SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) |
@@ -394,11 +441,14 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) |
CLzmaEncProps props = *props2; |
LzmaEncProps_Normalize(&props); |
- if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX || |
- props.dictSize > ((UInt32)1 << kDicLogSizeMaxCompress) || props.dictSize > ((UInt32)1 << 30)) |
+ if (props.lc > LZMA_LC_MAX |
+ || props.lp > LZMA_LP_MAX |
+ || props.pb > LZMA_PB_MAX |
+ || props.dictSize > ((UInt64)1 << kDicLogSizeMaxCompress) |
+ || props.dictSize > kMaxHistorySize) |
return SZ_ERROR_PARAM; |
+ |
p->dictSize = props.dictSize; |
- p->matchFinderCycles = props.mc; |
{ |
unsigned fb = props.fb; |
if (fb < 5) |
@@ -411,7 +461,7 @@ SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) |
p->lp = props.lp; |
p->pb = props.pb; |
p->fastMode = (props.algo == 0); |
- p->matchFinderBase.btMode = props.btMode; |
+ p->matchFinderBase.btMode = (Byte)(props.btMode ? 1 : 0); |
{ |
UInt32 numHashBytes = 4; |
if (props.btMode) |
@@ -455,8 +505,8 @@ static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, |
static void RangeEnc_Construct(CRangeEnc *p) |
{ |
- p->outStream = 0; |
- p->bufBase = 0; |
+ p->outStream = NULL; |
+ p->bufBase = NULL; |
} |
#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize) |
@@ -464,10 +514,10 @@ static void RangeEnc_Construct(CRangeEnc *p) |
#define RC_BUF_SIZE (1 << 16) |
static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) |
{ |
- if (p->bufBase == 0) |
+ if (!p->bufBase) |
{ |
p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE); |
- if (p->bufBase == 0) |
+ if (!p->bufBase) |
return 0; |
p->bufLim = p->bufBase + RC_BUF_SIZE; |
} |
@@ -508,7 +558,7 @@ static void RangeEnc_FlushStream(CRangeEnc *p) |
static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) |
{ |
- if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0) |
+ if ((UInt32)p->low < (UInt32)0xFF000000 || (unsigned)(p->low >> 32) != 0) |
{ |
Byte temp = p->cache; |
do |
@@ -534,7 +584,7 @@ static void RangeEnc_FlushData(CRangeEnc *p) |
RangeEnc_ShiftLow(p); |
} |
-static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits) |
+static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, unsigned numBits) |
{ |
do |
{ |
@@ -597,7 +647,7 @@ static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, |
while (symbol < 0x10000); |
} |
-void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) |
+static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) |
{ |
UInt32 i; |
for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) |
@@ -633,7 +683,7 @@ void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) |
#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits] |
#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] |
-static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices) |
+static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, const UInt32 *ProbPrices) |
{ |
UInt32 price = 0; |
symbol |= 0x100; |
@@ -646,7 +696,7 @@ static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *Pro |
return price; |
} |
-static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices) |
+static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, const UInt32 *ProbPrices) |
{ |
UInt32 price = 0; |
UInt32 offs = 0x100; |
@@ -690,7 +740,7 @@ static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLeve |
} |
} |
-static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) |
+static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, const UInt32 *ProbPrices) |
{ |
UInt32 price = 0; |
symbol |= (1 << numBitLevels); |
@@ -702,7 +752,7 @@ static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 s |
return price; |
} |
-static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) |
+static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, const UInt32 *ProbPrices) |
{ |
UInt32 price = 0; |
UInt32 m = 1; |
@@ -753,7 +803,7 @@ static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posSt |
} |
} |
-static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices) |
+static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, const UInt32 *ProbPrices) |
{ |
UInt32 a0 = GET_PRICE_0a(p->choice); |
UInt32 a1 = GET_PRICE_1a(p->choice); |
@@ -776,20 +826,20 @@ static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UIn |
prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices); |
} |
-static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices) |
+static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, const UInt32 *ProbPrices) |
{ |
LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices); |
p->counters[posState] = p->tableSize; |
} |
-static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices) |
+static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, const UInt32 *ProbPrices) |
{ |
UInt32 posState; |
for (posState = 0; posState < numPosStates; posState++) |
LenPriceEnc_UpdateTable(p, posState, ProbPrices); |
} |
-static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices) |
+static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, const UInt32 *ProbPrices) |
{ |
LenEnc_Encode(&p->p, rc, symbol, posState); |
if (updatePrice) |
@@ -803,9 +853,10 @@ static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 |
static void MovePos(CLzmaEnc *p, UInt32 num) |
{ |
#ifdef SHOW_STAT |
- ttt += num; |
- printf("\n MovePos %d", num); |
+ g_STAT_OFFSET += num; |
+ printf("\n MovePos %u", num); |
#endif |
+ |
if (num != 0) |
{ |
p->additionalOffset += num; |
@@ -818,28 +869,32 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes) |
UInt32 lenRes = 0, numPairs; |
p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); |
numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); |
+ |
#ifdef SHOW_STAT |
- printf("\n i = %d numPairs = %d ", ttt, numPairs / 2); |
- ttt++; |
+ printf("\n i = %u numPairs = %u ", g_STAT_OFFSET, numPairs / 2); |
+ g_STAT_OFFSET++; |
{ |
UInt32 i; |
for (i = 0; i < numPairs; i += 2) |
- printf("%2d %6d | ", p->matches[i], p->matches[i + 1]); |
+ printf("%2u %6u | ", p->matches[i], p->matches[i + 1]); |
} |
#endif |
+ |
if (numPairs > 0) |
{ |
lenRes = p->matches[numPairs - 2]; |
if (lenRes == p->numFastBytes) |
{ |
- const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; |
- UInt32 distance = p->matches[numPairs - 1] + 1; |
UInt32 numAvail = p->numAvail; |
if (numAvail > LZMA_MATCH_LEN_MAX) |
numAvail = LZMA_MATCH_LEN_MAX; |
{ |
- const Byte *pby2 = pby - distance; |
- for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++); |
+ const Byte *pbyCur = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; |
+ const Byte *pby = pbyCur + lenRes; |
+ ptrdiff_t dif = (ptrdiff_t)-1 - p->matches[numPairs - 1]; |
+ const Byte *pbyLim = pbyCur + numAvail; |
+ for (; pby != pbyLim && *pby == pby[dif]; pby++); |
+ lenRes = (UInt32)(pby - pbyCur); |
} |
} |
} |
@@ -924,7 +979,7 @@ static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur) |
return p->optimumCurrentIndex; |
} |
-#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 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) |
{ |
@@ -968,7 +1023,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) |
UInt32 lenTest; |
const Byte *data2; |
reps[i] = p->reps[i]; |
- data2 = data - (reps[i] + 1); |
+ data2 = data - reps[i] - 1; |
if (data[0] != data2[0] || data[1] != data2[1]) |
{ |
repLens[i] = 0; |
@@ -1112,12 +1167,12 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) |
cur = 0; |
#ifdef SHOW_STAT2 |
- if (position >= 0) |
+ /* if (position >= 0) */ |
{ |
unsigned i; |
printf("\n pos = %4X", position); |
for (i = cur; i <= lenEnd; i++) |
- printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price); |
+ printf("\nprice[%4X] = %u", position - cur + i, p->opt[i].price); |
} |
#endif |
@@ -1269,7 +1324,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) |
/* try Literal + rep0 */ |
UInt32 temp; |
UInt32 lenTest2; |
- const Byte *data2 = data - (reps[0] + 1); |
+ const Byte *data2 = data - reps[0] - 1; |
UInt32 limit = p->numFastBytes + 1; |
if (limit > numAvailFull) |
limit = numAvailFull; |
@@ -1312,7 +1367,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) |
UInt32 lenTest; |
UInt32 lenTestTemp; |
UInt32 price; |
- const Byte *data2 = data - (reps[repIndex] + 1); |
+ const Byte *data2 = data - reps[repIndex] - 1; |
if (data[0] != data2[0] || data[1] != data2[1]) |
continue; |
for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++); |
@@ -1342,13 +1397,13 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) |
{ |
UInt32 lenTest2 = lenTest + 1; |
UInt32 limit = lenTest2 + p->numFastBytes; |
- UInt32 nextRepMatchPrice; |
if (limit > numAvailFull) |
limit = numAvailFull; |
for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); |
lenTest2 -= lenTest + 1; |
if (lenTest2 >= 2) |
{ |
+ UInt32 nextRepMatchPrice; |
UInt32 state2 = kRepNextStates[state]; |
UInt32 posStateNext = (position + lenTest) & p->pbMask; |
UInt32 curAndLenCharPrice = |
@@ -1429,16 +1484,16 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) |
if (/*_maxMode && */lenTest == matches[offs]) |
{ |
/* Try Match + Literal + Rep0 */ |
- const Byte *data2 = data - (curBack + 1); |
+ const Byte *data2 = data - curBack - 1; |
UInt32 lenTest2 = lenTest + 1; |
UInt32 limit = lenTest2 + p->numFastBytes; |
- UInt32 nextRepMatchPrice; |
if (limit > numAvailFull) |
limit = numAvailFull; |
for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); |
lenTest2 -= lenTest + 1; |
if (lenTest2 >= 2) |
{ |
+ UInt32 nextRepMatchPrice; |
UInt32 state2 = kMatchNextStates[state]; |
UInt32 posStateNext = (position + lenTest) & p->pbMask; |
UInt32 curAndLenCharPrice = curAndLenPrice + |
@@ -1512,7 +1567,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) |
for (i = 0; i < LZMA_NUM_REPS; i++) |
{ |
UInt32 len; |
- const Byte *data2 = data - (p->reps[i] + 1); |
+ const Byte *data2 = data - p->reps[i] - 1; |
if (data[0] != data2[0] || data[1] != data2[1]) |
continue; |
for (len = 2; len < numAvail && data[len] == data2[len]; len++); |
@@ -1581,7 +1636,7 @@ static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) |
for (i = 0; i < LZMA_NUM_REPS; i++) |
{ |
UInt32 len, limit; |
- const Byte *data2 = data - (p->reps[i] + 1); |
+ const Byte *data2 = data - p->reps[i] - 1; |
if (data[0] != data2[0] || data[1] != data2[1]) |
continue; |
limit = mainLen - 1; |
@@ -1677,6 +1732,7 @@ void LzmaEnc_Construct(CLzmaEnc *p) |
{ |
RangeEnc_Construct(&p->rc); |
MatchFinder_Construct(&p->matchFinderBase); |
+ |
#ifndef _7ZIP_ST |
MatchFinderMt_Construct(&p->matchFinderMt); |
p->matchFinderMt.MatchFinder = &p->matchFinderBase; |
@@ -1693,15 +1749,15 @@ void LzmaEnc_Construct(CLzmaEnc *p) |
#endif |
LzmaEnc_InitPriceTables(p->ProbPrices); |
- p->litProbs = 0; |
- p->saveState.litProbs = 0; |
+ p->litProbs = NULL; |
+ p->saveState.litProbs = NULL; |
} |
CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) |
{ |
void *p; |
p = alloc->Alloc(alloc, sizeof(CLzmaEnc)); |
- if (p != 0) |
+ if (p) |
LzmaEnc_Construct((CLzmaEnc *)p); |
return p; |
} |
@@ -1710,8 +1766,8 @@ void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) |
{ |
alloc->Free(alloc, p->litProbs); |
alloc->Free(alloc, p->saveState.litProbs); |
- p->litProbs = 0; |
- p->saveState.litProbs = 0; |
+ p->litProbs = NULL; |
+ p->saveState.litProbs = NULL; |
} |
void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) |
@@ -1719,6 +1775,7 @@ void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) |
#ifndef _7ZIP_ST |
MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); |
#endif |
+ |
MatchFinder_Free(&p->matchFinderBase, allocBig); |
LzmaEnc_FreeLits(p, alloc); |
RangeEnc_Free(&p->rc, alloc); |
@@ -1755,7 +1812,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize |
ReadMatchDistances(p, &numPairs); |
RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0); |
p->state = kLiteralNextStates[p->state]; |
- curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset); |
+ curByte = *(p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset); |
LitEnc_Encode(&p->rc, p->litProbs, curByte); |
p->additionalOffset--; |
nowPos32++; |
@@ -1772,7 +1829,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize |
len = GetOptimum(p, nowPos32, &pos); |
#ifdef SHOW_STAT2 |
- printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos); |
+ printf("\n pos = %4X, len = %u pos = %u", nowPos32, len, pos); |
#endif |
posState = nowPos32 & p->pbMask; |
@@ -1881,7 +1938,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize |
RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize) |
break; |
} |
- else if (processed >= (1 << 15)) |
+ else if (processed >= (1 << 17)) |
{ |
p->nowPos64 += nowPos32 - startPos32; |
return CheckErrors(p); |
@@ -1897,22 +1954,21 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize |
static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) |
{ |
UInt32 beforeSize = kNumOpts; |
- Bool btMode; |
if (!RangeEnc_Alloc(&p->rc, alloc)) |
return SZ_ERROR_MEM; |
- btMode = (p->matchFinderBase.btMode != 0); |
+ |
#ifndef _7ZIP_ST |
- p->mtMode = (p->multiThread && !p->fastMode && btMode); |
+ p->mtMode = (p->multiThread && !p->fastMode && (p->matchFinderBase.btMode != 0)); |
#endif |
{ |
unsigned lclp = p->lc + p->lp; |
- if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp) |
+ if (!p->litProbs || !p->saveState.litProbs || p->lclp != lclp) |
{ |
LzmaEnc_FreeLits(p, alloc); |
- p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); |
- p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); |
- if (p->litProbs == 0 || p->saveState.litProbs == 0) |
+ p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb)); |
+ p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, ((UInt32)0x300 << lclp) * sizeof(CLzmaProb)); |
+ if (!p->litProbs || !p->saveState.litProbs) |
{ |
LzmaEnc_FreeLits(p, alloc); |
return SZ_ERROR_MEM; |
@@ -1921,7 +1977,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I |
} |
} |
- p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit); |
+ p->matchFinderBase.bigHash = (Byte)(p->dictSize > kBigHashDicLimit ? 1 : 0); |
if (beforeSize + p->dictSize < keepWindowSize) |
beforeSize = keepWindowSize - p->dictSize; |
@@ -1941,6 +1997,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, I |
p->matchFinderObj = &p->matchFinderBase; |
MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); |
} |
+ |
return SZ_OK; |
} |
@@ -1969,9 +2026,10 @@ void LzmaEnc_Init(CLzmaEnc *p) |
} |
{ |
- UInt32 num = 0x300 << (p->lp + p->lc); |
+ UInt32 num = (UInt32)0x300 << (p->lp + p->lc); |
+ CLzmaProb *probs = p->litProbs; |
for (i = 0; i < num; i++) |
- p->litProbs[i] = kProbInitValue; |
+ probs[i] = kProbInitValue; |
} |
{ |
@@ -2078,10 +2136,11 @@ void LzmaEnc_Finish(CLzmaEncHandle pp) |
if (p->mtMode) |
MatchFinderMt_ReleaseStream(&p->matchFinderMt); |
#else |
- pp = pp; |
+ UNUSED_VAR(pp); |
#endif |
} |
+ |
typedef struct |
{ |
ISeqOutStream funcTable; |
@@ -2111,12 +2170,14 @@ UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) |
return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); |
} |
+ |
const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) |
{ |
const CLzmaEnc *p = (CLzmaEnc *)pp; |
return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; |
} |
+ |
SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, |
Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) |
{ |
@@ -2151,23 +2212,23 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, |
return res; |
} |
+ |
static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) |
{ |
SRes res = SZ_OK; |
#ifndef _7ZIP_ST |
Byte allocaDummy[0x300]; |
- int i = 0; |
- for (i = 0; i < 16; i++) |
- allocaDummy[i] = (Byte)i; |
+ allocaDummy[0] = 0; |
+ allocaDummy[1] = allocaDummy[0]; |
#endif |
for (;;) |
{ |
res = LzmaEnc_CodeOneBlock(p, False, 0, 0); |
- if (res != SZ_OK || p->finished != 0) |
+ if (res != SZ_OK || p->finished) |
break; |
- if (progress != 0) |
+ if (progress) |
{ |
res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); |
if (res != SZ_OK) |
@@ -2177,10 +2238,19 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) |
} |
} |
} |
+ |
LzmaEnc_Finish(p); |
+ |
+ /* |
+ if (res == S_OK && !Inline_MatchFinder_IsFinishedOK(&p->matchFinderBase)) |
+ res = SZ_ERROR_FAIL; |
+ } |
+ */ |
+ |
return res; |
} |
+ |
SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, |
ISzAlloc *alloc, ISzAlloc *allocBig) |
{ |
@@ -2188,28 +2258,27 @@ SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *i |
return LzmaEnc_Encode2((CLzmaEnc *)pp, progress); |
} |
+ |
SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) |
{ |
CLzmaEnc *p = (CLzmaEnc *)pp; |
- int i; |
+ unsigned i; |
UInt32 dictSize = p->dictSize; |
if (*size < LZMA_PROPS_SIZE) |
return SZ_ERROR_PARAM; |
*size = LZMA_PROPS_SIZE; |
props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); |
- for (i = 11; i <= 30; i++) |
+ if (dictSize >= ((UInt32)1 << 22)) |
{ |
- if (dictSize <= ((UInt32)2 << i)) |
- { |
- dictSize = (2 << i); |
- break; |
- } |
- if (dictSize <= ((UInt32)3 << i)) |
- { |
- dictSize = (3 << i); |
- break; |
- } |
+ UInt32 kDictMask = ((UInt32)1 << 20) - 1; |
+ if (dictSize < (UInt32)0xFFFFFFFF - kDictMask) |
+ dictSize = (dictSize + kDictMask) & ~kDictMask; |
+ } |
+ else for (i = 11; i <= 30; i++) |
+ { |
+ if (dictSize <= ((UInt32)2 << i)) { dictSize = (2 << i); break; } |
+ if (dictSize <= ((UInt32)3 << i)) { dictSize = (3 << i); break; } |
} |
for (i = 0; i < 4; i++) |
@@ -2217,6 +2286,7 @@ SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) |
return SZ_OK; |
} |
+ |
SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, |
int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) |
{ |
@@ -2225,19 +2295,22 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte |
CSeqOutStreamBuf outStream; |
- LzmaEnc_SetInputBuf(p, src, srcLen); |
- |
outStream.funcTable.Write = MyWrite; |
outStream.data = dest; |
outStream.rem = *destLen; |
outStream.overflow = False; |
p->writeEndMark = writeEndMark; |
- |
p->rc.outStream = &outStream.funcTable; |
+ |
res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); |
+ |
if (res == SZ_OK) |
+ { |
res = LzmaEnc_Encode2(p, progress); |
+ if (res == SZ_OK && p->nowPos64 != srcLen) |
+ res = SZ_ERROR_FAIL; |
+ } |
*destLen -= outStream.rem; |
if (outStream.overflow) |
@@ -2245,13 +2318,14 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte |
return res; |
} |
+ |
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, |
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, |
ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) |
{ |
CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); |
SRes res; |
- if (p == 0) |
+ if (!p) |
return SZ_ERROR_MEM; |
res = LzmaEnc_SetProps(p, props); |