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 void SetSuccessor(CPpmd_State *p, CPpmd_Void_Ref v) { (p)->SuccessorLow = (ushort)v.Value; (p)->SuccessorHigh = (ushort)(v.Value >> 16); }