private PpmContext RemoveBinaryContexts(int order, PpmContext context) { if (context.NumberStatistics == 0) { PpmState state = context.FirstState; if ((Pointer)state.Successor >= Allocator.BaseUnit && order < modelOrder) { state.Successor = RemoveBinaryContexts(order + 1, state.Successor); } else { state.Successor = PpmContext.Zero; } if ((state.Successor == PpmContext.Zero) && (context.Suffix.NumberStatistics == 0 || context.Suffix.Flags == 0xff)) { Allocator.FreeUnits(context, 1); return(PpmContext.Zero); } else { return(context); } } for (PpmState state = context.Statistics + context.NumberStatistics; state >= context.Statistics; state--) { if ((Pointer)state.Successor >= Allocator.BaseUnit && order < modelOrder) { state.Successor = RemoveBinaryContexts(order + 1, state.Successor); } else { state.Successor = PpmContext.Zero; } } return(context); }
private PpmContext CutOff(int order, PpmContext context) { int index; PpmState state; if (context.NumberStatistics == 0) { state = context.FirstState; if ((Pointer)state.Successor >= Allocator.BaseUnit) { if (order < modelOrder) { state.Successor = CutOff(order + 1, state.Successor); } else { state.Successor = PpmContext.Zero; } if (state.Successor == PpmContext.Zero && order > OrderBound) { Allocator.SpecialFreeUnits(context); return(PpmContext.Zero); } return(context); } Allocator.SpecialFreeUnits(context); return(PpmContext.Zero); } uint unitCount = (uint)((context.NumberStatistics + 2) >> 1); context.Statistics = Allocator.MoveUnitsUp(context.Statistics, unitCount); index = context.NumberStatistics; for (state = context.Statistics + index; state >= context.Statistics; state--) { if (state.Successor < Allocator.BaseUnit) { state.Successor = PpmContext.Zero; Swap(state, context.Statistics[index--]); } else if (order < modelOrder) { state.Successor = CutOff(order + 1, state.Successor); } else { state.Successor = PpmContext.Zero; } } if (index != context.NumberStatistics && order != 0) { context.NumberStatistics = (byte)index; state = context.Statistics; if (index < 0) { Allocator.FreeUnits(state, unitCount); Allocator.SpecialFreeUnits(context); return(PpmContext.Zero); } if (index == 0) { context.Flags = (byte)((context.Flags & 0x10) + ((state.Symbol >= 0x40) ? 0x08 : 0x00)); Copy(context.FirstState, state); Allocator.FreeUnits(state, unitCount); context.FirstStateFrequency = (byte)((context.FirstStateFrequency + 11) >> 3); } else { Refresh(unitCount, context.SummaryFrequency > 16 * index, context); } } return(context); }
private void Rescale(PpmContext context) { uint oldUnitCount; int adder; uint escapeFrequency; uint index = context.NumberStatistics; byte localSymbol; byte localFrequency; PpmContext localSuccessor; PpmState p1; PpmState state; for (state = foundState; state != context.Statistics; state--) { Swap(state[0], state[-1]); } state.Frequency += 4; context.SummaryFrequency += 4; escapeFrequency = (uint)(context.SummaryFrequency - state.Frequency); adder = (orderFall != 0 || method > ModelRestorationMethod.Freeze) ? 1 : 0; state.Frequency = (byte)((state.Frequency + adder) >> 1); context.SummaryFrequency = state.Frequency; do { escapeFrequency -= (++state).Frequency; state.Frequency = (byte)((state.Frequency + adder) >> 1); context.SummaryFrequency += state.Frequency; if (state[0].Frequency > state[-1].Frequency) { p1 = state; localSymbol = p1.Symbol; localFrequency = p1.Frequency; localSuccessor = p1.Successor; do { Copy(p1[0], p1[-1]); }while (localFrequency > (--p1)[-1].Frequency); p1.Symbol = localSymbol; p1.Frequency = localFrequency; p1.Successor = localSuccessor; } }while (--index != 0); if (state.Frequency == 0) { do { index++; }while ((--state).Frequency == 0); escapeFrequency += index; oldUnitCount = (uint)((context.NumberStatistics + 2) >> 1); context.NumberStatistics -= (byte)index; if (context.NumberStatistics == 0) { localSymbol = context.Statistics.Symbol; localFrequency = context.Statistics.Frequency; localSuccessor = context.Statistics.Successor; localFrequency = (byte)((2 * localFrequency + escapeFrequency - 1) / escapeFrequency); if (localFrequency > MaximumFrequency / 3) { localFrequency = (byte)(MaximumFrequency / 3); } Allocator.FreeUnits(context.Statistics, oldUnitCount); context.FirstStateSymbol = localSymbol; context.FirstStateFrequency = localFrequency; context.FirstStateSuccessor = localSuccessor; context.Flags = (byte)((context.Flags & 0x10) + ((localSymbol >= 0x40) ? 0x08 : 0x00)); foundState = context.FirstState; return; } context.Statistics = Allocator.ShrinkUnits(context.Statistics, oldUnitCount, (uint)((context.NumberStatistics + 2) >> 1)); context.Flags &= 0xf7; index = context.NumberStatistics; state = context.Statistics; context.Flags |= (byte)((state.Symbol >= 0x40) ? 0x08 : 0x00); do { context.Flags |= (byte)(((++state).Symbol >= 0x40) ? 0x08 : 0x00); }while (--index != 0); } escapeFrequency -= (escapeFrequency >> 1); context.SummaryFrequency += (ushort)escapeFrequency; context.Flags |= 0x04; foundState = context.Statistics; }