Esempio n. 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));
            }
        }
Esempio n. 2
0
        // 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;
            }
        }