lzham_prefix_coding.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // File: lzham_prefix_coding.h
  2. // See Copyright Notice and license at the end of include/lzham.h
  3. #pragma once
  4. namespace lzham
  5. {
  6. namespace prefix_coding
  7. {
  8. const uint cMaxExpectedCodeSize = 16;
  9. const uint cMaxSupportedSyms = 1024;
  10. // This value can be tuned for a specific CPU.
  11. const uint cMaxTableBits = 11;
  12. bool limit_max_code_size(uint num_syms, uint8* pCodesizes, uint max_code_size);
  13. bool generate_codes(uint num_syms, const uint8* pCodesizes, uint16* pCodes);
  14. class decoder_tables
  15. {
  16. public:
  17. inline decoder_tables() :
  18. 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)
  19. {
  20. }
  21. inline decoder_tables(const decoder_tables& other) :
  22. 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)
  23. {
  24. *this = other;
  25. }
  26. inline decoder_tables& operator= (const decoder_tables& rhs)
  27. {
  28. assign(rhs);
  29. return *this;
  30. }
  31. inline bool assign(const decoder_tables& rhs)
  32. {
  33. if (this == &rhs)
  34. return true;
  35. uint32* pCur_lookup = m_lookup;
  36. uint16* pCur_sorted_symbol_order = m_sorted_symbol_order;
  37. memcpy(this, &rhs, sizeof(*this));
  38. if ((pCur_lookup) && (pCur_sorted_symbol_order) && (rhs.m_cur_lookup_size == m_cur_lookup_size) && (rhs.m_cur_sorted_symbol_order_size == m_cur_sorted_symbol_order_size))
  39. {
  40. m_lookup = pCur_lookup;
  41. m_sorted_symbol_order = pCur_sorted_symbol_order;
  42. memcpy(m_lookup, rhs.m_lookup, sizeof(m_lookup[0]) * m_cur_lookup_size);
  43. memcpy(m_sorted_symbol_order, rhs.m_sorted_symbol_order, sizeof(m_sorted_symbol_order[0]) * m_cur_sorted_symbol_order_size);
  44. }
  45. else
  46. {
  47. lzham_delete_array(pCur_lookup);
  48. m_lookup = NULL;
  49. if (rhs.m_lookup)
  50. {
  51. m_lookup = lzham_new_array<uint32>(m_cur_lookup_size);
  52. if (!m_lookup)
  53. return false;
  54. memcpy(m_lookup, rhs.m_lookup, sizeof(m_lookup[0]) * m_cur_lookup_size);
  55. }
  56. lzham_delete_array(pCur_sorted_symbol_order);
  57. m_sorted_symbol_order = NULL;
  58. if (rhs.m_sorted_symbol_order)
  59. {
  60. m_sorted_symbol_order = lzham_new_array<uint16>(m_cur_sorted_symbol_order_size);
  61. if (!m_sorted_symbol_order)
  62. return false;
  63. memcpy(m_sorted_symbol_order, rhs.m_sorted_symbol_order, sizeof(m_sorted_symbol_order[0]) * m_cur_sorted_symbol_order_size);
  64. }
  65. }
  66. return true;
  67. }
  68. inline void clear()
  69. {
  70. if (m_lookup)
  71. {
  72. lzham_delete_array(m_lookup);
  73. m_lookup = 0;
  74. m_cur_lookup_size = 0;
  75. }
  76. if (m_sorted_symbol_order)
  77. {
  78. lzham_delete_array(m_sorted_symbol_order);
  79. m_sorted_symbol_order = NULL;
  80. m_cur_sorted_symbol_order_size = 0;
  81. }
  82. }
  83. inline ~decoder_tables()
  84. {
  85. if (m_lookup)
  86. lzham_delete_array(m_lookup);
  87. if (m_sorted_symbol_order)
  88. lzham_delete_array(m_sorted_symbol_order);
  89. }
  90. // DO NOT use any complex classes here - it is bitwise copied.
  91. uint m_num_syms;
  92. uint m_total_used_syms;
  93. uint m_table_bits;
  94. uint m_table_shift;
  95. uint m_table_max_code;
  96. uint m_decode_start_code_size;
  97. uint8 m_min_code_size;
  98. uint8 m_max_code_size;
  99. uint m_max_codes[cMaxExpectedCodeSize + 1];
  100. int m_val_ptrs[cMaxExpectedCodeSize + 1];
  101. uint m_cur_lookup_size;
  102. uint32* m_lookup;
  103. uint m_cur_sorted_symbol_order_size;
  104. uint16* m_sorted_symbol_order;
  105. inline uint get_unshifted_max_code(uint len) const
  106. {
  107. LZHAM_ASSERT( (len >= 1) && (len <= cMaxExpectedCodeSize) );
  108. uint k = m_max_codes[len - 1];
  109. if (!k)
  110. return UINT_MAX;
  111. return (k - 1) >> (16 - len);
  112. }
  113. };
  114. bool generate_decoder_tables(uint num_syms, const uint8* pCodesizes, decoder_tables* pTables, uint table_bits);
  115. } // namespace prefix_coding
  116. } // namespace lzham