private void UpdateModel(PpmContext minimumContext) { PpmState state = PpmState.Zero; PpmContext Successor; PpmContext currentContext = maximumContext; uint numberStatistics; uint ns1; uint cf; uint sf; uint s0; uint foundStateFrequency = foundState.Frequency; byte foundStateSymbol = foundState.Symbol; byte symbol; byte flag; PpmContext foundStateSuccessor = foundState.Successor; PpmContext context = minimumContext.Suffix; if ((foundStateFrequency < MaximumFrequency / 4) && (context != PpmContext.Zero)) { if (context.NumberStatistics != 0) { state = context.Statistics; if (state.Symbol != foundStateSymbol) { do { symbol = state[1].Symbol; state++; } while (symbol != foundStateSymbol); if (state[0].Frequency >= state[-1].Frequency) { Swap(state[0], state[-1]); state--; } } cf = (uint)((state.Frequency < MaximumFrequency - 9) ? 2 : 0); state.Frequency += (byte)cf; context.SummaryFrequency += (byte)cf; } else { state = context.FirstState; state.Frequency += (byte)((state.Frequency < 32) ? 1 : 0); } } if (orderFall == 0 && foundStateSuccessor != PpmContext.Zero) { foundState.Successor = CreateSuccessors(true, state, minimumContext); if (foundState.Successor == PpmContext.Zero) { goto RestartModel; } maximumContext = foundState.Successor; return; } Allocator.Text[0] = foundStateSymbol; Allocator.Text++; Successor = Allocator.Text; if (Allocator.Text >= Allocator.BaseUnit) { goto RestartModel; } if (foundStateSuccessor != PpmContext.Zero) { if (foundStateSuccessor < Allocator.BaseUnit) { foundStateSuccessor = CreateSuccessors(false, state, minimumContext); } } else { foundStateSuccessor = ReduceOrder(state, minimumContext); } if (foundStateSuccessor == PpmContext.Zero) { goto RestartModel; } if (--orderFall == 0) { Successor = foundStateSuccessor; Allocator.Text -= (maximumContext != minimumContext) ? 1 : 0; } else if (method > ModelRestorationMethod.Freeze) { Successor = foundStateSuccessor; Allocator.Text = Allocator.Heap; orderFall = 0; } numberStatistics = minimumContext.NumberStatistics; s0 = minimumContext.SummaryFrequency - numberStatistics - foundStateFrequency; flag = (byte)((foundStateSymbol >= 0x40) ? 0x08 : 0x00); for (; currentContext != minimumContext; currentContext = currentContext.Suffix) { ns1 = currentContext.NumberStatistics; if (ns1 != 0) { if ((ns1 & 1) != 0) { state = Allocator.ExpandUnits(currentContext.Statistics, (ns1 + 1) >> 1); if (state == PpmState.Zero) { goto RestartModel; } currentContext.Statistics = state; } currentContext.SummaryFrequency += (ushort)((3 * ns1 + 1 < numberStatistics) ? 1 : 0); } else { state = Allocator.AllocateUnits(1); if (state == PpmState.Zero) { goto RestartModel; } Copy(state, currentContext.FirstState); currentContext.Statistics = state; if (state.Frequency < MaximumFrequency / 4 - 1) { state.Frequency += state.Frequency; } else { state.Frequency = (byte)(MaximumFrequency - 4); } currentContext.SummaryFrequency = (ushort)(state.Frequency + initialEscape + ((numberStatistics > 2) ? 1 : 0)); } cf = (uint)(2 * foundStateFrequency * (currentContext.SummaryFrequency + 6)); sf = s0 + currentContext.SummaryFrequency; if (cf < 6 * sf) { cf = (uint)(1 + ((cf > sf) ? 1 : 0) + ((cf >= 4 * sf) ? 1 : 0)); currentContext.SummaryFrequency += 4; } else { cf = (uint)(4 + ((cf > 9 * sf) ? 1 : 0) + ((cf > 12 * sf) ? 1 : 0) + ((cf > 15 * sf) ? 1 : 0)); currentContext.SummaryFrequency += (ushort)cf; } state = currentContext.Statistics + (++currentContext.NumberStatistics); state.Successor = Successor; state.Symbol = foundStateSymbol; state.Frequency = (byte)cf; currentContext.Flags |= flag; } maximumContext = foundStateSuccessor; return; RestartModel: RestoreModel(currentContext, minimumContext, foundStateSuccessor); }