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); }
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); }
/// <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)); }
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); }
private void Update2(PpmState state, PpmContext context) { foundState = state; foundState.Frequency += 4; context.SummaryFrequency += 4; if (state.Frequency > MaximumFrequency) { Rescale(context); } escapeCount++; runLength = initialRunLength; }
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; } }
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; }
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); }
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); }
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; }
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); } } }
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); } } }
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); }
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); }
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); }
private PpmContext RemoveBinaryContexts(int order, PpmContext context) { if (context.NumberStatistics == 0) { PpmState state = context.FirstState; if ((Pointer)state.Successor >= Allocator.BaseUnit && order < modelOrder) { state.Successor = RemoveBinaryContexts(order + 1, state.Successor); } else { state.Successor = PpmContext.Zero; } if ((state.Successor == PpmContext.Zero) && (context.Suffix.NumberStatistics == 0 || context.Suffix.Flags == 0xff)) { Allocator.FreeUnits(context, 1); return(PpmContext.Zero); } else { return(context); } } for (PpmState state = context.Statistics + context.NumberStatistics; state >= context.Statistics; state--) { if ((Pointer)state.Successor >= Allocator.BaseUnit && order < modelOrder) { state.Successor = RemoveBinaryContexts(order + 1, state.Successor); } else { state.Successor = PpmContext.Zero; } } return(context); }
private 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); }
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); } }
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; } }
private void Update2(PpmState state, PpmContext context) { foundState = state; foundState.Frequency += 4; context.SummaryFrequency += 4; if (state.Frequency > MaximumFrequency) Rescale(context); escapeCount++; runLength = initialRunLength; }
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; }
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; } }
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); }
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; }
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); }
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); }
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; } }
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; }
private PpmContext RemoveBinaryContexts(int order, PpmContext context) { if (context.NumberStatistics == 0) { PpmState state = context.FirstState; if ((Pointer)state.Successor >= Allocator.BaseUnit && order < modelOrder) state.Successor = RemoveBinaryContexts(order + 1, state.Successor); else state.Successor = PpmContext.Zero; if ((state.Successor == PpmContext.Zero) && (context.Suffix.NumberStatistics == 0 || context.Suffix.Flags == 0xff)) { Allocator.FreeUnits(context, 1); return PpmContext.Zero; } else { return context; } } for (PpmState state = context.Statistics + context.NumberStatistics; state >= context.Statistics; state--) { if ((Pointer)state.Successor >= Allocator.BaseUnit && order < modelOrder) state.Successor = RemoveBinaryContexts(order + 1, state.Successor); else state.Successor = PpmContext.Zero; } return context; }
private PpmContext CutOff(int order, PpmContext context) { int index; PpmState state; if (context.NumberStatistics == 0) { state = context.FirstState; if ((Pointer)state.Successor >= Allocator.BaseUnit) { if (order < modelOrder) state.Successor = CutOff(order + 1, state.Successor); else state.Successor = PpmContext.Zero; if (state.Successor == PpmContext.Zero && order > OrderBound) { Allocator.SpecialFreeUnits(context); return PpmContext.Zero; } return context; } 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; }
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; }
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; }
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; }
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; }
/// <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); } } }
/// <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); } }
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); }
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); }
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; }
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); }
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); }
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); }
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); }
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); }
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; } }
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); }
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); }