Beispiel #1
0
        internal void EncodeBlock(Stream target, Stream source, bool final)
        {
            while (true)
            {
                minimumContext   = maximumContext;
                numberStatistics = minimumContext.NumberStatistics;

                int c = source.ReadByte();
                if (c < 0 && !final)
                {
                    return;
                }

                if (numberStatistics != 0)
                {
                    EncodeSymbol1(c, minimumContext);
                    Coder.RangeEncodeSymbol();
                }
                else
                {
                    EncodeBinarySymbol(c, minimumContext);
                    Coder.RangeShiftEncodeSymbol(TotalBitCount);
                }

                while (foundState == PpmState.Zero)
                {
                    Coder.RangeEncoderNormalize(target);
                    do
                    {
                        orderFall++;
                        minimumContext = minimumContext.Suffix;
                        if (minimumContext == PpmContext.Zero)
                        {
                            goto StopEncoding;
                        }
                    } while (minimumContext.NumberStatistics == numberMasked);
                    EncodeSymbol2(c, minimumContext);
                    Coder.RangeEncodeSymbol();
                }

                if (orderFall == 0 && (Pointer)foundState.Successor >= Allocator.BaseUnit)
                {
                    maximumContext = foundState.Successor;
                }
                else
                {
                    UpdateModel(minimumContext);
                    if (escapeCount == 0)
                    {
                        ClearMask();
                    }
                }

                Coder.RangeEncoderNormalize(target);
            }

StopEncoding:
            Coder.RangeEncoderFlush(target);
        }
Beispiel #2
0
        internal void EncodeBlock(Stream target, Stream source, bool final)
        {
            while (true)
            {
                _minimumContext   = _maximumContext;
                _numberStatistics = _minimumContext.NumberStatistics;

                int c = source.ReadByte();
                if (c < 0 && !final)
                {
                    return;
                }

                if (_numberStatistics != 0)
                {
                    EncodeSymbol1(c, _minimumContext);
                    _coder.RangeEncodeSymbol();
                }
                else
                {
                    EncodeBinarySymbol(c, _minimumContext);
                    _coder.RangeShiftEncodeSymbol(TOTAL_BIT_COUNT);
                }

                while (_foundState == PpmState.ZERO)
                {
                    _coder.RangeEncoderNormalize(target);
                    do
                    {
                        _orderFall++;
                        _minimumContext = _minimumContext.Suffix;
                        if (_minimumContext == PpmContext.ZERO)
                        {
                            goto StopEncoding;
                        }
                    }while (_minimumContext.NumberStatistics == _numberMasked);
                    EncodeSymbol2(c, _minimumContext);
                    _coder.RangeEncodeSymbol();
                }

                if (_orderFall == 0 && (Pointer)_foundState.Successor >= _allocator._baseUnit)
                {
                    _maximumContext = _foundState.Successor;
                }
                else
                {
                    UpdateModel(_minimumContext);
                    if (_escapeCount == 0)
                    {
                        ClearMask();
                    }
                }

                _coder.RangeEncoderNormalize(target);
            }

StopEncoding:
            _coder.RangeEncoderFlush(target);
        }
Beispiel #3
0
 /// <summary>
 /// Indicates whether this instance and a specified object are equal.
 /// </summary>
 /// <returns>true if obj and this instance are the same type and represent the same value; otherwise, false.</returns>
 /// <param name="obj">Another object to compare to.</param>
 public override bool Equals(object obj)
 {
     if (obj is PpmContext)
     {
         PpmContext context = (PpmContext)obj;
         return(context._address == _address);
     }
     return(base.Equals(obj));
 }
Beispiel #4
0
 internal Coder DecodeStart(Stream source, PpmdProperties properties)
 {
     Allocator = properties.Allocator;
     Coder     = new Coder();
     Coder.RangeDecoderInitialize(source);
     StartModel(properties.ModelOrder, properties.ModelRestorationMethod);
     minimumContext   = maximumContext;
     numberStatistics = minimumContext.NumberStatistics;
     return(Coder);
 }
Beispiel #5
0
 private void Update2(PpmState state, PpmContext context)
 {
     foundState                = state;
     foundState.Frequency     += 4;
     context.SummaryFrequency += 4;
     if (state.Frequency > MaximumFrequency)
     {
         Rescale(context);
     }
     escapeCount++;
     runLength = initialRunLength;
 }
Beispiel #6
0
        private void DecodeSymbol2(PpmContext context)
        {
            See2Context see2Context = MakeEscapeFrequency(context);
            uint        currentSymbol;
            uint        count;
            uint        highCount  = 0;
            uint        index      = (uint)(context.NumberStatistics - _numberMasked);
            uint        stateIndex = 0;
            PpmState    state      = context.Statistics - 1;

            do
            {
                do
                {
                    currentSymbol = state[1].Symbol;
                    state++;
                }while (_characterMask[currentSymbol] == _escapeCount);
                highCount += state.Frequency;
                _decodeStates[stateIndex++] = state;

                // note that decodeStates is a static array that is re-used on each call to this method (for performance reasons)
            }while (--index != 0);

            _coder._scale += highCount;
            count          = _coder.RangeGetCurrentCount();
            stateIndex     = 0;
            state          = _decodeStates[stateIndex];
            if (count < highCount)
            {
                highCount = 0;
                while ((highCount += state.Frequency) <= count)
                {
                    state = _decodeStates[++stateIndex];
                }
                _coder._highCount = highCount;
                _coder._lowCount  = _coder._highCount - state.Frequency;
                see2Context.Update();
                Update2(state, context);
            }
            else
            {
                _coder._lowCount  = highCount;
                _coder._highCount = _coder._scale;
                index             = (uint)(context.NumberStatistics - _numberMasked);
                _numberMasked     = context.NumberStatistics;
                do
                {
                    _characterMask[_decodeStates[stateIndex].Symbol] = _escapeCount;
                    stateIndex++;
                }while (--index != 0);
                see2Context._summary += (ushort)_coder._scale;
            }
        }
Beispiel #7
0
 private void Update2(PpmState state, PpmContext context)
 {
     _foundState               = state;
     _foundState.Frequency    += 4;
     context.SummaryFrequency += 4;
     if (state.Frequency > MAXIMUM_FREQUENCY)
     {
         Rescale(context);
     }
     _escapeCount++;
     _runLength = _initialRunLength;
 }
Beispiel #8
0
        private void DecodeSymbol1(PpmContext context)
        {
            uint     index;
            uint     count;
            uint     highCount = context.Statistics.Frequency;
            PpmState state     = context.Statistics;

            Coder.Scale = context.SummaryFrequency;

            count = Coder.RangeGetCurrentCount();
            if (count < highCount)
            {
                Coder.HighCount           = highCount;
                previousSuccess           = (byte)((2 * Coder.HighCount >= Coder.Scale) ? 1 : 0);
                foundState                = state;
                highCount                += 4;
                foundState.Frequency      = (byte)highCount;
                context.SummaryFrequency += 4;
                runLength                += previousSuccess;
                if (highCount > MaximumFrequency)
                {
                    Rescale(context);
                }
                Coder.LowCount = 0;
                return;
            }

            index           = context.NumberStatistics;
            previousSuccess = 0;
            while ((highCount += (++state).Frequency) <= count)
            {
                if (--index == 0)
                {
                    Coder.LowCount = highCount;
                    characterMask[state.Symbol] = escapeCount;
                    numberMasked = context.NumberStatistics;
                    index        = context.NumberStatistics;
                    foundState   = PpmState.Zero;
                    do
                    {
                        characterMask[(--state).Symbol] = escapeCount;
                    }while (--index != 0);
                    Coder.HighCount = Coder.Scale;
                    return;
                }
            }
            Coder.HighCount = highCount;
            Coder.LowCount  = Coder.HighCount - state.Frequency;
            Update1(state, context);
        }
