crn_prefix_coding.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // File: crn_prefix_coding.h
  2. // See Copyright Notice and license at the end of inc/crnlib.h
  3. #pragma once
  4. namespace crnlib
  5. {
  6. namespace prefix_coding
  7. {
  8. const uint cMaxExpectedCodeSize = 16;
  9. const uint cMaxSupportedSyms = 8192;
  10. const uint cMaxTableBits = 11;
  11. bool limit_max_code_size(uint num_syms, uint8* pCodesizes, uint max_code_size);
  12. bool generate_codes(uint num_syms, const uint8* pCodesizes, uint16* pCodes);
  13. class decoder_tables
  14. {
  15. public:
  16. inline decoder_tables() :
  17. 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)
  18. {
  19. }
  20. inline decoder_tables(const decoder_tables& other) :
  21. 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)
  22. {
  23. *this = other;
  24. }
  25. decoder_tables& operator= (const decoder_tables& other)
  26. {
  27. if (this == &other)
  28. return *this;
  29. clear();
  30. memcpy(this, &other, sizeof(*this));
  31. if (other.m_lookup)
  32. {
  33. m_lookup = crnlib_new_array<uint32>(m_cur_lookup_size);
  34. memcpy(m_lookup, other.m_lookup, sizeof(m_lookup[0]) * m_cur_lookup_size);
  35. }
  36. if (other.m_sorted_symbol_order)
  37. {
  38. m_sorted_symbol_order = crnlib_new_array<uint16>(m_cur_sorted_symbol_order_size);
  39. memcpy(m_sorted_symbol_order, other.m_sorted_symbol_order, sizeof(m_sorted_symbol_order[0]) * m_cur_sorted_symbol_order_size);
  40. }
  41. return *this;
  42. }
  43. inline void clear()
  44. {
  45. if (m_lookup)
  46. {
  47. crnlib_delete_array(m_lookup);
  48. m_lookup = 0;
  49. m_cur_lookup_size = 0;
  50. }
  51. if (m_sorted_symbol_order)
  52. {
  53. crnlib_delete_array(m_sorted_symbol_order);
  54. m_sorted_symbol_order = NULL;
  55. m_cur_sorted_symbol_order_size = 0;
  56. }
  57. }
  58. inline ~decoder_tables()
  59. {
  60. if (m_lookup)
  61. crnlib_delete_array(m_lookup);
  62. if (m_sorted_symbol_order)
  63. crnlib_delete_array(m_sorted_symbol_order);
  64. }
  65. // DO NOT use any complex classes here - it is bitwise copied.
  66. uint m_num_syms;
  67. uint m_total_used_syms;
  68. uint m_table_bits;
  69. uint m_table_shift;
  70. uint m_table_max_code;
  71. uint m_decode_start_code_size;
  72. uint8 m_min_code_size;
  73. uint8 m_max_code_size;
  74. uint m_max_codes[cMaxExpectedCodeSize + 1];
  75. int m_val_ptrs[cMaxExpectedCodeSize + 1];
  76. uint m_cur_lookup_size;
  77. uint32* m_lookup;
  78. uint m_cur_sorted_symbol_order_size;
  79. uint16* m_sorted_symbol_order;
  80. inline uint get_unshifted_max_code(uint len) const
  81. {
  82. CRNLIB_ASSERT( (len >= 1) && (len <= cMaxExpectedCodeSize) );
  83. uint k = m_max_codes[len - 1];
  84. if (!k)
  85. return UINT_MAX;
  86. return (k - 1) >> (16 - len);
  87. }
  88. };
  89. bool generate_decoder_tables(uint num_syms, const uint8* pCodesizes, decoder_tables* pTables, uint table_bits);
  90. } // namespace prefix_coding
  91. } // namespace crnlib