File: lzham_prefix_coding.h

package info (click to toggle)
p7zip 16.02%2Bdfsg-6
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 14,144 kB
  • sloc: cpp: 167,145; ansic: 14,992; python: 1,911; asm: 1,688; sh: 1,132; makefile: 701
file content (157 lines) | stat: -rw-r--r-- 5,581 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// File: lzham_prefix_coding.h
// See Copyright Notice and license at the end of include/lzham.h
#pragma once
#include "lzham_huffman_codes.h"

namespace lzham
{
   namespace prefix_coding
   {
      const uint cMaxSupportedSyms = 1024;
      
      // This value can be tuned for a specific CPU.
      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(lzham_malloc_context malloc_context) :
            m_malloc_context(malloc_context),
            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_malloc_context(other.m_malloc_context),
            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;
         }

         inline decoder_tables& operator= (const decoder_tables& rhs)
         {
            assign(rhs);
            return *this;
         }

         inline bool assign(const decoder_tables& rhs)
         {
            if (this == &rhs)
               return true;

            if (m_malloc_context != rhs.m_malloc_context)
            {
               clear();

               m_malloc_context = rhs.m_malloc_context;
            }

            uint32* pCur_lookup = m_lookup;
            uint16* pCur_sorted_symbol_order = m_sorted_symbol_order;

            memcpy(this, &rhs, sizeof(*this));

            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))
            {
               m_lookup = pCur_lookup;
               m_sorted_symbol_order = pCur_sorted_symbol_order;

               memcpy(m_lookup, rhs.m_lookup, sizeof(m_lookup[0]) * m_cur_lookup_size);
               memcpy(m_sorted_symbol_order, rhs.m_sorted_symbol_order, sizeof(m_sorted_symbol_order[0]) * m_cur_sorted_symbol_order_size);
            }
            else
            {
               lzham_delete_array(m_malloc_context, pCur_lookup);
               m_lookup = NULL;

               if (rhs.m_lookup)
               {
                  m_lookup = lzham_new_array<uint32>(m_malloc_context, m_cur_lookup_size);
                  if (!m_lookup)
                     return false;
                  memcpy(m_lookup, rhs.m_lookup, sizeof(m_lookup[0]) * m_cur_lookup_size);
               }

               lzham_delete_array(m_malloc_context, pCur_sorted_symbol_order);
               m_sorted_symbol_order = NULL;

               if (rhs.m_sorted_symbol_order)
               {
                  m_sorted_symbol_order = lzham_new_array<uint16>(m_malloc_context, m_cur_sorted_symbol_order_size);
                  if (!m_sorted_symbol_order)
                     return false;
                  memcpy(m_sorted_symbol_order, rhs.m_sorted_symbol_order, sizeof(m_sorted_symbol_order[0]) * m_cur_sorted_symbol_order_size);
               }
            }

            return true;
         }
         
         inline void clear()
         {
            if (m_lookup)
            {
               lzham_delete_array(m_malloc_context, m_lookup);
               m_lookup = 0;
               m_cur_lookup_size = 0;
            }

            if (m_sorted_symbol_order)
            {
               lzham_delete_array(m_malloc_context, m_sorted_symbol_order);
               m_sorted_symbol_order = NULL;
               m_cur_sorted_symbol_order_size = 0;
            }
         }

         inline ~decoder_tables()
         {
            if (m_lookup)
               lzham_delete_array(m_malloc_context, m_lookup);

            if (m_sorted_symbol_order)
               lzham_delete_array(m_malloc_context, m_sorted_symbol_order);
         }

         // DO NOT use any complex classes here - it is bitwise copied.
         
         lzham_malloc_context m_malloc_context;

         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[cMaxExpectedHuffCodeSize + 1];
         int                  m_val_ptrs[cMaxExpectedHuffCodeSize + 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
         {
            LZHAM_ASSERT( (len >= 1) && (len <= cMaxExpectedHuffCodeSize) );
            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, const code_size_histogram &code_size_histo, bool sym_freq_all_ones);

   } // namespace prefix_coding

} // namespace lzham