Beispiel #9
0
        private void DecodeSymbol1(PpmContext context)
        {
            uint     index;
            uint     count;
            uint     highCount = context.Statistics.Frequency;
            PpmState state     = context.Statistics;

            _coder._scale = context.SummaryFrequency;

            count = _coder.RangeGetCurrentCount();
            if (count < highCount)
            {
                _coder._highCount         = highCount;
                _previousSuccess          = (byte)((2 * _coder._highCount >= _coder._scale) ? 1 : 0);
                _foundState               = state;
                highCount                += 4;
                _foundState.Frequency     = (byte)highCount;
                context.SummaryFrequency += 4;
                _runLength               += _previousSuccess;
                if (highCount > MAXIMUM_FREQUENCY)
                {
                    Rescale(context);
                }
                _coder._lowCount = 0;
                return;
            }

            index            = context.NumberStatistics;
            _previousSuccess = 0;
            while ((highCount += (++state).Frequency) <= count)
            {
                if (--index == 0)
                {
                    _coder._lowCount             = highCount;
                    _characterMask[state.Symbol] = _escapeCount;
                    _numberMasked = context.NumberStatistics;
                    index         = context.NumberStatistics;
                    _foundState   = PpmState.ZERO;
                    do
                    {
                        _characterMask[(--state).Symbol] = _escapeCount;
                    }while (--index != 0);
                    _coder._highCount = _coder._scale;
                    return;
                }
            }
            _coder._highCount = highCount;
            _coder._lowCount  = _coder._highCount - state.Frequency;
            Update1(state, context);
        }
Beispiel #10
0
        private static void Swap(PpmState state1, PpmState state2)
        {
            byte       swapSymbol    = state1.Symbol;
            byte       swapFrequency = state1.Frequency;
            PpmContext swapSuccessor = state1.Successor;

            state1.Symbol    = state2.Symbol;
            state1.Frequency = state2.Frequency;
            state1.Successor = state2.Successor;

            state2.Symbol    = swapSymbol;
            state2.Frequency = swapFrequency;
            state2.Successor = swapSuccessor;
        }
Beispiel #11
0
 private void Update1(PpmState state, PpmContext context)
 {
     foundState                = state;
     foundState.Frequency     += 4;
     context.SummaryFrequency += 4;
     if (state[0].Frequency > state[-1].Frequency)
     {
         Swap(state[0], state[-1]);
         foundState = --state;
         if (state.Frequency > MaximumFrequency)
         {
             Rescale(context);
         }
     }
 }
Beispiel #12
0
 private void Update1(PpmState state, PpmContext context)
 {
     _foundState               = state;
     _foundState.Frequency    += 4;
     context.SummaryFrequency += 4;
     if (state[0].Frequency > state[-1].Frequency)
     {
         Swap(state[0], state[-1]);
         _foundState = --state;
         if (state.Frequency > MAXIMUM_FREQUENCY)
         {
             Rescale(context);
         }
     }
 }
Beispiel #13
0
        private void EncodeSymbol1(int symbol, PpmContext context)
        {
            uint     lowCount;
            uint     index = context.Statistics.Symbol;
            PpmState state = context.Statistics;

            Coder.Scale = context.SummaryFrequency;
            if (index == symbol)
            {
                Coder.HighCount           = state.Frequency;
                previousSuccess           = (byte)((2 * Coder.HighCount >= Coder.Scale) ? 1 : 0);
                foundState                = state;
                foundState.Frequency     += 4;
                context.SummaryFrequency += 4;
                runLength += previousSuccess;
                if (state.Frequency > MaximumFrequency)
                {
                    Rescale(context);
                }
                Coder.LowCount = 0;
                return;
            }

            lowCount        = state.Frequency;
            index           = context.NumberStatistics;
            previousSuccess = 0;
            while ((++state).Symbol != symbol)
            {
                lowCount += state.Frequency;
                if (--index == 0)
                {
                    Coder.LowCount = lowCount;
                    characterMask[state.Symbol] = escapeCount;
                    numberMasked = context.NumberStatistics;
                    index        = context.NumberStatistics;
                    foundState   = PpmState.Zero;
                    do
                    {
                        characterMask[(--state).Symbol] = escapeCount;
                    }while (--index != 0);
                    Coder.HighCount = Coder.Scale;
                    return;
                }
            }
            Coder.HighCount = (Coder.LowCount = lowCount) + state.Frequency;
            Update1(state, context);
        }
Beispiel #14
0
        private void EncodeSymbol1(int symbol, PpmContext context)
        {
            uint     lowCount;
            uint     index = context.Statistics.Symbol;
            PpmState state = context.Statistics;

            _coder._scale = context.SummaryFrequency;
            if (index == symbol)
            {
                _coder._highCount         = state.Frequency;
                _previousSuccess          = (byte)((2 * _coder._highCount >= _coder._scale) ? 1 : 0);
                _foundState               = state;
                _foundState.Frequency    += 4;
                context.SummaryFrequency += 4;
                _runLength += _previousSuccess;
                if (state.Frequency > MAXIMUM_FREQUENCY)
                {
                    Rescale(context);
                }
                _coder._lowCount = 0;
                return;
            }

            lowCount         = state.Frequency;
            index            = context.NumberStatistics;
            _previousSuccess = 0;
            while ((++state).Symbol != symbol)
            {
                lowCount += state.Frequency;
                if (--index == 0)
                {
                    _coder._lowCount             = lowCount;
                    _characterMask[state.Symbol] = _escapeCount;
                    _numberMasked = context.NumberStatistics;
                    index         = context.NumberStatistics;
                    _foundState   = PpmState.ZERO;
                    do
                    {
                        _characterMask[(--state).Symbol] = _escapeCount;
                    }while (--index != 0);
                    _coder._highCount = _coder._scale;
                    return;
                }
            }
            _coder._highCount = (_coder._lowCount = lowCount) + state.Frequency;
            Update1(state, context);
        }
Beispiel #15
0
        private void EncodeSymbol2(int symbol, PpmContext context)
        {
            See2Context see2Context = MakeEscapeFrequency(context);
            uint        currentSymbol;
            uint        lowCount = 0;
            uint        index    = (uint)(context.NumberStatistics - _numberMasked);
            PpmState    state    = context.Statistics - 1;

            do
            {
                do
                {
                    currentSymbol = state[1].Symbol;
                    state++;
                }while (_characterMask[currentSymbol] == _escapeCount);
                _characterMask[currentSymbol] = _escapeCount;
                if (currentSymbol == symbol)
                {
                    goto SymbolFound;
                }
                lowCount += state.Frequency;
            }while (--index != 0);

            _coder._lowCount      = lowCount;
            _coder._scale        += _coder._lowCount;
            _coder._highCount     = _coder._scale;
            see2Context._summary += (ushort)_coder._scale;
            _numberMasked         = context.NumberStatistics;
            return;

SymbolFound:
            _coder._lowCount  = lowCount;
            lowCount         += state.Frequency;
            _coder._highCount = lowCount;
            for (PpmState p1 = state; --index != 0;)
            {
                do
                {
                    currentSymbol = p1[1].Symbol;
                    p1++;
                }while (_characterMask[currentSymbol] == _escapeCount);
                lowCount += p1.Frequency;
            }
            _coder._scale += lowCount;
            see2Context.Update();
            Update2(state, context);
        }
