Commit 754da0ef authored by Davis King's avatar Davis King
Browse files

Properly organized the svn repository. Finally.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%402199
parent 49388714
// Copyright (C) 2003 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ENTROPY_ENCODEr_
#define DLIB_ENTROPY_ENCODEr_
#include "entropy_encoder/entropy_encoder_kernel_1.h"
#include "entropy_encoder/entropy_encoder_kernel_2.h"
#include "entropy_encoder/entropy_encoder_kernel_c.h"
namespace dlib
{
class entropy_encoder
{
entropy_encoder() {}
public:
//----------- kernels ---------------
// kernel_1a
typedef entropy_encoder_kernel_1
kernel_1a;
typedef entropy_encoder_kernel_c<kernel_1a>
kernel_1a_c;
// kernel_2a
typedef entropy_encoder_kernel_2
kernel_2a;
typedef entropy_encoder_kernel_c<kernel_2a>
kernel_2a_c;
};
}
#endif // DLIB_ENTROPY_ENCODEr_
// Copyright (C) 2003 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ENTROPY_ENCODER_KERNEL_1_CPp_
#define DLIB_ENTROPY_ENCODER_KERNEL_1_CPp_
#include "entropy_encoder_kernel_1.h"
#include <iostream>
#include <streambuf>
namespace dlib
{
// ----------------------------------------------------------------------------------------
entropy_encoder_kernel_1::
entropy_encoder_kernel_1(
) :
initial_low(0x00000001),
initial_high(0xffffffff),
out(0),
low(initial_low),
high(initial_high),
buf(0),
buf_used(0)
{
}
// ----------------------------------------------------------------------------------------
entropy_encoder_kernel_1::
~entropy_encoder_kernel_1 (
)
{
try {
if (out != 0)
{
flush();
}
} catch (...) {}
}
// ----------------------------------------------------------------------------------------
void entropy_encoder_kernel_1::
clear(
)
{
if (out != 0)
{
flush();
}
out = 0;
}
// ----------------------------------------------------------------------------------------
void entropy_encoder_kernel_1::
set_stream (
std::ostream& out_
)
{
if (out != 0)
{
// if a stream is currently set then flush the buffers to it before
// we switch to the new stream
flush();
}
out = &out_;
streambuf = out_.rdbuf();
// reset the encoder state
buf_used = 0;
buf = 0;
low = initial_low;
high = initial_high;
}
// ----------------------------------------------------------------------------------------
bool entropy_encoder_kernel_1::
stream_is_set (
) const
{
if (out != 0)
return true;
else
return false;
}
// ----------------------------------------------------------------------------------------
std::ostream& entropy_encoder_kernel_1::
get_stream (
) const
{
return *out;
}
// ----------------------------------------------------------------------------------------
void entropy_encoder_kernel_1::
encode (
uint32 low_count,
uint32 high_count,
uint32 total
)
{
// note that we must add one because of the convention that
// high == the real upper range minus 1
uint32 r = (high-low+1)/total;
// note that we must subtract 1 to preserve the convention that
// high == the real upper range - 1
high = low + r*high_count-1;
low = low + r*low_count;
while (true)
{
// if the highest order bit in high and low is the same
if ( low >= 0x80000000 || high < 0x80000000)
{
// if buf is full then write it out
if (buf_used == 8)
{
if (streambuf->sputn(reinterpret_cast<char*>(&buf),1)==0)
{
throw std::ios_base::failure("error occured in the entropy_encoder object");
}
buf = 0;
buf_used = 0;
}
// write the high order bit from low into buf
buf <<= 1;
++buf_used;
if (low&0x80000000)
buf |= 0x1;
// roll off the bit we just wrote to buf
low <<= 1;
high <<= 1;
high |= 1; // note that it is ok to add one to high here because
// of the convention that high == real upper range - 1.
// so that means that if we want to shift the upper range
// left by one then we must shift a one into high also
// since real upper range == high + 0.999999999...
// make sure low is never zero
if (low == 0)
low = 1;
}
// if the distance between high and low is small and there aren't
// any bits we can roll off then round low up or high down.
else if (high-low < 0x10000)
{
if (high == 0x80000000)
high = 0x7fffffff;
else
low = 0x80000000;
}
else
{
break;
}
} // while (true)
}
// ----------------------------------------------------------------------------------------
void entropy_encoder_kernel_1::
flush (
)
{
// flush the next 4 or 5 bytes that are buffered
// thats whatever is contained in buf and then all of low plus any extra
// bits needed to pad that to be an even 4 or 5 bytes
if (buf_used != 8)
{
buf <<= (8-buf_used);
buf |= static_cast<unsigned char>(low>>(24+buf_used));
low <<= (8-buf_used);
}
if (streambuf->sputn(reinterpret_cast<char*>(&buf),1) == 0)
throw std::ios_base::failure("error occured in the entropy_encoder object");
buf = static_cast<unsigned char>((low >> 24)&0xFF);
if (streambuf->sputn(reinterpret_cast<char*>(&buf),1) == 0)
throw std::ios_base::failure("error occured in the entropy_encoder object");
buf = static_cast<unsigned char>((low >> 16)&0xFF);
if (streambuf->sputn(reinterpret_cast<char*>(&buf),1)==0)
throw std::ios_base::failure("error occured in the entropy_encoder object");
buf = static_cast<unsigned char>((low >> 8)&0xFF);
if (streambuf->sputn(reinterpret_cast<char*>(&buf),1)==0)
throw std::ios_base::failure("error occured in the entropy_encoder object");
if (buf_used != 0)
{
buf = static_cast<unsigned char>((low)&0xFF);
if (streambuf->sputn(reinterpret_cast<char*>(&buf),1)==0)
throw std::ios_base::failure("error occured in the entropy_encoder object");
}
// make sure the stream buffer flushes to its I/O channel
streambuf->pubsync();
// reset the encoder state
buf_used = 0;
buf = 0;
low = initial_low;
high = initial_high;
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_ENTROPY_ENCODER_KERNEL_1_CPp_
// Copyright (C) 2003 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ENTROPY_ENCODER_KERNEl_1_
#define DLIB_ENTROPY_ENCODER_KERNEl_1_
#include "../algs.h"
#include "entropy_encoder_kernel_abstract.h"
#include <iosfwd>
#include "../uintn.h"
namespace dlib
{
class entropy_encoder_kernel_1
{
/*!
GENERAL NOTES
this encoder is implemented using arithmetic coding
INITIAL VALUE
out == 0
buf_used == 0
buf == 0
initial_low == 0x00000001 (slightly more than zero)
initial_high == 0xffffffff (slightly less than one, 0.99999999976717)
low == initial_low
high == initial_high
CONVENTION
if (out != 0)
*out == get_stream()
true == stream_is_set()
streambuf == out->rdbuf()
else
false == stream_is_set()
buf == used to accumulate bits before writing them to out.
buf_used == the number of low order bits in buf that are currently
in use
low == the low end of the range used for arithmetic encoding.
this number is used as a 32bit fixed point real number.
the point is fixed just before the first bit, so it is
always in the range [0,1)
low is also never allowed to be zero to avoid overflow
in the calculation (high-low+1)/total.
high == the high end of the range - 1 used for arithmetic encoding.
this number is used as a 32bit fixed point real number.
the point is fixed just before the first bit, so when we
interpret high as a real number then it is always in the
range [0,1)
the range for arithmetic encoding is always
[low,high + 0.9999999...) the 0.9999999... is why
high == real upper range - 1
!*/
public:
entropy_encoder_kernel_1 (
);
virtual ~entropy_encoder_kernel_1 (
);
void clear(
);
void set_stream (
std::ostream& out
);
bool stream_is_set (
) const;
std::ostream& get_stream (
) const;
void encode (
uint32 low_count,
uint32 high_count,
uint32 total
);
private:
void flush (
);
/*!
requires
out != 0 (i.e. there is a stream object to flush the data to
!*/
// restricted functions
entropy_encoder_kernel_1(entropy_encoder_kernel_1&); // copy constructor
entropy_encoder_kernel_1& operator=(entropy_encoder_kernel_1&); // assignment operator
// data members
const uint32 initial_low;
const uint32 initial_high;
std::ostream* out;
uint32 low;
uint32 high;
unsigned char buf;
uint32 buf_used;
std::streambuf* streambuf;
};
}
#ifdef NO_MAKEFILE
#include "entropy_encoder_kernel_1.cpp"
#endif
#endif // DLIB_ENTROPY_ENCODER_KERNEl_1_
// Copyright (C) 2004 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ENTROPY_ENCODER_KERNEL_2_CPp_
#define DLIB_ENTROPY_ENCODER_KERNEL_2_CPp_
#include "entropy_encoder_kernel_2.h"
#include <iostream>
#include <streambuf>
namespace dlib
{
// ----------------------------------------------------------------------------------------
entropy_encoder_kernel_2::
entropy_encoder_kernel_2(
) :
initial_low(0x00000001),
initial_high(0xffffffff),
out(0),
low(initial_low),
high(initial_high)
{
}
// ----------------------------------------------------------------------------------------
entropy_encoder_kernel_2::
~entropy_encoder_kernel_2 (
)
{
try {
if (out != 0)
{
flush();
}
} catch (...) {}
}
// ----------------------------------------------------------------------------------------
void entropy_encoder_kernel_2::
clear(
)
{
if (out != 0)
{
flush();
}
out = 0;
}
// ----------------------------------------------------------------------------------------
void entropy_encoder_kernel_2::
set_stream (
std::ostream& out_
)
{
if (out != 0)
{
// if a stream is currently set then flush the buffers to it before
// we switch to the new stream
flush();
}
out = &out_;
streambuf = out_.rdbuf();
// reset the encoder state
low = initial_low;
high = initial_high;
}
// ----------------------------------------------------------------------------------------
bool entropy_encoder_kernel_2::
stream_is_set (
) const
{
if (out != 0)
return true;
else
return false;
}
// ----------------------------------------------------------------------------------------
std::ostream& entropy_encoder_kernel_2::
get_stream (
) const
{
return *out;
}
// ----------------------------------------------------------------------------------------
void entropy_encoder_kernel_2::
encode (
uint32 low_count,
uint32 high_count,
uint32 total
)
{
// note that we must add one because of the convention that
// high == the real upper range minus 1
uint32 r = (high-low+1)/total;
// note that we must subtract 1 to preserve the convention that
// high == the real upper range - 1
high = low + r*high_count-1;
low = low + r*low_count;
while (true )
{
// if high and low don't have the same 8 high order bits
if ((high&0xFF000000) != (low&0xFF000000))
{
// if the distance between high and low is small and there aren't
// any bits we can roll off then force high and low to have common high
// order bits.
if ((high-low < 0x10000))
{
if (high-low > 0x1000)
{
high>>=1;
low>>=1;
high = low = high+low;
high += 0xFF;
low -= 0xFF;
}
else /**/
{
high>>=1;
low>>=1;
high = low = high+low;
}
}
else
{
// there are no bits to roll off and high and low are not
// too close so just quit the loop
break;
}
}
// else if there are 8 bits we can roll off
else
{
// write the 8 high order bits from low into buf
unsigned char buf = static_cast<unsigned char>(low>>24);
// roll off the bits we just wrote to buf
high <<= 8;
low <<= 8;
high |= 0xFF; // note that it is ok to add 0xFF to high here because
// of the convention that high == real upper range - 1.
// so that means that if we want to shift the upper range
// left by one then we must shift a one into high also
// since real upper range == high + 0.999999999...
// make sure low is never zero
if (low == 0)
low = 1;
// write buf to the output stream
if (streambuf->sputn(reinterpret_cast<char*>(&buf),1)==0)
{
throw std::ios_base::failure("error occured in the entropy_encoder object");
}
}
} // while (true)
}
// ----------------------------------------------------------------------------------------
void entropy_encoder_kernel_2::
flush (
)
{
// flush low to the output stream
unsigned char buf;
buf = static_cast<unsigned char>((low >> 24)&0xFF);
if (streambuf->sputn(reinterpret_cast<char*>(&buf),1) == 0)
throw std::ios_base::failure("error occured in the entropy_encoder object");
buf = static_cast<unsigned char>((low >> 16)&0xFF);
if (streambuf->sputn(reinterpret_cast<char*>(&buf),1)==0)
throw std::ios_base::failure("error occured in the entropy_encoder object");
buf = static_cast<unsigned char>((low >> 8)&0xFF);
if (streambuf->sputn(reinterpret_cast<char*>(&buf),1)==0)
throw std::ios_base::failure("error occured in the entropy_encoder object");
buf = static_cast<unsigned char>((low)&0xFF);
if (streambuf->sputn(reinterpret_cast<char*>(&buf),1)==0)
throw std::ios_base::failure("error occured in the entropy_encoder object");
// make sure the stream buffer flushes to its I/O channel
streambuf->pubsync();
// reset the encoder state
low = initial_low;
high = initial_high;
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_ENTROPY_ENCODER_KERNEL_2_CPp_
// Copyright (C) 2004 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ENTROPY_ENCODER_KERNEl_2_
#define DLIB_ENTROPY_ENCODER_KERNEl_2_
#include "../algs.h"
#include "entropy_encoder_kernel_abstract.h"
#include <iosfwd>
#include "../uintn.h"
namespace dlib
{
class entropy_encoder_kernel_2
{
/*!
GENERAL NOTES
this encoder is implemented using "range" coding
INITIAL VALUE
out == 0
initial_low == 0x00000001 (slightly more than zero)
initial_high == 0xffffffff (slightly less than one, 0.99999999976717)
low == initial_low
high == initial_high
CONVENTION
if (out != 0)
*out == get_stream()
true == stream_is_set()
streambuf == out->rdbuf()
else
false == stream_is_set()
low == the low end of the range used for arithmetic encoding.
this number is used as a 32bit fixed point real number.
the point is fixed just before the first bit, so it is
always in the range [0,1)
low is also never allowed to be zero to avoid overflow
in the calculation (high-low+1)/total.
high == the high end of the range - 1 used for arithmetic encoding.
this number is used as a 32bit fixed point real number.
the point is fixed just before the first bit, so when we
interpret high as a real number then it is always in the
range [0,1)
the range for arithmetic encoding is always
[low,high + 0.9999999...) the 0.9999999... is why
high == real upper range - 1
!*/
public:
entropy_encoder_kernel_2 (
);
virtual ~entropy_encoder_kernel_2 (
);
void clear(
);
void set_stream (
std::ostream& out
);
bool stream_is_set (
) const;
std::ostream& get_stream (
) const;
void encode (
uint32 low_count,
uint32 high_count,
uint32 total
);
private:
void flush (
);
/*!
requires
out != 0 (i.e. there is a stream object to flush the data to
!*/
// restricted functions
entropy_encoder_kernel_2(entropy_encoder_kernel_2&); // copy constructor
entropy_encoder_kernel_2& operator=(entropy_encoder_kernel_2&); // assignment operator
// data members
const uint32 initial_low;
const uint32 initial_high;
std::ostream* out;
uint32 low;
uint32 high;
std::streambuf* streambuf;
};
}
#ifdef NO_MAKEFILE
#include "entropy_encoder_kernel_2.cpp"
#endif
#endif // DLIB_ENTROPY_ENCODER_KERNEl_2_
// Copyright (C) 2003 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#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
- std::bad_alloc
!*/
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_
// Copyright (C) 2003 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ENTROPY_ENCODER_KERNEl_C_
#define DLIB_ENTROPY_ENCODER_KERNEl_C_
#include "entropy_encoder_kernel_abstract.h"
#include "../algs.h"
#include "../assert.h"
#include <iostream>
namespace dlib
{
template <
typename encoder
>
class entropy_encoder_kernel_c : public encoder
{
public:
std::ostream& get_stream (
) const;
void encode (
uint32 low_count,
uint32 high_count,
uint32 total
);
void flush (
);
};
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// member function definitions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
typename encoder
>
std::ostream& entropy_encoder_kernel_c<encoder>::
get_stream (
) const
{
// make sure requires clause is not broken
DLIB_CASSERT( this->stream_is_set() == true,
"\tstd::ostream& entropy_encoder::get_stream()"
<< "\n\tyou must set a stream for this object before you can get it"
<< "\n\tthis: " << this
);
// call the real function
return encoder::get_stream();
}
// ----------------------------------------------------------------------------------------
template <
typename encoder
>
void entropy_encoder_kernel_c<encoder>::
encode (
uint32 low_count,
uint32 high_count,
uint32 total
)
{
// make sure requires clause is not broken
DLIB_CASSERT( (0 < total) && (total < 65536) && (low_count < high_count) && (high_count <= total) &&
(this->stream_is_set() == true),
"\tvoid entropy_encoder::encode()"
<< "\n\trefer to the ensures clause for this function for further information"
<< "\n\tthis: " << this
<< "\n\ttotal: " << total
<< "\n\tlow_count: " << low_count
<< "\n\thigh_count: " << high_count
<< "\n\tis_stream_set(): " << (this->stream_is_set() ? "true" : "false" )
);
// call the real function
encoder::encode(low_count,high_count,total);
}
// ----------------------------------------------------------------------------------------
template <
typename encoder
>
void entropy_encoder_kernel_c<encoder>::
flush (
)
{
// make sure requires clause is not broken
DLIB_CASSERT( this->stream_is_set() == true,
"\tvoid entropy_encoder::flush()"
<< "\n\tyou must set a stream for this object before you can flush to it"
<< "\n\tthis: " << this
);
// call the real function
encoder::flush();
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_ENTROPY_ENCODER_KERNEl_C_
// Copyright (C) 2004 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ENTROPY_ENCODER_MODEl_
#define DLIB_ENTROPY_ENCODER_MODEl_
#include "entropy_encoder_model/entropy_encoder_model_kernel_1.h"
#include "entropy_encoder_model/entropy_encoder_model_kernel_2.h"
#include "entropy_encoder_model/entropy_encoder_model_kernel_3.h"
#include "entropy_encoder_model/entropy_encoder_model_kernel_4.h"
#include "entropy_encoder_model/entropy_encoder_model_kernel_5.h"
#include "entropy_encoder_model/entropy_encoder_model_kernel_6.h"
#include "entropy_encoder_model/entropy_encoder_model_kernel_c.h"
#include "conditioning_class.h"
#include "memory_manager.h"
#include "sliding_buffer.h"
namespace dlib
{
template <
unsigned long alphabet_size,
typename entropy_encoder
>
class entropy_encoder_model
{
entropy_encoder_model() {}
typedef typename conditioning_class<alphabet_size+1>::kernel_1a cc1;
typedef typename conditioning_class<alphabet_size+1>::kernel_2a cc2;
typedef typename conditioning_class<alphabet_size+1>::kernel_3a cc3;
typedef typename conditioning_class<alphabet_size+1>::kernel_4a cc4a;
typedef typename conditioning_class<alphabet_size+1>::kernel_4b cc4b;
typedef typename conditioning_class<alphabet_size+1>::kernel_4c cc4c;
typedef typename conditioning_class<alphabet_size+1>::kernel_4d cc4d;
public:
//----------- kernels ---------------
// kernel_1
typedef entropy_encoder_model_kernel_1<alphabet_size,entropy_encoder,cc1>
kernel_1a;
typedef entropy_encoder_model_kernel_c<kernel_1a>
kernel_1a_c;
typedef entropy_encoder_model_kernel_1<alphabet_size,entropy_encoder,cc2>
kernel_1b;
typedef entropy_encoder_model_kernel_c<kernel_1b>
kernel_1b_c;
typedef entropy_encoder_model_kernel_1<alphabet_size,entropy_encoder,cc3>
kernel_1c;
typedef entropy_encoder_model_kernel_c<kernel_1c>
kernel_1c_c;
// --------------------
// kernel_2
typedef entropy_encoder_model_kernel_2<alphabet_size,entropy_encoder,cc1,cc1>
kernel_2a;
typedef entropy_encoder_model_kernel_c<kernel_2a>
kernel_2a_c;
typedef entropy_encoder_model_kernel_2<alphabet_size,entropy_encoder,cc2,cc2>
kernel_2b;
typedef entropy_encoder_model_kernel_c<kernel_2b>
kernel_2b_c;
typedef entropy_encoder_model_kernel_2<alphabet_size,entropy_encoder,cc3,cc3>
kernel_2c;
typedef entropy_encoder_model_kernel_c<kernel_2c>
kernel_2c_c;
typedef entropy_encoder_model_kernel_2<alphabet_size,entropy_encoder,cc2,cc4b>
kernel_2d;
typedef entropy_encoder_model_kernel_c<kernel_2d>
kernel_2d_c;
// --------------------
// kernel_3
typedef entropy_encoder_model_kernel_3<alphabet_size,entropy_encoder,cc1,cc4b>
kernel_3a;
typedef entropy_encoder_model_kernel_c<kernel_3a>
kernel_3a_c;
typedef entropy_encoder_model_kernel_3<alphabet_size,entropy_encoder,cc2,cc4b>
kernel_3b;
typedef entropy_encoder_model_kernel_c<kernel_3b>
kernel_3b_c;
typedef entropy_encoder_model_kernel_3<alphabet_size,entropy_encoder,cc3,cc4b>
kernel_3c;
typedef entropy_encoder_model_kernel_c<kernel_3c>
kernel_3c_c;
// --------------------
// kernel_4
typedef entropy_encoder_model_kernel_4<alphabet_size,entropy_encoder,200000,4>
kernel_4a;
typedef entropy_encoder_model_kernel_c<kernel_4a>
kernel_4a_c;
typedef entropy_encoder_model_kernel_4<alphabet_size,entropy_encoder,1000000,5>
kernel_4b;
typedef entropy_encoder_model_kernel_c<kernel_4b>
kernel_4b_c;
// --------------------
// kernel_5
typedef entropy_encoder_model_kernel_5<alphabet_size,entropy_encoder,200000,4>
kernel_5a;
typedef entropy_encoder_model_kernel_c<kernel_5a>
kernel_5a_c;
typedef entropy_encoder_model_kernel_5<alphabet_size,entropy_encoder,1000000,5>
kernel_5b;
typedef entropy_encoder_model_kernel_c<kernel_5b>
kernel_5b_c;
typedef entropy_encoder_model_kernel_5<alphabet_size,entropy_encoder,2500000,7>
kernel_5c;
typedef entropy_encoder_model_kernel_c<kernel_5c>
kernel_5c_c;
// --------------------
// kernel_6
typedef entropy_encoder_model_kernel_6<alphabet_size,entropy_encoder>
kernel_6a;
typedef entropy_encoder_model_kernel_c<kernel_6a>
kernel_6a_c;
};
}
#endif // DLIB_ENTROPY_ENCODER_MODEl_
// Copyright (C) 2004 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ENTROPY_ENCODER_MODEL_KERNEl_1_
#define DLIB_ENTROPY_ENCODER_MODEL_KERNEl_1_
#include "../algs.h"
#include "entropy_encoder_model_kernel_abstract.h"
#include "../assert.h"
namespace dlib
{
template <
unsigned long alphabet_size,
typename entropy_encoder,
typename cc
>
class entropy_encoder_model_kernel_1
{
/*!
REQUIREMENTS ON cc
cc is an implementation of conditioning_class/conditioning_class_kernel_abstract.h
cc::get_alphabet_size() == alphabet_size+1
INITIAL VALUE
Initially this object's finite context model is empty
CONVENTION
&get_entropy_encoder() == coder
&order_0.get_global_state() == &gs
This is an order-0 model. The last symbol in the order-0 context is
an escape into the order minus 1 context.
!*/
public:
typedef entropy_encoder entropy_encoder_type;
entropy_encoder_model_kernel_1 (
entropy_encoder& coder
);
virtual ~entropy_encoder_model_kernel_1 (
);
inline void clear(
);
inline void encode (
unsigned long symbol
);
entropy_encoder& get_entropy_encoder (
) { return coder; }
static unsigned long get_alphabet_size (
) { return alphabet_size; }
private:
entropy_encoder& coder;
typename cc::global_state_type gs;
cc order_0;
// restricted functions
entropy_encoder_model_kernel_1(entropy_encoder_model_kernel_1<alphabet_size,entropy_encoder,cc>&); // copy constructor
entropy_encoder_model_kernel_1<alphabet_size,entropy_encoder,cc>& operator=(entropy_encoder_model_kernel_1<alphabet_size,entropy_encoder,cc>&); // assignment operator
};
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// member function definitions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
typename cc
>
entropy_encoder_model_kernel_1<alphabet_size,entropy_encoder,cc>::
entropy_encoder_model_kernel_1 (
entropy_encoder& coder_
) :
coder(coder_),
order_0(gs)
{
COMPILE_TIME_ASSERT( 1 < alphabet_size && alphabet_size < 65535 );
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
typename cc
>
entropy_encoder_model_kernel_1<alphabet_size,entropy_encoder,cc>::
~entropy_encoder_model_kernel_1 (
)
{
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
typename cc
>
void entropy_encoder_model_kernel_1<alphabet_size,entropy_encoder,cc>::
clear(
)
{
order_0.clear();
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
typename cc
>
void entropy_encoder_model_kernel_1<alphabet_size,entropy_encoder,cc>::
encode (
unsigned long symbol
)
{
unsigned long low_count = 0, high_count = 0, total_count = 0;
// if we have seen this symbol in the order-0 context
if (order_0.get_range(symbol,low_count,high_count,total_count))
{
// update the count for this symbol
order_0.increment_count(symbol,2);
// encode this symbol
coder.encode(low_count,high_count,total_count);
return;
}
// if we are here then the symbol does not appear in the order-0 context
// since we have never seen the current symbol in this context
// escape from order-0 context
order_0.get_range(alphabet_size,low_count,high_count,total_count);
coder.encode(low_count,high_count,total_count);
// increment the count for the escape symbol
order_0.increment_count(alphabet_size);
// update the count for this symbol
order_0.increment_count(symbol,2);
// use order minus one context
coder.encode(symbol,symbol+1,alphabet_size);
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_ENTROPY_ENCODER_MODEL_KERNEl_1_
// Copyright (C) 2004 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ENTROPY_ENCODER_MODEL_KERNEl_2_
#define DLIB_ENTROPY_ENCODER_MODEL_KERNEl_2_
#include "../algs.h"
#include "entropy_encoder_model_kernel_abstract.h"
#include "../assert.h"
namespace dlib
{
template <
unsigned long alphabet_size,
typename entropy_encoder,
typename cc,
typename ccbig
>
class entropy_encoder_model_kernel_2
{
/*!
REQUIREMENTS ON cc
cc is an implementation of conditioning_class/conditioning_class_kernel_abstract.h
cc::get_alphabet_size() == alphabet_size+1
this will be used for the order-0 context
REQUIREMENTS ON ccbig
ccbig is an implementation of conditioning_class/conditioning_class_kernel_abstract.h
ccbig::get_alphabet_size() == alphabet_size+1
this will be used for the order-1 context
INITIAL VALUE
Initially this object's finite context model is empty
previous_symbol == 0
CONVENTION
&get_entropy_encoder() == coder
&order_0.get_global_state() == &gs
&order_1[i]->get_global_state() == &gsbig
This is an order-1-0 model. The last symbol in the order-0 and order-1
context is an escape into the lower context.
previous_symbol == the last symbol seen
!*/
public:
typedef entropy_encoder entropy_encoder_type;
entropy_encoder_model_kernel_2 (
entropy_encoder& coder
);
virtual ~entropy_encoder_model_kernel_2 (
);
inline void clear(
);
inline void encode (
unsigned long symbol
);
entropy_encoder& get_entropy_encoder (
) { return coder; }
static unsigned long get_alphabet_size (
) { return alphabet_size; }
private:
entropy_encoder& coder;
typename cc::global_state_type gs;
typename ccbig::global_state_type gsbig;
cc order_0;
ccbig* order_1[alphabet_size];
unsigned long previous_symbol;
// restricted functions
entropy_encoder_model_kernel_2(entropy_encoder_model_kernel_2<alphabet_size,entropy_encoder,cc,ccbig>&); // copy constructor
entropy_encoder_model_kernel_2<alphabet_size,entropy_encoder,cc,ccbig>& operator=(entropy_encoder_model_kernel_2<alphabet_size,entropy_encoder,cc,ccbig>&); // assignment operator
};
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// member function definitions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
typename cc,
typename ccbig
>
entropy_encoder_model_kernel_2<alphabet_size,entropy_encoder,cc,ccbig>::
entropy_encoder_model_kernel_2 (
entropy_encoder& coder_
) :
coder(coder_),
order_0(gs),
previous_symbol(0)
{
COMPILE_TIME_ASSERT( 1 < alphabet_size && alphabet_size < 65535 );
unsigned long i;
try
{
for (i = 0; i < alphabet_size; ++i)
{
order_1[i] = new ccbig(gsbig);
}
}
catch (...)
{
for (unsigned long j = 0; j < i; ++j)
{
delete order_1[j];
}
throw;
}
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
typename cc,
typename ccbig
>
entropy_encoder_model_kernel_2<alphabet_size,entropy_encoder,cc,ccbig>::
~entropy_encoder_model_kernel_2 (
)
{
for (unsigned long i = 0; i < alphabet_size; ++i)
{
delete order_1[i];
}
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
typename cc,
typename ccbig
>
void entropy_encoder_model_kernel_2<alphabet_size,entropy_encoder,cc,ccbig>::
clear(
)
{
previous_symbol = 0;
order_0.clear();
for (unsigned long i = 0; i < alphabet_size; ++i)
{
order_1[i]->clear();
}
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
typename cc,
typename ccbig
>
void entropy_encoder_model_kernel_2<alphabet_size,entropy_encoder,cc,ccbig>::
encode (
unsigned long symbol
)
{
unsigned long low_count = 0, high_count = 0, total_count = 0;
ccbig& context = *order_1[previous_symbol];
// if we have seen this symbol in the order-1 context
if (context.get_range(symbol,low_count,high_count,total_count))
{
// update the count for this symbol
context.increment_count(symbol,2);
// encode this symbol
coder.encode(low_count,high_count,total_count);
previous_symbol = symbol;
return;
}
// we didn't find the symbol in the order-1 context so we must escape to a
// lower context.
// escape to the order-0 context
context.get_range(alphabet_size,low_count,high_count,total_count);
coder.encode(low_count,high_count,total_count);
// increment counts for the escape symbol and the current symbol
context.increment_count(alphabet_size);
context.increment_count(symbol,2);
previous_symbol = symbol;
// if we have seen this symbol in the order-0 context
if (order_0.get_range(symbol,low_count,high_count,total_count))
{
// update the count for this symbol
order_0.increment_count(symbol,2);
// encode this symbol
coder.encode(low_count,high_count,total_count);
return;
}
// if we are here then the symbol does not appear in the order-0 context
// since we have never seen the current symbol in this context
// escape from order-0 context
order_0.get_range(alphabet_size,low_count,high_count,total_count);
coder.encode(low_count,high_count,total_count);
// increment the count for the escape symbol
order_0.increment_count(alphabet_size);
// update the count for this symbol
order_0.increment_count(symbol,2);
// use order minus one context
coder.encode(symbol,symbol+1,alphabet_size);
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_ENTROPY_ENCODER_MODEL_KERNEl_2_
// Copyright (C) 2004 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ENTROPY_ENCODER_MODEL_KERNEl_3_
#define DLIB_ENTROPY_ENCODER_MODEL_KERNEl_3_
#include "../algs.h"
#include "entropy_encoder_model_kernel_abstract.h"
#include "../assert.h"
namespace dlib
{
template <
unsigned long alphabet_size,
typename entropy_encoder,
typename cc,
typename cc_high
>
class entropy_encoder_model_kernel_3
{
/*!
REQUIREMENTS ON cc
cc is an implementation of conditioning_class/conditioning_class_kernel_abstract.h
cc::get_alphabet_size() == alphabet_size+1
REQUIREMENTS ON cc_high
cc_high is an implementation of conditioning_class/conditioning_class_kernel_abstract.h
cc_high::get_alphabet_size() == alphabet_size+1
INITIAL VALUE
- Initially this object's finite context model is empty
- previous_symbol == 0
- previous_symbol2 == 0
- order_1 == pointer to an array of alphabet_size elements
- order_2 == pointer to an array of alphabet_size*alphabet_size elements
- order_2[i] == 0
CONVENTION
&get_entropy_encoder() == coder
&order_0.get_global_state() == &gs
&order_1[i]->get_global_state() == &gs
if (order_2[i] != 0) then
&order_2[i]->get_global_state() == &gs_high
This is an order-2-1-0 model. The last symbol in the order-2, order-1 and
order-0 contexts is an escape into the lower context.
previous_symbol == the last symbol seen
previous_symbol2 == the symbol we saw before previous_symbol
!*/
public:
typedef entropy_encoder entropy_encoder_type;
entropy_encoder_model_kernel_3 (
entropy_encoder& coder
);
virtual ~entropy_encoder_model_kernel_3 (
);
inline void clear(
);
inline void encode (
unsigned long symbol
);
entropy_encoder& get_entropy_encoder (
) { return coder; }
static unsigned long get_alphabet_size (
) { return alphabet_size; }
private:
entropy_encoder& coder;
typename cc::global_state_type gs;
typename cc_high::global_state_type gs_high;
cc order_0;
cc** order_1;
unsigned long previous_symbol;
cc_high** order_2;
unsigned long previous_symbol2;
// restricted functions
entropy_encoder_model_kernel_3(entropy_encoder_model_kernel_3&); // copy constructor
entropy_encoder_model_kernel_3& operator=(entropy_encoder_model_kernel_3&); // assignment operator
};
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// member function definitions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
typename cc,
typename cc_high
>
entropy_encoder_model_kernel_3<alphabet_size,entropy_encoder,cc,cc_high>::
entropy_encoder_model_kernel_3 (
entropy_encoder& coder_
) :
coder(coder_),
order_0(gs),
order_1(0),
previous_symbol(0),
order_2(0),
previous_symbol2(0)
{
COMPILE_TIME_ASSERT( 1 < alphabet_size && alphabet_size < 65535 );
try
{
order_1 = new cc*[alphabet_size];
order_2 = new cc_high*[alphabet_size*alphabet_size];
}
catch (...)
{
if (order_1) delete [] order_1;
if (order_2) delete [] order_2;
throw;
}
unsigned long i;
for (i = 0; i < (alphabet_size*alphabet_size); ++i)
{
order_2[i] = 0;
}
try
{
for (i = 0; i < alphabet_size; ++i)
{
order_1[i] = new cc(gs);
}
}
catch (...)
{
for (unsigned long j = 0; j < i; ++j)
{
delete order_1[j];
}
throw;
}
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
typename cc,
typename cc_high
>
entropy_encoder_model_kernel_3<alphabet_size,entropy_encoder,cc,cc_high>::
~entropy_encoder_model_kernel_3 (
)
{
for (unsigned long i = 0; i < alphabet_size; ++i)
{
delete order_1[i];
}
for (unsigned long i = 0; i < alphabet_size*alphabet_size; ++i)
{
if (order_2[i] != 0)
delete order_2[i];
}
delete [] order_1;
delete [] order_2;
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
typename cc,
typename cc_high
>
void entropy_encoder_model_kernel_3<alphabet_size,entropy_encoder,cc,cc_high>::
clear(
)
{
previous_symbol = 0;
previous_symbol2 = 0;
order_0.clear();
for (unsigned long i = 0; i < alphabet_size; ++i)
{
order_1[i]->clear();
}
for (unsigned long i = 0; i < alphabet_size*alphabet_size; ++i)
{
if (order_2[i] != 0)
{
delete order_2[i];
order_2[i] = 0;
}
}
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
typename cc,
typename cc_high
>
void entropy_encoder_model_kernel_3<alphabet_size,entropy_encoder,cc,cc_high>::
encode (
unsigned long symbol
)
{
unsigned long low_count = 0, high_count = 0, total_count = 0;
// order-2 context stuff
{
unsigned long temp = previous_symbol + (previous_symbol2 * alphabet_size);
previous_symbol2 = previous_symbol;
if (order_2[temp] != 0)
{
if (order_2[temp]->get_range(symbol,low_count,high_count,total_count))
{
// there was an entry for this symbol in this context
// update the count for this symbol
order_2[temp]->increment_count(symbol,2);
// encode this symbol
coder.encode(low_count,high_count,total_count);
previous_symbol = symbol;
return;
}
// there was no entry for this symbol in this context so we must
// escape to order-1
// escape to the order-1 context
order_2[temp]->get_range(alphabet_size,low_count,high_count,total_count);
coder.encode(low_count,high_count,total_count);
// increment the count for the escape symbol
order_2[temp]->increment_count(alphabet_size);
}
else
{
order_2[temp] = new cc_high(gs_high);
// in this case the decoder knows to escape to order-1 because
// there was no conditioning_class object in this context yet.
// so we don't need to actually write the escape symbol
}
// update the count for this symbol in this context
order_2[temp]->increment_count(symbol,2);
}
// order-1 context stuff
{
cc& context = *order_1[previous_symbol];
// if we have seen this symbol in the order-1 context
if (context.get_range(symbol,low_count,high_count,total_count))
{
// update the count for this symbol
context.increment_count(symbol,2);
// encode this symbol
coder.encode(low_count,high_count,total_count);
previous_symbol = symbol;
return;
}
// we didn't find the symbol in the order-1 context so we must escape to a
// lower context.
// escape to the order-0 context
context.get_range(alphabet_size,low_count,high_count,total_count);
coder.encode(low_count,high_count,total_count);
// increment counts for the escape symbol and the current symbol
context.increment_count(alphabet_size);
context.increment_count(symbol,2);
}
previous_symbol = symbol;
// if we have seen this symbol in the order-0 context
if (order_0.get_range(symbol,low_count,high_count,total_count))
{
// update the count for this symbol
order_0.increment_count(symbol,2);
// encode this symbol
coder.encode(low_count,high_count,total_count);
return;
}
// if we are here then the symbol does not appear in the order-0 context
// since we have never seen the current symbol in this context
// escape from order-0 context
order_0.get_range(alphabet_size,low_count,high_count,total_count);
coder.encode(low_count,high_count,total_count);
// increment the count for the escape symbol
order_0.increment_count(alphabet_size);
// update the count for this symbol
order_0.increment_count(symbol,2);
// use order minus one context
coder.encode(symbol,symbol+1,alphabet_size);
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_ENTROPY_ENCODER_MODEL_KERNEl_3_
// Copyright (C) 2005 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ENTROPY_ENCODER_MODEL_KERNEl_4_
#define DLIB_ENTROPY_ENCODER_MODEL_KERNEl_4_
#include "../algs.h"
#include "entropy_encoder_model_kernel_abstract.h"
#include "../assert.h"
namespace dlib
{
namespace eemk4
{
struct node
{
node* next;
node* child_context;
node* parent_context;
unsigned short symbol;
unsigned short count;
unsigned short total;
unsigned short escapes;
};
}
template <
unsigned long alphabet_size,
typename entropy_encoder,
unsigned long total_nodes,
unsigned long order
>
class entropy_encoder_model_kernel_4
{
/*!
REQUIREMENTS ON total_nodes
- 4096 < total_nodes
- this is the total number of nodes that we will use in the tree
REQUIREMENTS ON order
- 0 <= order
- this is the maximum depth-1 the tree will be allowed to go (note
that the root level is depth 0).
GENERAL NOTES
This implementation follows more or less the implementation
strategy laid out by Alistair Moffat in his paper
Implementing the PPM data compression scheme. Published in IEEE
Transactions on Communications, 38(11):1917-1921, 1990.
The escape method used will be method D.
INITIAL VALUE
- root == pointer to an array of total_nodes nodes
- next_node == 1
- cur == root
- cur_order = 0
- root->next == 0
- root->parent_context == 0
- root->child_context == 0
- root->escapes == 0
- root->total == 0
CONVENTION
- &get_entropy_encoder() == coder
- root == pointer to an array of total_nodes nodes.
this is also the root of the tree.
- if (next_node < total_nodes) then
- next_node == the next node in root that has not yet been allocated
- root->next == 0
- root->parent_context == 0
- for every node in the tree:
{
- NOTATION:
- The "context" of a node is the string of symbols seen
when you go from the root of the tree down (down though
child context pointers) to the node, including the symbol at
the node itself. (note that the context of the root node
is "" or the empty string)
- A set of nodes is in the same "context set" if all the node's
contexts are of length n and all the node's contexts share
the same prefix of length n-1.
- The "child context set" of a node is a set of nodes with
contexts that are one symbol longer and prefixed by the node's
context. For example, if a node has a context "abc" then the
nodes for contexts "abca", "abcb", "abcc", etc... are all in
the child context set of the node.
- The "parent context" of a node is the context that is one
symbol shorter than the node's context and includes the
symbol in the node. So the parent context of a node with
context "abcd" would be the context "bcd".
- if (next != 0) then
- next == pointer to the next node in the same context set
- if (child_context != 0) then
- child_context == pointer to the first node of the child
context set for this node.
- if (parent_context != 0) then
- parent_context == pointer to the parent context of this node.
- else
- this node is the root node of the tree
- if (this is not the root node) then
- symbol == the symbol represented with this node
- count == the number of times this symbol has been seen in its
parent context.
- else
- the root doesn't have a symbol. i.e. the context for the
root node is "" or the empty string.
- total == The sum of the counts of all the nodes
in the child context set + escapes.
- escapes == the escape count for the context represented
by the node.
}
- cur_order < order
- cur_order == the depth of the node cur in the tree.
(note that the root node has depth 0)
- cur == pointer to the node in the tree who's context matches
the most recent symbols we have seen.
!*/
typedef eemk4::node node;
public:
typedef entropy_encoder entropy_encoder_type;
entropy_encoder_model_kernel_4 (
entropy_encoder& coder
);
virtual ~entropy_encoder_model_kernel_4 (
);
inline void clear(
);
inline void encode (
unsigned long symbol
);
entropy_encoder& get_entropy_encoder (
) { return coder; }
static unsigned long get_alphabet_size (
) { return alphabet_size; }
private:
inline eemk4::node* allocate_node (
);
/*!
requires
- space_left() == true
ensures
- returns a pointer to a new node
!*/
inline void destroy_tree (
);
/*!
ensures
- deallocates all nodes except the root
- #root->child_context == 0
- #root->escapes == 0
- #root->total == 0
- #cur == root
- #cur_order == 0
!*/
inline bool space_left (
) const;
/*!
ensures
- returns true if there is at least 1 free node left.
- returns false otherwise
!*/
inline void scale_counts (
node* n
);
/*!
ensures
- divides all the counts in the child context set of n by 2.
- none of the nodes in the child context set will have a count of 0
!*/
unsigned long next_node;
entropy_encoder& coder;
node* root;
node* cur;
unsigned long cur_order;
// restricted functions
entropy_encoder_model_kernel_4(entropy_encoder_model_kernel_4<alphabet_size,entropy_encoder,total_nodes,order>&); // copy constructor
entropy_encoder_model_kernel_4<alphabet_size,entropy_encoder,total_nodes,order>& operator=(entropy_encoder_model_kernel_4<alphabet_size,entropy_encoder,total_nodes,order>&); // assignment operator
};
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// member function definitions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
unsigned long total_nodes,
unsigned long order
>
entropy_encoder_model_kernel_4<alphabet_size,entropy_encoder,total_nodes,order>::
entropy_encoder_model_kernel_4 (
entropy_encoder& coder_
) :
next_node(1),
coder(coder_),
cur_order(0)
{
COMPILE_TIME_ASSERT( 1 < alphabet_size && alphabet_size < 65535 );
COMPILE_TIME_ASSERT( 4096 < total_nodes );
root = new node[total_nodes];
cur = root;
root->child_context = 0;
root->escapes = 0;
root->next = 0;
root->parent_context = 0;
root->total = 0;
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
unsigned long total_nodes,
unsigned long order
>
entropy_encoder_model_kernel_4<alphabet_size,entropy_encoder,total_nodes,order>::
~entropy_encoder_model_kernel_4 (
)
{
delete [] root;
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
unsigned long total_nodes,
unsigned long order
>
void entropy_encoder_model_kernel_4<alphabet_size,entropy_encoder,total_nodes,order>::
clear(
)
{
destroy_tree();
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
unsigned long total_nodes,
unsigned long order
>
void entropy_encoder_model_kernel_4<alphabet_size,entropy_encoder,total_nodes,order>::
encode (
unsigned long sym
)
{
unsigned short symbol = static_cast<unsigned short>(sym);
node* temp = cur;
cur = 0;
unsigned short low_count, high_count, total_count;
node* new_node = 0;
// local_order will track the level of temp in the tree
unsigned long local_order = cur_order;
while (true)
{
high_count = 0;
if (space_left())
{
total_count = temp->total;
if (total_count > 0)
{
// check if we need to scale the counts
if (total_count > 10000)
{
scale_counts(temp);
total_count = temp->total;
}
// find either the symbol we are looking for or the
// end of the context set
node* n = temp->child_context;
node* last = 0;
while (true)
{
high_count += n->count;
if (n->symbol == symbol || n->next == 0)
break;
last = n;
n = n->next;
}
low_count = high_count - n->count;
// if we found the symbol
if (n->symbol == symbol)
{
if (new_node != 0)
{
new_node->parent_context = n;
}
coder.encode(low_count,high_count,total_count);
n->count += 8;
temp->total += 8;
// move this node to the front
if (last)
{
last->next = n->next;
n->next = temp->child_context;
temp->child_context = n;
}
if (cur == 0)
{
if (local_order < order)
{
cur_order = local_order+1;
cur = n;
}
else
{
cur = n->parent_context;
cur_order = local_order;
}
}
break;
}
// if we hit the end of the context set without finding the symbol
else
{
if (new_node != 0)
{
new_node->parent_context = allocate_node();
new_node = new_node->parent_context;
}
else
{
new_node = allocate_node();
}
n->next = new_node;
// write an escape to a lower context
coder.encode(high_count,total_count,total_count);
}
}
else // if (total_count == 0)
{
// this means that temp->child_context == 0 so we should make
// a new node here.
if (new_node != 0)
{
new_node->parent_context = allocate_node();
new_node = new_node->parent_context;
}
else
{
new_node = allocate_node();
}
temp->child_context = new_node;
}
if (cur == 0 && local_order < order)
{
cur = new_node;
cur_order = local_order+1;
}
// fill out the new node
new_node->child_context = 0;
new_node->count = 4;
new_node->escapes = 0;
new_node->next = 0;
new_node->symbol = static_cast<unsigned short>(symbol);
new_node->total = 0;
temp->escapes += 4;
temp->total += 8;
if (temp != root)
{
temp = temp->parent_context;
--local_order;
continue;
}
// since this is the root we are going to the order-(-1) context
// so we can just take care of that here.
new_node->parent_context = root;
coder.encode(symbol,symbol+1,alphabet_size);
if (cur == 0)
{
cur = root;
cur_order = 0;
}
break;
}
else
{
// there isn't enough space so we should rebuild the tree
destroy_tree();
temp = cur;
local_order = cur_order;
cur = 0;
new_node = 0;
}
} // while (true)
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// private member function definitions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
unsigned long total_nodes,
unsigned long order
>
eemk4::node* entropy_encoder_model_kernel_4<alphabet_size,entropy_encoder,total_nodes,order>::
allocate_node (
)
{
node* temp;
temp = root + next_node;
++next_node;
return temp;
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
unsigned long total_nodes,
unsigned long order
>
void entropy_encoder_model_kernel_4<alphabet_size,entropy_encoder,total_nodes,order>::
destroy_tree (
)
{
next_node = 1;
root->child_context = 0;
root->escapes = 0;
root->total = 0;
cur = root;
cur_order = 0;
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
unsigned long total_nodes,
unsigned long order
>
bool entropy_encoder_model_kernel_4<alphabet_size,entropy_encoder,total_nodes,order>::
space_left (
) const
{
return (next_node < total_nodes);
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
unsigned long total_nodes,
unsigned long order
>
void entropy_encoder_model_kernel_4<alphabet_size,entropy_encoder,total_nodes,order>::
scale_counts (
node* temp
)
{
if (temp->escapes > 1)
temp->escapes >>= 1;
temp->total = temp->escapes;
node* n = temp->child_context;
while (n != 0)
{
if (n->count > 1)
n->count >>= 1;
temp->total += n->count;
n = n->next;
}
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_ENTROPY_ENCODER_MODEL_KERNEl_4_
// Copyright (C) 2005 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ENTROPY_ENCODER_MODEL_KERNEl_5_
#define DLIB_ENTROPY_ENCODER_MODEL_KERNEl_5_
#include "../algs.h"
#include "entropy_encoder_model_kernel_abstract.h"
#include "../assert.h"
namespace dlib
{
namespace eemk5
{
struct node
{
node* next;
node* child_context;
node* parent_context;
unsigned short symbol;
unsigned short count;
unsigned short total;
unsigned short escapes;
};
}
template <
unsigned long alphabet_size,
typename entropy_encoder,
unsigned long total_nodes,
unsigned long order
>
class entropy_encoder_model_kernel_5
{
/*!
REQUIREMENTS ON total_nodes
- 4096 < total_nodes
- this is the total number of nodes that we will use in the tree
REQUIREMENTS ON order
- 0 <= order
- this is the maximum depth-1 the tree will be allowed to go (note
that the root level is depth 0).
GENERAL NOTES
This implementation follows more or less the implementation
strategy laid out by Alistair Moffat in his paper
Implementing the PPM data compression scheme. Published in IEEE
Transactions on Communications, 38(11):1917-1921, 1990.
The escape method used will be method D.
This also uses Dmitry Shkarin's Information Inheritance scheme.
(described in "PPM: one step to practicality" and "Improving the
Efficiency of the PPM Algorithm")
INITIAL VALUE
- root == pointer to an array of total_nodes nodes
- next_node == 1
- cur == root
- cur_order = 0
- root->next == 0
- root->parent_context == 0
- root->child_context == 0
- root->escapes == 0
- root->total == 0
- stack_size == 0
- exc_used == false
- for all i: exc[i] == 0
CONVENTION
- pop() == stack[stack_size-1].n and stack[stack_size-1].nc
- exc_used == something_is_excluded()
- is_excluded(symbol) == bit symbol&0x1F from exc[symbol>>5]
- &get_entropy_encoder() == coder
- root == pointer to an array of total_nodes nodes.
this is also the root of the tree.
- if (next_node < total_nodes) then
- next_node == the next node in root that has not yet been allocated
- root->next == 0
- root->parent_context == 0
- for every node in the tree:
{
- NOTATION:
- The "context" of a node is the string of symbols seen
when you go from the root of the tree down (down though
child context pointers) to the node, including the symbol at
the node itself. (note that the context of the root node
is "" or the empty string)
- A set of nodes is in the same "context set" if all the node's
contexts are of length n and all the node's contexts share
the same prefix of length n-1.
- The "child context set" of a node is a set of nodes with
contexts that are one symbol longer and prefixed by the node's
context. For example, if a node has a context "abc" then the
nodes for contexts "abca", "abcb", "abcc", etc... are all in
the child context set of the node.
- The "parent context" of a node is the context that is one
symbol shorter than the node's context and includes the
symbol in the node. So the parent context of a node with
context "abcd" would be the context "bcd".
- if (next != 0) then
- next == pointer to the next node in the same context set
- if (child_context != 0) then
- child_context == pointer to the first node of the child
context set for this node.
- escapes > 0
- if (parent_context != 0) then
- parent_context == pointer to the parent context of this node.
- else
- this node is the root node of the tree
- if (this is not the root node) then
- symbol == the symbol represented with this node
- count == the number of times this symbol has been seen in its
parent context.
- else
- the root doesn't have a symbol. i.e. the context for the
root node is "" or the empty string.
- total == The sum of the counts of all the nodes
in the child context set + escapes.
- escapes == the escape count for the context represented
by the node.
- count > 0
}
- cur_order < order
- cur_order == the depth of the node cur in the tree.
(note that the root node has depth 0)
- cur == pointer to the node in the tree who's context matches
the most recent symbols we have seen.
!*/
typedef eemk5::node node;
public:
typedef entropy_encoder entropy_encoder_type;
entropy_encoder_model_kernel_5 (
entropy_encoder& coder
);
virtual ~entropy_encoder_model_kernel_5 (
);
inline void clear(
);
inline void encode (
unsigned long symbol
);
entropy_encoder& get_entropy_encoder (
) { return coder; }
static unsigned long get_alphabet_size (
) { return alphabet_size; }
private:
inline eemk5::node* allocate_node (
);
/*!
requires
- space_left() == true
ensures
- returns a pointer to a new node
!*/
inline bool space_left (
) const;
/*!
ensures
- returns true if there is at least 1 free node left.
- returns false otherwise
!*/
inline void exclude (
unsigned short symbol
);
/*!
ensures
- #is_excluded(symbol) == true
- #something_is_excluded() == true
!*/
inline bool something_is_excluded (
);
/*!
ensures
- returns true if some symbol has been excluded.
returns false otherwise
!*/
inline bool is_excluded (
unsigned short symbol
);
/*!
ensures
- if (symbol has been excluded) then
- returns true
- else
- returns false
!*/
inline void clear_exclusions (
);
/*!
ensures
- for all symbols #is_excluded(symbol) == false
- #something_is_excluded() == true
!*/
inline void scale_counts (
node* n
);
/*!
ensures
- divides all the counts in the child context set of n by 2.
- none of the nodes in the child context set will have a count of 0
!*/
inline void push (
node* n,
node* nc
);
/*!
requires
- stack_size < order
ensures
- #pop(a,b): a == n && b == nc
!*/
inline void pop (
node*& n,
node*& nc
);
/*!
requires
- stack_size > 0
ensures
- returns the two nodes at the top of the stack
!*/
struct nodes
{
node* n;
node* nc;
};
unsigned long next_node;
entropy_encoder& coder;
node* root;
node* cur;
unsigned long cur_order;
unsigned long exc[alphabet_size/32+1];
bool exc_used;
nodes stack[order+1];
unsigned long stack_size;
// restricted functions
entropy_encoder_model_kernel_5(entropy_encoder_model_kernel_5<alphabet_size,entropy_encoder,total_nodes,order>&); // copy constructor
entropy_encoder_model_kernel_5<alphabet_size,entropy_encoder,total_nodes,order>& operator=(entropy_encoder_model_kernel_5<alphabet_size,entropy_encoder,total_nodes,order>&); // assignment operator
};
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// member function definitions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
unsigned long total_nodes,
unsigned long order
>
entropy_encoder_model_kernel_5<alphabet_size,entropy_encoder,total_nodes,order>::
entropy_encoder_model_kernel_5 (
entropy_encoder& coder_
) :
next_node(1),
coder(coder_),
cur_order(0),
stack_size(0)
{
COMPILE_TIME_ASSERT( 1 < alphabet_size && alphabet_size < 65535 );
COMPILE_TIME_ASSERT( 4096 < total_nodes );
root = new node[total_nodes];
cur = root;
root->child_context = 0;
root->escapes = 0;
root->next = 0;
root->parent_context = 0;
root->total = 0;
clear_exclusions();
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
unsigned long total_nodes,
unsigned long order
>
entropy_encoder_model_kernel_5<alphabet_size,entropy_encoder,total_nodes,order>::
~entropy_encoder_model_kernel_5 (
)
{
delete [] root;
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
unsigned long total_nodes,
unsigned long order
>
void entropy_encoder_model_kernel_5<alphabet_size,entropy_encoder,total_nodes,order>::
clear(
)
{
next_node = 1;
root->child_context = 0;
root->escapes = 0;
root->total = 0;
cur = root;
cur_order = 0;
stack_size = 0;
clear_exclusions();
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
unsigned long total_nodes,
unsigned long order
>
void entropy_encoder_model_kernel_5<alphabet_size,entropy_encoder,total_nodes,order>::
encode (
unsigned long sym
)
{
unsigned short symbol = static_cast<unsigned short>(sym);
node* temp = cur;
cur = 0;
unsigned short low_count, high_count, total_count;
node* new_node = 0;
// local_order will track the level of temp in the tree
unsigned long local_order = cur_order;
unsigned short c; // c == t(a|sk)
unsigned short t; // t == T(sk)
if (something_is_excluded())
clear_exclusions();
while (true)
{
low_count = 0;
high_count = 0;
if (space_left())
{
total_count = temp->total;
if (total_count > 0)
{
// check if we need to scale the counts
if (total_count > 10000)
{
scale_counts(temp);
total_count = temp->total;
}
// find the symbol we are looking for and put a pointer to it
// into found_symbol. If it isn't found then found_symbol == 0.
// also, low_count and high_count will be correctly set.
node* n = temp->child_context;
node* found_symbol = 0;
node* last = 0;
if (something_is_excluded())
{
node* templast = 0;
while (true)
{
if (is_excluded(n->symbol) == false)
{
exclude(n->symbol);
if (found_symbol == 0)
{
high_count += n->count;
if (n->symbol == symbol)
{
found_symbol = n;
last = templast;
low_count = high_count - n->count;
}
}
}
else
{
total_count -= n->count;
}
if (n->next == 0)
break;
templast = n;
n = n->next;
}
}
else
{
while (true)
{
high_count += n->count;
exclude(n->symbol);
if (n->symbol == symbol)
{
found_symbol = n;
low_count = high_count - n->count;
break;
}
if (n->next == 0)
break;
last = n;
n = n->next;
}
}
// if we found the symbol
if (found_symbol)
{
n = found_symbol;
if (new_node != 0)
{
new_node->parent_context = found_symbol;
}
coder.encode(low_count,high_count,total_count);
c = n->count += 8;
t = temp->total += 8;
// move this node to the front
if (last)
{
last->next = n->next;
n->next = temp->child_context;
temp->child_context = n;
}
if (cur == 0)
{
if (local_order >= order)
{
cur = n->parent_context;
cur_order = local_order;
}
else
{
cur_order = local_order+1;
cur = n;
}
}
break;
}
// if we hit the end of the context set without finding the symbol
else
{
// finish excluding all the symbols
while (n->next)
{
exclude(n->symbol);
n = n->next;
}
if (new_node != 0)
{
new_node->parent_context = allocate_node();
new_node = new_node->parent_context;
}
else
{
new_node = allocate_node();
}
n->next = new_node;
// write an escape to a lower context
coder.encode(high_count,total_count,total_count);
}
}
else // if (total_count == 0)
{
// this means that temp->child_context == 0 so we should make
// a new node here.
if (new_node != 0)
{
new_node->parent_context = allocate_node();
new_node = new_node->parent_context;
}
else
{
new_node = allocate_node();
}
temp->child_context = new_node;
}
if (cur == 0 && local_order < order)
{
cur = new_node;
cur_order = local_order+1;
}
// fill out the new node
new_node->child_context = 0;
new_node->escapes = 0;
new_node->next = 0;
new_node->total = 0;
push(new_node,temp);
if (temp != root)
{
temp = temp->parent_context;
--local_order;
continue;
}
t = 2056;
c = 8;
// since this is the root we are going to the order-(-1) context
// so we can just take care of that here.
new_node->parent_context = root;
coder.encode(symbol,symbol+1,alphabet_size);
if (cur == 0)
{
cur = root;
cur_order = 0;
}
break;
}
else
{
// there isn't enough space so we should throw away the tree
clear();
temp = cur;
local_order = cur_order;
cur = 0;
new_node = 0;
}
} // while (true)
// initialize the counts and symbol for any new nodes we have added
// to the tree.
node* n, *nc;
while (stack_size > 0)
{
pop(n,nc);
n->symbol = static_cast<unsigned short>(symbol);
// if nc is not a determnistic context
if (nc->total)
{
unsigned long temp2 = t-c+nc->total - nc->escapes - nc->escapes;
unsigned long temp = nc->total;
temp *= c;
temp /= (temp2|1); // this oring by 1 is just to make sure that temp2 is never zero
temp += 2;
if (temp > 50000) temp = 50000;
n->count = static_cast<unsigned short>(temp);
nc->escapes += 4;
nc->total += static_cast<unsigned short>(temp) + 4;
}
else
{
n->count = 3 + 5*(c)/(t-c);
nc->escapes = 4;
nc->total = n->count + 4;
}
while (nc->total > 10000)
{
scale_counts(nc);
}
}
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// private member function definitions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
unsigned long total_nodes,
unsigned long order
>
eemk5::node* entropy_encoder_model_kernel_5<alphabet_size,entropy_encoder,total_nodes,order>::
allocate_node (
)
{
node* temp;
temp = root + next_node;
++next_node;
return temp;
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
unsigned long total_nodes,
unsigned long order
>
bool entropy_encoder_model_kernel_5<alphabet_size,entropy_encoder,total_nodes,order>::
space_left (
) const
{
return (next_node < total_nodes);
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
unsigned long total_nodes,
unsigned long order
>
void entropy_encoder_model_kernel_5<alphabet_size,entropy_encoder,total_nodes,order>::
exclude (
unsigned short symbol
)
{
exc_used = true;
unsigned long temp = 1;
temp <<= symbol&0x1F;
exc[symbol>>5] |= temp;
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
unsigned long total_nodes,
unsigned long order
>
bool entropy_encoder_model_kernel_5<alphabet_size,entropy_encoder,total_nodes,order>::
is_excluded (
unsigned short symbol
)
{
unsigned long temp = 1;
temp <<= symbol&0x1F;
return ((exc[symbol>>5]&temp) != 0);
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
unsigned long total_nodes,
unsigned long order
>
void entropy_encoder_model_kernel_5<alphabet_size,entropy_encoder,total_nodes,order>::
clear_exclusions (
)
{
exc_used = false;
for (unsigned long i = 0; i < alphabet_size/32+1; ++i)
{
exc[i] = 0;
}
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
unsigned long total_nodes,
unsigned long order
>
bool entropy_encoder_model_kernel_5<alphabet_size,entropy_encoder,total_nodes,order>::
something_is_excluded (
)
{
return exc_used;
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
unsigned long total_nodes,
unsigned long order
>
void entropy_encoder_model_kernel_5<alphabet_size,entropy_encoder,total_nodes,order>::
push (
node* n,
node* nc
)
{
stack[stack_size].n = n;
stack[stack_size].nc = nc;
++stack_size;
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
unsigned long total_nodes,
unsigned long order
>
void entropy_encoder_model_kernel_5<alphabet_size,entropy_encoder,total_nodes,order>::
pop (
node*& n,
node*& nc
)
{
--stack_size;
n = stack[stack_size].n;
nc = stack[stack_size].nc;
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder,
unsigned long total_nodes,
unsigned long order
>
void entropy_encoder_model_kernel_5<alphabet_size,entropy_encoder,total_nodes,order>::
scale_counts (
node* temp
)
{
if (temp->escapes > 1)
temp->escapes >>= 1;
temp->total = temp->escapes;
node* n = temp->child_context;
while (n != 0)
{
if (n->count > 1)
n->count >>= 1;
temp->total += n->count;
n = n->next;
}
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_ENTROPY_ENCODER_MODEL_KERNEl_5_
// Copyright (C) 2005 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ENTROPY_ENCODER_MODEL_KERNEl_6_
#define DLIB_ENTROPY_ENCODER_MODEL_KERNEl_6_
#include "../algs.h"
#include "entropy_encoder_model_kernel_abstract.h"
#include "../assert.h"
namespace dlib
{
template <
unsigned long alphabet_size,
typename entropy_encoder
>
class entropy_encoder_model_kernel_6
{
/*!
INITIAL VALUE
Initially this object's finite context model is empty
CONVENTION
&get_entropy_encoder() == coder
This is an order-(-1) model. So it doesn't really do anything.
Every symbol has the same probability.
!*/
public:
typedef entropy_encoder entropy_encoder_type;
entropy_encoder_model_kernel_6 (
entropy_encoder& coder
);
virtual ~entropy_encoder_model_kernel_6 (
);
inline void clear(
);
inline void encode (
unsigned long symbol
);
entropy_encoder& get_entropy_encoder (
) { return coder; }
static unsigned long get_alphabet_size (
) { return alphabet_size; }
private:
entropy_encoder& coder;
// restricted functions
entropy_encoder_model_kernel_6(entropy_encoder_model_kernel_6<alphabet_size,entropy_encoder>&); // copy constructor
entropy_encoder_model_kernel_6<alphabet_size,entropy_encoder>& operator=(entropy_encoder_model_kernel_6<alphabet_size,entropy_encoder>&); // assignment operator
};
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// member function definitions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder
>
entropy_encoder_model_kernel_6<alphabet_size,entropy_encoder>::
entropy_encoder_model_kernel_6 (
entropy_encoder& coder_
) :
coder(coder_)
{
COMPILE_TIME_ASSERT( 1 < alphabet_size && alphabet_size < 65535 );
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder
>
entropy_encoder_model_kernel_6<alphabet_size,entropy_encoder>::
~entropy_encoder_model_kernel_6 (
)
{
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder
>
void entropy_encoder_model_kernel_6<alphabet_size,entropy_encoder>::
clear(
)
{
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_encoder
>
void entropy_encoder_model_kernel_6<alphabet_size,entropy_encoder>::
encode (
unsigned long symbol
)
{
// use order minus one context
coder.encode(symbol,symbol+1,alphabet_size);
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_ENTROPY_ENCODER_MODEL_KERNEl_6_
// Copyright (C) 2004 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#undef DLIB_ENTROPY_ENCODER_MODEL_KERNEl_ABSTRACT_
#ifdef DLIB_ENTROPY_ENCODER_MODEL_KERNEl_ABSTRACT_
#include "../algs.h"
namespace dlib
{
template <
unsigned long alphabet_size,
typename entropy_encoder
>
class entropy_encoder_model
{
/*!
REQUIREMENTS ON alphabet_size
1 < alphabet_size < 65535
REQUIREMENTS ON entropy_encoder
is an implementation of entropy_encoder/entropy_encoder_kernel_abstract.h
INITIAL VALUE
Initially this object is at some predefined empty or ground state.
WHAT THIS OBJECT REPRESENTS
This object represents some kind of statistical model. You
can use it to write symbols to an entropy_encoder and it will calculate
the cumulative counts/probabilities and manage contexts for you.
Note that all implementations of entropy_encoder_model and
entropy_decoder_model are paired. This means that if you use
entropy_encoder_model_kernel_n to encode something then you must
use the corresponding entropy_decoder_model_kernel_n to decode it.
Also note that this object does not perform any buffering of symbols. It
writes them to its associated entropy_encoder immediately.
This makes it safe to use multiple entropy_encoder_model objects with
a single entropy_encoder without them trampling each other.
!*/
public:
typedef entropy_encoder entropy_encoder_type;
entropy_encoder_model (
entropy_encoder& coder
);
/*!
ensures
- #*this is properly initialized
- &#get_entropy_encoder() == &coder
throws
- any exception
!*/
virtual ~entropy_encoder_model (
);
/*!
ensures
- all memory associated with *this has been released
!*/
void clear(
);
/*!
ensures
- #*this has its initial value
- does not modify get_entropy_encoder()
throws
- any exception
if this exception is thrown then *this is unusable
until clear() is called and succeeds
!*/
void encode (
unsigned long symbol
);
/*!
requires
- symbol < alphabet_size
ensures
- encodes and writes the symbol to get_entropy_encoder().
This also means that there is no internal buffering. symbol is
written immediately to the entropy_encoder.
throws
- any exception
If this exception is thrown then #*this is unusable until
clear() is called and succeeds.
!*/
entropy_encoder& get_entropy_encoder (
);
/*!
ensures
- returns a reference to the entropy_encoder used by *this
!*/
static unsigned long get_alphabet_size (
);
/*!
ensures
- returns alphabet_size
!*/
private:
// restricted functions
entropy_encoder_model(entropy_encoder_model<alphabet_size,entropy_encoder>&); // copy constructor
entropy_encoder_model<alphabet_size,entropy_encoder>& operator=(entropy_encoder_model<alphabet_size,entropy_encoder>&); // assignment operator
};
}
#endif // DLIB_ENTROPY_ENCODER_MODEL_KERNEl_ABSTRACT_
// Copyright (C) 2004 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ENTROPY_ENCODER_MODEL_KERNEl_C_
#define DLIB_ENTROPY_ENCODER_MODEL_KERNEl_C_
#include "entropy_encoder_model_kernel_abstract.h"
#include "../algs.h"
#include "../assert.h"
#include <iostream>
namespace dlib
{
template <
typename eem_base
>
class entropy_encoder_model_kernel_c : public eem_base
{
const unsigned long alphabet_size;
typedef typename eem_base::entropy_encoder_type entropy_encoder;
public:
entropy_encoder_model_kernel_c (
entropy_encoder& coder
) : eem_base(coder), alphabet_size(eem_base::get_alphabet_size()) {}
void encode (
unsigned long symbol
);
};
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// member function definitions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
typename eem_base
>
void entropy_encoder_model_kernel_c<eem_base>::
encode (
unsigned long symbol
)
{
// make sure requires clause is not broken
DLIB_CASSERT(symbol < alphabet_size,
"\tvoid entropy_encoder_model::encode()"
<< "\n\tthe symbol must be in the range 0 to alphabet_size-1"
<< "\n\talphabet_size: " << alphabet_size
<< "\n\tsymbol: " << symbol
<< "\n\tthis: " << this
);
// call the real function
eem_base::encode(symbol);
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_ENTROPY_ENCODER_MODEL_KERNEl_C_
// Copyright (C) 2003 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ERROr_
#define DLIB_ERROr_
#include <string>
#include <new> // for std::bad_alloc
// -------------------------------
// ------ exception classes ------
// -------------------------------
namespace dlib
{
// ----------------------------------------------------------------------------------------
enum error_type
{
EOTHER,
EPORT_IN_USE,
ETIMEOUT,
ECONNECTION,
ELISTENER,
ERESOLVE,
EMONITOR,
ECREATE_THREAD,
ECREATE_MUTEX,
ECREATE_SIGNALER,
EUNSPECIFIED,
EGENERAL_TYPE1,
EGENERAL_TYPE2,
EGENERAL_TYPE3,
EINVALID_OPTION,
ETOO_FEW_ARGS,
ETOO_MANY_ARGS,
ESOCKET,
ETHREAD,
EGUI,
EFATAL,
EBROKEN_ASSERT,
EIMAGE_LOAD,
EDIR_CREATE,
EINCOMPATIBLE_OPTIONS,
EMISSING_REQUIRED_OPTION,
EINVALID_OPTION_ARG,
EMULTIPLE_OCCURANCES,
ECONFIG_READER,
EIMAGE_SAVE,
ECAST_TO_STRING,
ESTRING_CAST,
EUTF8_TO_UTF32
};
// ----------------------------------------------------------------------------------------
// the base exception class
class error : public std::exception
{
/*!
WHAT THIS OBJECT REPRESENTS
This is the base exception class for the dlib library. i.e. all
exceptions in this library inherit from this class.
!*/
public:
error(
error_type t,
const std::string& a
): info(a), type(t) {}
/*!
ensures
- #type == t
- #info == a
!*/
error(
error_type t
): type(t) {}
/*!
ensures
- #type == t
- #info == ""
!*/
error(
const std::string& a
): info(a), type(EUNSPECIFIED) {}
/*!
ensures
- #type == EUNSPECIFIED
- #info == a
!*/
error(
): type(EUNSPECIFIED) {}
/*!
ensures
- #type == EUNSPECIFIED
- #info == ""
!*/
virtual ~error(
) throw() {}
/*!
ensures
- does nothing
!*/
const char* what(
) const throw()
/*!
ensures
- if (info.size() != 0) then
- returns info.c_str()
- else
- returns type_to_string(type)
!*/
{
if (info.size() > 0)
return info.c_str();
else
return type_to_string();
}
const char* type_to_string (
) const throw()
/*!
ensures
- returns a string that names the contents of the type member.
!*/
{
if (type == EOTHER) return "EOTHER";
else if ( type == EPORT_IN_USE) return "EPORT_IN_USE";
else if ( type == ETIMEOUT) return "ETIMEOUT";
else if ( type == ECONNECTION) return "ECONNECTION";
else if ( type == ELISTENER) return "ELISTENER";
else if ( type == ERESOLVE) return "ERESOLVE";
else if ( type == EMONITOR) return "EMONITOR";
else if ( type == ECREATE_THREAD) return "ECREATE_THREAD";
else if ( type == ECREATE_MUTEX) return "ECREATE_MUTEX";
else if ( type == ECREATE_SIGNALER) return "ECREATE_SIGNALER";
else if ( type == EUNSPECIFIED) return "EUNSPECIFIED";
else if ( type == EGENERAL_TYPE1) return "EGENERAL_TYPE1";
else if ( type == EGENERAL_TYPE2) return "EGENERAL_TYPE2";
else if ( type == EGENERAL_TYPE3) return "EGENERAL_TYPE3";
else if ( type == EINVALID_OPTION) return "EINVALID_OPTION";
else if ( type == ETOO_FEW_ARGS) return "ETOO_FEW_ARGS";
else if ( type == ETOO_MANY_ARGS) return "ETOO_MANY_ARGS";
else if ( type == ESOCKET) return "ESOCKET";
else if ( type == ETHREAD) return "ETHREAD";
else if ( type == EGUI) return "EGUI";
else if ( type == EFATAL) return "EFATAL";
else if ( type == EBROKEN_ASSERT) return "EBROKEN_ASSERT";
else if ( type == EIMAGE_LOAD) return "EIMAGE_LOAD";
else if ( type == EDIR_CREATE) return "EDIR_CREATE";
else if ( type == EINCOMPATIBLE_OPTIONS) return "EINCOMPATIBLE_OPTIONS";
else if ( type == EMISSING_REQUIRED_OPTION) return "EMISSING_REQUIRED_OPTION";
else if ( type == EINVALID_OPTION_ARG) return "EINVALID_OPTION_ARG";
else if ( type == EMULTIPLE_OCCURANCES) return "EMULTIPLE_OCCURANCES";
else if ( type == ECONFIG_READER) return "ECONFIG_READER";
else if ( type == EIMAGE_SAVE) return "EIMAGE_SAVE";
else if ( type == ECAST_TO_STRING) return "ECAST_TO_STRING";
else if ( type == ESTRING_CAST) return "ESTRING_CAST";
else if ( type == EUTF8_TO_UTF32) return "EUTF8_TO_UTF32";
else return "undefined error type";
}
const std::string info; // info about the error
const error_type type; // the type of the error
private:
const error& operator=(const error&);
};
// ----------------------------------------------------------------------------------------
class fatal_error : public error
{
/*!
WHAT THIS OBJECT REPRESENTS
As the name says, this object represents some kind of fatal error.
It is also the exception thrown by the DLIB_ASSERT and DLIB_CASSERT macros.
!*/
public:
fatal_error(
error_type t,
const std::string& a
): error(t,a) {}
/*!
ensures
- #type == t
- #info == a
!*/
fatal_error(
error_type t
): error(t) {}
/*!
ensures
- #type == t
- #info == ""
!*/
fatal_error(
const std::string& a
): error(EFATAL,a) {}
/*!
ensures
- #type == EFATAL
- #info == a
!*/
fatal_error(
): error(EFATAL) {}
/*!
ensures
- #type == EFATAL
- #info == ""
!*/
};
// ----------------------------------------------------------------------------------------
class gui_error : public error
{
public:
gui_error(
error_type t,
const std::string& a
): error(t,a) {}
/*!
ensures
- #type == t
- #info == a
!*/
gui_error(
error_type t
): error(t) {}
/*!
ensures
- #type == t
- #info == ""
!*/
gui_error(
const std::string& a
): error(EGUI,a) {}
/*!
ensures
- #type == EGUI
- #info == a
!*/
gui_error(
): error(EGUI) {}
/*!
ensures
- #type == EGUI
- #info == ""
!*/
};
// ----------------------------------------------------------------------------------------
class socket_error : public error
{
public:
socket_error(
error_type t,
const std::string& a
): error(t,a) {}
/*!
ensures
- #type == t
- #info == a
!*/
socket_error(
error_type t
): error(t) {}
/*!
ensures
- #type == t
- #info == ""
!*/
socket_error(
const std::string& a
): error(ESOCKET,a) {}
/*!
ensures
- #type == ESOCKET
- #info == a
!*/
socket_error(
): error(ESOCKET) {}
/*!
ensures
- #type == ESOCKET
- #info == ""
!*/
};
// ----------------------------------------------------------------------------------------
class thread_error : public error
{
public:
thread_error(
error_type t,
const std::string& a
): error(t,a) {}
/*!
ensures
- #type == t
- #info == a
!*/
thread_error(
error_type t
): error(t) {}
/*!
ensures
- #type == t
- #info == ""
!*/
thread_error(
const std::string& a
): error(ETHREAD,a) {}
/*!
ensures
- #type == ETHREAD
- #info == a
!*/
thread_error(
): error(ETHREAD) {}
/*!
ensures
- #type == ETHREAD
- #info == ""
!*/
};
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_ERROr_
#include "dlib_include_path_tutorial.txt"
// Copyright (C) 2003 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_GENERAL_HASh_
#define DLIB_GENERAL_HASh_
#include <string>
namespace dlib
{
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// ----------------------- provide a general hashing function object ----------------------
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
typename T
>
class general_hash
{
public:
inline unsigned long operator() (
const T& item
) const;
};
/*!
Note that the default behavior of general hash is to attempt to cast
an object of type T to an unsigned long and use that as the hash.
REQUIREMENTS ON general_hash
- must have a default constructor
- must be a function object which overloads operator() as follows:
unsigned long operator()(const T& item)
- must take item, compute a hash number and return it
- must not throw
- must define the hash in such a way that all equivalent objects have
the same hash. where equivalent means the following:
definition of equivalent:
a is equivalent to b if
a < b == false and
b < a == false
!*/
// ---------------
template <
typename T
>
unsigned long general_hash<T>::
operator() (
const T& item
) const
{
// hash any types that have a conversion to unsigned long
return static_cast<unsigned long>(item);
}
// ---------------
// std::string hash
template <>
inline unsigned long general_hash<std::string>::
operator() (
const std::string& item
) const
{
unsigned long hash = 0;
std::string::size_type size = item.size();
for (std::string::size_type i = 0; i < size; ++i)
hash = hash*37 + static_cast<unsigned long>(item[i]);
return hash;
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_GENERAL_HASh_
// Copyright (C) 2008 Davis E. King (davisking@users.sourceforge.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_GEOMETRy_HEADER
#define DLIB_GEOMETRy_HEADER
#include "geometry/rectangle.h"
#include "geometry/vector.h"
#endif // DLIB_GEOMETRy_HEADER
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment