/// <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> /// 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)); } }
// 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; } }