Beispiel #16
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 #17
0
        private See2Context MakeEscapeFrequency(PpmContext context)
        {
            uint        numberStatistics = (uint)2 * context.NumberStatistics;
            See2Context see2Context;

            if (context.NumberStatistics != 0xff)
            {
                // Note that context.Flags is always in the range 0 .. 28 (this ensures that the index used for the second
                // dimension of the see2Contexts array is always in the range 0 .. 31).

                numberStatistics = context.Suffix.NumberStatistics;
                int index1 = probabilities[context.NumberStatistics + 2] - 3;
                int index2 = ((context.SummaryFrequency > 11 * (context.NumberStatistics + 1)) ? 1 : 0) + ((2 * context.NumberStatistics < numberStatistics + numberMasked) ? 2 : 0) + context.Flags;
                see2Context = see2Contexts[index1, index2];
                Coder.Scale = see2Context.Mean();
            }
            else
            {
                see2Context = emptySee2Context;
                Coder.Scale = 1;
            }

            return(see2Context);
        }
Beispiel #18
0
 private void Update1(PpmState state, PpmContext context)
 {
     foundState = state;
     foundState.Frequency += 4;
     context.SummaryFrequency += 4;
     if (state[0].Frequency > state[-1].Frequency)
     {
         Swap(state[0], state[-1]);
         foundState = --state;
         if (state.Frequency > MaximumFrequency)
             Rescale(context);
     }
 }
Beispiel #19
0
        private void DecodeSymbol2(PpmContext context)
        {
            See2Context see2Context = MakeEscapeFrequency(context);
            uint currentSymbol;
            uint count;
            uint highCount = 0;
            uint index = (uint)(context.NumberStatistics - numberMasked);
            uint stateIndex = 0;
            PpmState state = context.Statistics - 1;

            do
            {
                do
                {
                    currentSymbol = state[1].Symbol;
                    state++;
                } while (characterMask[currentSymbol] == escapeCount);
                highCount += state.Frequency;
                decodeStates[stateIndex++] = state;  // note that decodeStates is a static array that is re-used on each call to this method (for performance reasons)
            } while (--index != 0);

            Coder.Scale += highCount;
            count = Coder.RangeGetCurrentCount();
            stateIndex = 0;
            state = decodeStates[stateIndex];
            if (count < highCount)
            {
                highCount = 0;
                while ((highCount += state.Frequency) <= count)
                    state = decodeStates[++stateIndex];
                Coder.HighCount = highCount;
                Coder.LowCount = Coder.HighCount - state.Frequency;
                see2Context.Update();
                Update2(state, context);
            }
            else
            {
                Coder.LowCount = highCount;
                Coder.HighCount = Coder.Scale;
                index = (uint)(context.NumberStatistics - numberMasked);
                numberMasked = context.NumberStatistics;
                do
                {
                    characterMask[decodeStates[stateIndex].Symbol] = escapeCount;
                    stateIndex++;
                } while (--index != 0);
                see2Context.Summary += (ushort)Coder.Scale;
            }
        }
Beispiel #20
0
 private void Update2(PpmState state, PpmContext context)
 {
     foundState = state;
     foundState.Frequency += 4;
     context.SummaryFrequency += 4;
     if (state.Frequency > MaximumFrequency)
         Rescale(context);
     escapeCount++;
     runLength = initialRunLength;
 }
Beispiel #21
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;
        }
Beispiel #22
0
        private void RestoreModel(PpmContext context, PpmContext minimumContext, PpmContext foundStateSuccessor)
        {
            PpmContext currentContext;

            Allocator.Text = Allocator.Heap;
            for (currentContext = maximumContext; currentContext != context; currentContext = currentContext.Suffix)
            {
                if (--currentContext.NumberStatistics == 0)
                {
                    currentContext.Flags = (byte)((currentContext.Flags & 0x10) + ((currentContext.Statistics.Symbol >= 0x40) ? 0x08 : 0x00));
                    PpmState state = currentContext.Statistics;
                    Copy(currentContext.FirstState, state);
                    Allocator.SpecialFreeUnits(state);
                    currentContext.FirstStateFrequency = (byte)((currentContext.FirstStateFrequency + 11) >> 3);
                }
                else
                {
                    Refresh((uint)((currentContext.NumberStatistics + 3) >> 1), false, currentContext);
                }
            }

            for (; currentContext != minimumContext; currentContext = currentContext.Suffix)
            {
                if (currentContext.NumberStatistics == 0)
                {
                    currentContext.FirstStateFrequency -= (byte)(currentContext.FirstStateFrequency >> 1);
                }
                else if ((currentContext.SummaryFrequency += 4) > 128 + 4 * currentContext.NumberStatistics)
                {
                    Refresh((uint)((currentContext.NumberStatistics + 2) >> 1), true, currentContext);
                }
            }

            if (method > ModelRestorationMethod.Freeze)
            {
                maximumContext       = foundStateSuccessor;
                Allocator.GlueCount += (uint)(((Allocator.MemoryNodes[1].Stamp & 1) == 0) ? 1 : 0);
            }
            else if (method == ModelRestorationMethod.Freeze)
            {
                while (maximumContext.Suffix != PpmContext.Zero)
                {
                    maximumContext = maximumContext.Suffix;
                }

                RemoveBinaryContexts(0, maximumContext);
                method = (ModelRestorationMethod)(method + 1);
                Allocator.GlueCount = 0;
                orderFall           = modelOrder;
            }
            else if (method == ModelRestorationMethod.Restart || Allocator.GetMemoryUsed() < (Allocator.AllocatorSize >> 1))
            {
                StartModel(modelOrder, method);
                escapeCount = 0;
            }
            else
            {
                while (maximumContext.Suffix != PpmContext.Zero)
                {
                    maximumContext = maximumContext.Suffix;
                }

                do
                {
                    CutOff(0, maximumContext);
                    Allocator.ExpandText();
                } while (Allocator.GetMemoryUsed() > 3 * (Allocator.AllocatorSize >> 2));

                Allocator.GlueCount = 0;
                orderFall           = modelOrder;
            }
        }
Beispiel #23
0
        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);
        }
