/*
* Reference arithmetic coding
* Copyright (c) Project Nayuki
*
* https://www.nayuki.io/page/reference-arithmetic-coding
* https://github.com/nayuki/Reference-arithmetic-coding
*/
using System;
///
/// Encodes symbols and writes to an arithmetic-coded bit stream. Not thread-safe.
///
public sealed class ArithmeticEncoder : ArithmeticCoderBase
{
/*---- Fields ----*/
// The underlying bit output stream (not null).
private BitOutputStream output;
// Number of saved underflow bits. This value can grow without bound,
// so a truly correct implementation would use a BigInteger.
private int numUnderflow;
/*---- Constructor ----*/
///
/// Constructs an arithmetic coding encoder based on the specified bit output stream.
/// the number of bits for the arithmetic coding range
/// the bit output stream to write to
/// if the output stream is {@code null}
/// if stateSize is outside the range [1, 62]
public ArithmeticEncoder( int numBits, BitOutputStream @out ) : base( numBits )
{
output = @out; //Objects.requireNonNull(@out);
numUnderflow = 0;
}
/*---- Methods ----*/
///
/// Encodes the specified symbol based on the specified frequency table.
/// This updates this arithmetic coder's state and may write out some bits.
/// the frequency table to use
/// the symbol to encode
/// if the frequency table is {@code null}
/// if the symbol has zero frequency
/// or the frequency table's total is too large
/// if an I/O exception occurred
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: public void write(FrequencyTable freqs, int symbol) throws java.io.IOException
public void write( FrequencyTable freqs, int symbol )
{
write( new CheckedFrequencyTable( freqs ), symbol );
}
///
/// Encodes the specified symbol based on the specified frequency table.
/// Also updates this arithmetic coder's state and may write out some bits.
/// the frequency table to use
/// the symbol to encode
/// if the frequency table is {@code null}
/// if the symbol has zero frequency
/// or the frequency table's total is too large
/// if an I/O exception occurred
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: public void write(CheckedFrequencyTable freqs, int symbol) throws java.io.IOException
public void write( CheckedFrequencyTable freqs, int symbol )
{
update( freqs, symbol );
}
///
/// Terminates the arithmetic coding by flushing any buffered bits, so that the output can be decoded properly.
/// It is important that this method must be called at the end of the each encoding process.
/// Note that this method merely writes data to the underlying output stream but does not close it.
/// if an I/O exception occurred
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: public void finish() throws java.io.IOException
public void finish()
{
output.write( 1 );
}
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#:
//ORIGINAL LINE: protected void shift() throws java.io.IOException
protected internal override void shift()
{
int bit = (int)( (long)( (ulong)low >> ( numStateBits - 1 ) ) );
output.write( bit );
// Write out the saved underflow bits
for( ; numUnderflow > 0; numUnderflow-- )
{
output.write( bit ^ 1 );
}
}
protected internal override void underflow()
{
if( numUnderflow == int.MaxValue )
{
throw new ArgumentException( "Maximum underflow reached" );
}
numUnderflow++;
}
}