dlib C++ Library - entropy_encoder_model_kernel_3.h

// Copyright (C) 2004 Davis E. King (davis@dlib.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_

AltStyle によって変換されたページ (->オリジナル) /