Beispiel #24
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 > MAXIMUM_FREQUENCY / 3)
                    {
                        localFrequency = (byte)(MAXIMUM_FREQUENCY / 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;
        }
Beispiel #25
0
        private void EncodeSymbol2(int symbol, PpmContext context)
        {
            See2Context see2Context = MakeEscapeFrequency(context);
            uint currentSymbol;
            uint lowCount = 0;
            uint index = (uint)(context.NumberStatistics - numberMasked);
            PpmState state = context.Statistics - 1;

            do
            {
                do
                {
                    currentSymbol = state[1].Symbol;
                    state++;
                } while (characterMask[currentSymbol] == escapeCount);
                characterMask[currentSymbol] = escapeCount;
                if (currentSymbol == symbol)
                    goto SymbolFound;
                lowCount += state.Frequency;
            } while (--index != 0);

            Coder.LowCount = lowCount;
            Coder.Scale += Coder.LowCount;
            Coder.HighCount = Coder.Scale;
            see2Context.Summary += (ushort)Coder.Scale;
            numberMasked = context.NumberStatistics;
            return;

        SymbolFound:
            Coder.LowCount = lowCount;
            lowCount += state.Frequency;
            Coder.HighCount = lowCount;
            for (PpmState p1 = state; --index != 0; )
            {
                do
                {
                    currentSymbol = p1[1].Symbol;
                    p1++;
                } while (characterMask[currentSymbol] == escapeCount);
                lowCount += p1.Frequency;
            }
            Coder.Scale += lowCount;
            see2Context.Update();
            Update2(state, context);
        }
Beispiel #26
0
        private void EncodeSymbol1(int symbol, PpmContext context)
        {
            uint lowCount;
            uint index = context.Statistics.Symbol;
            PpmState state = context.Statistics;
            Coder.Scale = context.SummaryFrequency;
            if (index == symbol)
            {
                Coder.HighCount = state.Frequency;
                previousSuccess = (byte)((2 * Coder.HighCount >= Coder.Scale) ? 1 : 0);
                foundState = state;
                foundState.Frequency += 4;
                context.SummaryFrequency += 4;
                runLength += previousSuccess;
                if (state.Frequency > MaximumFrequency)
                    Rescale(context);
                Coder.LowCount = 0;
                return;
            }

            lowCount = state.Frequency;
            index = context.NumberStatistics;
            previousSuccess = 0;
            while ((++state).Symbol != symbol)
            {
                lowCount += state.Frequency;
                if (--index == 0)
                {
                    Coder.LowCount = lowCount;
                    characterMask[state.Symbol] = escapeCount;
                    numberMasked = context.NumberStatistics;
                    index = context.NumberStatistics;
                    foundState = PpmState.Zero;
                    do
                    {
                        characterMask[(--state).Symbol] = escapeCount;
                    } while (--index != 0);
                    Coder.HighCount = Coder.Scale;
                    return;
                }
            }
            Coder.HighCount = (Coder.LowCount = lowCount) + state.Frequency;
            Update1(state, context);
        }
Beispiel #27
0
        private void DecodeBinarySymbol(PpmContext context)
        {
            PpmState state = context.FirstState;
            int index1 = probabilities[state.Frequency - 1];
            int index2 = numberStatisticsToBinarySummaryIndex[context.Suffix.NumberStatistics] + previousSuccess + context.Flags + ((runLength >> 26) & 0x20);

            if (Coder.RangeGetCurrentShiftCount(TotalBitCount) < binarySummary[index1, index2])
            {
                foundState = state;
                state.Frequency += (byte)((state.Frequency < 196) ? 1 : 0);
                Coder.LowCount = 0;
                Coder.HighCount = binarySummary[index1, index2];
                binarySummary[index1, index2] += (ushort)(Interval - Mean(binarySummary[index1, index2], PeriodBitCount, 2));
                previousSuccess = 1;
                runLength++;
            }
            else
            {
                Coder.LowCount = binarySummary[index1, index2];
                binarySummary[index1, index2] -= (ushort)Mean(binarySummary[index1, index2], PeriodBitCount, 2);
                Coder.HighCount = BinaryScale;
                initialEscape = ExponentialEscapes[binarySummary[index1, index2] >> 10];
                characterMask[state.Symbol] = escapeCount;
                previousSuccess = 0;
                numberMasked = 0;
                foundState = PpmState.Zero;
            }
        }
Beispiel #28
0
 internal Coder DecodeStart(Stream source, PpmdProperties properties)
 {
     Allocator = properties.Allocator;
     Coder = new Coder();
     Coder.RangeDecoderInitialize(source);
     StartModel(properties.ModelOrder, properties.ModelRestorationMethod);
     minimumContext = maximumContext;
     numberStatistics = minimumContext.NumberStatistics;
     return Coder;
 }
Beispiel #29
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 #30
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;
                }
                else
                {
                    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;
                }
                else 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 #31
0
        private void Refresh(uint oldUnitCount, bool scale, PpmContext context)
        {
            int index = context.NumberStatistics;
            int escapeFrequency;
            int scaleValue = (scale ? 1 : 0);

            context.Statistics = Allocator.ShrinkUnits(context.Statistics, oldUnitCount, (uint)((index + 2) >> 1));
            PpmState statistics = context.Statistics;
            context.Flags = (byte)((context.Flags & (0x10 + (scale ? 0x04 : 0x00))) + ((statistics.Symbol >= 0x40) ? 0x08 : 0x00));
            escapeFrequency = context.SummaryFrequency - statistics.Frequency;
            statistics.Frequency = (byte)((statistics.Frequency + scaleValue) >> scaleValue);
            context.SummaryFrequency = statistics.Frequency;

            do
            {
                escapeFrequency -= (++statistics).Frequency;
                statistics.Frequency = (byte)((statistics.Frequency + scaleValue) >> scaleValue);
                context.SummaryFrequency += statistics.Frequency;
                context.Flags |= (byte)((statistics.Symbol >= 0x40) ? 0x08 : 0x00);
            } while (--index != 0);

            escapeFrequency = (escapeFrequency + scaleValue) >> scaleValue;
            context.SummaryFrequency += (ushort)escapeFrequency;
        }
Beispiel #32
0
        private PpmContext ReduceOrder(PpmState state, PpmContext context)
        {
            PpmState currentState;
            PpmState[] states = new PpmState[MaximumOrder];
            uint stateIndex = 0;
            PpmContext currentContext = context;
            PpmContext UpBranch = Allocator.Text;
            byte temporary;
            byte symbol = foundState.Symbol;

            states[stateIndex++] = foundState;
            foundState.Successor = UpBranch;
            orderFall++;

            bool gotoLoopEntry = false;
            if (state != PpmState.Zero)
            {
                context = context.Suffix;
                gotoLoopEntry = true;
            }

            while (true)
            {
                if (gotoLoopEntry)
                {
                    gotoLoopEntry = false;
                    goto LoopEntry;
                }

                if (context.Suffix == PpmContext.Zero)
                {
                    if (method > ModelRestorationMethod.Freeze)
                    {
                        do
                        {
                            states[--stateIndex].Successor = context;
                        } while (stateIndex != 0);
                        Allocator.Text = Allocator.Heap + 1;
                        orderFall = 1;
                    }
                    return context;
                }

                context = context.Suffix;
                if (context.NumberStatistics != 0)
                {
                    state = context.Statistics;
                    if (state.Symbol != symbol)
                    {
                        do
                        {
                            temporary = state[1].Symbol;
                            state++;
                        } while (temporary != symbol);
                    }
                    temporary = (byte) ((state.Frequency < MaximumFrequency - 9) ? 2 : 0);
                    state.Frequency += temporary;
                    context.SummaryFrequency += temporary;
                }
                else
                {
                    state = context.FirstState;
                    state.Frequency += (byte) ((state.Frequency < 32) ? 1 : 0);
                }

                LoopEntry:
                if (state.Successor != PpmContext.Zero)
                    break;
                states[stateIndex++] = state;
                state.Successor = UpBranch;
                orderFall++;
            }

            if (method > ModelRestorationMethod.Freeze)
            {
                context = state.Successor;
                do
                {
                    states[--stateIndex].Successor = context;
                } while (stateIndex != 0);
                Allocator.Text = Allocator.Heap + 1;
                orderFall = 1;
                return context;
            }
            else if (state.Successor <= UpBranch)
            {
                currentState = foundState;
                foundState = state;
                state.Successor = CreateSuccessors(false, PpmState.Zero, context);
                foundState = currentState;
            }

            if (orderFall == 1 && currentContext == maximumContext)
            {
                foundState.Successor = state.Successor;
                Allocator.Text--;
            }

            return state.Successor;
        }
Beispiel #33
0
        internal int DecodeBlock(Stream source, byte[] buffer, int offset, int count)
        {
            if (minimumContext == PpmContext.Zero)
                return 0;

            int total = 0;
            while (total < count)
            {
                if (numberStatistics != 0)
                    DecodeSymbol1(minimumContext);
                else
                    DecodeBinarySymbol(minimumContext);

                Coder.RangeRemoveSubrange();

                while (foundState == PpmState.Zero)
                {
                    Coder.RangeDecoderNormalize(source);
                    do
                    {
                        orderFall++;
                        minimumContext = minimumContext.Suffix;
                        if (minimumContext == PpmContext.Zero)
                            goto StopDecoding;
                    } while (minimumContext.NumberStatistics == numberMasked);
                    DecodeSymbol2(minimumContext);
                    Coder.RangeRemoveSubrange();
                }

                buffer[offset] = foundState.Symbol;
                offset++;
                total++;

                if (orderFall == 0 && (Pointer) foundState.Successor >= Allocator.BaseUnit)
                {
                    maximumContext = foundState.Successor;
                }
                else
                {
                    UpdateModel(minimumContext);
                    if (escapeCount == 0)
                        ClearMask();
                }

                minimumContext = maximumContext;
                numberStatistics = minimumContext.NumberStatistics;
                Coder.RangeDecoderNormalize(source);
            }

            StopDecoding:
            return total;
        }
Beispiel #34
0
        private PpmContext CreateSuccessors(bool skip, PpmState state, PpmContext context)
        {
            PpmContext upBranch = foundState.Successor;
            PpmState[] states = new PpmState[MaximumOrder];
            uint stateIndex = 0;
            byte symbol = foundState.Symbol;

            if (!skip)
            {
                states[stateIndex++] = foundState;
                if (context.Suffix == PpmContext.Zero)
                    goto NoLoop;
            }

            bool gotoLoopEntry = false;
            if (state != PpmState.Zero)
            {
                context = context.Suffix;
                gotoLoopEntry = true;
            }

            do
            {
                if (gotoLoopEntry)
                {
                    gotoLoopEntry = false;
                    goto LoopEntry;
                }

                context = context.Suffix;
                if (context.NumberStatistics != 0)
                {
                    byte temporary;
                    state = context.Statistics;
                    if (state.Symbol != symbol)
                    {
                        do
                        {
                            temporary = state[1].Symbol;
                            state++;
                        } while (temporary != symbol);
                    }
                    temporary = (byte) ((state.Frequency < MaximumFrequency - 9) ? 1 : 0);
                    state.Frequency += temporary;
                    context.SummaryFrequency += temporary;
                }
                else
                {
                    state = context.FirstState;
                    state.Frequency +=
                        (byte) (((context.Suffix.NumberStatistics == 0) ? 1 : 0) & ((state.Frequency < 24) ? 1 : 0));
                }

                LoopEntry:
                if (state.Successor != upBranch)
                {
                    context = state.Successor;
                    break;
                }
                states[stateIndex++] = state;
            } while (context.Suffix != PpmContext.Zero);

            NoLoop:
            if (stateIndex == 0)
                return context;

            byte localNumberStatistics = 0;
            byte localFlags = (byte) ((symbol >= 0x40) ? 0x10 : 0x00);
            symbol = upBranch.NumberStatistics;
            byte localSymbol = symbol;
            byte localFrequency;
            PpmContext localSuccessor = ((Pointer) upBranch) + 1;
            localFlags |= (byte) ((symbol >= 0x40) ? 0x08 : 0x00);

            if (context.NumberStatistics != 0)
            {
                state = context.Statistics;
                if (state.Symbol != symbol)
                {
                    byte temporary;
                    do
                    {
                        temporary = state[1].Symbol;
                        state++;
                    } while (temporary != symbol);
                }
                uint cf = (uint) (state.Frequency - 1);
                uint s0 = (uint) (context.SummaryFrequency - context.NumberStatistics - cf);
                localFrequency = (byte) (1 + ((2*cf <= s0) ? (uint) ((5*cf > s0) ? 1 : 0) : ((cf + 2*s0 - 3)/s0)));
            }
            else
            {
                localFrequency = context.FirstStateFrequency;
            }

            do
            {
                PpmContext currentContext = Allocator.AllocateContext();
                if (currentContext == PpmContext.Zero)
                    return PpmContext.Zero;
                currentContext.NumberStatistics = localNumberStatistics;
                currentContext.Flags = localFlags;
                currentContext.FirstStateSymbol = localSymbol;
                currentContext.FirstStateFrequency = localFrequency;
                currentContext.FirstStateSuccessor = localSuccessor;
                currentContext.Suffix = context;
                context = currentContext;
                states[--stateIndex].Successor = context;
            } while (stateIndex != 0);

            return context;
        }
Beispiel #35
0
        /// <summary>
        /// Initialise the model (unless the model order is set to 1 in which case the model should be cleared so that
        /// the statistics are carried over, allowing "solid" mode compression).
        /// </summary>
        private void StartModel(int modelOrder, ModelRestorationMethod modelRestorationMethod)
        {
            Array.Clear(characterMask, 0, characterMask.Length);
            escapeCount = 1;

            // Compress in "solid" mode if the model order value is set to 1 (this will examine the current PPM context
            // structures to determine the value of orderFall).

            if (modelOrder < 2)
            {
                orderFall = this.modelOrder;
                for (PpmContext context = maximumContext; context.Suffix != PpmContext.Zero; context = context.Suffix)
                {
                    orderFall--;
                }
                return;
            }

            this.modelOrder = modelOrder;
            orderFall       = modelOrder;
            method          = modelRestorationMethod;
            Allocator.Initialize();
            initialRunLength = -((modelOrder < 12) ? modelOrder : 12) - 1;
            runLength        = initialRunLength;

            // Allocate the context structure.

            maximumContext                  = Allocator.AllocateContext();
            maximumContext.Suffix           = PpmContext.Zero;
            maximumContext.NumberStatistics = 255;
            maximumContext.SummaryFrequency = (ushort)(maximumContext.NumberStatistics + 2);
            maximumContext.Statistics       = Allocator.AllocateUnits(256 / 2); // allocates enough space for 256 PPM states (each is 6 bytes)

            previousSuccess = 0;
            for (int index = 0; index < 256; index++)
            {
                PpmState state = maximumContext.Statistics[index];
                state.Symbol    = (byte)index;
                state.Frequency = 1;
                state.Successor = PpmContext.Zero;
            }

            uint probability = 0;

            for (int index1 = 0; probability < 25; probability++)
            {
                while (probabilities[index1] == probability)
                {
                    index1++;
                }
                for (int index2 = 0; index2 < 8; index2++)
                {
                    binarySummary[probability, index2] = (ushort)(BinaryScale - InitialBinaryEscapes[index2] / (index1 + 1));
                }
                for (int index2 = 8; index2 < 64; index2 += 8)
                {
                    for (int index3 = 0; index3 < 8; index3++)
                    {
                        binarySummary[probability, index2 + index3] = binarySummary[probability, index3];
                    }
                }
            }

            probability = 0;
            for (uint index1 = 0; probability < 24; probability++)
            {
                while (probabilities[index1 + 3] == probability + 3)
                {
                    index1++;
                }
                for (int index2 = 0; index2 < 32; index2++)
                {
                    see2Contexts[probability, index2].Initialize(2 * index1 + 5);
                }
            }
        }
