Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '7zip/Compress/PPMD/PPMDContext.h')
-rwxr-xr-x7zip/Compress/PPMD/PPMDContext.h153
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();