📄 model.hpp
字号:
if (--OrderFall == 0)
{
Successor=fs.Successor; SkipCount=1;
}
else
{
// if ((Successor = new PPM_CONTEXT()) == NULL)
if ((Successor = (PPM_CONTEXT *)AllocContext()) == NULL)
{
Successor->NumStats = 0;
goto RESTART_MODEL;
}
else
Successor->NumStats = 0;
}
if ( !MaxContext->NumStats ) {
MaxContext->oneState().Symbol = fs.Symbol;
MaxContext->oneState().Successor = Successor;
}
s0=MinContext->SummFreq-(ns=MinContext->NumStats)-(fs.Freq-1);
for (pc=MedContext;pc != MinContext;pc=pc->Suffix) {
if ((ns1=pc->NumStats) != 1) {
if ((ns1 & 1) == 0) {
pc->Stats=(PPM_CONTEXT::STATE*) ExpandUnits(pc->Stats,ns1 >> 1);
if ( !pc->Stats ) goto RESTART_MODEL;
}
pc->SummFreq += (2*ns1 < ns)+2*((4*ns1 <= ns) &
(pc->SummFreq <= 8*ns1));
} else {
p=(PPM_CONTEXT::STATE*) AllocUnitsRare(1);
if ( !p ) goto RESTART_MODEL;
*p=pc->oneState(); pc->Stats=p;
if (p->Freq < MAX_FREQ/4-1) p->Freq += p->Freq;
else p->Freq = MAX_FREQ-4;
pc->SummFreq=p->Freq+InitEsc+(ns > 3);
}
cf=2*fs.Freq*(pc->SummFreq+6); sf=s0+pc->SummFreq;
if (cf < 6*sf) {
cf=1+(cf > sf)+(cf >= 4*sf);
pc->SummFreq += 3;
} else {
cf=4+(cf >= 9*sf)+(cf >= 12*sf)+(cf >= 15*sf);
pc->SummFreq += cf;
}
p=pc->Stats+ns1; p->Successor=Successor;
p->Symbol = fs.Symbol; p->Freq = cf;
pc->NumStats=++ns1;
}
if ( fs.Successor ) {
if (!fs.Successor->NumStats && !MakeRoot(SkipCount,p1))
goto RESTART_MODEL;
MinContext=FoundState->Successor;
} else {
FoundState->Successor=Successor; OrderFall++;
}
MedContext=MinContext; MaxContext=Successor;
return;
RESTART_MODEL:
StartModel();
EscCount=0; PrintCount=0xFF;
}
// Tabulated escapes for exponential symbol distribution
static const BYTE ExpEscape[16]={ 25,14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
#define GET_MEAN(SUMM,SHIFT,ROUND) ((SUMM+(1 << (SHIFT-ROUND))) >> (SHIFT))
inline void PPM_CONTEXT::encodeBinSymbol(int symbol)
{
STATE& rs=oneState();
WORD& bs=BinSumm[rs.Freq-1][PrevSuccess+NS2BSIndx[Suffix->NumStats-1]];
if (rs.Symbol == symbol) {
FoundState=&rs; rs.Freq += (rs.Freq < 128);
SubRange.LowCount=0; SubRange.HighCount=bs;
bs += INTERVAL-GET_MEAN(bs,PERIOD_BITS,2);
PrevSuccess=1;
} else {
SubRange.LowCount=bs; bs -= GET_MEAN(bs,PERIOD_BITS,2);
SubRange.HighCount=BIN_SCALE; InitEsc=ExpEscape[bs >> 10];
NumMasked=1; CharMask[rs.Symbol]=EscCount;
PrevSuccess=0; FoundState=NULL;
}
}
inline void PPM_CONTEXT::decodeBinSymbol()
{
STATE& rs=oneState();
WORD& bs=BinSumm[rs.Freq-1][PrevSuccess+NS2BSIndx[Suffix->NumStats-1]];
if (ariGetCurrentShiftCount(INT_BITS+PERIOD_BITS) < bs) {
FoundState=&rs; rs.Freq += (rs.Freq < 128);
SubRange.LowCount=0; SubRange.HighCount=bs;
bs += INTERVAL-GET_MEAN(bs,PERIOD_BITS,2);
PrevSuccess=1;
} else {
SubRange.LowCount=bs; bs -= GET_MEAN(bs,PERIOD_BITS,2);
SubRange.HighCount=BIN_SCALE; InitEsc=ExpEscape[bs >> 10];
NumMasked=1; CharMask[rs.Symbol]=EscCount;
PrevSuccess=0; FoundState=NULL;
}
}
inline void PPM_CONTEXT::update1(STATE* p)
{
(FoundState=p)->Freq += 4; SummFreq += 4;
if (p[0].Freq > p[-1].Freq) {
SWAP(p[0],p[-1]); FoundState=--p;
if (p->Freq > MAX_FREQ) rescale();
}
}
inline void PPM_CONTEXT::encodeSymbol1(int symbol)
{
SubRange.scale=SummFreq;
STATE* p=Stats;
if (p->Symbol == symbol) {
PrevSuccess=(2*(SubRange.HighCount=p->Freq) > SubRange.scale);
(FoundState=p)->Freq += 4; SummFreq += 4;
if (p->Freq > MAX_FREQ) rescale();
SubRange.LowCount=0; return;
}
PrevSuccess=0;
int LoCnt=p->Freq, i=NumStats-1;
while ((++p)->Symbol != symbol) {
LoCnt += p->Freq;
if (--i == 0) {
SubRange.LowCount=LoCnt; CharMask[p->Symbol]=EscCount;
i=(NumMasked=NumStats)-1; FoundState=NULL;
do { CharMask[(--p)->Symbol]=EscCount; } while ( --i );
SubRange.HighCount=SubRange.scale;
return;
}
}
SubRange.HighCount=(SubRange.LowCount=LoCnt)+p->Freq;
update1(p);
}
inline void PPM_CONTEXT::decodeSymbol1()
{
SubRange.scale=SummFreq;
STATE* p=Stats;
int i, count, HiCnt;
if ((count=ariGetCurrentCount()) < (HiCnt=p->Freq)) {
PrevSuccess=(2*(SubRange.HighCount=HiCnt) > SubRange.scale);
(FoundState=p)->Freq=(HiCnt += 4); SummFreq += 4;
if (HiCnt > MAX_FREQ) rescale();
SubRange.LowCount=0; return;
}
PrevSuccess=0; i=NumStats-1;
while ((HiCnt += (++p)->Freq) <= count)
if (--i == 0) {
SubRange.LowCount=HiCnt; CharMask[p->Symbol]=EscCount;
i=(NumMasked=NumStats)-1; FoundState=NULL;
do { CharMask[(--p)->Symbol]=EscCount; } while ( --i );
SubRange.HighCount=SubRange.scale;
return;
}
SubRange.LowCount=(SubRange.HighCount=HiCnt)-p->Freq;
update1(p);
}
inline void PPM_CONTEXT::update2(STATE* p)
{
(FoundState=p)->Freq += 4; SummFreq += 4;
if (p->Freq > MAX_FREQ) rescale();
EscCount++;
}
inline SEE2_CONTEXT* PPM_CONTEXT::makeEscFreq2(int Diff)
{
SEE2_CONTEXT* psee2c;
if (NumStats != 256) {
psee2c=SEE2Cont[NS2Indx[Diff-1]]+(Diff < Suffix->NumStats-NumStats)+
2*(SummFreq < 11*NumStats)+4*(NumMasked > Diff);
SubRange.scale=psee2c->getMean();
} else {
psee2c=SEE2Cont[43];
SubRange.scale=1;
}
return psee2c;
}
inline void PPM_CONTEXT::encodeSymbol2(int symbol)
{
int HiCnt, i=NumStats-NumMasked;
SEE2_CONTEXT* psee2c=makeEscFreq2(i);
STATE* p=Stats-1; HiCnt=0;
do {
do { p++; } while (CharMask[p->Symbol] == EscCount);
HiCnt += p->Freq;
if (p->Symbol == symbol) goto SYMBOL_FOUND;
CharMask[p->Symbol]=EscCount;
} while ( --i );
SubRange.HighCount=(SubRange.scale += (SubRange.LowCount=HiCnt));
psee2c->Summ += SubRange.scale; NumMasked = NumStats;
return;
SYMBOL_FOUND:
SubRange.LowCount = (SubRange.HighCount=HiCnt)-p->Freq;
if ( --i ) {
STATE* p1=p;
do {
do { p1++; } while (CharMask[p1->Symbol] == EscCount);
HiCnt += p1->Freq;
} while ( --i );
}
SubRange.scale += HiCnt;
psee2c->update(); update2(p);
}
inline void PPM_CONTEXT::decodeSymbol2()
{
int count, HiCnt, i=NumStats-NumMasked;
SEE2_CONTEXT* psee2c=makeEscFreq2(i);
STATE* ps[256], ** pps=ps, * p=Stats-1;
HiCnt=0;
do {
do { p++; } while (CharMask[p->Symbol] == EscCount);
HiCnt += p->Freq; *pps++ = p;
} while ( --i );
SubRange.scale += HiCnt; count=ariGetCurrentCount();
p=*(pps=ps);
if (count < HiCnt) {
HiCnt=0;
while ((HiCnt += p->Freq) <= count) p=*++pps;
SubRange.LowCount = (SubRange.HighCount=HiCnt)-p->Freq;
psee2c->update(); update2(p);
} else {
SubRange.LowCount=HiCnt; SubRange.HighCount=SubRange.scale;
i=NumStats-NumMasked; pps--;
do { CharMask[(*++pps)->Symbol]=EscCount; } while ( --i );
psee2c->Summ += SubRange.scale; NumMasked = NumStats;
}
}
inline void ClearMask()
{
EscCount=1;
memset(CharMask,0,sizeof(CharMask));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -