Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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;
        }