private static void SwapStates(CPpmd_State *t1, CPpmd_State *t2) { CPpmd_State tmp = *t1; *t1 = *t2; *t2 = tmp; }
private static void RestartModel(CPpmd7 p) { uint i, k, m; //memset(p.FreeList, 0, sizeof(p.FreeList)); for (i = 0; i < p.FreeList.Length; i++) { p.FreeList[i] = default(CPpmd_Void_Ref); } p.Text = p.Base + p.AlignOffset; p.HiUnit = p.Text + p.Size; p.LoUnit = p.UnitsStart = p.HiUnit - p.Size / 8 / UNIT_SIZE * 7 * UNIT_SIZE; p.GlueCount = 0; p.OrderFall = p.MaxOrder; p.RunLength = p.InitRL = -(Int32)((p.MaxOrder < 12) ? p.MaxOrder : 12) - 1; p.PrevSuccess = 0; p.MinContext = p.MaxContext = (CPpmd7_Context *)(p.HiUnit -= UNIT_SIZE); /* AllocContext(p); */ p.MinContext->Suffix = default(CPpmd7_Context_Ref); p.MinContext->NumStats = 256; p.MinContext->SummFreq = 256 + 1; p.FoundState = (CPpmd_State *)p.LoUnit; /* AllocUnits(p, PPMD_NUM_INDEXES - 1); */ p.LoUnit += U2B(256 / 2); p.MinContext->Stats = REF(p, p.FoundState); for (i = 0; i < 256; i++) { CPpmd_State *s = &p.FoundState[i]; s->Symbol = (byte)i; s->Freq = 1; SetSuccessor(s, default(CPpmd_Void_Ref)); } for (i = 0; i < 128; i++) { for (k = 0; k < 8; k++) { ushort *dest = p.BinSumm[i] + k; ushort val = (ushort)(PPMD_BIN_SCALE - kInitBinEsc[k] / (i + 2)); for (m = 0; m < 64; m += 8) { dest[m] = val; } } } for (i = 0; i < 25; i++) { for (k = 0; k < 16; k++) { CPpmd_See *s = &p.See[i][k]; s->Summ = (ushort)((5 * i + 10) << (s->Shift = PPMD_PERIOD_BITS - 4)); s->Count = 4; } } }
public static void Ppmd7_Update1(CPpmd7 p) { CPpmd_State *s = p.FoundState; s->Freq += 4; p.MinContext->SummFreq += 4; if (s[0].Freq > s[-1].Freq) { SwapStates(&s[0], &s[-1]); p.FoundState = --s; if (s->Freq > MAX_FREQ) { Rescale(p); } } NextContext(p); }
private static void UpdateModel(CPpmd7 p) { CPpmd_Void_Ref successor, fSuccessor = SUCCESSOR(p.FoundState); CPpmd7_Context *c; uint s0, ns; if (p.FoundState->Freq < MAX_FREQ / 4 && p.MinContext->Suffix.Value != 0) { c = SUFFIX(p, p.MinContext); if (c->NumStats == 1) { CPpmd_State *s = ONE_STATE(c); if (s->Freq < 32) { s->Freq++; } } else { CPpmd_State *s = STATS(p, c); if (s->Symbol != p.FoundState->Symbol) { do { s++; } while (s->Symbol != p.FoundState->Symbol); if (s[0].Freq >= s[-1].Freq) { SwapStates(&s[0], &s[-1]); s--; } } if (s->Freq < MAX_FREQ - 9) { s->Freq += 2; c->SummFreq += 2; } } } if (p.OrderFall == 0) { p.MinContext = p.MaxContext = CreateSuccessors(p, true); if (p.MinContext == null) { RestartModel(p); return; } SetSuccessor(p.FoundState, REF(p, p.MinContext)); return; } *p.Text++ = p.FoundState->Symbol; successor = REF(p, p.Text); if (p.Text >= p.UnitsStart) { RestartModel(p); return; } if (fSuccessor.Value != 0) { if (fSuccessor.Value <= successor.Value) { CPpmd7_Context *cs = CreateSuccessors(p, false); if (cs == null) { RestartModel(p); return; } fSuccessor = REF(p, cs); } if (--p.OrderFall == 0) { successor = fSuccessor; p.Text -= (p.MaxContext != p.MinContext) ? 1 : 0; } } else { SetSuccessor(p.FoundState, successor); fSuccessor = REF(p, p.MinContext); } s0 = p.MinContext->SummFreq - (ns = p.MinContext->NumStats) - (p.FoundState->Freq - 1u); for (c = p.MaxContext; c != p.MinContext; c = SUFFIX(p, c)) { uint ns1; uint cf, sf; if ((ns1 = c->NumStats) != 1) { if ((ns1 & 1) == 0) { /* Expand for one UNIT */ uint oldNU = ns1 >> 1; uint i = U2I(p, oldNU); if (i != U2I(p, oldNU + 1)) { void *ptr = AllocUnits(p, i + 1); void *oldPtr; if (ptr == null) { RestartModel(p); return; } oldPtr = STATS(p, c); MyMem12Cpy(ptr, oldPtr, oldNU); InsertNode(p, oldPtr, i); c->Stats = STATS_REF(p, ptr); } } c->SummFreq = (ushort)(c->SummFreq + (2 * ns1 < ns ? 1u : 0u) + 2 * ((4 * ns1 <= ns ? 1u : 0u) & (c->SummFreq <= 8 * ns1 ? 1u : 0u))); } else { CPpmd_State *s = (CPpmd_State *)AllocUnits(p, 0); if (s == null) { RestartModel(p); return; } *s = *ONE_STATE(c); c->Stats = REF(p, s); if (s->Freq < MAX_FREQ / 4 - 1) { s->Freq <<= 1; } else { s->Freq = MAX_FREQ - 4; } c->SummFreq = (ushort)(s->Freq + p.InitEsc + (ns > 3 ? 1u : 0u)); } cf = 2 * (uint)p.FoundState->Freq * (c->SummFreq + 6u); sf = (uint)s0 + c->SummFreq; if (cf < 6 * sf) { cf = 1 + (cf > sf ? 1u : 0u) + (cf >= 4 * sf ? 1u : 0u); c->SummFreq += 3; } else { cf = 4 + (cf >= 9 * sf ? 1u : 0u) + (cf >= 12 * sf ? 1u : 0u) + (cf >= 15 * sf ? 1u : 0u); c->SummFreq = (ushort)(c->SummFreq + cf); } { CPpmd_State *s = STATS(p, c) + ns1; SetSuccessor(s, successor); s->Symbol = p.FoundState->Symbol; s->Freq = (byte)cf; c->NumStats = (ushort)(ns1 + 1); } } p.MaxContext = p.MinContext = CTX(p, fSuccessor); }
private static CPpmd7_Context *CreateSuccessors(CPpmd7 p, bool skip) { CPpmd_State upState; CPpmd7_Context *c = p.MinContext; CPpmd_Byte_Ref upBranch = (CPpmd_Byte_Ref)SUCCESSOR(p.FoundState); CPpmd_State *[] ps = new CPpmd_State *[PPMD7_MAX_ORDER]; uint numPs = 0; if (!skip) { ps[numPs++] = p.FoundState; } while (c->Suffix.Value != 0) { CPpmd_Void_Ref successor; CPpmd_State * s; c = SUFFIX(p, c); if (c->NumStats != 1) { for (s = STATS(p, c); s->Symbol != p.FoundState->Symbol; s++) { ; } } else { s = ONE_STATE(c); } successor = SUCCESSOR(s); if (successor != upBranch) { c = CTX(p, successor); if (numPs == 0) { return(c); } break; } ps[numPs++] = s; } upState.Symbol = *(byte *)Ppmd7_GetPtr(p, upBranch); SetSuccessor(&upState, new CPpmd_Byte_Ref(upBranch.Value + 1)); if (c->NumStats == 1) { upState.Freq = ONE_STATE(c)->Freq; } else { uint cf, s0; CPpmd_State *s; for (s = STATS(p, c); s->Symbol != upState.Symbol; s++) { ; } cf = s->Freq - 1u; s0 = (uint)c->SummFreq - (uint)c->NumStats - cf; upState.Freq = (byte)(1 + ((2 * cf <= s0) ? (5 * cf > s0 ? 1u : 0u) : ((2 * cf + 3 * s0 - 1) / (2 * s0)))); } do { /* Create Child */ CPpmd7_Context *c1; /* = AllocContext(p); */ if (p.HiUnit != p.LoUnit) { c1 = (CPpmd7_Context *)(p.HiUnit -= UNIT_SIZE); } else if (p.FreeList[0].Value != 0) { c1 = (CPpmd7_Context *)RemoveNode(p, 0); } else { c1 = (CPpmd7_Context *)AllocUnitsRare(p, 0); if (c1 == null) { return(null); } } c1->NumStats = 1; *ONE_STATE(c1) = upState; c1->Suffix = REF(p, c); SetSuccessor(ps[--numPs], REF(p, c1)); c = c1; }while (numPs != 0); return(c); }
private static void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v) { (p)->SuccessorLow = (ushort)v.Value; (p)->SuccessorHigh = (ushort)(v.Value >> 16); }
private static CPpmd_Void_Ref SUCCESSOR(CPpmd_State *p) => new CPpmd_Void_Ref((uint)p->SuccessorLow | ((uint)p->SuccessorHigh << 16));
private static void Rescale(CPpmd7 p) { uint i, adder, sumFreq, escFreq; CPpmd_State *stats = STATS(p, p.MinContext); CPpmd_State *s = p.FoundState; { CPpmd_State tmp = *s; for (; s != stats; s--) { s[0] = s[-1]; } *s = tmp; } escFreq = (uint)p.MinContext->SummFreq - s->Freq; s->Freq += 4; adder = (p.OrderFall != 0) ? 1u : 0u; s->Freq = (byte)((s->Freq + adder) >> 1); sumFreq = s->Freq; i = (uint)p.MinContext->NumStats - 1; do { escFreq -= (++s)->Freq; s->Freq = (byte)((s->Freq + adder) >> 1); sumFreq += s->Freq; if (s[0].Freq > s[-1].Freq) { CPpmd_State *s1 = s; CPpmd_State tmp = *s1; do { s1[0] = s1[-1]; }while (--s1 != stats && tmp.Freq > s1[-1].Freq); *s1 = tmp; } }while (--i != 0); if (s->Freq == 0) { uint numStats = p.MinContext->NumStats; uint n0, n1; do { i++; } while ((--s)->Freq == 0); escFreq += i; p.MinContext->NumStats = (ushort)(p.MinContext->NumStats - i); if (p.MinContext->NumStats == 1) { CPpmd_State tmp = *stats; do { tmp.Freq = (byte)(tmp.Freq - (tmp.Freq >> 1)); escFreq >>= 1; }while (escFreq > 1); InsertNode(p, stats, U2I(p, ((numStats + 1) >> 1))); *(p.FoundState = ONE_STATE(p.MinContext)) = tmp; return; } n0 = (numStats + 1) >> 1; n1 = ((uint)p.MinContext->NumStats + 1) >> 1; if (n0 != n1) { p.MinContext->Stats = STATS_REF(p, ShrinkUnits(p, stats, n0, n1)); } } p.MinContext->SummFreq = (ushort)(sumFreq + escFreq - (escFreq >> 1)); p.FoundState = STATS(p, p.MinContext); }