/// <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));
     }
 }
Exemple #3
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);
 }
Exemple #4
0
        /// <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));
     }
 }