private void EmitE3Mappings(WriteBitDelegate bitWriter, bool value)
 {
     // perform e3 mappings
     for (; _scale > 0; _scale--)
     {
         bitWriter(value);
     }
 }
        /// <summary>
        ///     Writes the bit representation of <paramref name="symbol" /> with <paramref name="bitWriter" />.
        /// </summary>
        public void WriteCode(TSymbolType symbol, WriteBitDelegate bitWriter)
        {
            var bits = GetCachedBits(symbol);

            for (var i = 0; i < bits.Length; ++i)
            {
                bitWriter(bits[i]);
            }
        }
Example #3
0
 /// <summary>
 ///     Writes the code for the entry at <paramref name="index" /> to <paramref name="bitWriter" />.
 /// </summary>
 private void WriteCode(uint index, WriteBitDelegate bitWriter)
 {
     if (_entries.Length > 1)
     {
         var parentIndex = _entries[index].ParentIndex;
         if (parentIndex != Root)
         {
             WriteCode(parentIndex, bitWriter);
         }
         bitWriter(_entries[parentIndex].GetBit(index));
     }
 }
        /// <summary>
        /// Encodes <paramref name="symbol"/> using the <paramref name="coder"/> with
        /// the provided <paramref name="model"/>.
        /// </summary>
        public static void Encode <TSymbolType>(this ArithmeticCoder coder, TSymbolType symbol, IModel <TSymbolType> model,
                                                WriteBitDelegate bitWriter)
            where TSymbolType : struct
        {
            // cumulate frequencies
            Range count = model.GetRange(symbol);

            // encode symbol
            coder.Encode(count, model.TotalFrequencies, bitWriter);

            // update model
            model.Update(symbol);
        }
        /// <summary>
        /// Encodes the range updating the state of the encoder.
        /// </summary>
        public void Encode(Range counts,
                           uint total,
                           WriteBitDelegate bitWriter)
        // total < 2^29
        {
            if (total >= RangeLimit)
            {
                throw new ArgumentOutOfRangeException("total");
            }
            if (counts.Low >= RangeLimit || counts.High >= RangeLimit)
            {
                throw new ArgumentOutOfRangeException("counts");
            }
            if (counts.Low >= counts.High)
            {
                throw new ArgumentException("counts");
            }
            if (bitWriter == null)
            {
                throw new ArgumentNullException("bitWriter");
            }
            // partition number space into single steps
            _step = (_range.Length()) / total; // interval open at the top => +1

            // Update bounds -- interval open at the top => -1 for High.
            _range = (counts * _step + _range.Low) - BoundaryAdjust;

            // apply 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;

                bitWriter(!isHighLessThanHalf);
                EmitE3Mappings(bitWriter, isHighLessThanHalf);

                _range = (_range - sub) * 2 + BoundaryAdjust;
            }

            // e3
            while (_range.In(FirstQuarter, ThirdQuarter))
            {
                // keep necessary e3 mappings in mind
                _scale++;
                _range = (_range - FirstQuarter) * 2 + BoundaryAdjust;
            }
        }
        /// <summary>
        /// Finishes encoding, writing any remaining bits.
        /// </summary>
        /// <param name="bitWriter"></param>
        public void EncodeFinish(WriteBitDelegate bitWriter)
        {
            if (bitWriter == null)
            {
                throw new ArgumentNullException("bitWriter");
            }
            // There are two possibilities of how _range.Low and _range.High can be distributed,
            // which means that two bits are enough to distinguish them.

            bool isLowGreaterThanFirstQuarter = _range.Low >= FirstQuarter;

            bitWriter(isLowGreaterThanFirstQuarter);

            if (!isLowGreaterThanFirstQuarter)   // The alternative defaults missing bits to zero.
            {
                ++_scale;                        // Ensures at least one additional bit is written.
                EmitE3Mappings(bitWriter, true); // These will default to false for the other case.
            }

            Reset();
        }
