```// Copyright (C) 2003  Davis E. King (davis@dlib.net)
#undef DLIB_ENTROPY_ENCODER_KERNEl_ABSTRACT_
#ifdef DLIB_ENTROPY_ENCODER_KERNEl_ABSTRACT_

#include "../algs.h"
#include <iosfwd>
#include "../uintn.h"

namespace dlib
{

class entropy_encoder
{
/*!
INITIAL VALUE
stream_is_set() == false

WHAT THIS OBJECT REPRESENTS
This object represents an entropy encoder (could be implemented as an
arithmetic encoder for example).

Note that all implementations of entropy_encoder and entropy_decoder
are paired. This means that if you use entropy_encoder_kernel_n to
encode something then you must use the corresponding
entropy_decoder_kernel_n to decode it.

NOTATION:
At any moment each symbol has a certain probability of appearing in
the input stream.  These probabilities may change as each symbol is
encountered and the probability model is updated accordingly.

let P(i) be a function which gives the probability of seeing the ith
symbol of an N symbol alphabet BEFORE the probability model is updated
to account for the current symbol.  ( The domain of P(i) is from 0 to N-1. )

for each i: P(i) == COUNT/TOTAL where COUNT and TOTAL are integers.
and TOTAL is the same number for all P(i) but COUNT may vary.

let LOW_COUNT(i)  be the sum of all P(x)*TOTAL from x == 0 to x == i-1
(note that LOW_COUNT(0) == 0)
let HIGH_COUNT(i) be the sum of all P(x)*TOTAL from x == 0 to x == i
!*/

public:

entropy_encoder (
);
/*!
ensures
- #*this is properly initialized
throws
!*/

virtual ~entropy_encoder (
);
/*!
ensures
- all memory associated with *this has been released
- if (stream_is_set()) then
- any buffered data in *this will be written to get_stream()
!*/

void clear(
);
/*!
ensures
- #*this has its initial value
- if (stream_is_set()) then
- any buffered data in *this will be written to get_stream()
- clears any memory of all previous calls to encode() from #*this
throws
- std::ios_base::failure
if (stream_is_set() && there was a problem writing to get_stream())
then this exception will be thrown.  #*this will be unusable until
clear() is called and succeeds
- any other exception
if this exception is thrown then #*this is unusable
until clear() is called and succeeds
!*/

void set_stream (
std::ostream& out
);
/*!
ensures
- #get_stream()    == out
- #stream_is_set() == true
- if (stream_is_set()) then
- any buffered data in *this will be written to get_stream()
- clears any memory of all previous calls to encode() from #*this
throws
- std::ios_base::failure
if (stream_is_set() && there was a problem writing to get_stream())
then this exception will be thrown.  #*this will be unusable until
clear() is called and succeeds
- any other exception
if this exception is thrown then #*this is unusable
until clear() is called and succeeds
!*/

bool stream_is_set (
) const;
/*!
ensures
- returns true if a stream has been associated with *this by calling
set_stream()
!*/

std::ostream& get_stream (
) const;
/*!
requires
- stream_is_set() == true
ensures
- returns a reference to the ostream object that *this writes its
encoded data to
!*/

void encode (
uint32 low_count,
uint32 high_count,
uint32 total
);
/*!
requires
- 0 < total <  65536 (2^16)
- total == TOTAL
- low_count < high_count <= total
- stream_is_set() == true
ensures
- encodes the symbol S where:
- LOW_COUNT(S)  == low_count
- HIGH_COUNT(S) == high_count
throws
- std::ios_base::failure
if (there was a problem writing to get_stream()) then
this exception will be thrown.  #*this will be unusable until
clear() is called and succeeds
- any other exception
if this exception is thrown then #*this is unusable
until clear() is called and succeeds
!*/

private:

// restricted functions
entropy_encoder(entropy_encoder&);        // copy constructor
entropy_encoder& operator=(entropy_encoder&);    // assignment operator

};

}

#endif // DLIB_ENTROPY_ENCODER_KERNEl_ABSTRACT_

```