Beispiel #36
0
        /// <summary>
        /// Initialise the model (unless the model order is set to 1 in which case the model should be cleared so that
        /// the statistics are carried over, allowing "solid" mode compression).
        /// </summary>
        private void StartModel(int modelOrder, ModelRestorationMethod modelRestorationMethod)
        {
            Array.Clear(characterMask, 0, characterMask.Length);
            escapeCount = 1;

            // Compress in "solid" mode if the model order value is set to 1 (this will examine the current PPM context
            // structures to determine the value of orderFall).

            if (modelOrder < 2)
            {
                orderFall = this.modelOrder;
                for (PpmContext context = maximumContext; context.Suffix != PpmContext.Zero; context = context.Suffix)
                    orderFall--;
                return;
            }

            this.modelOrder = modelOrder;
            orderFall = modelOrder;
            method = modelRestorationMethod;
            Allocator.Initialize();
            initialRunLength = -((modelOrder < 12) ? modelOrder : 12) - 1;
            runLength = initialRunLength;

            // Allocate the context structure.

            maximumContext = Allocator.AllocateContext();
            maximumContext.Suffix = PpmContext.Zero;
            maximumContext.NumberStatistics = 255;
            maximumContext.SummaryFrequency = (ushort) (maximumContext.NumberStatistics + 2);
            maximumContext.Statistics = Allocator.AllocateUnits(256/2);
                // allocates enough space for 256 PPM states (each is 6 bytes)

            previousSuccess = 0;
            for (int index = 0; index < 256; index++)
            {
                PpmState state = maximumContext.Statistics[index];
                state.Symbol = (byte) index;
                state.Frequency = 1;
                state.Successor = PpmContext.Zero;
            }

            uint probability = 0;
            for (int index1 = 0; probability < 25; probability++)
            {
                while (probabilities[index1] == probability)
                    index1++;
                for (int index2 = 0; index2 < 8; index2++)
                    binarySummary[probability, index2] =
                        (ushort) (BinaryScale - InitialBinaryEscapes[index2]/(index1 + 1));
                for (int index2 = 8; index2 < 64; index2 += 8)
                    for (int index3 = 0; index3 < 8; index3++)
                        binarySummary[probability, index2 + index3] = binarySummary[probability, index3];
            }

            probability = 0;
            for (uint index1 = 0; probability < 24; probability++)
            {
                while (probabilities[index1 + 3] == probability + 3)
                    index1++;
                for (int index2 = 0; index2 < 32; index2++)
                    see2Contexts[probability, index2].Initialize(2*index1 + 5);
            }
        }
Beispiel #37
0
        private PpmContext CreateSuccessors(bool skip, PpmState state, PpmContext context)
        {
            PpmContext upBranch = foundState.Successor;

            PpmState[] states     = new PpmState[MaximumOrder];
            uint       stateIndex = 0;
            byte       symbol     = foundState.Symbol;

            if (!skip)
            {
                states[stateIndex++] = foundState;
                if (context.Suffix == PpmContext.Zero)
                {
                    goto NoLoop;
                }
            }

            bool gotoLoopEntry = false;

            if (state != PpmState.Zero)
            {
                context       = context.Suffix;
                gotoLoopEntry = true;
            }

            do
            {
                if (gotoLoopEntry)
                {
                    gotoLoopEntry = false;
                    goto LoopEntry;
                }

                context = context.Suffix;
                if (context.NumberStatistics != 0)
                {
                    byte temporary;
                    state = context.Statistics;
                    if (state.Symbol != symbol)
                    {
                        do
                        {
                            temporary = state[1].Symbol;
                            state++;
                        } while (temporary != symbol);
                    }
                    temporary                 = (byte)((state.Frequency < MaximumFrequency - 9) ? 1 : 0);
                    state.Frequency          += temporary;
                    context.SummaryFrequency += temporary;
                }
                else
                {
                    state            = context.FirstState;
                    state.Frequency += (byte)(((context.Suffix.NumberStatistics == 0) ? 1 : 0) & ((state.Frequency < 24) ? 1 : 0));
                }

LoopEntry:
                if (state.Successor != upBranch)
                {
                    context = state.Successor;
                    break;
                }
                states[stateIndex++] = state;
            } while (context.Suffix != PpmContext.Zero);

NoLoop:
            if (stateIndex == 0)
            {
                return(context);
            }

            byte localNumberStatistics = 0;
            byte localFlags            = (byte)((symbol >= 0x40) ? 0x10 : 0x00);

            symbol = upBranch.NumberStatistics;
            byte       localSymbol = symbol;
            byte       localFrequency;
            PpmContext localSuccessor = ((Pointer)upBranch) + 1;

            localFlags |= (byte)((symbol >= 0x40) ? 0x08 : 0x00);

            if (context.NumberStatistics != 0)
            {
                state = context.Statistics;
                if (state.Symbol != symbol)
                {
                    byte temporary;
                    do
                    {
                        temporary = state[1].Symbol;
                        state++;
                    } while (temporary != symbol);
                }
                uint cf = (uint)(state.Frequency - 1);
                uint s0 = (uint)(context.SummaryFrequency - context.NumberStatistics - cf);
                localFrequency = (byte)(1 + ((2 * cf <= s0) ? (uint)((5 * cf > s0) ? 1 : 0) : ((cf + 2 * s0 - 3) / s0)));
            }
            else
            {
                localFrequency = context.FirstStateFrequency;
            }

            do
            {
                PpmContext currentContext = Allocator.AllocateContext();
                if (currentContext == PpmContext.Zero)
                {
                    return(PpmContext.Zero);
                }
                currentContext.NumberStatistics    = localNumberStatistics;
                currentContext.Flags               = localFlags;
                currentContext.FirstStateSymbol    = localSymbol;
                currentContext.FirstStateFrequency = localFrequency;
                currentContext.FirstStateSuccessor = localSuccessor;
                currentContext.Suffix              = context;
                context = currentContext;
                states[--stateIndex].Successor = context;
            } while (stateIndex != 0);

            return(context);
        }
