xenia/third_party/crunch/crnlib/crn_prefix_coding.h

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