Master commit of OpenFace.

This commit is contained in:
unknown
2016-04-28 15:40:36 -04:00
parent 5346d303ab
commit 57e58a6949
4406 changed files with 1441342 additions and 0 deletions

View File

@@ -0,0 +1,173 @@
// Copyright (C) 2004 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ENTROPY_DECODER_MODEL_KERNEl_1_
#define DLIB_ENTROPY_DECODER_MODEL_KERNEl_1_
#include "../algs.h"
#include "entropy_decoder_model_kernel_abstract.h"
#include "../assert.h"
namespace dlib
{
template <
unsigned long alphabet_size,
typename entropy_decoder,
typename cc
>
class entropy_decoder_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_decoder() == 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_decoder entropy_decoder_type;
entropy_decoder_model_kernel_1 (
entropy_decoder& coder
);
virtual ~entropy_decoder_model_kernel_1 (
);
inline void clear(
);
inline void decode (
unsigned long& symbol
);
entropy_decoder& get_entropy_decoder (
) { return coder; }
static unsigned long get_alphabet_size (
) { return alphabet_size; }
private:
entropy_decoder& coder;
typename cc::global_state_type gs;
cc order_0;
// restricted functions
entropy_decoder_model_kernel_1(entropy_decoder_model_kernel_1<alphabet_size,entropy_decoder,cc>&); // copy constructor
entropy_decoder_model_kernel_1<alphabet_size,entropy_decoder,cc>& operator=(entropy_decoder_model_kernel_1<alphabet_size,entropy_decoder,cc>&); // assignment operator
};
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// member function definitions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder,
typename cc
>
entropy_decoder_model_kernel_1<alphabet_size,entropy_decoder,cc>::
entropy_decoder_model_kernel_1 (
entropy_decoder& coder_
) :
coder(coder_),
order_0(gs)
{
COMPILE_TIME_ASSERT( 1 < alphabet_size && alphabet_size < 65535 );
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder,
typename cc
>
entropy_decoder_model_kernel_1<alphabet_size,entropy_decoder,cc>::
~entropy_decoder_model_kernel_1 (
)
{
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder,
typename cc
>
void entropy_decoder_model_kernel_1<alphabet_size,entropy_decoder,cc>::
clear(
)
{
order_0.clear();
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder,
typename cc
>
void entropy_decoder_model_kernel_1<alphabet_size,entropy_decoder,cc>::
decode (
unsigned long& symbol
)
{
unsigned long current_symbol, low_count, high_count, target;
// look in the order-0 context
target = coder.get_target(order_0.get_total());
order_0.get_symbol(target,current_symbol,low_count,high_count);
// have coder decode the next symbol
coder.decode(low_count,high_count);
// if current_symbol is not an escape from the order-0 context
if (current_symbol != alphabet_size)
{
// update the count for this symbol
order_0.increment_count(current_symbol,2);
symbol = current_symbol;
return;
}
// update the count for the escape symbol
order_0.increment_count(alphabet_size);
// go into the order minus one context
target = coder.get_target(alphabet_size);
coder.decode(target,target+1);
// update the count for this symbol in the order-0 context
order_0.increment_count(target,2);
symbol = target;
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_ENTROPY_DECODER_MODEL_KERNEl_1_

View File

@@ -0,0 +1,245 @@
// Copyright (C) 2004 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ENTROPY_DECODER_MODEL_KERNEl_2_
#define DLIB_ENTROPY_DECODER_MODEL_KERNEl_2_
#include "../algs.h"
#include "entropy_decoder_model_kernel_abstract.h"
#include "../assert.h"
namespace dlib
{
template <
unsigned long alphabet_size,
typename entropy_decoder,
typename cc,
typename ccbig
>
class entropy_decoder_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_decoder() == 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_decoder entropy_decoder_type;
entropy_decoder_model_kernel_2 (
entropy_decoder& coder
);
virtual ~entropy_decoder_model_kernel_2 (
);
inline void clear(
);
inline void decode (
unsigned long& symbol
);
entropy_decoder& get_entropy_decoder (
) { return coder; }
static unsigned long get_alphabet_size (
) { return alphabet_size; }
private:
entropy_decoder& 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_decoder_model_kernel_2(entropy_decoder_model_kernel_2<alphabet_size,entropy_decoder,cc,ccbig>&); // copy constructor
entropy_decoder_model_kernel_2<alphabet_size,entropy_decoder,cc,ccbig>& operator=(entropy_decoder_model_kernel_2<alphabet_size,entropy_decoder,cc,ccbig>&); // assignment operator
};
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// member function definitions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder,
typename cc,
typename ccbig
>
entropy_decoder_model_kernel_2<alphabet_size,entropy_decoder,cc,ccbig>::
entropy_decoder_model_kernel_2 (
entropy_decoder& 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_decoder,
typename cc,
typename ccbig
>
entropy_decoder_model_kernel_2<alphabet_size,entropy_decoder,cc,ccbig>::
~entropy_decoder_model_kernel_2 (
)
{
for (unsigned long i = 0; i < alphabet_size; ++i)
{
delete order_1[i];
}
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder,
typename cc,
typename ccbig
>
void entropy_decoder_model_kernel_2<alphabet_size,entropy_decoder,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_decoder,
typename cc,
typename ccbig
>
void entropy_decoder_model_kernel_2<alphabet_size,entropy_decoder,cc,ccbig>::
decode (
unsigned long& symbol
)
{
unsigned long current_symbol, low_count, high_count, target;
// look in the order-1 context
target = coder.get_target(order_1[previous_symbol]->get_total());
order_1[previous_symbol]->get_symbol(target,current_symbol,low_count,high_count);
// have the coder decode the next symbol
coder.decode(low_count,high_count);
// if the current_symbol is not an escape from the order-1 context
if (current_symbol != alphabet_size)
{
symbol = current_symbol;
order_1[previous_symbol]->increment_count(current_symbol,2);
previous_symbol = current_symbol;
return;
}
// since this is an escape to order-0 we should increment
// the escape symbol
order_1[previous_symbol]->increment_count(alphabet_size);
// look in the order-0 context
target = coder.get_target(order_0.get_total());
order_0.get_symbol(target,current_symbol,low_count,high_count);
// have coder decode the next symbol
coder.decode(low_count,high_count);
// if current_symbol is not an escape from the order-0 context
if (current_symbol != alphabet_size)
{
// update the count for this symbol
order_1[previous_symbol]->increment_count(current_symbol,2);
order_0.increment_count(current_symbol,2);
symbol = current_symbol;
previous_symbol = current_symbol;
return;
}
// update the count for the escape symbol
order_0.increment_count(current_symbol);
// go into the order minus one context
target = coder.get_target(alphabet_size);
coder.decode(target,target+1);
// update the count for this symbol
order_1[previous_symbol]->increment_count(target,2);
order_0.increment_count(target,2);
symbol = target;
previous_symbol = target;
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_ENTROPY_DECODER_MODEL_KERNEl_2_

View File

@@ -0,0 +1,335 @@
// Copyright (C) 2004 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ENTROPY_DECODER_MODEL_KERNEl_3_
#define DLIB_ENTROPY_DECODER_MODEL_KERNEl_3_
#include "../algs.h"
#include "entropy_decoder_model_kernel_abstract.h"
#include "../assert.h"
namespace dlib
{
template <
unsigned long alphabet_size,
typename entropy_decoder,
typename cc,
typename cc_high
>
class entropy_decoder_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
- for all values of i: 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_decoder entropy_decoder_type;
entropy_decoder_model_kernel_3 (
entropy_decoder& coder
);
virtual ~entropy_decoder_model_kernel_3 (
);
inline void clear(
);
inline void decode (
unsigned long& symbol
);
entropy_decoder& get_entropy_decoder (
) { return coder; }
static unsigned long get_alphabet_size (
) { return alphabet_size; }
private:
entropy_decoder& 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_decoder_model_kernel_3(entropy_decoder_model_kernel_3&); // copy constructor
entropy_decoder_model_kernel_3& operator=(entropy_decoder_model_kernel_3&); // assignment operator
};
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// member function definitions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder,
typename cc,
typename cc_high
>
entropy_decoder_model_kernel_3<alphabet_size,entropy_decoder,cc,cc_high>::
entropy_decoder_model_kernel_3 (
entropy_decoder& 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_decoder,
typename cc,
typename cc_high
>
entropy_decoder_model_kernel_3<alphabet_size,entropy_decoder,cc,cc_high>::
~entropy_decoder_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_decoder,
typename cc,
typename cc_high
>
void entropy_decoder_model_kernel_3<alphabet_size,entropy_decoder,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_decoder,
typename cc,
typename cc_high
>
void entropy_decoder_model_kernel_3<alphabet_size,entropy_decoder,cc,cc_high>::
decode (
unsigned long& symbol
)
{
unsigned long current_symbol, low_count, high_count, target;
// look in the order-2 context
unsigned long temp = previous_symbol + (previous_symbol2 * alphabet_size);
if (order_2[temp] != 0)
{
target = coder.get_target(order_2[temp]->get_total());
order_2[temp]->get_symbol(target,current_symbol,low_count,high_count);
// have the coder decode the next symbol
coder.decode(low_count,high_count);
// if the current_symbol is not an escape from the order-2 context
if (current_symbol != alphabet_size)
{
symbol = current_symbol;
order_2[temp]->increment_count(current_symbol,2);
previous_symbol2 = previous_symbol;
previous_symbol = current_symbol;
return;
}
// since this is an escape to order-1 we should increment
// the escape symbol
order_2[temp]->increment_count(alphabet_size);
}
else
{
order_2[temp] = new cc_high(gs_high);
}
// look in the order-1 context
target = coder.get_target(order_1[previous_symbol]->get_total());
order_1[previous_symbol]->get_symbol(target,current_symbol,low_count,high_count);
// have the coder decode the next symbol
coder.decode(low_count,high_count);
// if the current_symbol is not an escape from the order-1 context
if (current_symbol != alphabet_size)
{
symbol = current_symbol;
order_2[temp]->increment_count(current_symbol,2);
order_1[previous_symbol]->increment_count(current_symbol,2);
previous_symbol2 = previous_symbol;
previous_symbol = current_symbol;
return;
}
// since this is an escape to order-0 we should increment
// the escape symbol
order_1[previous_symbol]->increment_count(alphabet_size);
// look in the order-0 context
target = coder.get_target(order_0.get_total());
order_0.get_symbol(target,current_symbol,low_count,high_count);
// have coder decode the next symbol
coder.decode(low_count,high_count);
// if current_symbol is not an escape from the order-0 context
if (current_symbol != alphabet_size)
{
// update the count for this symbol
order_2[temp]->increment_count(current_symbol,2);
order_1[previous_symbol]->increment_count(current_symbol,2);
order_0.increment_count(current_symbol,2);
symbol = current_symbol;
previous_symbol2 = previous_symbol;
previous_symbol = current_symbol;
return;
}
// update the count for the escape symbol
order_0.increment_count(current_symbol);
// go into the order minus one context
target = coder.get_target(alphabet_size);
coder.decode(target,target+1);
// update the count for this symbol
order_2[temp]->increment_count(target,2);
order_1[previous_symbol]->increment_count(target,2);
order_0.increment_count(target,2);
symbol = target;
previous_symbol2 = previous_symbol;
previous_symbol = target;
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_ENTROPY_DECODER_MODEL_KERNEl_3_

View File

@@ -0,0 +1,622 @@
// Copyright (C) 2005 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ENTROPY_DECODER_MODEL_KERNEl_4_
#define DLIB_ENTROPY_DECODER_MODEL_KERNEl_4_
#include "../algs.h"
#include "entropy_decoder_model_kernel_abstract.h"
#include "../assert.h"
namespace dlib
{
namespace edmk4
{
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_decoder,
unsigned long total_nodes,
unsigned long order
>
class entropy_decoder_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
- stack_size == 0
CONVENTION
- pop() == stack[stack_size-1]
- &get_entropy_decoder() == 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 edmk4::node node;
public:
typedef entropy_decoder entropy_decoder_type;
entropy_decoder_model_kernel_4 (
entropy_decoder& coder
);
virtual ~entropy_decoder_model_kernel_4 (
);
inline void clear(
);
inline void decode (
unsigned long& symbol
);
entropy_decoder& get_entropy_decoder (
) { return coder; }
static unsigned long get_alphabet_size (
) { return alphabet_size; }
private:
inline void push (
edmk4::node* n
);
/*!
requires
- stack_size <= order
ensures
- #pop() == n
!*/
inline edmk4::node* pop (
);
/*!
requires
- stack_size > 0
ensures
- returns the node at the top of the stack
!*/
inline edmk4::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
- #stack_size == 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
!*/
entropy_decoder& coder;
unsigned long next_node;
node* root;
node* cur;
unsigned long cur_order;
node* stack[order+1];
unsigned long stack_size;
// restricted functions
entropy_decoder_model_kernel_4(entropy_decoder_model_kernel_4<alphabet_size,entropy_decoder,total_nodes,order>&); // copy constructor
entropy_decoder_model_kernel_4<alphabet_size,entropy_decoder,total_nodes,order>& operator=(entropy_decoder_model_kernel_4<alphabet_size,entropy_decoder,total_nodes,order>&); // assignment operator
};
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// member function definitions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder,
unsigned long total_nodes,
unsigned long order
>
entropy_decoder_model_kernel_4<alphabet_size,entropy_decoder,total_nodes,order>::
entropy_decoder_model_kernel_4 (
entropy_decoder& coder_
) :
coder(coder_),
next_node(1),
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;
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder,
unsigned long total_nodes,
unsigned long order
>
entropy_decoder_model_kernel_4<alphabet_size,entropy_decoder,total_nodes,order>::
~entropy_decoder_model_kernel_4 (
)
{
delete [] root;
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder,
unsigned long total_nodes,
unsigned long order
>
void entropy_decoder_model_kernel_4<alphabet_size,entropy_decoder,total_nodes,order>::
clear(
)
{
destroy_tree();
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder,
unsigned long total_nodes,
unsigned long order
>
void entropy_decoder_model_kernel_4<alphabet_size,entropy_decoder,total_nodes,order>::
decode (
unsigned long& symbol
)
{
node* temp = cur;
cur = 0;
unsigned long low_count, high_count, total_count;
unsigned long target;
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;
}
target = coder.get_target(total_count);
// 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 (high_count > target || n->next == 0)
break;
last = n;
n = n->next;
}
low_count = high_count - n->count;
// if we found the symbol
if (high_count > target)
{
if (new_node != 0)
{
new_node->parent_context = n;
}
symbol = n->symbol;
coder.decode(low_count,high_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;
// get the escape code
coder.decode(high_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;
push(new_node);
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.
target = coder.get_target(alphabet_size);
new_node->parent_context = root;
coder.decode(target,target+1);
symbol = target;
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)
while (stack_size > 0)
{
pop()->symbol = static_cast<unsigned short>(symbol);
}
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// private member function definitions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder,
unsigned long total_nodes,
unsigned long order
>
edmk4::node* entropy_decoder_model_kernel_4<alphabet_size,entropy_decoder,total_nodes,order>::
allocate_node (
)
{
node* temp;
temp = root + next_node;
++next_node;
return temp;
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder,
unsigned long total_nodes,
unsigned long order
>
void entropy_decoder_model_kernel_4<alphabet_size,entropy_decoder,total_nodes,order>::
destroy_tree (
)
{
next_node = 1;
root->child_context = 0;
root->escapes = 0;
root->total = 0;
cur = root;
cur_order = 0;
stack_size = 0;
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder,
unsigned long total_nodes,
unsigned long order
>
bool entropy_decoder_model_kernel_4<alphabet_size,entropy_decoder,total_nodes,order>::
space_left (
) const
{
return (next_node < total_nodes);
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder,
unsigned long total_nodes,
unsigned long order
>
void entropy_decoder_model_kernel_4<alphabet_size,entropy_decoder,total_nodes,order>::
push (
edmk4::node* n
)
{
stack[stack_size] = n;
++stack_size;
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder,
unsigned long total_nodes,
unsigned long order
>
edmk4::node* entropy_decoder_model_kernel_4<alphabet_size,entropy_decoder,total_nodes,order>::
pop (
)
{
--stack_size;
return stack[stack_size];
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder,
unsigned long total_nodes,
unsigned long order
>
void entropy_decoder_model_kernel_4<alphabet_size,entropy_decoder,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_DECODER_MODEL_KERNEl_4_

View File

@@ -0,0 +1,793 @@
// Copyright (C) 2005 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ENTROPY_DECODER_MODEL_KERNEl_5_
#define DLIB_ENTROPY_DECODER_MODEL_KERNEl_5_
#include "../algs.h"
#include "entropy_decoder_model_kernel_abstract.h"
#include "../assert.h"
namespace dlib
{
namespace edmk5
{
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_decoder,
unsigned long total_nodes,
unsigned long order
>
class entropy_decoder_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
- exc_used == something_is_excluded()
- pop() == stack[stack_size-1].n and stack[stack_size-1].nc
- is_excluded(symbol) == bit symbol&0x1F from exc[symbol>>5]
- &get_entropy_decoder() == 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 edmk5::node node;
public:
typedef entropy_decoder entropy_decoder_type;
entropy_decoder_model_kernel_5 (
entropy_decoder& coder
);
virtual ~entropy_decoder_model_kernel_5 (
);
inline void clear(
);
inline void decode (
unsigned long& symbol
);
entropy_decoder& get_entropy_decoder (
) { return coder; }
static unsigned long get_alphabet_size (
) { return alphabet_size; }
private:
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
!*/
inline edmk5::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 is_excluded (
unsigned short symbol
);
/*!
ensures
- if (symbol has been excluded) then
- returns true
- else
- returns false
!*/
inline bool something_is_excluded (
);
/*!
ensures
- returns true if some symbol has been excluded.
returns false otherwise
!*/
inline void clear_exclusions (
);
/*!
ensures
- for all symbols #is_excluded(symbol) == false
- #something_is_excluded() == false
!*/
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
!*/
struct nodes
{
node* n;
node* nc;
};
entropy_decoder& coder;
unsigned long next_node;
node* root;
node* cur;
unsigned long cur_order;
unsigned long exc[alphabet_size/32+1];
nodes stack[order+1];
unsigned long stack_size;
bool exc_used;
// restricted functions
entropy_decoder_model_kernel_5(entropy_decoder_model_kernel_5<alphabet_size,entropy_decoder,total_nodes,order>&); // copy constructor
entropy_decoder_model_kernel_5<alphabet_size,entropy_decoder,total_nodes,order>& operator=(entropy_decoder_model_kernel_5<alphabet_size,entropy_decoder,total_nodes,order>&); // assignment operator
};
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// member function definitions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder,
unsigned long total_nodes,
unsigned long order
>
entropy_decoder_model_kernel_5<alphabet_size,entropy_decoder,total_nodes,order>::
entropy_decoder_model_kernel_5 (
entropy_decoder& coder_
) :
coder(coder_),
next_node(1),
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_decoder,
unsigned long total_nodes,
unsigned long order
>
entropy_decoder_model_kernel_5<alphabet_size,entropy_decoder,total_nodes,order>::
~entropy_decoder_model_kernel_5 (
)
{
delete [] root;
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder,
unsigned long total_nodes,
unsigned long order
>
void entropy_decoder_model_kernel_5<alphabet_size,entropy_decoder,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_decoder,
unsigned long total_nodes,
unsigned long order
>
void entropy_decoder_model_kernel_5<alphabet_size,entropy_decoder,total_nodes,order>::
decode (
unsigned long& symbol
)
{
node* temp = cur;
cur = 0;
unsigned long low_count, high_count, total_count;
unsigned long target;
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)
{
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;
}
if (something_is_excluded())
{
node* n = temp->child_context;
total_count = temp->escapes;
while (true)
{
if (is_excluded(n->symbol) == false)
{
total_count += n->count;
}
if (n->next == 0)
break;
n = n->next;
}
}
target = coder.get_target(total_count);
// 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)
{
if (is_excluded(n->symbol) == false)
{
high_count += n->count;
exclude(n->symbol);
}
if (high_count > target || n->next == 0)
break;
last = n;
n = n->next;
}
// if we found the symbol
if (high_count > target)
{
low_count = high_count - n->count;
if (new_node != 0)
{
new_node->parent_context = n;
}
symbol = n->symbol;
coder.decode(low_count,high_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_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;
// get the escape code
coder.decode(high_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;
push(new_node,temp);
new_node->total = 0;
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.
target = coder.get_target(alphabet_size);
new_node->parent_context = root;
coder.decode(target,target+1);
symbol = target;
if (cur == 0)
{
cur = root;
cur_order = 0;
}
break;
}
else
{
// there isn't enough space so we should rebuild 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_decoder,
unsigned long total_nodes,
unsigned long order
>
edmk5::node* entropy_decoder_model_kernel_5<alphabet_size,entropy_decoder,total_nodes,order>::
allocate_node (
)
{
node* temp;
temp = root + next_node;
++next_node;
return temp;
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder,
unsigned long total_nodes,
unsigned long order
>
bool entropy_decoder_model_kernel_5<alphabet_size,entropy_decoder,total_nodes,order>::
space_left (
) const
{
return (next_node < total_nodes);
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder,
unsigned long total_nodes,
unsigned long order
>
void entropy_decoder_model_kernel_5<alphabet_size,entropy_decoder,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_decoder,
unsigned long total_nodes,
unsigned long order
>
bool entropy_decoder_model_kernel_5<alphabet_size,entropy_decoder,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_decoder,
unsigned long total_nodes,
unsigned long order
>
void entropy_decoder_model_kernel_5<alphabet_size,entropy_decoder,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_decoder,
unsigned long total_nodes,
unsigned long order
>
void entropy_decoder_model_kernel_5<alphabet_size,entropy_decoder,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_decoder,
unsigned long total_nodes,
unsigned long order
>
void entropy_decoder_model_kernel_5<alphabet_size,entropy_decoder,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_decoder,
unsigned long total_nodes,
unsigned long order
>
bool entropy_decoder_model_kernel_5<alphabet_size,entropy_decoder,total_nodes,order>::
something_is_excluded (
)
{
return exc_used;
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder,
unsigned long total_nodes,
unsigned long order
>
void entropy_decoder_model_kernel_5<alphabet_size,entropy_decoder,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_DECODER_MODEL_KERNEl_5_

View File

@@ -0,0 +1,131 @@
// Copyright (C) 2005 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ENTROPY_DECODER_MODEL_KERNEl_6_
#define DLIB_ENTROPY_DECODER_MODEL_KERNEl_6_
#include "../algs.h"
#include "entropy_decoder_model_kernel_abstract.h"
#include "../assert.h"
namespace dlib
{
template <
unsigned long alphabet_size,
typename entropy_decoder
>
class entropy_decoder_model_kernel_6
{
/*!
INITIAL VALUE
This object has no state
CONVENTION
&get_entropy_decoder() == coder
This is an order-(-1) model. So it doesn't really do anything.
Every symbol has the same probability.
!*/
public:
typedef entropy_decoder entropy_decoder_type;
entropy_decoder_model_kernel_6 (
entropy_decoder& coder
);
virtual ~entropy_decoder_model_kernel_6 (
);
inline void clear(
);
inline void decode (
unsigned long& symbol
);
entropy_decoder& get_entropy_decoder (
) { return coder; }
static unsigned long get_alphabet_size (
) { return alphabet_size; }
private:
entropy_decoder& coder;
// restricted functions
entropy_decoder_model_kernel_6(entropy_decoder_model_kernel_6<alphabet_size,entropy_decoder>&); // copy constructor
entropy_decoder_model_kernel_6<alphabet_size,entropy_decoder>& operator=(entropy_decoder_model_kernel_6<alphabet_size,entropy_decoder>&); // assignment operator
};
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// member function definitions
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder
>
entropy_decoder_model_kernel_6<alphabet_size,entropy_decoder>::
entropy_decoder_model_kernel_6 (
entropy_decoder& coder_
) :
coder(coder_)
{
COMPILE_TIME_ASSERT( 1 < alphabet_size && alphabet_size < 65535 );
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder
>
entropy_decoder_model_kernel_6<alphabet_size,entropy_decoder>::
~entropy_decoder_model_kernel_6 (
)
{
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder
>
void entropy_decoder_model_kernel_6<alphabet_size,entropy_decoder>::
clear(
)
{
}
// ----------------------------------------------------------------------------------------
template <
unsigned long alphabet_size,
typename entropy_decoder
>
void entropy_decoder_model_kernel_6<alphabet_size,entropy_decoder>::
decode (
unsigned long& symbol
)
{
unsigned long target;
target = coder.get_target(alphabet_size);
coder.decode(target,target+1);
symbol = target;
}
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_ENTROPY_DECODER_MODEL_KERNEl_6_

View File

@@ -0,0 +1,116 @@
// Copyright (C) 2004 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#undef DLIB_ENTROPY_DECODER_MODEL_KERNEl_ABSTRACT_
#ifdef DLIB_ENTROPY_DECODER_MODEL_KERNEl_ABSTRACT_
#include "../algs.h"
namespace dlib
{
template <
unsigned long alphabet_size,
typename entropy_decoder
>
class entropy_decoder_model
{
/*!
REQUIREMENTS ON alphabet_size
1 < alphabet_size < 65535
REQUIREMENTS ON entropy_decoder
is an implementation of entropy_decoder/entropy_decoder_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 read symbols from an entropy_decoder 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
reads them from its associated entropy_decoder simply as it needs them.
This makes it safe to use multiple entropy_decoder_model objects with
a single entropy_decoder without them trampling each other.
!*/
public:
typedef entropy_decoder entropy_decoder_type;
entropy_decoder_model (
entropy_decoder& coder
);
/*!
ensures
- #*this is properly initialized
- &#get_entropy_decoder() == &coder
throws
- any exception
!*/
virtual ~entropy_decoder_model (
);
/*!
ensures
- all memory associated with *this has been released
!*/
void clear(
);
/*!
ensures
- #*this has its initial value
- does not modify get_entropy_decoder()
throws
- any exception
if this exception is thrown then *this is unusable
until clear() is called and succeeds
!*/
void decode (
unsigned long& symbol
);
/*!
ensures
- decodes the next symbol
- #symbol == the next symbol
- #symbol < alphabet_size
throws
- any exception
If this exception is thrown then #*this is unusable until
clear() is called and succeeds.
!*/
entropy_decoder& get_entropy_decoder (
);
/*!
ensures
- returns a reference to the entropy_decoder used by *this
!*/
static unsigned long get_alphabet_size (
);
/*!
ensures
- returns alphabet_size
!*/
private:
// restricted functions
entropy_decoder_model(entropy_decoder_model<alphabet_size>&); // copy constructor
entropy_decoder_model<alphabet_size>& operator=(entropy_decoder_model<alphabet_size>&); // assignment operator
};
}
#endif // DLIB_ENTROPY_DECODER_MODEL_KERNEl_ABSTRACT_