Beispiel #38
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 > ORDER_BOUND)
                    {
                        _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 #39
0
        private See2Context MakeEscapeFrequency(PpmContext context)
        {
            uint numberStatistics = (uint)2 * context.NumberStatistics;
            See2Context see2Context;

            if (context.NumberStatistics != 0xff)
            {
                // Note that context.Flags is always in the range 0 .. 28 (this ensures that the index used for the second
                // dimension of the see2Contexts array is always in the range 0 .. 31).

                numberStatistics = context.Suffix.NumberStatistics;
                int index1 = probabilities[context.NumberStatistics + 2] - 3;
                int index2 = ((context.SummaryFrequency > 11 * (context.NumberStatistics + 1)) ? 1 : 0) + ((2 * context.NumberStatistics < numberStatistics + numberMasked) ? 2 : 0) + context.Flags;
                see2Context = see2Contexts[index1, index2];
                Coder.Scale = see2Context.Mean();
            }
            else
            {
                see2Context = emptySee2Context;
                Coder.Scale = 1;
            }

            return see2Context;
        }
Beispiel #40
0
        internal int DecodeBlock(Stream source, byte[] buffer, int offset, int count)
        {
            if (minimumContext == PpmContext.Zero)
            {
                return(0);
            }

            int total = 0;

            while (total < count)
            {
                if (numberStatistics != 0)
                {
                    DecodeSymbol1(minimumContext);
                }
                else
                {
                    DecodeBinarySymbol(minimumContext);
                }

                Coder.RangeRemoveSubrange();

                while (foundState == PpmState.Zero)
                {
                    Coder.RangeDecoderNormalize(source);
                    do
                    {
                        orderFall++;
                        minimumContext = minimumContext.Suffix;
                        if (minimumContext == PpmContext.Zero)
                        {
                            goto StopDecoding;
                        }
                    } while (minimumContext.NumberStatistics == numberMasked);
                    DecodeSymbol2(minimumContext);
                    Coder.RangeRemoveSubrange();
                }

                buffer[offset] = foundState.Symbol;
                offset++;
                total++;

                if (orderFall == 0 && (Pointer)foundState.Successor >= Allocator.BaseUnit)
                {
                    maximumContext = foundState.Successor;
                }
                else
                {
                    UpdateModel(minimumContext);
                    if (escapeCount == 0)
                    {
                        ClearMask();
                    }
                }

                minimumContext   = maximumContext;
                numberStatistics = minimumContext.NumberStatistics;
                Coder.RangeDecoderNormalize(source);
            }

StopDecoding:
            return(total);
        }
Beispiel #41
0
        internal int DecodeBlock(Stream source, byte[] buffer, int offset, int count)
        {
            if (_minimumContext == PpmContext.ZERO)
            {
                return(0);
            }

            int total = 0;

            while (total < count)
            {
                if (_numberStatistics != 0)
                {
                    DecodeSymbol1(_minimumContext);
                }
                else
                {
                    DecodeBinarySymbol(_minimumContext);
                }

                _coder.RangeRemoveSubrange();

                while (_foundState == PpmState.ZERO)
                {
                    _coder.RangeDecoderNormalize(source);
                    do
                    {
                        _orderFall++;
                        _minimumContext = _minimumContext.Suffix;
                        if (_minimumContext == PpmContext.ZERO)
                        {
                            goto StopDecoding;
                        }
                    }while (_minimumContext.NumberStatistics == _numberMasked);
                    DecodeSymbol2(_minimumContext);
                    _coder.RangeRemoveSubrange();
                }

                buffer[offset] = _foundState.Symbol;
                offset++;
                total++;

                if (_orderFall == 0 && (Pointer)_foundState.Successor >= _allocator._baseUnit)
                {
                    _maximumContext = _foundState.Successor;
                }
                else
                {
                    UpdateModel(_minimumContext);
                    if (_escapeCount == 0)
                    {
                        ClearMask();
                    }
                }

                _minimumContext   = _maximumContext;
                _numberStatistics = _minimumContext.NumberStatistics;
                _coder.RangeDecoderNormalize(source);
            }

StopDecoding:
            return(total);
        }
Beispiel #42
0
        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);
        }
Beispiel #43
0
        private PpmContext ReduceOrder(PpmState state, PpmContext context)
        {
            PpmState currentState;

            PpmState[] states         = new PpmState[MAXIMUM_ORDER];
            uint       stateIndex     = 0;
            PpmContext currentContext = context;
            PpmContext upBranch       = _allocator._text;
            byte       temporary;
            byte       symbol = _foundState.Symbol;

            states[stateIndex++]  = _foundState;
            _foundState.Successor = upBranch;
            _orderFall++;

            bool gotoLoopEntry = false;

            if (state != PpmState.ZERO)
            {
                context       = context.Suffix;
                gotoLoopEntry = true;
            }

            while (true)
            {
                if (gotoLoopEntry)
                {
                    gotoLoopEntry = false;
                    goto LoopEntry;
                }

                if (context.Suffix == PpmContext.ZERO)
                {
                    if (_method > ModelRestorationMethod.Freeze)
                    {
                        do
                        {
                            states[--stateIndex].Successor = context;
                        }while (stateIndex != 0);
                        _allocator._text = _allocator._heap + 1;
                        _orderFall       = 1;
                    }
                    return(context);
                }

                context = context.Suffix;
                if (context.NumberStatistics != 0)
                {
                    state = context.Statistics;
                    if (state.Symbol != symbol)
                    {
                        do
                        {
                            temporary = state[1].Symbol;
                            state++;
                        }while (temporary != symbol);
                    }
                    temporary                 = (byte)((state.Frequency < MAXIMUM_FREQUENCY - 9) ? 2 : 0);
                    state.Frequency          += temporary;
                    context.SummaryFrequency += temporary;
                }
                else
                {
                    state            = context.FirstState;
                    state.Frequency += (byte)((state.Frequency < 32) ? 1 : 0);
                }

LoopEntry:
                if (state.Successor != PpmContext.ZERO)
                {
                    break;
                }
                states[stateIndex++] = state;
                state.Successor      = upBranch;
                _orderFall++;
            }

            if (_method > ModelRestorationMethod.Freeze)
            {
                context = state.Successor;
                do
                {
                    states[--stateIndex].Successor = context;
                }while (stateIndex != 0);
                _allocator._text = _allocator._heap + 1;
                _orderFall       = 1;
                return(context);
            }
            if (state.Successor <= upBranch)
            {
                currentState    = _foundState;
                _foundState     = state;
                state.Successor = CreateSuccessors(false, PpmState.ZERO, context);
                _foundState     = currentState;
            }

            if (_orderFall == 1 && currentContext == _maximumContext)
            {
                _foundState.Successor = state.Successor;
                _allocator._text--;
            }

            return(state.Successor);
        }
