void PPMdDecodeBinSymbol(PPMdContext *self,PPMdCoreModel *model,uint16_t *bs,int freqlimit,BOOL altnextbit) { PPMdState *rs=PPMdContextOneState(self); int bit; if(altnextbit) bit=NextWeightedBitFromRangeCoder2(&model->coder,*bs,TOT_BITS); else bit=NextWeightedBitFromRangeCoder(&model->coder,*bs,1<<TOT_BITS); if(bit==0) { model->PrevSuccess=1; model->RunLength++; model->FoundState=rs; if(rs->Freq<freqlimit) rs->Freq++; *bs+=INTERVAL-GET_MEAN(*bs,PERIOD_BITS,2); } else { model->PrevSuccess=0; model->FoundState=NULL; model->LastMaskIndex=0; model->CharMask[rs->Symbol]=model->EscCount; *bs-=GET_MEAN(*bs,PERIOD_BITS,2); model->InitEsc=ExpEscape[*bs>>10]; } }
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; }
PPMdContext *NewPPMdContextAsChildOf(PPMdCoreModel *model,PPMdContext *suffixcontext,PPMdState *suffixstate,PPMdState *firststate) { PPMdContext *context=OffsetToPointer(model->alloc,AllocContext(model->alloc)); if(context) { context->LastStateIndex=0; context->Flags=0; SetPPMdContextSuffixPointer(context,suffixcontext,model); SetPPMdStateSuccessorPointer(suffixstate,context,model); if(firststate) *(PPMdContextOneState(context))=*firststate; } return context; }
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 {