/// <summary> /// Reads a symbol using the bits retrieved with <paramref name="bitReader" />. /// </summary> public TSymbolType GetSymbol(ReadBitDelegate bitReader) { var current = (uint)_entries.Length - 1; while (!_entries[current].IsSymbol) { current = _entries[current].GetChild(bitReader()); } return(_entries[current].Symbol); }
/// <summary> /// Initializes the decoder by reading the first set of values for the state. /// </summary> /// <param name="bitReader"></param> public void DecodeStart(ReadBitDelegate bitReader) { if (bitReader == null) { throw new ArgumentNullException("bitReader"); } // Fill buffer with bits from the input stream for (int i = 0; i < 31; i++) // just use the 31 least significant bits { _buffer = (_buffer << 1) | ((uint)(bitReader() ? 1 : 0)); } }
/// <summary> /// Handles reading the symbol from the symbol space (including the NotYetTransmitted sequence). /// </summary> private SymbolSpace GetSymbolInternal(ReadBitDelegate bitReader) { if (_entries.Length > 1) { var index = Root; while (!_entries[index].IsLeaf) { index = _entries[index].GetIndex(bitReader()); } return(_entries[index].Symbol); } return(SymbolSpace.NotYetTransmitted); }
/// <summary> /// Retrieves a symbol. If the bit sequence from <paramref name="bitReader" /> /// identifies a symbol literal, <paramref name="symbolReader" /> is called. /// </summary> public TSymbolType GetSymbol(ReadBitDelegate bitReader, ReadSymbolDelegate <TSymbolType> symbolReader) { var result = GetSymbolInternal(bitReader); if (result.IsValid) { UpdateSymbolInternal(result, 1); UpdateSymbolInternal(SymbolSpace.NotYetTransmitted, GetTweak(result.Symbol, false)); return(result.Symbol); } result = symbolReader(); UpdateSymbolInternal(SymbolSpace.NotYetTransmitted, GetTweak(result.Symbol, true)); UpdateSymbolInternal(result, 1); return(result.Symbol); }
/// <summary> /// Decodes a symbol using the <paramref name="coder"/> with the provided /// <paramref name="model"/>. /// </summary> public static TSymbolType Decode <TSymbolType>(this ArithmeticCoder coder, IModel <TSymbolType> model, ReadBitDelegate bitReader) where TSymbolType : struct { // read value uint value = coder.DecodeTarget(model.TotalFrequencies); // determine symbol RangeSymbol <TSymbolType> rangeSymbol = model.Decode(value); // adapt decoder coder.Decode(rangeSymbol.Range, bitReader); // update model model.Update(rangeSymbol.Symbol); return(rangeSymbol.Symbol); }
/// <summary> /// Updates the decoder based on the provided range. /// </summary> public void Decode(Range counts, ReadBitDelegate bitReader) { if (counts.Low >= counts.High) { throw new ArgumentException("counts"); } if (counts.Low >= RangeLimit || counts.High >= RangeLimit) { throw new ArgumentOutOfRangeException("counts"); } if (bitReader == null) { throw new ArgumentNullException("bitReader"); } // Update bounds -- interval open at the top => -1 for High _range = (counts * _step + _range.Low) - BoundaryAdjust; // e1/e2 mapping while ((_range.High < Half) || (_range.Low >= Half)) { bool isHighLessThanHalf = _range.High < Half; // true => emit false for lower half. uint sub = isHighLessThanHalf ? 0 : Half; _range = (_range - sub) * 2 + BoundaryAdjust; _buffer = (_buffer - sub) * 2 + ((uint)(bitReader() ? 1 : 0)); _scale = 0; } // e3 mapping while (_range.In(FirstQuarter, ThirdQuarter)) { _scale++; _range = (_range - FirstQuarter) * 2 + BoundaryAdjust; _buffer = 2 * (_buffer - FirstQuarter) + ((uint)(bitReader() ? 1 : 0)); } }
/// <summary> /// Updates the decoder based on the provided range. /// </summary> public void Decode(Range counts, ReadBitDelegate bitReader) { if (counts.Low >= counts.High) { throw new ArgumentException("counts"); } if (counts.Low >= RangeLimit || counts.High >= RangeLimit) { throw new ArgumentOutOfRangeException("counts"); } if (bitReader == null) { throw new ArgumentNullException("bitReader"); } // Update bounds -- interval open at the top => -1 for High _range = (counts*_step + _range.Low) - BoundaryAdjust; // e1/e2 mapping while ((_range.High < Half) || (_range.Low >= Half)) { bool isHighLessThanHalf = _range.High < Half; // true => emit false for lower half. uint sub = isHighLessThanHalf ? 0 : Half; _range = (_range - sub)*2 + BoundaryAdjust; _buffer = (_buffer - sub)*2 + ((uint) (bitReader() ? 1 : 0)); _scale = 0; } // e3 mapping while (_range.In(FirstQuarter, ThirdQuarter)) { _scale++; _range = (_range - FirstQuarter)*2 + BoundaryAdjust; _buffer = 2*(_buffer - FirstQuarter) + ((uint) (bitReader() ? 1 : 0)); } }
/// <summary> /// Initializes the decoder by reading the first set of values for the state. /// </summary> /// <param name="bitReader"></param> public void DecodeStart(ReadBitDelegate bitReader) { if (bitReader == null) { throw new ArgumentNullException("bitReader"); } // Fill buffer with bits from the input stream for (int i = 0; i < 31; i++) // just use the 31 least significant bits { _buffer = (_buffer << 1) | ((uint) (bitReader() ? 1 : 0)); } }