void RescalePPMdContext(PPMdContext *self,PPMdCoreModel *model) { PPMdState *states=PPMdContextStates(self,model); int n=self->LastStateIndex+1; // Bump frequency of found state model->FoundState->Freq+=4; // Divide all frequencies and sort list int escfreq=self->SummFreq+4; int adder=(model->OrderFall==0?0:1); self->SummFreq=0; for(int i=0;i<n;i++) { escfreq-=states[i].Freq; states[i].Freq=(states[i].Freq+adder)>>1; self->SummFreq+=states[i].Freq; // Keep states sorted by decreasing frequency if(i>0&&states[i].Freq>states[i-1].Freq) { // If not sorted, move current state upwards until list is sorted PPMdState tmp=states[i]; int j=i-1; while(j>0&&tmp.Freq>states[j-1].Freq) j--; memmove(&states[j+1],&states[j],sizeof(PPMdState)*(i-j)); states[j]=tmp; } } // TODO: add better sorting stage here. // Drop states whose frequency has fallen to 0 if(states[n-1].Freq==0) { int numzeros=1; while(numzeros<n&&states[n-1-numzeros].Freq==0) numzeros++; escfreq+=numzeros; self->LastStateIndex-=numzeros; if(self->LastStateIndex==0) { PPMdState tmp=states[0]; do { tmp.Freq=(tmp.Freq+1)>>1; escfreq>>=1; } while(escfreq>1); FreeUnits(model->alloc,self->States,(n+1)>>1); model->FoundState=PPMdContextOneState(self); *model->FoundState=tmp; return; }
int PPMdDecodeSymbol1(PPMdContext *self,PPMdCoreModel *model,BOOL greaterorequal) { model->scale=self->SummFreq; PPMdState *states=PPMdContextStates(self,model); int firstcount=states[0].Freq; int count=RangeCoderCurrentCount(&model->coder,model->scale); int adder=greaterorequal?1:0; if(count<firstcount) { RemoveRangeCoderSubRange(&model->coder,0,firstcount); if(2*firstcount+adder>model->scale) { model->PrevSuccess=1; model->RunLength++; } else model->PrevSuccess=0; model->FoundState=&states[0]; states[0].Freq=firstcount+4; self->SummFreq+=4; if(firstcount+4>MAX_FREQ) model->RescalePPMdContext(self,model); return -1; } int highcount=firstcount; model->PrevSuccess=0; for(int i=1;i<=self->LastStateIndex;i++) { highcount+=states[i].Freq; if(highcount>count) { RemoveRangeCoderSubRange(&model->coder,highcount-states[i].Freq,highcount); UpdatePPMdContext1(self,model,&states[i]); return -1; } } int lastsym=model->FoundState->Symbol; //if ( Suffix ) PrefetchData(Suffix); RemoveRangeCoderSubRange(&model->coder,highcount,model->scale); model->LastMaskIndex=self->LastStateIndex; model->FoundState=NULL; for(int i=0;i<=self->LastStateIndex;i++) model->CharMask[states[i].Symbol]=model->EscCount; return lastsym; }
static void RestartModel(PPMdModelVariantI *self) { InitSubAllocator(self->core.alloc); memset(self->core.CharMask,0,sizeof(self->core.CharMask)); self->core.PrevSuccess=0; self->core.OrderFall=self->MaxOrder; self->core.RunLength=self->core.InitRL=-((self->MaxOrder<12)?self->MaxOrder:12)-1; self->MaxContext=NewPPMdContext(&self->core); self->MaxContext->LastStateIndex=255; self->MaxContext->SummFreq=257; self->MaxContext->States=AllocUnits(self->core.alloc,256/2); PPMdState *maxstates=PPMdContextStates(self->MaxContext,&self->core); for(int i=0;i<256;i++) { maxstates[i].Symbol=i; maxstates[i].Freq=1; maxstates[i].Successor=0; } static const uint16_t InitBinEsc[8]={0x3cdd,0x1f3f,0x59bf,0x48f3,0x64a1,0x5abc,0x6632,0x6051}; int i=0; for(int m=0;m<25;m++) { while(self->QTable[i]==m) i++; for(int k=0;k<8;k++) self->BinSumm[m][k]=BIN_SCALE-InitBinEsc[k]/(i+1); for(int k=8;k<64;k+=8) memcpy(&self->BinSumm[m][k],&self->BinSumm[m][0],8*sizeof(uint16_t)); } i=0; for(int m=0;m<24;m++) { while(self->QTable[i+3]==m+3) i++; for(int k=0;k<32;k++) self->SEE2Cont[m][k]=MakeSEE2(2*i+5,7); } }
void PPMdDecodeSymbol2(PPMdContext *self,PPMdCoreModel *model,SEE2Context *see) { int n=self->LastStateIndex-model->LastMaskIndex; PPMdState *ps[256]; int total=0; PPMdState *state=PPMdContextStates(self,model); for(int i=0;i<n;i++) { while(model->CharMask[state->Symbol]==model->EscCount) state++; total+=state->Freq; ps[i]=state++; } model->scale+=total; int count=RangeCoderCurrentCount(&model->coder,model->scale); if(count<total) { int i=0,highcount=ps[0]->Freq; while(highcount<=count) highcount+=ps[++i]->Freq; RemoveRangeCoderSubRange(&model->coder,highcount-ps[i]->Freq,highcount); UpdateSEE2(see); UpdatePPMdContext2(self,model,ps[i]); } else { RemoveRangeCoderSubRange(&model->coder,total,model->scale); model->LastMaskIndex=self->LastStateIndex; see->Summ+=model->scale; for(int i=0;i<n;i++) model->CharMask[ps[i]->Symbol]=model->EscCount; } }
static void UpdateModel(PPMdModelVariantI *self,PPMdContext *mincontext) { PPMdState fs=*self->core.FoundState; PPMdState *state=NULL; PPMdContext *currcontext=self->MaxContext; if(fs.Freq<MAX_FREQ/4&&mincontext->Suffix) { PPMdContext *context=PPMdContextSuffix(mincontext,&self->core); if(context->LastStateIndex!=0) { state=PPMdContextStates(context,&self->core); if(state->Symbol!=fs.Symbol) { do state++; while(state->Symbol!=fs.Symbol); if(state[0].Freq>=state[-1].Freq) { SWAP(state[0],state[-1]); state--; } } if(state->Freq<MAX_FREQ-9) { state->Freq+=2; context->SummFreq+=2; } } else { state=PPMdContextOneState(context); if(state->Freq<32) state->Freq++; } } if(self->core.OrderFall==0&&fs.Successor) { PPMdContext *newsuccessor=CreateSuccessors(self,true,state,mincontext); SetPPMdStateSuccessorPointer(self->core.FoundState,newsuccessor,&self->core); if(!newsuccessor) goto RESTART_MODEL; self->MaxContext=newsuccessor; return; } *self->alloc->pText++=fs.Symbol; PPMdContext *Successor=(PPMdContext *)self->alloc->pText; if(self->alloc->pText>=self->alloc->UnitsStart) goto RESTART_MODEL; if(fs.Successor) { if((uint8_t *)PPMdStateSuccessor(&fs,&self->core)<self->alloc->UnitsStart) { SetPPMdStateSuccessorPointer(&fs,CreateSuccessors(self,false,state,mincontext),&self->core); } } else { SetPPMdStateSuccessorPointer(&fs,ReduceOrder(self,state,mincontext),&self->core); } if(!fs.Successor) goto RESTART_MODEL; if(--self->core.OrderFall==0) { Successor=PPMdStateSuccessor(&fs,&self->core); if(self->MaxContext!=mincontext) self->alloc->pText--; } else if(self->MRMethod>MRM_FREEZE) { Successor=PPMdStateSuccessor(&fs,&self->core); self->alloc->pText=self->alloc->HeapStart; self->core.OrderFall=0; } int minnum=mincontext->LastStateIndex+1; int s0=mincontext->SummFreq-minnum-(fs.Freq-1); uint8_t flag=fs.Symbol>=0x40?8:0; for(;currcontext!=mincontext;currcontext=PPMdContextSuffix(currcontext,&self->core)) { int currnum=currcontext->LastStateIndex+1; if(currnum!=1) { if((currnum&1)==0) { uint32_t states=ExpandUnits(self->core.alloc,currcontext->States,currnum>>1); if(!states) goto RESTART_MODEL; currcontext->States=states; } if(3*currnum-1<minnum) currcontext->SummFreq++; } else {