diff options
Diffstat (limited to '7zip/Compress/PPMD/PPMDContext.h')
-rwxr-xr-x | 7zip/Compress/PPMD/PPMDContext.h | 153 |
1 files changed, 96 insertions, 57 deletions
diff --git a/7zip/Compress/PPMD/PPMDContext.h b/7zip/Compress/PPMD/PPMDContext.h index 1b926585..6f154fc4 100755 --- a/7zip/Compress/PPMD/PPMDContext.h +++ b/7zip/Compress/PPMD/PPMDContext.h @@ -15,9 +15,9 @@ namespace NPPMD { const int INT_BITS=7, PERIOD_BITS=7, TOT_BITS=INT_BITS+PERIOD_BITS, INTERVAL=1 << INT_BITS, BIN_SCALE=1 << TOT_BITS, MAX_FREQ=124; -#pragma pack(1) struct SEE2_CONTEXT -{ // SEE-contexts for PPM-contexts with masked symbols +{ + // SEE-contexts for PPM-contexts with masked symbols UInt16 Summ; Byte Shift, Count; void init(int InitVal) { Summ=InitVal << (Shift=PERIOD_BITS-4); Count=4; } @@ -39,9 +39,25 @@ struct SEE2_CONTEXT struct PPM_CONTEXT { - UInt16 NumStats,SummFreq; // sizeof(UInt16) > sizeof(Byte) - struct STATE { Byte Symbol, Freq; PPM_CONTEXT* Successor; } _PACK_ATTR * Stats; - PPM_CONTEXT* Suffix; + UInt16 NumStats; // sizeof(UInt16) > sizeof(Byte) + UInt16 SummFreq; + + struct STATE + { + Byte Symbol, Freq; + UInt16 SuccessorLow; + UInt16 SuccessorHigh; + + UInt32 GetSuccessor() const { return SuccessorLow | ((UInt32)SuccessorHigh << 16); } + void SetSuccessor(UInt32 v) + { + SuccessorLow = (UInt16)(v & 0xFFFF); + SuccessorHigh = (UInt16)((v >> 16) & 0xFFFF); + } + }; + + UInt32 Stats; + UInt32 Suffix; PPM_CONTEXT* createChild(CSubAllocator &subAllocator, STATE* pStats, STATE& FirstState) { @@ -50,15 +66,14 @@ struct PPM_CONTEXT { pc->NumStats = 1; pc->oneState() = FirstState; - pc->Suffix = this; - pStats->Successor = pc; + pc->Suffix = subAllocator.GetOffset(this); + pStats->SetSuccessor(subAllocator.GetOffsetNoCheck(pc)); } return pc; } STATE& oneState() const { return (STATE&) SummFreq; } }; -#pragma pack() ///////////////////////////////// @@ -68,8 +83,8 @@ const UInt16 InitBinEsc[] = struct CInfo { CSubAllocator SubAllocator; - SEE2_CONTEXT _PACK_ATTR SEE2Cont[25][16], DummySEE2Cont; - PPM_CONTEXT _PACK_ATTR * MinContext, * MaxContext; + SEE2_CONTEXT SEE2Cont[25][16], DummySEE2Cont; + PPM_CONTEXT * MinContext, * MaxContext; PPM_CONTEXT::STATE* FoundState; // found next state transition int NumMasked, InitEsc, OrderFall, RunLength, InitRL, MaxOrder; @@ -86,6 +101,11 @@ struct CInfo ((RunLength >> 26) & 0x20)]; } + PPM_CONTEXT *GetContext(UInt32 offset) const { return (PPM_CONTEXT *)SubAllocator.GetPtr(offset); } + PPM_CONTEXT *GetContextNoCheck(UInt32 offset) const { return (PPM_CONTEXT *)SubAllocator.GetPtrNoCheck(offset); } + PPM_CONTEXT::STATE *GetState(UInt32 offset) const { return (PPM_CONTEXT::STATE *)SubAllocator.GetPtr(offset); } + PPM_CONTEXT::STATE *GetStateNoCheck(UInt32 offset) const { return (PPM_CONTEXT::STATE *)SubAllocator.GetPtr(offset); } + void RestartModelRare() { int i, k, m; @@ -93,15 +113,17 @@ struct CInfo SubAllocator.InitSubAllocator(); InitRL = -((MaxOrder < 12) ? MaxOrder : 12) - 1; MinContext = MaxContext = (PPM_CONTEXT*) SubAllocator.AllocContext(); - MinContext->Suffix = NULL; + MinContext->Suffix = 0; OrderFall = MaxOrder; MinContext->SummFreq = (MinContext->NumStats = 256) + 1; - FoundState = MinContext->Stats = (PPM_CONTEXT::STATE*) SubAllocator.AllocUnits(256 / 2); + FoundState = (PPM_CONTEXT::STATE*)SubAllocator.AllocUnits(256 / 2); + MinContext->Stats = SubAllocator.GetOffsetNoCheck(FoundState); for (RunLength = InitRL, PrevSuccess = i = 0; i < 256; i++) { - MinContext->Stats[i].Symbol = i; - MinContext->Stats[i].Freq = 1; - MinContext->Stats[i].Successor = NULL; + PPM_CONTEXT::STATE &state = FoundState[i]; + state.Symbol = i; + state.Freq = 1; + state.SetSuccessor(0); } for (i = 0; i < 128; i++) for (k = 0; k < 8; k++) @@ -121,12 +143,12 @@ struct CInfo memset(CharMask,0,sizeof(CharMask)); OrderFall = this->MaxOrder; MinContext = MaxContext; - while (MinContext->Suffix != NULL) + while (MinContext->Suffix != 0) { - MinContext = MinContext->Suffix; - OrderFall--; + MinContext = GetContextNoCheck(MinContext->Suffix); + OrderFall--; } - FoundState = MinContext->Stats; + FoundState = GetState(MinContext->Stats); MinContext = MaxContext; } else @@ -160,7 +182,8 @@ struct CInfo // static PPM_CONTEXT::STATE UpState; PPM_CONTEXT::STATE UpState; - PPM_CONTEXT* pc = MinContext, * UpBranch = FoundState->Successor; + PPM_CONTEXT *pc = MinContext; + PPM_CONTEXT *UpBranch = GetContext(FoundState->GetSuccessor()); PPM_CONTEXT::STATE * p, * ps[MAX_O], ** pps = ps; if ( !skip ) { @@ -171,23 +194,23 @@ struct CInfo if ( p1 ) { p = p1; - pc = pc->Suffix; + pc = GetContext(pc->Suffix); goto LOOP_ENTRY; } do { - pc = pc->Suffix; + pc = GetContext(pc->Suffix); if (pc->NumStats != 1) { - if ((p = pc->Stats)->Symbol != FoundState->Symbol) + if ((p = GetStateNoCheck(pc->Stats))->Symbol != FoundState->Symbol) do { p++; } while (p->Symbol != FoundState->Symbol); } else p = &(pc->oneState()); LOOP_ENTRY: - if (p->Successor != UpBranch) + if (GetContext(p->GetSuccessor()) != UpBranch) { - pc = p->Successor; + pc = GetContext(p->GetSuccessor()); break; } *pps++ = p; @@ -197,10 +220,10 @@ NO_LOOP: if (pps == ps) return pc; UpState.Symbol = *(Byte*) UpBranch; - UpState.Successor = (PPM_CONTEXT*) (((Byte*) UpBranch)+1); + UpState.SetSuccessor(SubAllocator.GetOffset(UpBranch) + 1); if (pc->NumStats != 1) { - if ((p = pc->Stats)->Symbol != UpState.Symbol) + if ((p = GetStateNoCheck(pc->Stats))->Symbol != UpState.Symbol) do { p++; } while (p->Symbol != UpState.Symbol); unsigned int cf = p->Freq-1; unsigned int s0 = pc->SummFreq - pc->NumStats - cf; @@ -224,11 +247,13 @@ NO_LOOP: PPM_CONTEXT::STATE fs = *FoundState, * p = NULL; PPM_CONTEXT* pc, * Successor; unsigned int ns1, ns, cf, sf, s0; - if (fs.Freq < MAX_FREQ/4 && (pc=MinContext->Suffix) != NULL) + if (fs.Freq < MAX_FREQ / 4 && MinContext->Suffix != 0) { + pc = GetContextNoCheck(MinContext->Suffix); + if (pc->NumStats != 1) { - if ((p = pc->Stats)->Symbol != fs.Symbol) + if ((p = GetStateNoCheck(pc->Stats))->Symbol != fs.Symbol) { do { p++; } while (p->Symbol != fs.Symbol); if (p[0].Freq >= p[-1].Freq) @@ -251,8 +276,9 @@ NO_LOOP: } if ( !OrderFall ) { - MinContext = MaxContext = FoundState->Successor = CreateSuccessors(true, p); - if ( !MinContext ) + MinContext = MaxContext = CreateSuccessors(true, p); + FoundState->SetSuccessor(SubAllocator.GetOffset(MinContext)); + if (MinContext == 0) goto RESTART_MODEL; return; } @@ -260,31 +286,36 @@ NO_LOOP: Successor = (PPM_CONTEXT*) SubAllocator.pText; if (SubAllocator.pText >= SubAllocator.UnitsStart) goto RESTART_MODEL; - if ( fs.Successor ) + if (fs.GetSuccessor() != 0) { - if ((Byte*) fs.Successor <= SubAllocator.pText && - (fs.Successor=CreateSuccessors(false, p)) == NULL) - goto RESTART_MODEL; + if ((Byte *)GetContext(fs.GetSuccessor()) <= SubAllocator.pText) + { + PPM_CONTEXT* cs = CreateSuccessors(false, p); + fs.SetSuccessor(SubAllocator.GetOffset(cs)); + if (cs == NULL) + goto RESTART_MODEL; + } if ( !--OrderFall ) { - Successor = fs.Successor; + Successor = GetContext(fs.GetSuccessor()); SubAllocator.pText -= (MaxContext != MinContext); } } else { - FoundState->Successor = Successor; - fs.Successor = MinContext; + FoundState->SetSuccessor(SubAllocator.GetOffsetNoCheck(Successor)); + fs.SetSuccessor(SubAllocator.GetOffsetNoCheck(MinContext)); } s0 = MinContext->SummFreq - (ns = MinContext->NumStats) - (fs.Freq - 1); - for (pc = MaxContext; pc != MinContext; pc = pc->Suffix) + for (pc = MaxContext; pc != MinContext; pc = GetContext(pc->Suffix)) { if ((ns1 = pc->NumStats) != 1) { if ((ns1 & 1) == 0) { - pc->Stats = (PPM_CONTEXT::STATE*) SubAllocator.ExpandUnits(pc->Stats, ns1 >> 1); - if ( !pc->Stats ) + void *ppp = SubAllocator.ExpandUnits(GetState(pc->Stats), ns1 >> 1); + pc->Stats = SubAllocator.GetOffset(ppp); + if (!ppp) goto RESTART_MODEL; } pc->SummFreq += (2 * ns1 < ns) + 2 * ((4 * ns1 <= ns) & @@ -296,7 +327,7 @@ NO_LOOP: if ( !p ) goto RESTART_MODEL; *p = pc->oneState(); - pc->Stats = p; + pc->Stats = SubAllocator.GetOffsetNoCheck(p); if (p->Freq < MAX_FREQ / 4 - 1) p->Freq += p->Freq; else @@ -315,13 +346,13 @@ NO_LOOP: cf = 4 + (cf >= 9 * sf) + (cf >= 12 * sf) + (cf >= 15 * sf); pc->SummFreq += cf; } - p = pc->Stats + ns1; - p->Successor = Successor; + p = GetState(pc->Stats) + ns1; + p->SetSuccessor(SubAllocator.GetOffset(Successor)); p->Symbol = fs.Symbol; p->Freq = cf; pc->NumStats = ++ns1; } - MaxContext = MinContext = fs.Successor; + MaxContext = MinContext = GetContext(fs.GetSuccessor()); return; RESTART_MODEL: RestartModelRare(); @@ -366,8 +397,11 @@ RESTART_MODEL: SEE2_CONTEXT* psee2c; if (MinContext->NumStats != 256) { - psee2c = SEE2Cont[NS2Indx[Diff-1]] + (Diff < MinContext->Suffix->NumStats - MinContext->NumStats)+ - 2 * (MinContext->SummFreq < 11 * MinContext->NumStats) + 4 * (NumMasked > Diff) + HiBitsFlag; + psee2c = SEE2Cont[NS2Indx[Diff-1]] + + (Diff < (GetContext(MinContext->Suffix))->NumStats - MinContext->NumStats) + + 2 * (MinContext->SummFreq < 11 * MinContext->NumStats) + + 4 * (NumMasked > Diff) + + HiBitsFlag; scale = psee2c->getMean(); } else @@ -384,9 +418,10 @@ RESTART_MODEL: { int OldNS = MinContext->NumStats, i = MinContext->NumStats - 1, Adder, EscFreq; PPM_CONTEXT::STATE* p1, * p; - for (p = FoundState; p != MinContext->Stats; p--) + PPM_CONTEXT::STATE *stats = GetStateNoCheck(MinContext->Stats); + for (p = FoundState; p != stats; p--) _PPMD_SWAP(p[0], p[-1]); - MinContext->Stats->Freq += 4; + stats->Freq += 4; MinContext->SummFreq += 4; EscFreq = MinContext->SummFreq - p->Freq; Adder = (OrderFall != 0); @@ -398,7 +433,11 @@ RESTART_MODEL: if (p[0].Freq > p[-1].Freq) { PPM_CONTEXT::STATE tmp = *(p1 = p); - do { p1[0] = p1[-1]; } while (--p1 != MinContext->Stats && tmp.Freq > p1[-1].Freq); + do + { + p1[0] = p1[-1]; + } + while (--p1 != stats && tmp.Freq > p1[-1].Freq); *p1 = tmp; } } @@ -409,24 +448,24 @@ RESTART_MODEL: EscFreq += i; if ((MinContext->NumStats -= i) == 1) { - PPM_CONTEXT::STATE tmp = *MinContext->Stats; + PPM_CONTEXT::STATE tmp = *stats; do { tmp.Freq -= (tmp.Freq >> 1); EscFreq >>= 1; } while (EscFreq > 1); - SubAllocator.FreeUnits(MinContext->Stats, (OldNS+1) >> 1); + SubAllocator.FreeUnits(stats, (OldNS+1) >> 1); *(FoundState = &MinContext->oneState()) = tmp; return; } } MinContext->SummFreq += (EscFreq -= (EscFreq >> 1)); int n0 = (OldNS+1) >> 1, n1 = (MinContext->NumStats + 1) >> 1; if (n0 != n1) - MinContext->Stats = - (PPM_CONTEXT::STATE*) SubAllocator.ShrinkUnits(MinContext->Stats, n0, n1); - FoundState = MinContext->Stats; + MinContext->Stats = SubAllocator.GetOffset(SubAllocator.ShrinkUnits(stats, n0, n1)); + FoundState = GetState(MinContext->Stats); } void NextContext() { - if (!OrderFall && (Byte*) FoundState->Successor > SubAllocator.pText) - MinContext = MaxContext = FoundState->Successor; + PPM_CONTEXT *c = GetContext(FoundState->GetSuccessor()); + if (!OrderFall && (Byte *)c > SubAllocator.pText) + MinContext = MaxContext = c; else { UpdateModel(); |