117 lines
3.7 KiB
C
117 lines
3.7 KiB
C
|
// File: crn_prefix_coding.h
|
||
|
// See Copyright Notice and license at the end of inc/crnlib.h
|
||
|
#pragma once
|
||
|
|
||
|
namespace crnlib
|
||
|
{
|
||
|
namespace prefix_coding
|
||
|
{
|
||
|
const uint cMaxExpectedCodeSize = 16;
|
||
|
const uint cMaxSupportedSyms = 8192;
|
||
|
const uint cMaxTableBits = 11;
|
||
|
|
||
|
bool limit_max_code_size(uint num_syms, uint8* pCodesizes, uint max_code_size);
|
||
|
|
||
|
bool generate_codes(uint num_syms, const uint8* pCodesizes, uint16* pCodes);
|
||
|
|
||
|
class decoder_tables
|
||
|
{
|
||
|
public:
|
||
|
inline decoder_tables() :
|
||
|
m_table_shift(0), m_table_max_code(0), m_decode_start_code_size(0), m_cur_lookup_size(0), m_lookup(NULL), m_cur_sorted_symbol_order_size(0), m_sorted_symbol_order(NULL)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
inline decoder_tables(const decoder_tables& other) :
|
||
|
m_table_shift(0), m_table_max_code(0), m_decode_start_code_size(0), m_cur_lookup_size(0), m_lookup(NULL), m_cur_sorted_symbol_order_size(0), m_sorted_symbol_order(NULL)
|
||
|
{
|
||
|
*this = other;
|
||
|
}
|
||
|
|
||
|
decoder_tables& operator= (const decoder_tables& other)
|
||
|
{
|
||
|
if (this == &other)
|
||
|
return *this;
|
||
|
|
||
|
clear();
|
||
|
|
||
|
memcpy(this, &other, sizeof(*this));
|
||
|
|
||
|
if (other.m_lookup)
|
||
|
{
|
||
|
m_lookup = crnlib_new_array<uint32>(m_cur_lookup_size);
|
||
|
memcpy(m_lookup, other.m_lookup, sizeof(m_lookup[0]) * m_cur_lookup_size);
|
||
|
}
|
||
|
|
||
|
if (other.m_sorted_symbol_order)
|
||
|
{
|
||
|
m_sorted_symbol_order = crnlib_new_array<uint16>(m_cur_sorted_symbol_order_size);
|
||
|
memcpy(m_sorted_symbol_order, other.m_sorted_symbol_order, sizeof(m_sorted_symbol_order[0]) * m_cur_sorted_symbol_order_size);
|
||
|
}
|
||
|
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
inline void clear()
|
||
|
{
|
||
|
if (m_lookup)
|
||
|
{
|
||
|
crnlib_delete_array(m_lookup);
|
||
|
m_lookup = 0;
|
||
|
m_cur_lookup_size = 0;
|
||
|
}
|
||
|
|
||
|
if (m_sorted_symbol_order)
|
||
|
{
|
||
|
crnlib_delete_array(m_sorted_symbol_order);
|
||
|
m_sorted_symbol_order = NULL;
|
||
|
m_cur_sorted_symbol_order_size = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
inline ~decoder_tables()
|
||
|
{
|
||
|
if (m_lookup)
|
||
|
crnlib_delete_array(m_lookup);
|
||
|
|
||
|
if (m_sorted_symbol_order)
|
||
|
crnlib_delete_array(m_sorted_symbol_order);
|
||
|
}
|
||
|
|
||
|
// DO NOT use any complex classes here - it is bitwise copied.
|
||
|
|
||
|
uint m_num_syms;
|
||
|
uint m_total_used_syms;
|
||
|
uint m_table_bits;
|
||
|
uint m_table_shift;
|
||
|
uint m_table_max_code;
|
||
|
uint m_decode_start_code_size;
|
||
|
|
||
|
uint8 m_min_code_size;
|
||
|
uint8 m_max_code_size;
|
||
|
|
||
|
uint m_max_codes[cMaxExpectedCodeSize + 1];
|
||
|
int m_val_ptrs[cMaxExpectedCodeSize + 1];
|
||
|
|
||
|
uint m_cur_lookup_size;
|
||
|
uint32* m_lookup;
|
||
|
|
||
|
uint m_cur_sorted_symbol_order_size;
|
||
|
uint16* m_sorted_symbol_order;
|
||
|
|
||
|
inline uint get_unshifted_max_code(uint len) const
|
||
|
{
|
||
|
CRNLIB_ASSERT( (len >= 1) && (len <= cMaxExpectedCodeSize) );
|
||
|
uint k = m_max_codes[len - 1];
|
||
|
if (!k)
|
||
|
return UINT_MAX;
|
||
|
return (k - 1) >> (16 - len);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
bool generate_decoder_tables(uint num_syms, const uint8* pCodesizes, decoder_tables* pTables, uint table_bits);
|
||
|
|
||
|
} // namespace prefix_coding
|
||
|
|
||
|
} // namespace crnlib
|