Beispiel #44
0
        private PpmContext ReduceOrder(PpmState state, PpmContext context)
        {
            PpmState currentState;

            PpmState[] states         = new PpmState[MaximumOrder];
            uint       stateIndex     = 0;
            PpmContext currentContext = context;
            PpmContext UpBranch       = Allocator.Text;
            byte       temporary;
            byte       symbol = foundState.Symbol;

            states[stateIndex++] = foundState;
            foundState.Successor = UpBranch;
            orderFall++;

            bool gotoLoopEntry = false;

            if (state != PpmState.Zero)
            {
                context       = context.Suffix;
                gotoLoopEntry = true;
            }

            while (true)
            {
                if (gotoLoopEntry)
                {
                    gotoLoopEntry = false;
                    goto LoopEntry;
                }

                if (context.Suffix == PpmContext.Zero)
                {
                    if (method > ModelRestorationMethod.Freeze)
                    {
                        do
                        {
                            states[--stateIndex].Successor = context;
                        } while (stateIndex != 0);
                        Allocator.Text = Allocator.Heap + 1;
                        orderFall      = 1;
                    }
                    return(context);
                }

                context = context.Suffix;
                if (context.NumberStatistics != 0)
                {
                    state = context.Statistics;
                    if (state.Symbol != symbol)
                    {
                        do
                        {
                            temporary = state[1].Symbol;
                            state++;
                        } while (temporary != symbol);
                    }
                    temporary                 = (byte)((state.Frequency < MaximumFrequency - 9) ? 2 : 0);
                    state.Frequency          += temporary;
                    context.SummaryFrequency += temporary;
                }
                else
                {
                    state            = context.FirstState;
                    state.Frequency += (byte)((state.Frequency < 32) ? 1 : 0);
                }

LoopEntry:
                if (state.Successor != PpmContext.Zero)
                {
                    break;
                }
                states[stateIndex++] = state;
                state.Successor      = UpBranch;
                orderFall++;
            }

            if (method > ModelRestorationMethod.Freeze)
            {
                context = state.Successor;
                do
                {
                    states[--stateIndex].Successor = context;
                } while (stateIndex != 0);
                Allocator.Text = Allocator.Heap + 1;
                orderFall      = 1;
                return(context);
            }
            else if (state.Successor <= UpBranch)
            {
                currentState    = foundState;
                foundState      = state;
                state.Successor = CreateSuccessors(false, PpmState.Zero, context);
                foundState      = currentState;
            }

            if (orderFall == 1 && currentContext == maximumContext)
            {
                foundState.Successor = state.Successor;
                Allocator.Text--;
            }

            return(state.Successor);
        }
Beispiel #45
0
        private void RestoreModel(PpmContext context, PpmContext minimumContext, PpmContext foundStateSuccessor)
        {
            PpmContext currentContext;

            Allocator.Text = Allocator.Heap;
            for (currentContext = maximumContext; currentContext != context; currentContext = currentContext.Suffix)
            {
                if (--currentContext.NumberStatistics == 0)
                {
                    currentContext.Flags =
                        (byte)
                        ((currentContext.Flags & 0x10) + ((currentContext.Statistics.Symbol >= 0x40) ? 0x08 : 0x00));
                    PpmState state = currentContext.Statistics;
                    Copy(currentContext.FirstState, state);
                    Allocator.SpecialFreeUnits(state);
                    currentContext.FirstStateFrequency = (byte) ((currentContext.FirstStateFrequency + 11) >> 3);
                }
                else
                {
                    Refresh((uint) ((currentContext.NumberStatistics + 3) >> 1), false, currentContext);
                }
            }

            for (; currentContext != minimumContext; currentContext = currentContext.Suffix)
            {
                if (currentContext.NumberStatistics == 0)
                    currentContext.FirstStateFrequency -= (byte) (currentContext.FirstStateFrequency >> 1);
                else if ((currentContext.SummaryFrequency += 4) > 128 + 4*currentContext.NumberStatistics)
                    Refresh((uint) ((currentContext.NumberStatistics + 2) >> 1), true, currentContext);
            }

            if (method > ModelRestorationMethod.Freeze)
            {
                maximumContext = foundStateSuccessor;
                Allocator.GlueCount += (uint) (((Allocator.MemoryNodes[1].Stamp & 1) == 0) ? 1 : 0);
            }
            else if (method == ModelRestorationMethod.Freeze)
            {
                while (maximumContext.Suffix != PpmContext.Zero)
                    maximumContext = maximumContext.Suffix;

                RemoveBinaryContexts(0, maximumContext);
                method = (ModelRestorationMethod) (method + 1);
                Allocator.GlueCount = 0;
                orderFall = modelOrder;
            }
            else if (method == ModelRestorationMethod.Restart ||
                     Allocator.GetMemoryUsed() < (Allocator.AllocatorSize >> 1))
            {
                StartModel(modelOrder, method);
                escapeCount = 0;
            }
            else
            {
                while (maximumContext.Suffix != PpmContext.Zero)
                    maximumContext = maximumContext.Suffix;

                do
                {
                    CutOff(0, maximumContext);
                    Allocator.ExpandText();
                } while (Allocator.GetMemoryUsed() > 3*(Allocator.AllocatorSize >> 2));

                Allocator.GlueCount = 0;
                orderFall = modelOrder;
            }
        }
Beispiel #46
0
        internal void EncodeBlock(Stream target, Stream source, bool final)
        {
            while (true)
            {
                minimumContext = maximumContext;
                numberStatistics = minimumContext.NumberStatistics;

                int c = source.ReadByte();
                if (c < 0 && !final)
                    return;

                if (numberStatistics != 0)
                {
                    EncodeSymbol1(c, minimumContext);
                    Coder.RangeEncodeSymbol();
                }
                else
                {
                    EncodeBinarySymbol(c, minimumContext);
                    Coder.RangeShiftEncodeSymbol(TotalBitCount);
                }

                while (foundState == PpmState.Zero)
                {
                    Coder.RangeEncoderNormalize(target);
                    do
                    {
                        orderFall++;
                        minimumContext = minimumContext.Suffix;
                        if (minimumContext == PpmContext.Zero)
                            goto StopEncoding;
                    } while (minimumContext.NumberStatistics == numberMasked);
                    EncodeSymbol2(c, minimumContext);
                    Coder.RangeEncodeSymbol();
                }

                if (orderFall == 0 && (Pointer) foundState.Successor >= Allocator.BaseUnit)
                {
                    maximumContext = foundState.Successor;
                }
                else
                {
                    UpdateModel(minimumContext);
                    if (escapeCount == 0)
                        ClearMask();
                }

                Coder.RangeEncoderNormalize(target);
            }

            StopEncoding:
            Coder.RangeEncoderFlush(target);
        }
Beispiel #47
0
        private void DecodeSymbol1(PpmContext context)
        {
            uint index;
            uint count;
            uint highCount = context.Statistics.Frequency;
            PpmState state = context.Statistics;
            Coder.Scale = context.SummaryFrequency;

            count = Coder.RangeGetCurrentCount();
            if (count < highCount)
            {
                Coder.HighCount = highCount;
                previousSuccess = (byte)((2 * Coder.HighCount >= Coder.Scale) ? 1 : 0);
                foundState = state;
                highCount += 4;
                foundState.Frequency = (byte)highCount;
                context.SummaryFrequency += 4;
                runLength += previousSuccess;
                if (highCount > MaximumFrequency)
                    Rescale(context);
                Coder.LowCount = 0;
                return;
            }

            index = context.NumberStatistics;
            previousSuccess = 0;
            while ((highCount += (++state).Frequency) <= count)
            {
                if (--index == 0)
                {
                    Coder.LowCount = highCount;
                    characterMask[state.Symbol] = escapeCount;
                    numberMasked = context.NumberStatistics;
                    index = context.NumberStatistics;
                    foundState = PpmState.Zero;
                    do
                    {
                        characterMask[(--state).Symbol] = escapeCount;
                    } while (--index != 0);
                    Coder.HighCount = Coder.Scale;
                    return;
                }
            }
            Coder.HighCount = highCount;
            Coder.LowCount = Coder.HighCount - state.Frequency;
            Update1(state, context);
        }