Example #7
0
        /// <summary>
        ///     Writes the code for <paramref name="symbol" />.  If the symbol was not previously encountered,
        ///     the bit sequence to mark a symbol literal is written to <paramref name="bitWriter" />
        ///     and the symbol through <paramref name="symbolWriter" />.
        /// </summary>
        public void WriteCode(TSymbolType symbol, WriteBitDelegate bitWriter,
                              WriteSymbolDelegate <TSymbolType> symbolWriter)
        {
            var nytSeen = false;

            if (HasSymbol(symbol))
            {
                WriteCodeInternal(symbol, bitWriter);
            }
            else
            {
                WriteCodeInternal(SymbolSpace.NotYetTransmitted, bitWriter);
                UpdateSymbolInternal(SymbolSpace.NotYetTransmitted, GetTweak(symbol, true));
                symbolWriter(symbol);
                nytSeen = true;
            }
            UpdateSymbolInternal(symbol, 1);
            if (!nytSeen)
            {
                UpdateSymbolInternal(SymbolSpace.NotYetTransmitted, GetTweak(symbol, false));
            }
        }
Example #8
0
 /// <summary>
 ///     Converts writing <paramref name="symbol" /> to writing based on its corresponding index in the tree.
 /// </summary>
 private void WriteCodeInternal(SymbolSpace symbol, WriteBitDelegate bitWriter)
 {
     WriteCode(_map[symbol], bitWriter);
 }
 private void EmitE3Mappings(WriteBitDelegate bitWriter, bool value)
 {
     // perform e3 mappings
     for (; _scale > 0; _scale--)
     {
         bitWriter(value);
     }
 }
        /// <summary>
        /// Finishes encoding, writing any remaining bits.
        /// </summary>
        /// <param name="bitWriter"></param>
        public void EncodeFinish(WriteBitDelegate bitWriter)
        {
            if (bitWriter == null)
            {
                throw new ArgumentNullException("bitWriter");
            }
            // There are two possibilities of how _range.Low and _range.High can be distributed,
            // which means that two bits are enough to distinguish them.

            bool isLowGreaterThanFirstQuarter = _range.Low >= FirstQuarter;
            bitWriter(isLowGreaterThanFirstQuarter);

            if (!isLowGreaterThanFirstQuarter) // The alternative defaults missing bits to zero.
            {
                ++_scale; // Ensures at least one additional bit is written.
                EmitE3Mappings(bitWriter, true); // These will default to false for the other case.
            }

            Reset();
        }
        // total < 2^29
        /// <summary>
        /// Encodes the range updating the state of the encoder.
        /// </summary>
        public void Encode(Range counts,
                           uint total,
                           WriteBitDelegate bitWriter)
        {
            if (total >= RangeLimit)
            {
                throw new ArgumentOutOfRangeException("total");
            }
            if (counts.Low >= RangeLimit || counts.High >= RangeLimit)
            {
                throw new ArgumentOutOfRangeException("counts");
            }
            if (counts.Low >= counts.High)
            {
                throw new ArgumentException("counts");
            }
            if (bitWriter == null)
            {
                throw new ArgumentNullException("bitWriter");
            }
            // partition number space into single steps
            _step = (_range.Length())/total; // interval open at the top => +1

            // Update bounds -- interval open at the top => -1 for High.
            _range = (counts*_step + _range.Low) - BoundaryAdjust;

            // apply 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;

                bitWriter(!isHighLessThanHalf);
                EmitE3Mappings(bitWriter, isHighLessThanHalf);

                _range = (_range - sub)*2 + BoundaryAdjust;
            }

            // e3
            while (_range.In(FirstQuarter, ThirdQuarter))
            {
                // keep necessary e3 mappings in mind
                _scale++;
                _range = (_range - FirstQuarter)*2 + BoundaryAdjust;
            }
        }