?? lzmaenc.c
字號:
}
*/
p->multiThread = (props.numThreads > 1);
#endif
return SZ_OK;
}
static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
#define IsCharState(s) ((s) < 7)
#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1)
#define kInfinityPrice (1 << 30)
static void RangeEnc_Construct(CRangeEnc *p)
{
p->outStream = 0;
p->bufBase = 0;
}
#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
#define RC_BUF_SIZE (1 << 16)
static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
{
if (p->bufBase == 0)
{
p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
if (p->bufBase == 0)
return 0;
p->bufLim = p->bufBase + RC_BUF_SIZE;
}
return 1;
}
static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc)
{
alloc->Free(alloc, p->bufBase);
p->bufBase = 0;
}
static void RangeEnc_Init(CRangeEnc *p)
{
/* Stream.Init(); */
p->low = 0;
p->range = 0xFFFFFFFF;
p->cacheSize = 1;
p->cache = 0;
p->buf = p->bufBase;
p->processed = 0;
p->res = SZ_OK;
}
static void RangeEnc_FlushStream(CRangeEnc *p)
{
size_t num;
if (p->res != SZ_OK)
return;
num = p->buf - p->bufBase;
if (num != p->outStream->Write(p->outStream, p->bufBase, num))
p->res = SZ_ERROR_WRITE;
p->processed += num;
p->buf = p->bufBase;
}
static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
{
if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0)
{
Byte temp = p->cache;
do
{
Byte *buf = p->buf;
*buf++ = (Byte)(temp + (Byte)(p->low >> 32));
p->buf = buf;
if (buf == p->bufLim)
RangeEnc_FlushStream(p);
temp = 0xFF;
}
while (--p->cacheSize != 0);
p->cache = (Byte)((UInt32)p->low >> 24);
}
p->cacheSize++;
p->low = (UInt32)p->low << 8;
}
static void RangeEnc_FlushData(CRangeEnc *p)
{
int i;
for (i = 0; i < 5; i++)
RangeEnc_ShiftLow(p);
}
static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits)
{
do
{
p->range >>= 1;
p->low += p->range & (0 - ((value >> --numBits) & 1));
if (p->range < kTopValue)
{
p->range <<= 8;
RangeEnc_ShiftLow(p);
}
}
while (numBits != 0);
}
static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol)
{
UInt32 ttt = *prob;
UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt;
if (symbol == 0)
{
p->range = newBound;
ttt += (kBitModelTotal - ttt) >> kNumMoveBits;
}
else
{
p->low += newBound;
p->range -= newBound;
ttt -= ttt >> kNumMoveBits;
}
*prob = (CLzmaProb)ttt;
if (p->range < kTopValue)
{
p->range <<= 8;
RangeEnc_ShiftLow(p);
}
}
static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol)
{
symbol |= 0x100;
do
{
RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1);
symbol <<= 1;
}
while (symbol < 0x10000);
}
static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte)
{
UInt32 offs = 0x100;
symbol |= 0x100;
do
{
matchByte <<= 1;
RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1);
symbol <<= 1;
offs &= ~(matchByte ^ symbol);
}
while (symbol < 0x10000);
}
static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
{
UInt32 i;
for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
{
const int kCyclesBits = kNumBitPriceShiftBits;
UInt32 w = i;
UInt32 bitCount = 0;
int j;
for (j = 0; j < kCyclesBits; j++)
{
w = w * w;
bitCount <<= 1;
while (w >= ((UInt32)1 << 16))
{
w >>= 1;
bitCount++;
}
}
ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);
}
}
#define GET_PRICE(prob, symbol) \
p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
#define GET_PRICEa(prob, symbol) \
ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits]
#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
#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)
{
UInt32 price = 0;
symbol |= 0x100;
do
{
price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1);
symbol <<= 1;
}
while (symbol < 0x10000);
return price;
}
static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices)
{
UInt32 price = 0;
UInt32 offs = 0x100;
symbol |= 0x100;
do
{
matchByte <<= 1;
price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1);
symbol <<= 1;
offs &= ~(matchByte ^ symbol);
}
while (symbol < 0x10000);
return price;
}
static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
{
UInt32 m = 1;
int i;
for (i = numBitLevels; i != 0;)
{
UInt32 bit;
i--;
bit = (symbol >> i) & 1;
RangeEnc_EncodeBit(rc, probs + m, bit);
m = (m << 1) | bit;
}
}
static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
{
UInt32 m = 1;
int i;
for (i = 0; i < numBitLevels; i++)
{
UInt32 bit = symbol & 1;
RangeEnc_EncodeBit(rc, probs + m, bit);
m = (m << 1) | bit;
symbol >>= 1;
}
}
static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
{
UInt32 price = 0;
symbol |= (1 << numBitLevels);
while (symbol != 1)
{
price += GET_PRICEa(probs[symbol >> 1], symbol & 1);
symbol >>= 1;
}
return price;
}
static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
{
UInt32 price = 0;
UInt32 m = 1;
int i;
for (i = numBitLevels; i != 0; i--)
{
UInt32 bit = symbol & 1;
symbol >>= 1;
price += GET_PRICEa(probs[m], bit);
m = (m << 1) | bit;
}
return price;
}
static void LenEnc_Init(CLenEnc *p)
{
unsigned i;
p->choice = p->choice2 = kProbInitValue;
for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++)
p->low[i] = kProbInitValue;
for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++)
p->mid[i] = kProbInitValue;
for (i = 0; i < kLenNumHighSymbols; i++)
p->high[i] = kProbInitValue;
}
static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState)
{
if (symbol < kLenNumLowSymbols)
{
RangeEnc_EncodeBit(rc, &p->choice, 0);
RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol);
}
else
{
RangeEnc_EncodeBit(rc, &p->choice, 1);
if (symbol < kLenNumLowSymbols + kLenNumMidSymbols)
{
RangeEnc_EncodeBit(rc, &p->choice2, 0);
RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols);
}
else
{
RangeEnc_EncodeBit(rc, &p->choice2, 1);
RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols);
}
}
}
static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices)
{
UInt32 a0 = GET_PRICE_0a(p->choice);
UInt32 a1 = GET_PRICE_1a(p->choice);
UInt32 b0 = a1 + GET_PRICE_0a(p->choice2);
UInt32 b1 = a1 + GET_PRICE_1a(p->choice2);
UInt32 i = 0;
for (i = 0; i < kLenNumLowSymbols; i++)
{
if (i >= numSymbols)
return;
prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices);
}
for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++)
{
if (i >= numSymbols)
return;
prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices);
}
for (; i < numSymbols; i++)
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)
{
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)
{
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)
{
LenEnc_Encode(&p->p, rc, symbol, posState);
if (updatePrice)
if (--p->counters[posState] == 0)
LenPriceEnc_UpdateTable(p, posState, ProbPrices);
}
static void MovePos(CLzmaEnc *p, UInt32 num)
{
#ifdef SHOW_STAT
ttt += num;
printf("\n MovePos %d", num);
#endif
if (num != 0)
{
p->additionalOffset += num;
p->matchFinder.Skip(p->matchFinderObj, num);
}
}
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++;
{
UInt32 i;
for (i = 0; i < numPairs; i += 2)
printf("%2d %6d | ", 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++);
}
}
}
p->additionalOffset++;
*numDistancePairsRes = numPairs;
return lenRes;
}
#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False;
#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False;
#define IsShortRep(p) ((p)->backPrev == 0)
static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState)
{
return
GET_PRICE_0(p->isRepG0[state]) +
GET_PRICE_0(p->isRep0Long[state][posState]);
}
static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState)
{
UInt32 price;
if (repIndex == 0)
{
price = GET_PRICE_0(p->isRepG0[state]);
price += GET_PRICE_1(p->isRep0Long[state][posState]);
}
else
{
price = GET_PRICE_1(p->isRepG0[state]);
if (repIndex == 1)
price += GET_PRICE_0(p->isRepG1[state]);
else
{
price += GET_PRICE_1(p->isRepG1[state]);
price += GET_PRICE(p->isRepG2[state], repIndex - 2);
}
}
return price;
}
static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)
{
return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] +
GetPureRepPrice(p, repIndex, state, posState);
}
static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
{
UInt32 posMem = p->opt[cur].posPrev;
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -