?? lzmaenc.c
字號(hào):
{
UInt32 distance = p->reps[pos];
RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1);
if (pos == 1)
RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0);
else
{
RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1);
RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2);
if (pos == 3)
p->reps[3] = p->reps[2];
p->reps[2] = p->reps[1];
}
p->reps[1] = p->reps[0];
p->reps[0] = distance;
}
if (len == 1)
p->state = kShortRepNextStates[p->state];
else
{
LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
p->state = kRepNextStates[p->state];
}
}
else
{
UInt32 posSlot;
RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
p->state = kMatchNextStates[p->state];
LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
pos -= LZMA_NUM_REPS;
GetPosSlot(pos, posSlot);
RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);
if (posSlot >= kStartPosModelIndex)
{
UInt32 footerBits = ((posSlot >> 1) - 1);
UInt32 base = ((2 | (posSlot & 1)) << footerBits);
UInt32 posReduced = pos - base;
if (posSlot < kEndPosModelIndex)
RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced);
else
{
RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);
p->alignPriceCount++;
}
}
p->reps[3] = p->reps[2];
p->reps[2] = p->reps[1];
p->reps[1] = p->reps[0];
p->reps[0] = pos;
p->matchPriceCount++;
}
}
p->additionalOffset -= len;
nowPos32 += len;
if (p->additionalOffset == 0)
{
UInt32 processed;
if (!p->fastMode)
{
if (p->matchPriceCount >= (1 << 7))
FillDistancesPrices(p);
if (p->alignPriceCount >= kAlignTableSize)
FillAlignPrices(p);
}
if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
break;
processed = nowPos32 - startPos32;
if (useLimits)
{
if (processed + kNumOpts + 300 >= maxUnpackSize ||
RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)
break;
}
else if (processed >= (1 << 15))
{
p->nowPos64 += nowPos32 - startPos32;
return CheckErrors(p);
}
}
}
p->nowPos64 += nowPos32 - startPos32;
return Flush(p, nowPos32);
}
#define kBigHashDicLimit ((UInt32)1 << 24)
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);
#ifdef COMPRESS_MF_MT
p->mtMode = (p->multiThread && !p->fastMode && btMode);
#endif
{
unsigned lclp = p->lc + p->lp;
if (p->litProbs == 0 || p->saveState.litProbs == 0 || 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)
{
LzmaEnc_FreeLits(p, alloc);
return SZ_ERROR_MEM;
}
p->lclp = lclp;
}
}
p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit);
if (beforeSize + p->dictSize < keepWindowSize)
beforeSize = keepWindowSize - p->dictSize;
#ifdef COMPRESS_MF_MT
if (p->mtMode)
{
RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig));
p->matchFinderObj = &p->matchFinderMt;
MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
}
else
#endif
{
if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig))
return SZ_ERROR_MEM;
p->matchFinderObj = &p->matchFinderBase;
MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);
}
return SZ_OK;
}
static void LzmaEnc_Init(CLzmaEnc *p)
{
UInt32 i;
p->state = 0;
for (i = 0 ; i < LZMA_NUM_REPS; i++)
p->reps[i] = 0;
RangeEnc_Init(&p->rc);
for (i = 0; i < kNumStates; i++)
{
UInt32 j;
for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++)
{
p->isMatch[i][j] = kProbInitValue;
p->isRep0Long[i][j] = kProbInitValue;
}
p->isRep[i] = kProbInitValue;
p->isRepG0[i] = kProbInitValue;
p->isRepG1[i] = kProbInitValue;
p->isRepG2[i] = kProbInitValue;
}
{
UInt32 num = 0x300 << (p->lp + p->lc);
for (i = 0; i < num; i++)
p->litProbs[i] = kProbInitValue;
}
{
for (i = 0; i < kNumLenToPosStates; i++)
{
CLzmaProb *probs = p->posSlotEncoder[i];
UInt32 j;
for (j = 0; j < (1 << kNumPosSlotBits); j++)
probs[j] = kProbInitValue;
}
}
{
for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
p->posEncoders[i] = kProbInitValue;
}
LenEnc_Init(&p->lenEnc.p);
LenEnc_Init(&p->repLenEnc.p);
for (i = 0; i < (1 << kNumAlignBits); i++)
p->posAlignEncoder[i] = kProbInitValue;
p->optimumEndIndex = 0;
p->optimumCurrentIndex = 0;
p->additionalOffset = 0;
p->pbMask = (1 << p->pb) - 1;
p->lpMask = (1 << p->lp) - 1;
}
static void LzmaEnc_InitPrices(CLzmaEnc *p)
{
if (!p->fastMode)
{
FillDistancesPrices(p);
FillAlignPrices(p);
}
p->lenEnc.tableSize =
p->repLenEnc.tableSize =
p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN;
LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices);
LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices);
}
static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
{
UInt32 i;
for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)
if (p->dictSize <= ((UInt32)1 << i))
break;
p->distTableSize = i * 2;
p->finished = False;
p->result = SZ_OK;
RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig));
LzmaEnc_Init(p);
LzmaEnc_InitPrices(p);
p->nowPos64 = 0;
return SZ_OK;
}
static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqInStream *inStream, ISeqOutStream *outStream,
ISzAlloc *alloc, ISzAlloc *allocBig)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
p->inStream = inStream;
p->rc.outStream = outStream;
return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig);
}
/*static SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
ISeqInStream *inStream, UInt32 keepWindowSize,
ISzAlloc *alloc, ISzAlloc *allocBig)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
p->inStream = inStream;
return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
}*/
static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
{
p->seqBufInStream.funcTable.Read = MyRead;
p->seqBufInStream.data = src;
p->seqBufInStream.rem = srcLen;
}
/*static SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
LzmaEnc_SetInputBuf(p, src, srcLen);
p->inStream = &p->seqBufInStream.funcTable;
return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
}*/
static void LzmaEnc_Finish(CLzmaEncHandle pp)
{
#ifdef COMPRESS_MF_MT
CLzmaEnc *p = (CLzmaEnc *)pp;
if (p->mtMode)
MatchFinderMt_ReleaseStream(&p->matchFinderMt);
#else
pp = pp;
#endif
}
typedef struct _CSeqOutStreamBuf
{
ISeqOutStream funcTable;
Byte *data;
SizeT rem;
Bool overflow;
} CSeqOutStreamBuf;
static size_t MyWrite(void *pp, const void *data, size_t size)
{
CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp;
if (p->rem < size)
{
size = p->rem;
p->overflow = True;
}
memcpy(p->data, data, size);
p->rem -= size;
p->data += size;
return size;
}
/*static UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
{
const CLzmaEnc *p = (CLzmaEnc *)pp;
return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
}*/
/*static const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
{
const CLzmaEnc *p = (CLzmaEnc *)pp;
return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
}*/
/*static SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
UInt64 nowPos64;
SRes res;
CSeqOutStreamBuf outStream;
outStream.funcTable.Write = MyWrite;
outStream.data = dest;
outStream.rem = *destLen;
outStream.overflow = False;
p->writeEndMark = False;
p->finished = False;
p->result = SZ_OK;
if (reInit)
LzmaEnc_Init(p);
LzmaEnc_InitPrices(p);
nowPos64 = p->nowPos64;
RangeEnc_Init(&p->rc);
p->rc.outStream = &outStream.funcTable;
res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize);
*unpackSize = (UInt32)(p->nowPos64 - nowPos64);
*destLen -= outStream.rem;
if (outStream.overflow)
return SZ_ERROR_OUTPUT_EOF;
return res;
}*/
SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
ISzAlloc *alloc, ISzAlloc *allocBig)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
SRes res = SZ_OK;
#ifdef COMPRESS_MF_MT
Byte allocaDummy[0x300];
int i = 0;
for (i = 0; i < 16; i++)
allocaDummy[i] = (Byte)i;
#endif
RINOK(LzmaEnc_Prepare(pp, inStream, outStream, alloc, allocBig));
for (;;)
{
res = LzmaEnc_CodeOneBlock(p, False, 0, 0);
if (res != SZ_OK || p->finished != 0)
break;
if (progress != 0)
{
res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
if (res != SZ_OK)
{
res = SZ_ERROR_PROGRESS;
break;
}
}
}
LzmaEnc_Finish(pp);
return res;
}
SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
{
CLzmaEnc *p = (CLzmaEnc *)pp;
int 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)2 << i))
{
dictSize = (2 << i);
break;
}
if (dictSize <= ((UInt32)3 << i))
{
dictSize = (3 << i);
break;
}
}
for (i = 0; i < 4; i++)
props[1 + i] = (Byte)(dictSize >> (8 * i));
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)
{
SRes res;
CLzmaEnc *p = (CLzmaEnc *)pp;
CSeqOutStreamBuf outStream;
LzmaEnc_SetInputBuf(p, src, srcLen);
outStream.funcTable.Write = MyWrite;
outStream.data = dest;
outStream.rem = *destLen;
outStream.overflow = False;
p->writeEndMark = writeEndMark;
res = LzmaEnc_Encode(pp, &outStream.funcTable, &p->seqBufInStream.funcTable,
progress, alloc, allocBig);
*destLen -= outStream.rem;
if (outStream.overflow)
return SZ_ERROR_OUTPUT_EOF;
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)
return SZ_ERROR_MEM;
res = LzmaEnc_SetProps(p, props);
if (res == SZ_OK)
{
res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize);
if (res == SZ_OK)
res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen,
writeEndMark, progress, alloc, allocBig);
}
LzmaEnc_Destroy(p, alloc, allocBig);
return res;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -