/programs/other/kpack/kerpack_linux/lzma_c/LZMAEncoder.c |
---|
0,0 → 1,1078 |
#include "LZMAEncoder.h" |
#include "MatchFinder.h" |
const byte kLiteralNextStates[kNumStates] = {0,0,0,0,1,2,3,4,5,6,4,5}; |
const byte kMatchNextStates[kNumStates] = {7,7,7,7,7,7,7,10,10,10,10,10}; |
const byte kRepNextStates[kNumStates] = {8,8,8,8,8,8,8,11,11,11,11,11}; |
const byte kShortRepNextStates[kNumStates] = {9,9,9,9,9,9,9,11,11,11,11,11}; |
static CState _state; |
static byte _previousByte; |
static unsigned _repDistances[kNumRepDistances]; |
static COptimal _optimum[kNumOpts]; |
static CMyBitEncoder _isMatch[kNumStates][kNumPosStatesEncodingMax]; |
static CMyBitEncoder _isRep[kNumStates]; |
static CMyBitEncoder _isRepG0[kNumStates]; |
static CMyBitEncoder _isRepG1[kNumStates]; |
static CMyBitEncoder _isRepG2[kNumStates]; |
static CMyBitEncoder _isRep0Long[kNumStates][kNumPosStatesEncodingMax]; |
static NRangeCoder_CBitTreeEncoder _posSlotEncoder[kNumLenToPosStates]; |
static CMyBitEncoder _posEncoders[kNumFullDistances - kEndPosModelIndex]; |
static NRangeCoder_CBitTreeEncoder _posAlignEncoder; |
static NLength_CPriceTableEncoder _lenEncoder; |
static NLength_CPriceTableEncoder _repMatchLenEncoder; |
static CLiteralEncoder _literalEncoder; |
static unsigned _matchDistances[kMatchMaxLen+1]; |
static unsigned _numFastBytes; |
static unsigned _longestMatchLength; |
static unsigned _additionalOffset; |
static unsigned _optimumEndIndex; |
static unsigned _optimumCurrentIndex; |
static bool _longestMatchWasFound; |
static unsigned _posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; |
static unsigned _distancesPrices[kNumLenToPosStates][kNumFullDistances]; |
static unsigned _alignPrices[kAlignTableSize]; |
static unsigned _alignPriceCount; |
static unsigned _distTableSize; |
static unsigned _posStateBits; |
static unsigned _posStateMask; |
static unsigned _numLiteralPosStateBits; |
static unsigned _numLiteralContextBits; |
static unsigned _dictionarySize; |
static uint64 lastPosSlotFillingPos; |
static uint64 nowPos64; |
static bool _finished; |
static bool _writeEndMark; |
static byte g_FastPos[1024]; |
// must be called before work |
static void FastPosInit(void) |
{ |
int c = 2; |
int slotFast; |
unsigned j,k; |
g_FastPos[0] = 0; |
g_FastPos[1] = 1; |
for (slotFast = 2; slotFast < 20; slotFast++) |
{ |
k = (1 << ((slotFast >> 1) - 1)); |
for (j=0;j<k;j++) g_FastPos[c++] = slotFast; |
} |
} |
static unsigned GetPosSlot(unsigned pos) |
{ |
if (pos < (1<<10)) |
return g_FastPos[pos]; |
if (pos < (1<<19)) |
return g_FastPos[pos>>9]+18; |
return g_FastPos[pos>>18]+36; |
} |
static unsigned GetPosSlot2(unsigned pos) |
{ |
if (pos < (1<<16)) |
return g_FastPos[pos>>6]+12; |
if (pos < (1<<25)) |
return g_FastPos[pos>>15]+30; |
return g_FastPos[pos>>24]+48; |
} |
unsigned pack_length; |
unsigned pack_pos; |
const byte* curin; |
byte* curout; |
static void NLength_CEncoder_Init(NLength_CEncoder*e, unsigned numPosStates) |
{ |
unsigned posState; |
CMyBitEncoder_Init(e->_choice); |
CMyBitEncoder_Init(e->_choice2); |
for (posState=0;posState<numPosStates;posState++) |
{ |
CBitTreeEncoder_Init(&e->_lowCoder[posState],kNumLowBits); |
CBitTreeEncoder_Init(&e->_midCoder[posState],kNumMidBits); |
} |
CBitTreeEncoder_Init(&e->_highCoder,kNumHighBits); |
} |
static void NLength_CEncoder_Encode(NLength_CEncoder*e, unsigned symbol, unsigned posState) |
{ |
if (symbol < kNumLowSymbols) |
{ |
CMyBitEncoder_Encode(&e->_choice,0); |
CBitTreeEncoder_Encode(&e->_lowCoder[posState],symbol); |
} |
else |
{ |
CMyBitEncoder_Encode(&e->_choice,1); |
if (symbol < kNumLowSymbols + kNumMidSymbols) |
{ |
CMyBitEncoder_Encode(&e->_choice2,0); |
CBitTreeEncoder_Encode(&e->_midCoder[posState],symbol-kNumLowSymbols); |
} |
else |
{ |
CMyBitEncoder_Encode(&e->_choice2,1); |
CBitTreeEncoder_Encode(&e->_highCoder,symbol-kNumLowSymbols-kNumMidSymbols); |
} |
} |
} |
static unsigned NLength_CEncoder_GetPrice(NLength_CEncoder*e, unsigned symbol, unsigned posState) |
{ |
unsigned price; |
if (symbol < kNumLowSymbols) |
return CMyBitEncoder_GetPrice0(&e->_choice) + |
CBitTreeEncoder_GetPrice(&e->_lowCoder[posState],symbol); |
price = CMyBitEncoder_GetPrice1(&e->_choice); |
if (symbol < kNumLowSymbols + kNumMidSymbols) |
{ |
price += CMyBitEncoder_GetPrice0(&e->_choice2); |
price += CBitTreeEncoder_GetPrice(&e->_midCoder[posState],symbol-kNumLowSymbols); |
} |
else |
{ |
price += CMyBitEncoder_GetPrice1(&e->_choice2); |
price += CBitTreeEncoder_GetPrice(&e->_highCoder,symbol-kNumLowSymbols-kNumMidSymbols); |
} |
return price; |
} |
static void CPriceTableEncoder_SetTableSize(NLength_CPriceTableEncoder*pte,unsigned tableSize) |
{pte->_tableSize = tableSize;} |
static unsigned CPriceTableEncoder_GetPrice(NLength_CPriceTableEncoder*pte,unsigned symbol,unsigned posState) |
{return pte->_prices[symbol][posState];} |
static void CPriceTableEncoder_UpdateTable(NLength_CPriceTableEncoder*pte,unsigned posState) |
{ |
unsigned len; |
for (len=0;len<pte->_tableSize;len++) |
pte->_prices[len][posState] = NLength_CEncoder_GetPrice(&pte->base,len,posState); |
pte->_counters[posState] = pte->_tableSize; |
} |
static void CPriceTableEncoder_UpdateTables(NLength_CPriceTableEncoder*pte,unsigned numPosStates) |
{ |
unsigned posState; |
for (posState=0;posState<numPosStates;posState++) |
CPriceTableEncoder_UpdateTable(pte,posState); |
} |
static void CPriceTableEncoder_Encode(NLength_CPriceTableEncoder*pte, unsigned symbol, unsigned posState) |
{ |
NLength_CEncoder_Encode(&pte->base,symbol,posState); |
if (--pte->_counters[posState] == 0) |
CPriceTableEncoder_UpdateTable(pte,posState); |
} |
static void CBaseState_Init(void) |
{ |
unsigned i; |
CState_Init(_state); |
_previousByte = 0; |
for (i=0;i<kNumRepDistances;i++) |
_repDistances[i] = 0; |
} |
static void CLiteralEncoder2_Init(CLiteralEncoder2 le) |
{ |
int i; |
for (i=0;i<0x300;i++) |
CMyBitEncoder_Init(le[i]); |
} |
static void CLiteralEncoder2_Encode(CLiteralEncoder2 le, byte symbol) |
{ |
unsigned context = 1; |
int i; |
unsigned bit; |
for (i=8;i--;) |
{ |
bit = (symbol >> i) & 1; |
CMyBitEncoder_Encode(&le[context],bit); |
context = (context << 1) | bit; |
} |
} |
static void CLiteralEncoder2_EncodeMatched(CLiteralEncoder2 le, byte matchByte, byte symbol) |
{ |
unsigned context = 1; |
int i; |
unsigned bit,matchBit; |
for (i=8;i--;) |
{ |
bit = (symbol >> i) & 1; |
matchBit = (matchByte >> i) & 1; |
CMyBitEncoder_Encode(&le[0x100 + (matchBit<<8) + context],bit); |
context = (context << 1) | bit; |
if (matchBit != bit) |
{ |
while (i--) |
{ |
bit = (symbol >> i) & 1; |
CMyBitEncoder_Encode(&le[context],bit); |
context = (context << 1) | bit; |
} |
break; |
} |
} |
} |
static unsigned CLiteralEncoder2_GetPrice(CLiteralEncoder2 le, bool matchMode, byte matchByte, byte symbol) |
{ |
unsigned price = 0; |
unsigned context = 1; |
unsigned bit,matchBit; |
int i = 8; |
if (matchMode) |
{ |
do |
{ |
i--; |
matchBit = (matchByte >> i) & 1; |
bit = (symbol >> i) & 1; |
price += CMyBitEncoder_GetPrice(&le[0x100 + (matchBit<<8) + context],bit); |
context = (context << 1) | bit; |
if (matchBit != bit) |
break; |
} while (i); |
} |
while (i--) |
{ |
bit = (symbol >> i) & 1; |
price += CMyBitEncoder_GetPrice(&le[context],bit); |
context = (context << 1) | bit; |
} |
return price; |
} |
static void WriteEndMarker(unsigned posState) |
{ |
unsigned posSlot; |
if (!_writeEndMark) |
return; |
CMyBitEncoder_Encode(&_isMatch[_state][posState],1); |
CMyBitEncoder_Encode(&_isRep[_state],0); |
CState_UpdateMatch(_state); |
CPriceTableEncoder_Encode(&_lenEncoder,0,posState); |
posSlot = (1<<kNumPosSlotBits) - 1; |
CBitTreeEncoder_Encode(&_posSlotEncoder[GetLenToPosState(kMatchMinLen)],posSlot); |
RangeEncoder_EncodeDirectBits(((1<<30)-1)>>kNumAlignBits,30-kNumAlignBits); |
CBitTreeEncoder_ReverseEncode(&_posAlignEncoder,((1<<30)-1) & kAlignMask); |
} |
static void CEncoder_Flush(void) |
{ |
WriteEndMarker((unsigned)nowPos64 & _posStateMask); |
RangeEncoder_FlushData(); |
} |
static void CLiteralEncoder_Create(CLiteralEncoder*le, byte** memory, int numPosBits, int numPrevBits) |
{ |
unsigned numStates; |
le->_coders = (CLiteralEncoder2*)*memory; |
numStates = 1 << (numPosBits+numPrevBits); |
*memory = (byte*)(le->_coders + numStates); |
le->_numPosBits = numPosBits; |
le->_posMask = (1<<numPosBits) - 1; |
le->_numPrevBits = numPrevBits; |
} |
static void CLiteralEncoder_Init(CLiteralEncoder*le) |
{ |
unsigned numStates,i; |
numStates = 1 << (le->_numPosBits + le->_numPrevBits); |
for (i=0;i<numStates;i++) |
CLiteralEncoder2_Init(le->_coders[i]); |
} |
static unsigned CLiteralEncoder_GetState(CLiteralEncoder*le,unsigned pos,byte prevByte) |
{return ((pos&le->_posMask)<<le->_numPrevBits)+(prevByte>>(8-le->_numPrevBits));} |
static CLiteralEncoder2* CLiteralEncoder_GetSubCoder(CLiteralEncoder*le,unsigned pos,byte prevByte) |
{return &le->_coders[CLiteralEncoder_GetState(le,pos,prevByte)];} |
static unsigned CLiteralEncoder_GetPrice(CLiteralEncoder*le,unsigned pos,byte prevByte, |
bool matchMode, byte matchByte, byte symbol) |
{ |
return CLiteralEncoder2_GetPrice(le->_coders[CLiteralEncoder_GetState(le,pos,prevByte)], |
matchMode, matchByte, symbol); |
} |
static void CEncoder_Create(void*workmem) |
{ |
byte* workpos = (byte*)workmem; |
/* align on dword boundary */ |
unsigned a; |
a = (unsigned)workpos & 3; |
if (a) workpos += 4-a; |
/* sizeof(CLiteralEncoder2) * (1<<(numPosBits+numPrevBits)) for literal encoders */ |
/* = 0xC00 * 8 = 0x6000 with current settings */ |
CLiteralEncoder_Create(&_literalEncoder,&workpos,_numLiteralPosStateBits,_numLiteralContextBits); |
/* (dictsize+0x1223)*1.5+256 for LZ input window */ |
/* (0x140400 + (dictsize+1)*2) * 4 for match finder hash */ |
MatchFinder_Create(_dictionarySize,kNumOpts,_numFastBytes, |
kMatchMaxLen*2+1-_numFastBytes,&workpos); |
/* total 0x508C3C + dictsize*9.5 */ |
/* plus max 6 bytes for alignment */ |
} |
static void CEncoder_Init(void) |
{ |
int i; |
unsigned j; |
CBaseState_Init(); |
RangeEncoder_Init(); |
for (i=0;i<kNumStates;i++) |
{ |
for (j=0;j<=_posStateMask;j++) |
{ |
CMyBitEncoder_Init(_isMatch[i][j]); |
CMyBitEncoder_Init(_isRep0Long[i][j]); |
} |
CMyBitEncoder_Init(_isRep[i]); |
CMyBitEncoder_Init(_isRepG0[i]); |
CMyBitEncoder_Init(_isRepG1[i]); |
CMyBitEncoder_Init(_isRepG2[i]); |
} |
CLiteralEncoder_Init(&_literalEncoder); |
for (i=0;i<kNumLenToPosStates;i++) |
CBitTreeEncoder_Init(_posSlotEncoder+i,kNumPosSlotBits); |
for (i=0;i<kNumFullDistances-kEndPosModelIndex;i++) |
CMyBitEncoder_Init(_posEncoders[i]); |
CPriceTableEncoder_Init(_lenEncoder, 1<<_posStateBits); |
CPriceTableEncoder_Init(_repMatchLenEncoder,1<<_posStateBits); |
CBitTreeEncoder_Init(&_posAlignEncoder,kNumAlignBits); |
_longestMatchWasFound = false; |
_optimumEndIndex = 0; |
_optimumCurrentIndex = 0; |
_additionalOffset = 0; |
} |
static void MovePos(unsigned num) |
{ |
for (;num--;) |
{ |
DummyLongestMatch(); |
MatchFinder_MovePos(); |
_additionalOffset++; |
} |
} |
static unsigned Backward(unsigned* backRes, unsigned cur) |
{ |
unsigned posMem,backMem; |
unsigned posPrev,backCur; |
_optimumEndIndex = cur; |
posMem = _optimum[cur].PosPrev; |
backMem = _optimum[cur].BackPrev; |
do |
{ |
if (_optimum[cur].Prev1IsChar) |
{ |
COptimal_MakeAsChar(&_optimum[posMem]); |
_optimum[posMem].PosPrev = posMem-1; |
if (_optimum[cur].Prev2) |
{ |
_optimum[posMem-1].Prev1IsChar = false; |
_optimum[posMem-1].PosPrev = _optimum[cur].PosPrev2; |
_optimum[posMem-1].BackPrev = _optimum[cur].BackPrev2; |
} |
} |
posPrev = posMem; |
backCur = backMem; |
backMem = _optimum[posPrev].BackPrev; |
posMem = _optimum[posPrev].PosPrev; |
_optimum[posPrev].BackPrev = backCur; |
_optimum[posPrev].PosPrev = cur; |
cur = posPrev; |
} while (cur); |
*backRes = _optimum[0].BackPrev; |
_optimumCurrentIndex = _optimum[0].PosPrev; |
return _optimumCurrentIndex; |
} |
static unsigned ReadMatchDistances(void) |
{ |
unsigned res; |
res = GetLongestMatch(_matchDistances); |
if (res == _numFastBytes) |
res += GetMatchLen(res,_matchDistances[res],kMatchMaxLen-res); |
_additionalOffset++; |
MatchFinder_MovePos(); |
return res; |
} |
static void FillPosSlotPrices(void) |
{ |
unsigned lenToPosState,posSlot; |
for (lenToPosState=0;lenToPosState<kNumLenToPosStates;lenToPosState++) |
{ |
for (posSlot=0;posSlot<kEndPosModelIndex && posSlot<_distTableSize;posSlot++) |
_posSlotPrices[lenToPosState][posSlot] = CBitTreeEncoder_GetPrice(&_posSlotEncoder[lenToPosState],posSlot); |
for (;posSlot<_distTableSize;posSlot++) |
_posSlotPrices[lenToPosState][posSlot] = CBitTreeEncoder_GetPrice(&_posSlotEncoder[lenToPosState],posSlot) + |
(((posSlot>>1)-1-kNumAlignBits)<<kNumBitPriceShiftBits); |
} |
} |
static void FillDistancesPrices(void) |
{ |
unsigned lenToPosState,i; |
unsigned posSlot,footerBits,base; |
for (lenToPosState=0;lenToPosState<kNumLenToPosStates;lenToPosState++) |
{ |
for (i=0;i<kStartPosModelIndex;i++) |
_distancesPrices[lenToPosState][i] = _posSlotPrices[lenToPosState][i]; |
for (;i<kNumFullDistances;i++) |
{ |
posSlot = GetPosSlot(i); |
footerBits = ((posSlot>>1)-1); |
base = (2|(posSlot&1))<<footerBits; |
_distancesPrices[lenToPosState][i] = _posSlotPrices[lenToPosState][posSlot] + |
ReverseBitTreeGetPrice(_posEncoders+base-posSlot-1,footerBits,i-base); |
} |
} |
} |
static void FillAlignPrices(void) |
{ |
unsigned i; |
for (i=0;i<kAlignTableSize;i++) |
_alignPrices[i] = CBitTreeEncoder_ReverseGetPrice(&_posAlignEncoder,i); |
_alignPriceCount = kAlignTableSize; |
} |
static unsigned GetRepLen1Price(CState state, unsigned posState) |
{ |
return CMyBitEncoder_GetPrice0(&_isRepG0[state]) + |
CMyBitEncoder_GetPrice0(&_isRep0Long[state][posState]); |
} |
static unsigned GetRepPrice(unsigned repIndex, unsigned len, CState state, unsigned posState) |
{ |
unsigned price; |
price = CPriceTableEncoder_GetPrice(&_repMatchLenEncoder,len-kMatchMinLen,posState); |
if (!repIndex) |
{ |
price += CMyBitEncoder_GetPrice0(&_isRepG0[state]); |
price += CMyBitEncoder_GetPrice1(&_isRep0Long[state][posState]); |
} |
else |
{ |
price += CMyBitEncoder_GetPrice1(&_isRepG0[state]); |
if (repIndex == 1) |
price += CMyBitEncoder_GetPrice0(&_isRepG1[state]); |
else |
{ |
price += CMyBitEncoder_GetPrice1(&_isRepG1[state]); |
price += CMyBitEncoder_GetPrice(&_isRepG2[state],repIndex-2); |
} |
} |
return price; |
} |
static unsigned GetPosLenPrice(unsigned pos, unsigned len, unsigned posState) |
{ |
unsigned price,lenToPosState; |
if (len==2 && pos>=0x80) |
return kIfinityPrice; |
lenToPosState = GetLenToPosState(len); |
if (pos < kNumFullDistances) |
price = _distancesPrices[lenToPosState][pos]; |
else |
price = _posSlotPrices[lenToPosState][GetPosSlot2(pos)] + |
_alignPrices[pos & kAlignMask]; |
return price + CPriceTableEncoder_GetPrice(&_lenEncoder,len-kMatchMinLen,posState); |
} |
static void GetOptimum(unsigned position,unsigned*backRes,unsigned*lenRes) |
{ |
int lenMain,lenEnd; |
COptimal* opt,*prevOpt; |
int reps[kNumRepDistances]; |
int repLens[kNumRepDistances]; |
int repIndex,repMaxIndex; |
int i,len,repLen,lenTest,newLen,lenTestTemp,lenTest2; |
int posState,posStateNext; |
byte currentByte,matchByte; |
unsigned matchPrice,repMatchPrice,shortRepPrice,normalMatchPrice,curAndLenPrice,curPrice,curAnd1Price,curAndLenCharPrice; |
unsigned nextMatchPrice,nextRepMatchPrice; |
int cur,posPrev,pos; |
CState state,state2; |
const byte* data; |
bool nextIsChar; |
int numAvailableBytesFull,numAvailableBytes; |
int backOffset,offset; |
int limit; |
if (_optimumEndIndex != _optimumCurrentIndex) |
{ |
opt = &_optimum[_optimumCurrentIndex]; |
*lenRes = opt->PosPrev - _optimumCurrentIndex; |
*backRes = opt->BackPrev; |
_optimumCurrentIndex = opt->PosPrev; |
return; |
} |
_optimumCurrentIndex = _optimumEndIndex = 0; |
if (!_longestMatchWasFound) |
lenMain = ReadMatchDistances(); |
else |
{ |
lenMain = _longestMatchLength; |
_longestMatchWasFound = false; |
} |
for (i=0;i<kNumRepDistances;i++) |
{ |
reps[i] = _repDistances[i]; |
repLens[i] = GetMatchLen(0-1,reps[i],kMatchMaxLen); |
if (i==0 || repLens[i] > repLens[repMaxIndex]) |
repMaxIndex = i; |
} |
if (repLens[repMaxIndex] >= _numFastBytes) |
{ |
*backRes = repMaxIndex; |
*lenRes = repLens[repMaxIndex]; |
MovePos(*lenRes-1); |
return; |
} |
if (lenMain >= _numFastBytes) |
{ |
*backRes = _matchDistances[_numFastBytes]+kNumRepDistances; |
*lenRes = lenMain; |
MovePos(lenMain-1); |
return; |
} |
currentByte = GetIndexByte(0-1); |
_optimum[0].State = _state; |
matchByte = GetIndexByte(0-_repDistances[0]-2); |
posState = position & _posStateMask; |
_optimum[1].Price = CMyBitEncoder_GetPrice0(&_isMatch[_state][posState]) + |
CLiteralEncoder_GetPrice(&_literalEncoder,position,_previousByte, |
(bool)!CState_IsCharState(_state),matchByte,currentByte); |
COptimal_MakeAsChar(&_optimum[1]); |
_optimum[1].PosPrev = 0; |
for (i=0;i<kNumRepDistances;i++) |
_optimum[0].Backs[i] = reps[i]; |
matchPrice = CMyBitEncoder_GetPrice1(&_isMatch[_state][posState]); |
repMatchPrice = matchPrice + CMyBitEncoder_GetPrice1(&_isRep[_state]); |
if (matchByte == currentByte) |
{ |
shortRepPrice = repMatchPrice + GetRepLen1Price(_state,posState); |
if (shortRepPrice < _optimum[1].Price) |
{ |
_optimum[1].Price = shortRepPrice; |
COptimal_MakeAsShortRep(&_optimum[1]); |
} |
} |
if (lenMain < 2) |
{ |
*backRes = _optimum[1].BackPrev; |
*lenRes = 1; |
return; |
} |
normalMatchPrice = matchPrice + CMyBitEncoder_GetPrice0(&_isRep[_state]); |
if (lenMain <= repLens[repMaxIndex]) |
lenMain = 0; |
for (len=2;len<=lenMain;len++) |
{ |
_optimum[len].PosPrev = 0; |
_optimum[len].BackPrev = _matchDistances[len] + kNumRepDistances; |
_optimum[len].Price = normalMatchPrice + GetPosLenPrice(_matchDistances[len],len,posState); |
_optimum[len].Prev1IsChar = false; |
} |
if (lenMain < repLens[repMaxIndex]) |
lenMain = repLens[repMaxIndex]; |
for (;len<=lenMain;len++) |
_optimum[len].Price = kIfinityPrice; |
for (i=0;i<kNumRepDistances;i++) |
{ |
repLen = repLens[i]; |
for (lenTest=2;lenTest<=repLen;lenTest++) |
{ |
curAndLenPrice = repMatchPrice + GetRepPrice(i,lenTest,_state,posState); |
opt = &_optimum[lenTest]; |
if (curAndLenPrice < opt->Price) |
{ |
opt->Price = curAndLenPrice; |
opt->PosPrev = 0; |
opt->BackPrev = i; |
opt->Prev1IsChar = false; |
} |
} |
} |
cur=0; |
lenEnd = lenMain; |
while (1) |
{ |
cur++; |
if (cur==lenEnd) |
{ |
*lenRes = Backward(backRes,cur); |
return; |
} |
position++; |
opt = &_optimum[cur]; |
posPrev = opt->PosPrev; |
if (opt->Prev1IsChar) |
{ |
posPrev--; |
if (opt->Prev2) |
{ |
state = _optimum[opt->PosPrev2].State; |
if (opt->BackPrev2 < kNumRepDistances) |
CState_UpdateRep(state); |
else |
CState_UpdateMatch(state); |
} |
else |
state = _optimum[posPrev].State; |
CState_UpdateChar(state); |
} |
else |
state = _optimum[posPrev].State; |
if (posPrev == cur-1) |
{ |
if (COptimal_IsShortRep(opt)) |
CState_UpdateShortRep(state); |
else |
CState_UpdateChar(state); |
} |
else |
{ |
if (opt->Prev1IsChar && opt->Prev2) |
{ |
posPrev = opt->PosPrev2; |
pos = opt->BackPrev2; |
CState_UpdateRep(state); |
} |
else |
{ |
pos = opt->BackPrev; |
if (pos < kNumRepDistances) |
CState_UpdateRep(state); |
else |
CState_UpdateMatch(state); |
} |
prevOpt = &_optimum[posPrev]; |
if (pos < kNumRepDistances) |
{ |
reps[0] = prevOpt->Backs[pos]; |
for (i=1;i<=pos;i++) |
reps[i] = prevOpt->Backs[i-1]; |
for (;i<kNumRepDistances;i++) |
reps[i] = prevOpt->Backs[i]; |
} |
else |
{ |
reps[0] = pos-kNumRepDistances; |
for (i=1;i<kNumRepDistances;i++) |
reps[i] = prevOpt->Backs[i-1]; |
} |
} |
opt->State = state; |
for (i=0;i<kNumRepDistances;i++) |
opt->Backs[i] = reps[i]; |
newLen = ReadMatchDistances(); |
if (newLen >= _numFastBytes) |
{ |
_longestMatchLength = newLen; |
_longestMatchWasFound = true; |
*lenRes = Backward(backRes,cur); |
return; |
} |
curPrice = opt->Price; |
data = GetPointerToCurrentPos()-1; |
currentByte = *data; |
matchByte = data[-1-reps[0]]; |
posState = position & _posStateMask; |
curAnd1Price = curPrice + CMyBitEncoder_GetPrice0(&_isMatch[state][posState]) + |
CLiteralEncoder_GetPrice(&_literalEncoder,position,data[-1],(bool)!CState_IsCharState(state),matchByte,currentByte); |
opt = &_optimum[cur+1]; |
nextIsChar = false; |
if (curAnd1Price < opt->Price) |
{ |
opt->Price = curAnd1Price; |
opt->PosPrev = cur; |
COptimal_MakeAsChar(opt); |
nextIsChar = true; |
} |
matchPrice = curPrice + CMyBitEncoder_GetPrice1(&_isMatch[state][posState]); |
repMatchPrice = matchPrice + CMyBitEncoder_GetPrice1(&_isRep[state]); |
if (matchByte == currentByte && !(opt->PosPrev<cur && !opt->BackPrev)) |
{ |
shortRepPrice = repMatchPrice + GetRepLen1Price(state,posState); |
if (shortRepPrice <= opt->Price) |
{ |
opt->Price = shortRepPrice; |
opt->PosPrev = cur; |
COptimal_MakeAsShortRep(opt); |
} |
} |
numAvailableBytesFull = GetNumAvailableBytes()+1; |
if (numAvailableBytesFull > kNumOpts-1-cur) |
numAvailableBytesFull = kNumOpts-1-cur; |
numAvailableBytes = numAvailableBytesFull; |
if (numAvailableBytes < 2) |
continue; |
if (numAvailableBytes > _numFastBytes) |
numAvailableBytes = _numFastBytes; |
if (numAvailableBytes >= 3 && !nextIsChar) |
{ |
// try Literal + rep0 |
int temp; |
backOffset = reps[0]+1; |
for (temp=1;temp<numAvailableBytes;temp++) |
if (data[temp]!=data[temp-backOffset]) |
break; |
lenTest = temp-1; |
if (lenTest>=2) |
{ |
int posStateNext; |
unsigned nextRepMatchPrice; |
state2 = state; |
CState_UpdateChar(state2); |
posStateNext = (position+1) & _posStateMask; |
nextRepMatchPrice = curAnd1Price + |
CMyBitEncoder_GetPrice1(&_isMatch[state2][posStateNext]) + |
CMyBitEncoder_GetPrice1(&_isRep[state2]); |
while (lenEnd < cur+1+lenTest) |
_optimum[++lenEnd].Price = kIfinityPrice; |
curAndLenPrice = nextRepMatchPrice + GetRepPrice(0,lenTest,state2,posStateNext); |
opt = &_optimum[cur+1+lenTest]; |
if (curAndLenPrice < opt->Price) |
{ |
opt->Price = curAndLenPrice; |
opt->PosPrev = cur+1; |
opt->BackPrev = 0; |
opt->Prev1IsChar = true; |
opt->Prev2 = false; |
} |
} |
} |
for (repIndex=0;repIndex<kNumRepDistances;repIndex++) |
{ |
backOffset = reps[repIndex]+1; |
if (data[0] != data[0-backOffset] || |
data[1] != data[1-backOffset]) |
continue; |
for (lenTest=2;lenTest<numAvailableBytes;lenTest++) |
if (data[lenTest]!=data[lenTest-backOffset]) |
break; |
lenTestTemp = lenTest; |
do |
{ |
while (lenEnd < cur+lenTest) |
_optimum[++lenEnd].Price = kIfinityPrice; |
curAndLenPrice = repMatchPrice + GetRepPrice(repIndex,lenTest,state,posState); |
opt = &_optimum[cur+lenTest]; |
if (curAndLenPrice < opt->Price) |
{ |
opt->Price = curAndLenPrice; |
opt->PosPrev = cur; |
opt->BackPrev = repIndex; |
opt->Prev1IsChar = false; |
} |
} while (--lenTest>=2); |
lenTest = lenTestTemp; |
lenTest2 = lenTest+1; |
limit = lenTest2 + _numFastBytes; |
if (limit > numAvailableBytesFull) |
limit = numAvailableBytesFull; |
for (;lenTest2<limit;lenTest2++) |
if (data[lenTest2] != data[lenTest2-backOffset]) |
break; |
lenTest2 -= lenTest+1; |
if (lenTest2 >= 2) |
{ |
unsigned nextMatchPrice,nextRepMatchPrice; |
int offset; |
state2 = state; |
CState_UpdateRep(state2); |
posStateNext = (position+lenTest)&_posStateMask; |
curAndLenCharPrice = repMatchPrice + GetRepPrice(repIndex,lenTest,state,posState) + |
CMyBitEncoder_GetPrice0(&_isMatch[state2][posStateNext]) + |
CLiteralEncoder_GetPrice(&_literalEncoder,position+lenTest,data[lenTest-1],true,data[lenTest-backOffset],data[lenTest]); |
CState_UpdateChar(state2); |
posStateNext = (position+lenTest+1)&_posStateMask; |
nextMatchPrice = curAndLenCharPrice + CMyBitEncoder_GetPrice1(&_isMatch[state2][posStateNext]); |
nextRepMatchPrice = nextMatchPrice + CMyBitEncoder_GetPrice1(&_isRep[state2]); |
offset = lenTest+1+lenTest2; |
while (lenEnd<cur+offset) |
_optimum[++lenEnd].Price = kIfinityPrice; |
curAndLenPrice = nextRepMatchPrice + GetRepPrice(0,lenTest2,state2,posStateNext); |
opt = &_optimum[cur+offset]; |
if (curAndLenPrice < opt->Price) |
{ |
opt->Price = curAndLenPrice; |
opt->PosPrev = cur+lenTest+1; |
opt->BackPrev = 0; |
opt->Prev1IsChar = true; |
opt->Prev2 = true; |
opt->PosPrev2 = cur; |
opt->BackPrev2 = repIndex; |
} |
} |
} |
if (newLen > numAvailableBytes) |
newLen = numAvailableBytes; |
if (newLen >= 2) |
{ |
if (newLen==2 && _matchDistances[2] >= 0x80) |
continue; |
normalMatchPrice = matchPrice + CMyBitEncoder_GetPrice0(&_isRep[state]); |
while (lenEnd < cur+newLen) |
_optimum[++lenEnd].Price = kIfinityPrice; |
for (lenTest=newLen;lenTest>=2;lenTest--) |
{ |
backOffset = _matchDistances[lenTest]; |
curAndLenPrice = normalMatchPrice + GetPosLenPrice(backOffset,lenTest,posState); |
opt = &_optimum[cur+lenTest]; |
if (curAndLenPrice < opt->Price) |
{ |
opt->Price = curAndLenPrice; |
opt->PosPrev = cur; |
opt->BackPrev = backOffset+kNumRepDistances; |
opt->Prev1IsChar = false; |
} |
if (lenTest==newLen || backOffset!=_matchDistances[lenTest+1]) |
{ |
// Try Match + Literal + Rep0 |
backOffset++; |
lenTest2 = lenTest+1; |
limit = lenTest2+_numFastBytes; |
if (limit > numAvailableBytesFull) |
limit = numAvailableBytesFull; |
for (;lenTest2<limit;lenTest2++) |
if (data[lenTest2]!=data[lenTest2-backOffset]) |
break; |
lenTest2 -= lenTest+1; |
if (lenTest2 >= 2) |
{ |
state2 = state; |
CState_UpdateMatch(state2); |
posStateNext = (position+lenTest)&_posStateMask; |
curAndLenCharPrice = curAndLenPrice + CMyBitEncoder_GetPrice0(&_isMatch[state2][posStateNext]) + |
CLiteralEncoder_GetPrice(&_literalEncoder,position+lenTest,data[lenTest-1],true,data[lenTest-backOffset],data[lenTest]); |
CState_UpdateChar(state2); |
posStateNext = (position+lenTest+1)&_posStateMask; |
nextMatchPrice = curAndLenCharPrice + CMyBitEncoder_GetPrice1(&_isMatch[state2][posStateNext]); |
nextRepMatchPrice = nextMatchPrice + CMyBitEncoder_GetPrice1(&_isRep[state2]); |
offset = lenTest+1+lenTest2; |
while (lenEnd<cur+offset) |
_optimum[++lenEnd].Price = kIfinityPrice; |
curAndLenPrice = nextRepMatchPrice + GetRepPrice(0,lenTest2,state2,posStateNext); |
opt = &_optimum[cur+offset]; |
if (curAndLenPrice < opt->Price) |
{ |
opt->Price = curAndLenPrice; |
opt->PosPrev = cur+lenTest+1; |
opt->BackPrev = 0; |
opt->Prev1IsChar = true; |
opt->Prev2 = true; |
opt->PosPrev2 = cur; |
opt->BackPrev2 = backOffset - 1 + kNumRepDistances; |
} |
} |
} |
} |
} |
} |
} |
static bool CodeOneBlock(void) |
{ |
unsigned posState; |
byte curByte,matchByte; |
unsigned pos,len,distance,i; |
unsigned posSlot,lenToPosState; |
CLiteralEncoder2* subCoder; |
uint64 progressPosValuePrev; |
if (_finished) |
return false; |
_finished = true; |
progressPosValuePrev = nowPos64; |
if (nowPos64 == 0) |
{ |
if (GetNumAvailableBytes() == 0) |
{ |
CEncoder_Flush(); |
return false; |
} |
ReadMatchDistances(); |
posState = (unsigned)nowPos64 & _posStateMask; |
CMyBitEncoder_Encode(&_isMatch[_state][posState],0); |
CState_UpdateChar(_state); |
curByte = GetIndexByte(0 - _additionalOffset); |
CLiteralEncoder2_Encode( |
*CLiteralEncoder_GetSubCoder(&_literalEncoder,(unsigned)nowPos64,_previousByte), |
curByte); |
_previousByte = curByte; |
_additionalOffset--; |
nowPos64++; |
} |
if (GetNumAvailableBytes() == 0) |
{ |
CEncoder_Flush(); |
return false; |
} |
for (;;) |
{ |
posState = (unsigned)nowPos64 & _posStateMask; |
GetOptimum((unsigned)nowPos64,&pos,&len); |
if (len==1 && pos==0xFFFFFFFF) |
{ |
CMyBitEncoder_Encode(&_isMatch[_state][posState],0); |
curByte = GetIndexByte(0-_additionalOffset); |
subCoder = CLiteralEncoder_GetSubCoder(&_literalEncoder,(unsigned)nowPos64, |
_previousByte); |
if (!CState_IsCharState(_state)) |
{ |
matchByte = GetIndexByte(0-_repDistances[0]-1-_additionalOffset); |
CLiteralEncoder2_EncodeMatched(*subCoder,matchByte,curByte); |
} |
else |
CLiteralEncoder2_Encode(*subCoder,curByte); |
CState_UpdateChar(_state); |
_previousByte = curByte; |
} |
else |
{ |
CMyBitEncoder_Encode(&_isMatch[_state][posState],1); |
if (pos < kNumRepDistances) |
{ |
CMyBitEncoder_Encode(&_isRep[_state],1); |
if (pos==0) |
{ |
CMyBitEncoder_Encode(&_isRepG0[_state],0); |
CMyBitEncoder_Encode(&_isRep0Long[_state][posState], |
(len==1) ? 0 : 1); |
} |
else |
{ |
CMyBitEncoder_Encode(&_isRepG0[_state],1); |
if (pos==1) |
CMyBitEncoder_Encode(&_isRepG1[_state],0); |
else |
{ |
CMyBitEncoder_Encode(&_isRepG1[_state],1); |
CMyBitEncoder_Encode(&_isRepG2[_state],pos-2); |
} |
} |
if (len==1) |
CState_UpdateShortRep(_state); |
else |
{ |
CPriceTableEncoder_Encode(&_repMatchLenEncoder,len-kMatchMinLen,posState); |
CState_UpdateRep(_state); |
} |
distance = _repDistances[pos]; |
if (pos) |
{ |
for (i=pos;i;i--) |
_repDistances[i] = _repDistances[i-1]; |
_repDistances[0] = distance; |
} |
} |
else |
{ |
CMyBitEncoder_Encode(&_isRep[_state],0); |
CState_UpdateMatch(_state); |
CPriceTableEncoder_Encode(&_lenEncoder,len-kMatchMinLen,posState); |
pos -= kNumRepDistances; |
posSlot = GetPosSlot(pos); |
lenToPosState = GetLenToPosState(len); |
CBitTreeEncoder_Encode(&_posSlotEncoder[lenToPosState],posSlot); |
if (posSlot >= kStartPosModelIndex) |
{ |
unsigned footerBits; |
unsigned base,posReduced; |
footerBits = (posSlot>>1)-1; |
base = (2 | (posSlot&1)) << footerBits; |
posReduced = pos-base; |
if (posSlot < kEndPosModelIndex) |
ReverseBitTreeEncode(_posEncoders+base-posSlot-1, |
footerBits,posReduced); |
else |
{ |
RangeEncoder_EncodeDirectBits(posReduced>>kNumAlignBits,footerBits-kNumAlignBits); |
CBitTreeEncoder_ReverseEncode(&_posAlignEncoder,posReduced&kAlignMask); |
if (--_alignPriceCount == 0) |
FillAlignPrices(); |
} |
} |
distance = pos; |
for (i=kNumRepDistances-1;i;i--) |
_repDistances[i] = _repDistances[i-1]; |
_repDistances[0] = distance; |
} |
_previousByte = GetIndexByte(len-1-_additionalOffset); |
} |
_additionalOffset -= len; |
nowPos64 += len; |
if (nowPos64 - lastPosSlotFillingPos >= (1<<9)) |
{ |
FillPosSlotPrices(); |
FillDistancesPrices(); |
lastPosSlotFillingPos = nowPos64; |
} |
if (!_additionalOffset) |
{ |
if (GetNumAvailableBytes() == 0) |
{ |
CEncoder_Flush(); |
return false; |
} |
if (nowPos64 - progressPosValuePrev >= (1<<12)) |
{ |
_finished = false; |
return true; |
} |
} |
} |
} |
extern void __stdcall lzma_set_dict_size( |
unsigned logdictsize) |
{ |
_dictionarySize = 1 << logdictsize; |
_distTableSize = logdictsize*2; |
} |
extern unsigned __stdcall lzma_compress( |
const void* source, |
void* destination, |
unsigned length, |
void* workmem) |
{ |
FastPosInit(); |
//memset(&encoder,0,sizeof(encoder)); |
//memset(&rangeEncoder,0,sizeof(rangeEncoder)); |
// CEncoder::CEncoder, CEncoder::SetCoderProperties |
_numFastBytes = 128; |
#ifdef FOR_KERPACK |
_posStateBits = 0; |
_posStateMask = 0; |
#else |
_posStateBits = 2; |
_posStateMask = 3; |
#endif |
_numLiteralContextBits = 3; |
_numLiteralPosStateBits = 0; |
_writeEndMark = false; |
// CEncoder::Code - ïîåõàëè! |
_finished = false; |
CEncoder_Create(workmem); |
CEncoder_Init(); |
FillPosSlotPrices(); |
FillDistancesPrices(); |
FillAlignPrices(); |
CPriceTableEncoder_SetTableSize(&_lenEncoder,_numFastBytes+1-kMatchMinLen); |
CPriceTableEncoder_UpdateTables(&_lenEncoder,1<<_posStateBits); |
CPriceTableEncoder_SetTableSize(&_repMatchLenEncoder,_numFastBytes+1-kMatchMinLen); |
CPriceTableEncoder_UpdateTables(&_repMatchLenEncoder,1<<_posStateBits); |
lastPosSlotFillingPos = 0; |
nowPos64 = 0; |
pack_length = length; |
pack_pos = 0; |
curin = (const byte*)source; |
curout = (byte*)destination; |
MatchFinder_Init(); |
while (CodeOneBlock()) ; |
return curout - (byte*)destination; |
} |
/programs/other/kpack/kerpack_linux/lzma_c/LZMAEncoder.h |
---|
0,0 → 1,53 |
#ifndef _LZMA_ENCODER_H |
#define _LZMA_ENCODER_H |
#include "lzma.h" |
#include "RangeCoderBitTree.h" |
typedef struct |
{ |
CState State; |
bool Prev1IsChar; |
bool Prev2; |
unsigned PosPrev2; |
unsigned BackPrev2; |
unsigned Price; |
unsigned PosPrev; |
unsigned BackPrev; |
unsigned Backs[kNumRepDistances]; |
} COptimal; |
#define COptimal_MakeAsChar(a) (a)->BackPrev=(unsigned)-1,(a)->Prev1IsChar=false |
#define COptimal_MakeAsShortRep(a) (a)->BackPrev=0,(a)->Prev1IsChar=false |
#define COptimal_IsShortRep(a) ((a)->BackPrev==0) |
#define kIfinityPrice 0xFFFFFFF |
#define kNumOpts (1<<12) |
typedef CMyBitEncoder CLiteralEncoder2[0x300]; |
typedef struct |
{ |
CLiteralEncoder2* _coders; |
int _numPrevBits; |
int _numPosBits; |
unsigned _posMask; |
} CLiteralEncoder; |
typedef struct |
{ |
CMyBitEncoder _choice; |
CMyBitEncoder _choice2; |
NRangeCoder_CBitTreeEncoder _lowCoder[kNumPosStatesEncodingMax]; |
NRangeCoder_CBitTreeEncoder _midCoder[kNumPosStatesEncodingMax]; |
NRangeCoder_CBitTreeEncoder _highCoder; |
} NLength_CEncoder; |
typedef struct |
{ |
NLength_CEncoder base; |
unsigned _prices[kNumSymbolsTotal][kNumPosStatesEncodingMax]; |
unsigned _tableSize; |
unsigned _counters[kNumPosStatesEncodingMax]; |
} NLength_CPriceTableEncoder; |
#define CPriceTableEncoder_Init(a,b) NLength_CEncoder_Init(&a.base,b) |
#endif |
/programs/other/kpack/kerpack_linux/lzma_c/MatchFinder.c |
---|
0,0 → 1,422 |
#include "MatchFinder.h" |
/* memcpy must be inlined - we do not want to use RTL */ |
#include <memory.h> |
/*#pragma function(memcpy) |
void* __cdecl memcpy(void* _Dst, const void* _Src, size_t _Size) |
{ |
unsigned long i; |
for (i = 0; i < _Size; i++) |
((char*)_Dst)[i] = ((char*)_Src)[i]; |
return _Dst; |
}*/ |
//#pragma intrinsic(memcpy) |
#define kMaxValForNormalize (((unsigned)1<<31)-1) |
/* settings for bt4: |
defined HASH_ARRAY_2 |
defined HASH_ARRAY_3 |
*/ |
//#define kHash2Size 0x400 |
#define kNumHashDirectBytes 0 |
#define kNumHashBytes 3 |
//#define kHash3Size 0x40000 |
#define kHash2Size 0x10000 |
#define kHashSize 0x100000 |
#define kHashSizeSum (kHashSize+kHash2Size) |
#define kHash2Offset kHashSize |
static unsigned _cyclicBufferPos; |
static unsigned _cyclicBufferSize; |
static unsigned _matchMaxLen; |
static unsigned* _hash; |
static unsigned _cutValue; |
#ifdef GENERIC_INPUT |
static byte* _bufferBase; |
static unsigned _posLimit; |
static bool _streamEndWasReached; |
static byte* _pointerToLastSafePosition; |
static byte* _buffer; |
static unsigned _blockSize; |
static unsigned _pos; |
static unsigned _keepSizeBefore; |
static unsigned _keepSizeAfter; |
static unsigned _keepSizeReserv; |
static unsigned _streamPos; |
#else |
#define _buffer curin |
#define _pos pack_pos |
#define _streamPos pack_length |
#endif |
#ifdef GENERIC_INPUT |
/* LZ Window */ |
static void LZInWindow_Create(unsigned keepSizeBefore,unsigned keepSizeAfter,unsigned keepSizeReserv,byte**mem) |
{ |
_keepSizeBefore = keepSizeBefore; |
_keepSizeAfter = keepSizeAfter; |
_keepSizeReserv = keepSizeReserv; |
_blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv; |
_bufferBase = *mem; |
_blockSize = (_blockSize + 3) & ~3; |
*mem += _blockSize; |
_pointerToLastSafePosition = _bufferBase + _blockSize - keepSizeAfter; |
} |
static void ReadBlock(void) |
{ |
if (_streamEndWasReached) |
return; |
for (;;) |
{ |
unsigned size; |
size = (unsigned)(_bufferBase-_buffer) + _blockSize - _streamPos; |
if (!size) return; |
if (size > pack_length - pack_pos) |
size = pack_length - pack_pos; |
memcpy(_buffer+_streamPos,curin,size); |
curin += size; |
pack_pos += size; |
if (size == 0) |
{ |
byte* pointerToPosition; |
_posLimit = _streamPos; |
pointerToPosition = _buffer + _posLimit; |
if (pointerToPosition > _pointerToLastSafePosition) |
_posLimit = _pointerToLastSafePosition - _buffer; |
_streamEndWasReached = true; |
return; |
} |
_streamPos += size; |
if (_streamPos >= _pos + _keepSizeAfter) |
{ |
_posLimit = _streamPos - _keepSizeAfter; |
return; |
} |
} |
} |
static void LZInWindow_Init(void) |
{ |
_buffer = _bufferBase; |
_pos = 0; |
_streamPos = 0; |
_streamEndWasReached = false; |
ReadBlock(); |
} |
#else |
#define LZInWindow_Create(a,b,c,d) /* nothing */ |
#define LZInWindow_Init() _buffer--, _pos++, _streamPos++ |
#endif |
const byte* GetPointerToCurrentPos(void) {return _buffer+_pos;} |
#ifdef GENERIC_INPUT |
static void MoveBlock(void) |
{ |
unsigned offset,numBytes; |
offset = _buffer-_bufferBase+_pos-_keepSizeBefore; |
numBytes = _buffer-_bufferBase+_streamPos-offset; |
// copying backwards: safe to use memcpy instead of memmove |
memcpy(_bufferBase,_bufferBase+offset,numBytes); |
_buffer -= offset; |
} |
static void LZInWindow_MovePos(void) |
{ |
_pos++; |
if (_pos > _posLimit) |
{ |
const byte* pointerToPosition = _buffer+_pos; |
if (pointerToPosition > _pointerToLastSafePosition) |
MoveBlock(); |
ReadBlock(); |
} |
} |
#else |
#define LZInWindow_MovePos() _pos++ |
#endif |
byte GetIndexByte(int index) {return _buffer[_pos+index];} |
unsigned GetMatchLen(int index,unsigned distance,unsigned limit) |
{ |
const byte* pby; |
unsigned i; |
#ifdef GENERIC_INPUT |
if (_streamEndWasReached) |
if ((_pos+index)+limit > _streamPos) |
limit = _streamPos - (_pos+index); |
#else |
unsigned limit2 = pack_length - (pack_pos + index); |
if (limit > limit2) |
limit = limit2; |
#endif |
distance++; |
pby = _buffer + _pos + index; |
for (i=0;i<limit && pby[i]==pby[(int)(i-distance)];i++) ; |
return i; |
} |
unsigned GetNumAvailableBytes(void) {return _streamPos-_pos;} |
#ifdef GENERIC_INPUT |
void ReduceOffsets(int subValue) |
{ |
_buffer += subValue; |
_posLimit -= subValue; |
_pos -= subValue; |
_streamPos -= subValue; |
} |
#else |
#define ReduceOffsets(a) /* nothing */ |
#endif |
/* Binary tree Match Finder */ |
static unsigned crc_table[256]; |
void MatchFinder_Create(unsigned historySize,unsigned keepAddBufferBefore,unsigned matchMaxLen,unsigned keepAddBufferAfter,byte**mem) |
{ |
unsigned sizeReserv; |
sizeReserv = (historySize + keepAddBufferBefore + matchMaxLen + keepAddBufferAfter)/2+256; |
LZInWindow_Create(historySize+keepAddBufferBefore,matchMaxLen+keepAddBufferAfter,sizeReserv,mem); |
_matchMaxLen = matchMaxLen; |
_cyclicBufferSize = historySize+1; |
_hash = (unsigned*)*mem; |
*mem += (kHashSizeSum + _cyclicBufferSize*2) * sizeof(unsigned); |
_cutValue = 0xFF; |
} |
void MatchFinder_Init(void) |
{ |
unsigned i,j,r; |
LZInWindow_Init(); |
for (i=0;i<kHashSizeSum;i++) |
_hash[i] = 0; |
_cyclicBufferPos = 0; |
ReduceOffsets(-1); |
for (i=0;i<256;i++) |
{ |
r = i; |
for (j=0;j<8;j++) |
{ |
if (r & 1) |
r = (r>>1) ^ 0xEDB88320; |
else |
r >>= 1; |
} |
crc_table[i] = r; |
} |
} |
static unsigned Hash(const byte* ptr, unsigned* hash2Value) |
{ |
unsigned temp; |
temp = crc_table[ptr[0]] ^ ptr[1]; |
*hash2Value = *(word*)ptr; //ptr[0] + ((unsigned)ptr[1] << 8); |
return (temp ^ ((unsigned)ptr[2]<<8)) & (kHashSize - 1); |
} |
unsigned GetLongestMatch(unsigned* distances) |
{ |
unsigned lenLimit,maxLen=0; |
unsigned matchMinPos; |
const byte* cur; |
unsigned hash2Value,hashValue; |
unsigned curMatch,curMatch2; |
unsigned *son,*ptr0,*ptr1; |
unsigned len0,len1,count; |
if (_pos + _matchMaxLen <= _streamPos) |
lenLimit = _matchMaxLen; |
else |
{ |
lenLimit = _streamPos - _pos; |
if (lenLimit < kNumHashBytes) |
return 0; |
} |
matchMinPos = (_pos>_cyclicBufferSize) ? (_pos-_cyclicBufferSize) : 0; |
cur = _buffer+_pos; |
hashValue = Hash(cur,&hash2Value); |
curMatch = _hash[hashValue]; |
curMatch2 = _hash[kHash2Offset + hash2Value]; |
_hash[kHash2Offset + hash2Value] = _pos; |
distances[2] = 0xFFFFFFFF; |
if (curMatch2 > matchMinPos) |
//if (_buffer[curMatch2] == cur[0]) |
{ |
distances[2] = _pos - curMatch2 - 1; |
maxLen = 2; |
} |
_hash[hashValue] = _pos; |
son = _hash + kHashSizeSum; |
ptr0 = son + (_cyclicBufferPos << 1) + 1; |
ptr1 = son + (_cyclicBufferPos << 1); |
distances[kNumHashBytes] = 0xFFFFFFFF; |
len0 = len1 = kNumHashDirectBytes; |
count = _cutValue; |
for (;;) |
{ |
const byte* pb; |
unsigned len,delta; |
unsigned cyclicPos; |
unsigned* pair; |
if (curMatch <= matchMinPos || count--==0) |
{ |
*ptr0 = *ptr1 = 0; |
break; |
} |
pb = _buffer+curMatch; |
len = (len0<len1) ? len0 : len1; |
do |
if (pb[len] != cur[len]) break; |
while (++len != lenLimit); |
delta = _pos - curMatch; |
while (maxLen < len) |
distances[++maxLen] = delta-1; |
cyclicPos = (delta <= _cyclicBufferPos) ? |
(_cyclicBufferPos - delta) : |
(_cyclicBufferPos - delta + _cyclicBufferSize); |
pair = son + (cyclicPos<<1); |
if (len != lenLimit) |
{ |
if (pb[len] < cur[len]) |
{ |
*ptr1 = curMatch; |
ptr1 = pair+1; |
curMatch = *ptr1; |
len1 = len; |
} |
else |
{ |
*ptr0 = curMatch; |
ptr0 = pair; |
curMatch = *ptr0; |
len0 = len; |
} |
} |
else |
{ |
*ptr1 = pair[0]; |
*ptr0 = pair[1]; |
break; |
} |
} |
/*if (distances[4] < distances[3]) |
distances[3] = distances[4]; |
if (distances[3] < distances[2]) |
distances[2] = distances[3];*/ |
return maxLen; |
} |
void DummyLongestMatch(void) |
{ |
unsigned lenLimit; |
unsigned matchMinPos; |
const byte* cur; |
unsigned hash2Value,hashValue; |
unsigned curMatch; |
unsigned* son,*ptr0,*ptr1; |
unsigned len0,len1,count; |
if (_pos + _matchMaxLen <= _streamPos) |
lenLimit = _matchMaxLen; |
else |
{ |
lenLimit = _streamPos - _pos; |
if (lenLimit < kNumHashBytes) |
return; |
} |
matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0; |
cur = _buffer+_pos; |
hashValue = Hash(cur,&hash2Value); |
_hash[kHash2Offset + hash2Value] = _pos; |
curMatch = _hash[hashValue]; |
_hash[hashValue] = _pos; |
son = _hash+kHashSizeSum; |
ptr0 = son + (_cyclicBufferPos << 1) + 1; |
ptr1 = son + (_cyclicBufferPos << 1); |
len0 = len1 = kNumHashDirectBytes; |
count = _cutValue; |
for (;;) |
{ |
const byte* pb; |
unsigned len; |
unsigned delta,cyclicPos; |
unsigned* pair; |
if (curMatch <= matchMinPos || count--==0) |
break; |
pb = _buffer+curMatch; |
len = (len0<len1) ? len0 : len1; |
do |
if (pb[len] != cur[len]) break; |
while (++len != lenLimit); |
delta = _pos - curMatch; |
cyclicPos = (delta <= _cyclicBufferPos) ? |
(_cyclicBufferPos - delta) : |
(_cyclicBufferPos - delta + _cyclicBufferSize); |
pair = son + (cyclicPos << 1); |
if (len != lenLimit) |
{ |
if (pb[len] < cur[len]) |
{ |
*ptr1 = curMatch; |
ptr1 = pair+1; |
curMatch = *ptr1; |
len1 = len; |
} |
else |
{ |
*ptr0 = curMatch; |
ptr0 = pair; |
curMatch = *ptr0; |
len0 = len; |
} |
} |
else |
{ |
*ptr1 = pair[0]; |
*ptr0 = pair[1]; |
return; |
} |
} |
*ptr0 = *ptr1 = 0; |
} |
#ifdef GENERIC_INPUT |
// for memory input size is always less than kMaxValForNormalize |
static void Normalize(void) |
{ |
unsigned subValue; |
unsigned* items; |
unsigned i,numItems; |
subValue = _pos - _cyclicBufferSize; |
items = _hash; |
numItems = (kHashSizeSum + _cyclicBufferSize*2); |
for (i=0;i<numItems;i++) |
{ |
unsigned value; |
value = items[i]; |
if (value <= subValue) |
value = 0; |
else |
value -= subValue; |
items[i] = value; |
} |
ReduceOffsets(subValue); |
} |
#endif |
void MatchFinder_MovePos(void) |
{ |
if (++_cyclicBufferPos == _cyclicBufferSize) |
_cyclicBufferPos = 0; |
LZInWindow_MovePos(); |
#ifdef GENERIC_INPUT |
if (_pos == kMaxValForNormalize) |
Normalize(); |
#endif |
} |
/programs/other/kpack/kerpack_linux/lzma_c/MatchFinder.h |
---|
0,0 → 1,13 |
#include "common.h" |
extern const byte* GetPointerToCurrentPos(void); |
extern byte GetIndexByte(int index); |
extern unsigned GetMatchLen(int index,unsigned distance,unsigned limit); |
extern unsigned GetNumAvailableBytes(void); |
extern void ReduceOffsets(int subValue); |
extern void MatchFinder_Init(void); |
extern void MatchFinder_Create(unsigned historySize,unsigned keepAddBufferBefore,unsigned matchMaxLen,unsigned keepAddBufferAfter,byte**mem); |
extern unsigned GetLongestMatch(unsigned*distances); |
extern void DummyLongestMatch(void); |
extern void MatchFinder_MovePos(void); |
/programs/other/kpack/kerpack_linux/lzma_c/RangeCoder.c |
---|
0,0 → 1,191 |
#include "RangeCoderBitTree.h" |
#include "lzma.h" |
static unsigned _cacheSize; |
static byte _cache; |
static uint64 low; |
static unsigned range; |
static unsigned PriceTable[kBitModelTotal >> kNumMoveReducingBits]; |
void RangeEncoder_Init(void) |
{ |
int i; |
unsigned start,end,j; |
low = 0; |
range = 0xFFFFFFFF; |
_cacheSize = 1; |
_cache = 0; |
/* init price table */ |
#define kNumBits (kNumBitModelTotalBits - kNumMoveReducingBits) |
for (i=kNumBits;i--;) |
{ |
start = 1 << (kNumBits - i - 1); |
end = 1 << (kNumBits - i); |
for (j=start;j<end;j++) |
PriceTable[j] = (i<<kNumBitPriceShiftBits) + |
(((end-j)<<kNumBitPriceShiftBits) >> (kNumBits - i - 1)); |
} |
#undef kNumBits |
} |
void RangeEncoder_ShiftLow(void) |
{ |
if ((unsigned)low < 0xFF000000U || (int)(low>>32)) |
{ |
byte temp = _cache; |
do |
{ |
*curout++ = (byte)(temp + (byte)(low>>32)); |
temp = 0xFF; |
} while (--_cacheSize); |
_cache = (byte)((unsigned)low>>24); |
} |
_cacheSize++; |
low = (unsigned)low << 8; |
} |
void RangeEncoder_FlushData(void) |
{ |
int i; |
for (i=0;i<5;i++) |
RangeEncoder_ShiftLow(); |
} |
void RangeEncoder_EncodeDirectBits(unsigned value,int numTotalBits) |
{ |
int i; |
for (i=numTotalBits;i--;) |
{ |
range >>= 1; |
if (((value >> i) & 1) == 1) |
low += range; |
if (range < kTopValue) |
{ |
range <<= 8; |
RangeEncoder_ShiftLow(); |
} |
} |
} |
void CMyBitEncoder_Encode(CMyBitEncoder* e,unsigned symbol) |
{ |
unsigned newBound; |
newBound = (range >> kNumBitModelTotalBits) * *e; |
if (symbol == 0) |
{ |
range = newBound; |
*e += (kBitModelTotal - *e) >> kNumMoveBits; |
} |
else |
{ |
low += newBound; |
range -= newBound; |
*e -= *e >> kNumMoveBits; |
} |
if (range < kTopValue) |
{ |
range <<= 8; |
RangeEncoder_ShiftLow(); |
} |
} |
unsigned CMyBitEncoder_GetPrice(CMyBitEncoder* e, unsigned symbol) |
{ |
return PriceTable[(((*e-symbol)^((-(int)symbol))) & (kBitModelTotal-1)) >> kNumMoveReducingBits]; |
} |
unsigned CMyBitEncoder_GetPrice0(CMyBitEncoder* e) |
{ |
return PriceTable[*e >> kNumMoveReducingBits]; |
} |
unsigned CMyBitEncoder_GetPrice1(CMyBitEncoder* e) |
{ |
return PriceTable[(kBitModelTotal - *e) >> kNumMoveReducingBits]; |
} |
void CBitTreeEncoder_Init(NRangeCoder_CBitTreeEncoder*e,int numBitLevels) |
{ |
unsigned i; |
e->numBitLevels = numBitLevels; |
for (i=1;i<((unsigned)1<<numBitLevels);i++) |
CMyBitEncoder_Init(e->Models[i]); |
} |
void CBitTreeEncoder_Encode(NRangeCoder_CBitTreeEncoder*e,unsigned symbol) |
{ |
unsigned modelIndex = 1; |
int bitIndex; |
unsigned bit; |
for (bitIndex = e->numBitLevels; bitIndex--;) |
{ |
bit = (symbol >> bitIndex) & 1; |
CMyBitEncoder_Encode(&e->Models[modelIndex],bit); |
modelIndex = (modelIndex << 1) | bit; |
} |
} |
void CBitTreeEncoder_ReverseEncode(NRangeCoder_CBitTreeEncoder*e,unsigned symbol) |
{ |
unsigned modelIndex = 1; |
int i; |
unsigned bit; |
for (i=0;i<e->numBitLevels;i++) |
{ |
bit = symbol & 1; |
CMyBitEncoder_Encode(&e->Models[modelIndex],bit); |
modelIndex = (modelIndex << 1) | bit; |
symbol >>= 1; |
} |
} |
unsigned CBitTreeEncoder_GetPrice(NRangeCoder_CBitTreeEncoder*e,unsigned symbol) |
{ |
unsigned price = 0; |
symbol |= (1 << e->numBitLevels); |
while (symbol != 1) |
{ |
price += CMyBitEncoder_GetPrice(&e->Models[symbol>>1],symbol&1); |
symbol >>= 1; |
} |
return price; |
} |
unsigned CBitTreeEncoder_ReverseGetPrice(NRangeCoder_CBitTreeEncoder*e,unsigned symbol) |
{ |
unsigned price=0; |
unsigned modelIndex=1; |
int i; |
unsigned bit; |
for (i=e->numBitLevels;i;i--) |
{ |
bit = symbol&1; |
symbol >>= 1; |
price += CMyBitEncoder_GetPrice(&e->Models[modelIndex],bit); |
modelIndex = (modelIndex<<1)|bit; |
} |
return price; |
} |
unsigned ReverseBitTreeGetPrice(CMyBitEncoder*Models,unsigned NumBitLevels,unsigned symbol) |
{ |
unsigned price=0; |
unsigned modelIndex=1; |
unsigned bit; |
int i; |
for (i=NumBitLevels;i;i--) |
{ |
bit = symbol & 1; |
symbol >>= 1; |
price += CMyBitEncoder_GetPrice(Models+modelIndex,bit); |
modelIndex = (modelIndex<<1)|bit; |
} |
return price; |
} |
void ReverseBitTreeEncode(CMyBitEncoder*Models,int NumBitLevels,unsigned symbol) |
{ |
unsigned modelIndex = 1; |
int i; |
unsigned bit; |
for (i=0;i<NumBitLevels;i++) |
{ |
bit = symbol & 1; |
CMyBitEncoder_Encode(Models+modelIndex,bit); |
modelIndex = (modelIndex<<1)|bit; |
symbol >>= 1; |
} |
} |
/programs/other/kpack/kerpack_linux/lzma_c/RangeCoder.h |
---|
0,0 → 1,7 |
#include "common.h" |
#define kNumTopBits 24 |
#define kTopValue (1<<kNumTopBits) |
extern void RangeEncoder_Init(void); |
extern void RangeEncoder_FlushData(void); |
extern void RangeEncoder_ShiftLow(void); |
extern void RangeEncoder_EncodeDirectBits(unsigned value,int numTotalBits); |
/programs/other/kpack/kerpack_linux/lzma_c/RangeCoderBit.h |
---|
0,0 → 1,18 |
#include "RangeCoder.h" |
#define kNumBitModelTotalBits 11 |
#define kBitModelTotal (1<<kNumBitModelTotalBits) |
#define kNumMoveReducingBits 2 |
#define kNumBitPriceShiftBits 6 |
#define kBitPrice (1<<kNumBitPriceShiftBits) |
typedef unsigned NRangeCoder_CBitModel; |
typedef NRangeCoder_CBitModel CMyBitEncoder; |
extern void CMyBitEncoder_Encode(CMyBitEncoder* e,unsigned symbol); |
extern unsigned CMyBitEncoder_GetPrice(CMyBitEncoder* e, unsigned symbol); |
extern unsigned CMyBitEncoder_GetPrice0(CMyBitEncoder* e); |
extern unsigned CMyBitEncoder_GetPrice1(CMyBitEncoder* e); |
#define CMyBitEncoder_Init(a) a=kBitModelTotal/2 |
/programs/other/kpack/kerpack_linux/lzma_c/RangeCoderBitTree.h |
---|
0,0 → 1,15 |
#include "RangeCoderBit.h" |
typedef struct |
{ |
CMyBitEncoder Models[1<<8]; |
int numBitLevels; |
} NRangeCoder_CBitTreeEncoder; |
extern void CBitTreeEncoder_Init(NRangeCoder_CBitTreeEncoder*e,int numBitLevels); |
extern void CBitTreeEncoder_Encode(NRangeCoder_CBitTreeEncoder*e,unsigned symbol); |
extern void CBitTreeEncoder_ReverseEncode(NRangeCoder_CBitTreeEncoder*e,unsigned symbol); |
extern unsigned CBitTreeEncoder_GetPrice(NRangeCoder_CBitTreeEncoder*e,unsigned symbol); |
extern unsigned CBitTreeEncoder_ReverseGetPrice(NRangeCoder_CBitTreeEncoder*e,unsigned symbol); |
extern unsigned ReverseBitTreeGetPrice(CMyBitEncoder*Models,unsigned NumBitLevels,unsigned symbol); |
extern void ReverseBitTreeEncode(CMyBitEncoder*Models,int NumBitLevels,unsigned symbol); |
/programs/other/kpack/kerpack_linux/lzma_c/common.h |
---|
0,0 → 1,22 |
#ifndef _COMMON_H |
#define _COMMON_H |
typedef unsigned char byte; |
typedef unsigned short word; |
// conditional compiling, mike.dld |
#ifdef WIN32 |
typedef unsigned __int64 uint64; |
#else |
typedef unsigned long long uint64; |
#define __stdcall __attribute__((stdcall)) |
#endif |
typedef byte bool; |
#define true 1 |
#define false 0 |
extern unsigned pack_length; |
extern unsigned pack_pos; |
extern const byte* curin; |
extern byte* curout; |
#endif |
/programs/other/kpack/kerpack_linux/lzma_c/lzma.h |
---|
0,0 → 1,52 |
#include "common.h" |
#define kNumRepDistances 4 |
#define kNumStates 12 |
extern const byte kLiteralNextStates[kNumStates]; |
extern const byte kMatchNextStates[kNumStates]; |
extern const byte kRepNextStates[kNumStates]; |
extern const byte kShortRepNextStates[kNumStates]; |
typedef byte CState; |
#define CState_Init(a) a=0 |
#define CState_UpdateChar(a) a=kLiteralNextStates[a] |
#define CState_UpdateMatch(a) a=kMatchNextStates[a] |
#define CState_UpdateRep(a) a=kRepNextStates[a] |
#define CState_UpdateShortRep(a) a=kShortRepNextStates[a] |
#define CState_IsCharState(a) (a<7) |
#define kNumPosSlotBits 6 |
#define kDicLogSizeMin 0 |
#define kDicLogSizeMax 32 |
#define kDistTableSizeMax (kDicLogSizeMax*2) |
#define kNumLenToPosStates 4 |
#define GetLenToPosState(len) ((len<kNumLenToPosStates+2)?len-2:kNumLenToPosStates-1) |
#define kNumPosStatesBitsMax 4 |
#define kNumPosStatesMax (1<<kNumPosStatesBitsMax) |
#define kNumPosStatesBitsEncodingMax 4 |
#define kNumPosStatesEncodingMax (1 << kNumPosStatesBitsEncodingMax) |
#define kNumLowBits 3 |
#define kNumMidBits 3 |
#define kNumHighBits 8 |
#define kNumLowSymbols (1<<kNumLowBits) |
#define kNumMidSymbols (1<<kNumMidBits) |
#define kNumSymbolsTotal (kNumLowSymbols + kNumMidSymbols + (1<<kNumHighBits)) |
#define kMatchMinLen 2 |
#define kMatchMaxLen (kMatchMinLen + kNumSymbolsTotal - 1) |
#define kNumAlignBits 4 |
#define kAlignTableSize (1<<kNumAlignBits) |
#define kAlignMask (kAlignTableSize-1) |
#define kStartPosModelIndex 4 |
#define kEndPosModelIndex 14 |
#define kNumPosModels (kEndPosModelIndex-kStartPosModelIndex) |
#define kNumFullDistances (1<<(kEndPosModelIndex/2)) |
#define kNumLitPosStatesBitsEncodingMax 4 |
#define kNumLitContextBitsMax 8 |
#define kNumMoveBits 5 |
/programs/other/kpack/kerpack_linux/lzma_c/lzmapack.dsp |
---|
0,0 → 1,132 |
# Microsoft Developer Studio Project File - Name="lzmapack" - Package Owner=<4> |
# Microsoft Developer Studio Generated Build File, Format Version 6.00 |
# ** DO NOT EDIT ** |
# TARGTYPE "Win32 (x86) Static Library" 0x0104 |
CFG=lzmapack - Win32 Debug |
!MESSAGE This is not a valid makefile. To build this project using NMAKE, |
!MESSAGE use the Export Makefile command and run |
!MESSAGE |
!MESSAGE NMAKE /f "lzmapack.mak". |
!MESSAGE |
!MESSAGE You can specify a configuration when running NMAKE |
!MESSAGE by defining the macro CFG on the command line. For example: |
!MESSAGE |
!MESSAGE NMAKE /f "lzmapack.mak" CFG="lzmapack - Win32 Debug" |
!MESSAGE |
!MESSAGE Possible choices for configuration are: |
!MESSAGE |
!MESSAGE "lzmapack - Win32 Release" (based on "Win32 (x86) Static Library") |
!MESSAGE "lzmapack - Win32 Debug" (based on "Win32 (x86) Static Library") |
!MESSAGE |
# Begin Project |
# PROP AllowPerConfigDependencies 0 |
# PROP Scc_ProjName "" |
# PROP Scc_LocalPath "" |
CPP=cl.exe |
RSC=rc.exe |
!IF "$(CFG)" == "lzmapack - Win32 Release" |
# PROP BASE Use_MFC 0 |
# PROP BASE Use_Debug_Libraries 0 |
# PROP BASE Output_Dir "Release" |
# PROP BASE Intermediate_Dir "Release" |
# PROP BASE Target_Dir "" |
# PROP Use_MFC 0 |
# PROP Use_Debug_Libraries 0 |
# PROP Output_Dir "" |
# PROP Intermediate_Dir "Release" |
# PROP Target_Dir "" |
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c |
# ADD CPP /nologo /W3 /GX /O1 /Ob1 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /Zl /FD /c |
# ADD BASE RSC /l 0x419 /d "NDEBUG" |
# ADD RSC /l 0x419 /d "NDEBUG" |
BSC32=bscmake.exe |
# ADD BASE BSC32 /nologo |
# ADD BSC32 /nologo |
LIB32=link.exe -lib |
# ADD BASE LIB32 /nologo |
# ADD LIB32 /nologo |
!ELSEIF "$(CFG)" == "lzmapack - Win32 Debug" |
# PROP BASE Use_MFC 0 |
# PROP BASE Use_Debug_Libraries 1 |
# PROP BASE Output_Dir "Debug" |
# PROP BASE Intermediate_Dir "Debug" |
# PROP BASE Target_Dir "" |
# PROP Use_MFC 0 |
# PROP Use_Debug_Libraries 1 |
# PROP Output_Dir "" |
# PROP Intermediate_Dir "Debug" |
# PROP Target_Dir "" |
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c |
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c |
# ADD BASE RSC /l 0x419 /d "_DEBUG" |
# ADD RSC /l 0x419 /d "_DEBUG" |
BSC32=bscmake.exe |
# ADD BASE BSC32 /nologo |
# ADD BSC32 /nologo |
LIB32=link.exe -lib |
# ADD BASE LIB32 /nologo |
# ADD LIB32 /nologo |
!ENDIF |
# Begin Target |
# Name "lzmapack - Win32 Release" |
# Name "lzmapack - Win32 Debug" |
# Begin Group "Source Files" |
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" |
# Begin Source File |
SOURCE=.\LZMAEncoder.c |
# End Source File |
# Begin Source File |
SOURCE=.\MatchFinder.c |
# End Source File |
# Begin Source File |
SOURCE=.\RangeCoder.c |
# End Source File |
# End Group |
# Begin Group "Header Files" |
# PROP Default_Filter "h;hpp;hxx;hm;inl" |
# Begin Source File |
SOURCE=.\common.h |
# End Source File |
# Begin Source File |
SOURCE=.\lzma.h |
# End Source File |
# Begin Source File |
SOURCE=.\LZMAEncoder.h |
# End Source File |
# Begin Source File |
SOURCE=.\MatchFinder.h |
# End Source File |
# Begin Source File |
SOURCE=.\RangeCoder.h |
# End Source File |
# Begin Source File |
SOURCE=.\RangeCoderBit.h |
# End Source File |
# Begin Source File |
SOURCE=.\RangeCoderBitTree.h |
# End Source File |
# End Group |
# End Target |
# End Project |
/programs/other/kpack/kerpack_linux/lzma_c/lzmapack.dsw |
---|
0,0 → 1,44 |
Microsoft Developer Studio Workspace File, Format Version 6.00 |
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! |
############################################################################### |
Project: "lzmapack"=.\lzmapack.dsp - Package Owner=<4> |
Package=<5> |
{{{ |
}}} |
Package=<4> |
{{{ |
}}} |
############################################################################### |
Project: "lzmatest"=.\lzmatest\lzmatest.dsp - Package Owner=<4> |
Package=<5> |
{{{ |
}}} |
Package=<4> |
{{{ |
Begin Project Dependency |
Project_Dep_Name lzmapack |
End Project Dependency |
}}} |
############################################################################### |
Global: |
Package=<5> |
{{{ |
}}} |
Package=<3> |
{{{ |
}}} |
############################################################################### |
/programs/other/kpack/kerpack_linux/lzma_c/lzmatest/lzmatest.dsp |
---|
0,0 → 1,102 |
# Microsoft Developer Studio Project File - Name="lzmatest" - Package Owner=<4> |
# Microsoft Developer Studio Generated Build File, Format Version 6.00 |
# ** DO NOT EDIT ** |
# TARGTYPE "Win32 (x86) Console Application" 0x0103 |
CFG=lzmatest - Win32 Debug |
!MESSAGE This is not a valid makefile. To build this project using NMAKE, |
!MESSAGE use the Export Makefile command and run |
!MESSAGE |
!MESSAGE NMAKE /f "lzmatest.mak". |
!MESSAGE |
!MESSAGE You can specify a configuration when running NMAKE |
!MESSAGE by defining the macro CFG on the command line. For example: |
!MESSAGE |
!MESSAGE NMAKE /f "lzmatest.mak" CFG="lzmatest - Win32 Debug" |
!MESSAGE |
!MESSAGE Possible choices for configuration are: |
!MESSAGE |
!MESSAGE "lzmatest - Win32 Release" (based on "Win32 (x86) Console Application") |
!MESSAGE "lzmatest - Win32 Debug" (based on "Win32 (x86) Console Application") |
!MESSAGE |
# Begin Project |
# PROP AllowPerConfigDependencies 0 |
# PROP Scc_ProjName "" |
# PROP Scc_LocalPath "" |
CPP=cl.exe |
RSC=rc.exe |
!IF "$(CFG)" == "lzmatest - Win32 Release" |
# PROP BASE Use_MFC 0 |
# PROP BASE Use_Debug_Libraries 0 |
# PROP BASE Output_Dir "Release" |
# PROP BASE Intermediate_Dir "Release" |
# PROP BASE Target_Dir "" |
# PROP Use_MFC 0 |
# PROP Use_Debug_Libraries 0 |
# PROP Output_Dir "Release" |
# PROP Intermediate_Dir "Release" |
# PROP Ignore_Export_Lib 0 |
# PROP Target_Dir "" |
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c |
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c |
# ADD BASE RSC /l 0x419 /d "NDEBUG" |
# ADD RSC /l 0x419 /d "NDEBUG" |
BSC32=bscmake.exe |
# ADD BASE BSC32 /nologo |
# ADD BSC32 /nologo |
LINK32=link.exe |
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 |
# ADD LINK32 kernel32.lib ..\lzmapack.lib /nologo /subsystem:console /machine:I386 |
!ELSEIF "$(CFG)" == "lzmatest - Win32 Debug" |
# PROP BASE Use_MFC 0 |
# PROP BASE Use_Debug_Libraries 1 |
# PROP BASE Output_Dir "Debug" |
# PROP BASE Intermediate_Dir "Debug" |
# PROP BASE Target_Dir "" |
# PROP Use_MFC 0 |
# PROP Use_Debug_Libraries 1 |
# PROP Output_Dir "Debug" |
# PROP Intermediate_Dir "Debug" |
# PROP Ignore_Export_Lib 0 |
# PROP Target_Dir "" |
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c |
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c |
# ADD BASE RSC /l 0x419 /d "_DEBUG" |
# ADD RSC /l 0x419 /d "_DEBUG" |
BSC32=bscmake.exe |
# ADD BASE BSC32 /nologo |
# ADD BSC32 /nologo |
LINK32=link.exe |
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept |
# ADD LINK32 kernel32.lib ..\lzmapack.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept |
!ENDIF |
# Begin Target |
# Name "lzmatest - Win32 Release" |
# Name "lzmatest - Win32 Debug" |
# Begin Group "Source Files" |
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" |
# Begin Source File |
SOURCE=.\main.cpp |
# End Source File |
# End Group |
# Begin Group "Header Files" |
# PROP Default_Filter "h;hpp;hxx;hm;inl" |
# End Group |
# Begin Group "Resource Files" |
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" |
# End Group |
# End Target |
# End Project |
/programs/other/kpack/kerpack_linux/lzma_c/lzmatest/main.cpp |
---|
0,0 → 1,31 |
#include <stdio.h> |
#include <windows.h> |
extern "C" __stdcall lzma_set_dict_size(unsigned logdictsize); |
extern "C" __stdcall lzma_compress( |
const void* source, |
void* destination, |
unsigned length, |
void* workmem); |
int main() |
{ |
FILE* f; |
f = fopen("test.in","rb"); |
fseek(f,0,SEEK_END); |
unsigned inlen = ftell(f); |
fseek(f,0,SEEK_SET); |
void* in = VirtualAlloc(NULL,inlen,MEM_COMMIT,PAGE_READWRITE); |
void* out = VirtualAlloc(NULL,inlen,MEM_COMMIT,PAGE_READWRITE); |
fread(in,1,inlen,f); |
fclose(f); |
unsigned logdictsize,dictsize; |
for (logdictsize=0,dictsize=1;dictsize<inlen && logdictsize<=28;logdictsize++,dictsize<<=1) ; |
lzma_set_dict_size(logdictsize); |
void* work = VirtualAlloc(NULL,dictsize*19/2+0x509000,MEM_COMMIT,PAGE_READWRITE); |
unsigned outlen = lzma_compress(in,out,inlen,work); |
printf("%d -> %d\n",inlen,outlen); |
f = fopen("test.out","wb"); |
fwrite(out,1,outlen,f); |
fclose(f); |
return 0; |
} |
/programs/other/kpack/kerpack_linux/lzma_c/readme.txt |
---|
0,0 → 1,44 |
 ýòîì êàòàëîãå íàõîäèòñÿ óïðîùåííàÿ ïåðåïèñàííàÿ íà C ìíîþ, diamond'îì, âåðñèÿ |
LZMA-óïàêîâùèêà. Îðèãèíàëüíûé LZMA SDK 4.32 ÿâëÿåòñÿ copyright (c) 1999-2005 |
Igor Pavlov, ìîæåò áûòü ïîëó÷åí íà ñòðàíèöå http://www.7-zip.org/sdk.html, |
ñîäåðæèò, â ÷àñòíîñòè, âåðñèè èñõîäíîãî êîäà íà C++,C# è Java äëÿ óïàêîâêè è |
ðàñïàêîâêè, êîä LZMA-ðàñïàêîâêè íà ANSI-C, îïèñàíèå ôîðìàòà 7z. |
Ýòà âåðñèÿ íå ÿâëÿåòñÿ áåçîïàñíîé â ìíîãîïîòî÷íîé ñðåäå, ïîääåðæèâàåò òîëüêî |
bt4 match-finder, íåêîòîðûå ïàðàìåòðû óïàêîâêè çàôèêñèðîâàíû (âïðî÷åì, ýòî ïðè |
íåîáõîäèìîñòè ëåãêî ìîäèôèöèðîâàòü), ïîääåðæèâàåòñÿ òîëüêî ñæàòèå äàííûõ â |
îïåðàòèâíîé ïàìÿòè. (Ýòèõ îãðàíè÷åíèé íåò â îðèãèíàëüíîì LZMA |
SDK.) Ýòà âåðñèÿ íå îáÿçàíà êîìïèëèðîâàòüñÿ ëþáûì êîìïèëÿòîðîì, èáî ÿ èñïîëüçóþ |
òîëüêî VC++, õîòÿ åäèíñòâåííîå èçâåñòíîå ìíå îòêëîíåíèå îò ANSI C ñîñòîèò â |
èñïîëüçîâàíèè VC-ñïåöèôè÷íîé äèðåêòèâû #pragma intrinsic(memcpy), íåîáõîäèìîé, |
÷òîáû memcpy áûëà âñòðîåíà ïðÿìî â êîä - â ðåçóëüòàòå áèáëèîòåêà íå ññûëàåòñÿ |
íè íà îäíó èç ôóíêöèé C run-time library. (Ìíå ýòî íåîáõîäèìî, ïîñêîëüêó |
áèáëèîòåêà èñïîëüçóåòñÿ â àññåìáëåðíîé ïðîãðàììå MtApPack, íå èñïîëüçóþùåé |
RTL è ê òîìó æå ñóùåñòâóþùåé è äëÿ Windows, è äëÿ Kolibri.) |
Ýòà áèáëèîòåêà, êàê è îðèãèíàëüíûé LZMA SDK, ìîæåò áûòü èñïîëüçîâàíà â äðóãèõ |
ïðîãðàììàõ â ñîîòâåòñòâèè ñ îäíîé èç ëèöåíçèé (íà âàø âûáîð) GNU LGPL èëè |
GNU CPL. (Îðèãèíàëüíûé SDK òàêæå äîïóñêàåò èñïîëüçîâàíèå îðèãèíàëüíîé |
áèáëèîòåêè áåç îãðàíè÷åíèé ïðè óñëîâèè èñïîëüçîâàíèÿ îáúåêòíûõ ôàéëîâ áåç |
ìîäèôèêàöèè êîäà, íà äàííóþ âåðñèþ ýòî íå ðàñïðîñòðàíÿåòñÿ.) |
Ýêñïîðòèðóþòñÿ äâå ôóíêöèè: â C++-ñòèëå îáúÿâëåíèå âûãëÿäèò òàê: |
extern "C" __stdcall void lzma_set_dict_size(unsigned logdictsize); |
extern "C" __stdcall unsigned lzma_compress( |
const void* source, |
void* destination, |
unsigned length, |
void* workmem); |
Ïåðåä óïàêîâêîé òðåáóåòñÿ óñòàíîâèòü ðàçìåð ñëîâàðÿ ïåðâîé èç ýòèõ ôóíêöèé, |
ïðèíèìàþùåé ëîãàðèôì ïî îñíîâàíèþ 2 ýòîãî çíà÷åíèÿ |
(ò.å. dictsize == (1<<logdictsize)). Ìàêñèìàëüíûé ðàçìåð áóôåðà ðàâåí 256Mb, |
òàê ÷òî ïàðàìåòð logdictsize íå äîëæåí ïðåâîñõîäèòü 28. Åñëè ðàçìåð áóôåðà |
áîëüøå ðàçìåðà âõîäíûõ äàííûõ, òî ðåçóëüòàò íå çàâèñèò îò ðàçìåðà áóôåðà, |
ò.å. äëÿ äàííûõ ðàçìåðîì 12345 áàéò ðåçóëüòàòû ñæàòèÿ ñ áóôåðîì íà 16384 áàéò è |
íà 1 ìåãàáàéò îäèíàêîâû. |
Óïàêîâêà ïðîèçâîäèòñÿ âûçîâîì âòîðîé èç ýòèõ ôóíêöèé. source - óêàçàòåëü íà |
âõîäíûå äàííûå, destination - óêàçàòåëü íà áóôåð äëÿ óïàêîâàííûõ äàííûõ, |
length - äëèíà âõîäíûõ äàííûõ, workmem - óêàçàòåëü íà âðåìåííóþ ïàìÿòü, |
èñïîëüçóåìóþ óïàêîâùèêîì; äîëæíî áûòü âûäåëåíî íå ìåíåå 0x509000+dictsize*19/2 |
áàéò. Äëÿ óïàêîâàííûõ äàííûõ â õóäøåì ñëó÷àå äîñòàòî÷íî 0x10 + length*9/8 áàéò. |