extlzham 0.0.1.PROTOTYPE3-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +27 -0
  3. data/README.md +74 -0
  4. data/Rakefile +152 -0
  5. data/contrib/lzham/LICENSE +22 -0
  6. data/contrib/lzham/README.md +209 -0
  7. data/contrib/lzham/include/lzham.h +781 -0
  8. data/contrib/lzham/lzhamcomp/lzham_comp.h +38 -0
  9. data/contrib/lzham/lzhamcomp/lzham_lzbase.cpp +244 -0
  10. data/contrib/lzham/lzhamcomp/lzham_lzbase.h +45 -0
  11. data/contrib/lzham/lzhamcomp/lzham_lzcomp.cpp +608 -0
  12. data/contrib/lzham/lzhamcomp/lzham_lzcomp_internal.cpp +1966 -0
  13. data/contrib/lzham/lzhamcomp/lzham_lzcomp_internal.h +472 -0
  14. data/contrib/lzham/lzhamcomp/lzham_lzcomp_state.cpp +1413 -0
  15. data/contrib/lzham/lzhamcomp/lzham_match_accel.cpp +562 -0
  16. data/contrib/lzham/lzhamcomp/lzham_match_accel.h +146 -0
  17. data/contrib/lzham/lzhamcomp/lzham_null_threading.h +97 -0
  18. data/contrib/lzham/lzhamcomp/lzham_pthreads_threading.cpp +229 -0
  19. data/contrib/lzham/lzhamcomp/lzham_pthreads_threading.h +520 -0
  20. data/contrib/lzham/lzhamcomp/lzham_threading.h +12 -0
  21. data/contrib/lzham/lzhamcomp/lzham_win32_threading.cpp +220 -0
  22. data/contrib/lzham/lzhamcomp/lzham_win32_threading.h +368 -0
  23. data/contrib/lzham/lzhamdecomp/lzham_assert.cpp +66 -0
  24. data/contrib/lzham/lzhamdecomp/lzham_assert.h +40 -0
  25. data/contrib/lzham/lzhamdecomp/lzham_checksum.cpp +73 -0
  26. data/contrib/lzham/lzhamdecomp/lzham_checksum.h +13 -0
  27. data/contrib/lzham/lzhamdecomp/lzham_config.h +23 -0
  28. data/contrib/lzham/lzhamdecomp/lzham_core.h +264 -0
  29. data/contrib/lzham/lzhamdecomp/lzham_decomp.h +37 -0
  30. data/contrib/lzham/lzhamdecomp/lzham_helpers.h +54 -0
  31. data/contrib/lzham/lzhamdecomp/lzham_huffman_codes.cpp +262 -0
  32. data/contrib/lzham/lzhamdecomp/lzham_huffman_codes.h +14 -0
  33. data/contrib/lzham/lzhamdecomp/lzham_lzdecomp.cpp +1527 -0
  34. data/contrib/lzham/lzhamdecomp/lzham_lzdecompbase.cpp +131 -0
  35. data/contrib/lzham/lzhamdecomp/lzham_lzdecompbase.h +89 -0
  36. data/contrib/lzham/lzhamdecomp/lzham_math.h +142 -0
  37. data/contrib/lzham/lzhamdecomp/lzham_mem.cpp +284 -0
  38. data/contrib/lzham/lzhamdecomp/lzham_mem.h +112 -0
  39. data/contrib/lzham/lzhamdecomp/lzham_platform.cpp +157 -0
  40. data/contrib/lzham/lzhamdecomp/lzham_platform.h +284 -0
  41. data/contrib/lzham/lzhamdecomp/lzham_prefix_coding.cpp +351 -0
  42. data/contrib/lzham/lzhamdecomp/lzham_prefix_coding.h +146 -0
  43. data/contrib/lzham/lzhamdecomp/lzham_symbol_codec.cpp +1484 -0
  44. data/contrib/lzham/lzhamdecomp/lzham_symbol_codec.h +556 -0
  45. data/contrib/lzham/lzhamdecomp/lzham_timer.cpp +147 -0
  46. data/contrib/lzham/lzhamdecomp/lzham_timer.h +99 -0
  47. data/contrib/lzham/lzhamdecomp/lzham_traits.h +141 -0
  48. data/contrib/lzham/lzhamdecomp/lzham_types.h +97 -0
  49. data/contrib/lzham/lzhamdecomp/lzham_utils.h +58 -0
  50. data/contrib/lzham/lzhamdecomp/lzham_vector.cpp +75 -0
  51. data/contrib/lzham/lzhamdecomp/lzham_vector.h +588 -0
  52. data/contrib/lzham/lzhamlib/lzham_lib.cpp +179 -0
  53. data/examples/basic.rb +48 -0
  54. data/ext/constants.c +64 -0
  55. data/ext/decoder.c +313 -0
  56. data/ext/depend +5 -0
  57. data/ext/encoder.c +372 -0
  58. data/ext/error.c +80 -0
  59. data/ext/extconf.rb +29 -0
  60. data/ext/extlzham.c +34 -0
  61. data/ext/extlzham.h +62 -0
  62. data/gemstub.rb +22 -0
  63. data/lib/2.0/extlzham.so +0 -0
  64. data/lib/2.1/extlzham.so +0 -0
  65. data/lib/2.2/extlzham.so +0 -0
  66. data/lib/extlzham.rb +158 -0
  67. data/lib/extlzham/version.rb +5 -0
  68. data/test/test_extlzham.rb +35 -0
  69. metadata +156 -0
@@ -0,0 +1,556 @@
1
+ // File: lzham_symbol_codec.h
2
+ // See Copyright Notice and license at the end of include/lzham.h
3
+ #pragma once
4
+ #include "lzham_prefix_coding.h"
5
+
6
+ namespace lzham
7
+ {
8
+ class symbol_codec;
9
+ class adaptive_arith_data_model;
10
+
11
+ const uint cSymbolCodecArithMinLen = 0x01000000U;
12
+ const uint cSymbolCodecArithMaxLen = 0xFFFFFFFFU;
13
+
14
+ const uint cSymbolCodecArithProbBits = 11;
15
+ const uint cSymbolCodecArithProbScale = 1 << cSymbolCodecArithProbBits;
16
+ const uint cSymbolCodecArithProbHalfScale = 1 << (cSymbolCodecArithProbBits - 1);
17
+ const uint cSymbolCodecArithProbMoveBits = 5;
18
+
19
+ typedef uint64 bit_cost_t;
20
+ const uint32 cBitCostScaleShift = 24;
21
+ const uint32 cBitCostScale = (1U << cBitCostScaleShift);
22
+ const bit_cost_t cBitCostMax = UINT64_MAX;
23
+
24
+ inline bit_cost_t convert_to_scaled_bitcost(uint bits) { LZHAM_ASSERT(bits <= 255); uint32 scaled_bits = bits << cBitCostScaleShift; return static_cast<bit_cost_t>(scaled_bits); }
25
+
26
+ extern uint32 g_prob_cost[cSymbolCodecArithProbScale];
27
+
28
+ class raw_quasi_adaptive_huffman_data_model
29
+ {
30
+ public:
31
+ raw_quasi_adaptive_huffman_data_model(bool encoding = false, uint total_syms = 0, uint max_update_interval = 0, uint adapt_rate = 0);
32
+ raw_quasi_adaptive_huffman_data_model(const raw_quasi_adaptive_huffman_data_model& other);
33
+ ~raw_quasi_adaptive_huffman_data_model();
34
+
35
+ bool assign(const raw_quasi_adaptive_huffman_data_model& rhs);
36
+ raw_quasi_adaptive_huffman_data_model& operator= (const raw_quasi_adaptive_huffman_data_model& rhs);
37
+
38
+ void clear();
39
+
40
+ bool init2(bool encoding, uint total_syms, uint max_update_interval, uint adapt_rate, const uint16 *pInitial_sym_freq);
41
+ bool reset();
42
+
43
+ inline uint get_total_syms() const { return m_total_syms; }
44
+
45
+ void rescale();
46
+ void reset_update_rate();
47
+
48
+ bool update_sym(uint sym);
49
+
50
+ inline bit_cost_t get_cost(uint sym) const { return convert_to_scaled_bitcost(m_code_sizes[sym]); }
51
+
52
+ public:
53
+ lzham::vector<uint16> m_initial_sym_freq;
54
+
55
+ lzham::vector<uint16> m_sym_freq;
56
+
57
+ lzham::vector<uint16> m_codes;
58
+ lzham::vector<uint8> m_code_sizes;
59
+
60
+ prefix_coding::decoder_tables* m_pDecode_tables;
61
+
62
+ uint m_total_syms;
63
+
64
+ uint m_max_cycle;
65
+ uint m_update_cycle;
66
+ uint m_symbols_until_update;
67
+
68
+ uint m_total_count;
69
+
70
+ uint8 m_decoder_table_bits;
71
+ uint16 m_max_update_interval; // def=16, typical range 12-128, controls the max interval between table updates, higher=longer max interval (faster decode/lower ratio)
72
+ uint16 m_adapt_rate; // def=10, 8 or higher, scaled by 8, controls the slowing of the update update freq, higher=more rapid slowing (faster decode/lower ratio)
73
+ bool m_encoding;
74
+
75
+ bool update_tables(int force_update_cycle = -1, bool sym_freq_all_ones = false);
76
+
77
+ friend class symbol_codec;
78
+ };
79
+
80
+ struct quasi_adaptive_huffman_data_model : public raw_quasi_adaptive_huffman_data_model
81
+ {
82
+ #if LZHAM_64BIT_POINTERS
83
+ // Ensures sizeof(quasi_adaptive_huffman_data_model) is 128 bytes on x64 (it's 64 on x86).
84
+ char m_unused_alignment[128 - sizeof(raw_quasi_adaptive_huffman_data_model)];
85
+ #endif
86
+ };
87
+
88
+ class adaptive_bit_model
89
+ {
90
+ public:
91
+ inline adaptive_bit_model() { clear(); }
92
+ adaptive_bit_model(float prob0);
93
+ adaptive_bit_model(const adaptive_bit_model& other);
94
+
95
+ inline adaptive_bit_model& operator= (const adaptive_bit_model& rhs) { m_bit_0_prob = rhs.m_bit_0_prob; return *this; }
96
+
97
+ inline void clear() { m_bit_0_prob = 1U << (cSymbolCodecArithProbBits - 1); }
98
+
99
+ void set_probability_0(float prob0);
100
+
101
+ inline void update(uint bit)
102
+ {
103
+ if (!bit)
104
+ m_bit_0_prob += ((cSymbolCodecArithProbScale - m_bit_0_prob) >> cSymbolCodecArithProbMoveBits);
105
+ else
106
+ m_bit_0_prob -= (m_bit_0_prob >> cSymbolCodecArithProbMoveBits);
107
+ LZHAM_ASSERT(m_bit_0_prob >= 1);
108
+ LZHAM_ASSERT(m_bit_0_prob < cSymbolCodecArithProbScale);
109
+ }
110
+
111
+ inline bit_cost_t get_cost(uint bit) const { return g_prob_cost[bit ? (cSymbolCodecArithProbScale - m_bit_0_prob) : m_bit_0_prob]; }
112
+
113
+ public:
114
+ uint16 m_bit_0_prob;
115
+
116
+ friend class symbol_codec;
117
+ friend class adaptive_arith_data_model;
118
+ };
119
+
120
+ // This class is not actually used by LZHAM - it's only here for comparison/experimental purposes.
121
+ class adaptive_arith_data_model
122
+ {
123
+ public:
124
+ adaptive_arith_data_model(bool encoding = true, uint total_syms = 0);
125
+ adaptive_arith_data_model(const adaptive_arith_data_model& other);
126
+ ~adaptive_arith_data_model();
127
+
128
+ adaptive_arith_data_model& operator= (const adaptive_arith_data_model& rhs);
129
+
130
+ void clear();
131
+
132
+ bool init(bool encoding, uint total_syms);
133
+ bool init(bool encoding, uint total_syms, bool fast_encoding) { LZHAM_NOTE_UNUSED(fast_encoding); return init(encoding, total_syms); }
134
+ void reset();
135
+
136
+ void reset_update_rate();
137
+
138
+ bool update(uint sym);
139
+
140
+ uint get_total_syms() const { return m_total_syms; }
141
+ bit_cost_t get_cost(uint sym) const;
142
+
143
+ public:
144
+ uint m_total_syms;
145
+ typedef lzham::vector<adaptive_bit_model> adaptive_bit_model_vector;
146
+ adaptive_bit_model_vector m_probs;
147
+
148
+ friend class symbol_codec;
149
+ };
150
+
151
+ #if LZHAM_CPU_HAS_64BIT_REGISTERS
152
+ #define LZHAM_SYMBOL_CODEC_USE_64_BIT_BUFFER 1
153
+ #else
154
+ #define LZHAM_SYMBOL_CODEC_USE_64_BIT_BUFFER 0
155
+ #endif
156
+
157
+ class symbol_codec
158
+ {
159
+ public:
160
+ symbol_codec();
161
+
162
+ void reset();
163
+
164
+ // clear() is like reset(), except it also frees all memory.
165
+ void clear();
166
+
167
+ // Encoding
168
+ bool start_encoding(uint expected_file_size);
169
+ bool encode_bits(uint bits, uint num_bits);
170
+ bool encode_arith_init();
171
+ bool encode_align_to_byte();
172
+ bool encode(uint sym, quasi_adaptive_huffman_data_model& model);
173
+ bool encode(uint bit, adaptive_bit_model& model, bool update_model = true);
174
+ bool encode(uint sym, adaptive_arith_data_model& model);
175
+
176
+ inline uint encode_get_total_bits_written() const { return m_total_bits_written; }
177
+
178
+ bool stop_encoding(bool support_arith);
179
+
180
+ const lzham::vector<uint8>& get_encoding_buf() const { return m_output_buf; }
181
+ lzham::vector<uint8>& get_encoding_buf() { return m_output_buf; }
182
+
183
+ // Decoding
184
+
185
+ typedef void (*need_bytes_func_ptr)(size_t num_bytes_consumed, void *pPrivate_data, const uint8* &pBuf, size_t &buf_size, bool &eof_flag);
186
+
187
+ bool start_decoding(const uint8* pBuf, size_t buf_size, bool eof_flag = true, need_bytes_func_ptr pNeed_bytes_func = NULL, void *pPrivate_data = NULL);
188
+
189
+ inline void decode_set_input_buffer(const uint8* pBuf, size_t buf_size, const uint8* pBuf_next, bool eof_flag)
190
+ {
191
+ m_pDecode_buf = pBuf;
192
+ m_pDecode_buf_next = pBuf_next;
193
+ m_decode_buf_size = buf_size;
194
+ m_pDecode_buf_end = pBuf + buf_size;
195
+ m_decode_buf_eof = eof_flag;
196
+ }
197
+ inline uint64 decode_get_bytes_consumed() const { return m_pDecode_buf_next - m_pDecode_buf; }
198
+ inline uint64 decode_get_bits_remaining() const { return ((m_pDecode_buf_end - m_pDecode_buf_next) << 3) + m_bit_count; }
199
+
200
+ void start_arith_decoding();
201
+ uint decode_bits(uint num_bits);
202
+ uint decode_peek_bits(uint num_bits);
203
+ void decode_remove_bits(uint num_bits);
204
+ void decode_align_to_byte();
205
+ int decode_remove_byte_from_bit_buf();
206
+ uint decode(quasi_adaptive_huffman_data_model& model);
207
+ uint decode(adaptive_bit_model& model, bool update_model = true);
208
+ uint decode(adaptive_arith_data_model& model);
209
+ uint64 stop_decoding();
210
+
211
+ uint get_total_model_updates() const { return m_total_model_updates; }
212
+
213
+ public:
214
+ const uint8* m_pDecode_buf;
215
+ const uint8* m_pDecode_buf_next;
216
+ const uint8* m_pDecode_buf_end;
217
+ size_t m_decode_buf_size;
218
+ bool m_decode_buf_eof;
219
+
220
+ need_bytes_func_ptr m_pDecode_need_bytes_func;
221
+ void* m_pDecode_private_data;
222
+
223
+ #if LZHAM_SYMBOL_CODEC_USE_64_BIT_BUFFER
224
+ typedef uint64 bit_buf_t;
225
+ enum { cBitBufSize = 64 };
226
+ #else
227
+ typedef uint32 bit_buf_t;
228
+ enum { cBitBufSize = 32 };
229
+ #endif
230
+
231
+ bit_buf_t m_bit_buf;
232
+ int m_bit_count;
233
+
234
+ uint m_total_model_updates;
235
+
236
+ lzham::vector<uint8> m_output_buf;
237
+ lzham::vector<uint8> m_arith_output_buf;
238
+
239
+ struct output_symbol
240
+ {
241
+ uint m_bits;
242
+
243
+ enum
244
+ {
245
+ cArithSym = -1,
246
+ cAlignToByteSym = -2,
247
+ cArithInit = -3
248
+ };
249
+ int16 m_num_bits;
250
+
251
+ uint16 m_arith_prob0;
252
+ };
253
+ lzham::vector<output_symbol> m_output_syms;
254
+
255
+ uint m_total_bits_written;
256
+
257
+ uint m_arith_base;
258
+ uint m_arith_value;
259
+ uint m_arith_length;
260
+ uint m_arith_total_bits;
261
+
262
+ quasi_adaptive_huffman_data_model* m_pSaved_huff_model;
263
+ void* m_pSaved_model;
264
+ uint m_saved_node_index;
265
+
266
+ bool put_bits_init(uint expected_size);
267
+ bool record_put_bits(uint bits, uint num_bits);
268
+
269
+ void arith_propagate_carry();
270
+ bool arith_renorm_enc_interval();
271
+ void arith_start_encoding();
272
+ bool arith_stop_encoding();
273
+
274
+ bool put_bits(uint bits, uint num_bits);
275
+ bool put_bits_align_to_byte();
276
+ bool flush_bits();
277
+ bool assemble_output_buf();
278
+
279
+ uint get_bits(uint num_bits);
280
+ void remove_bits(uint num_bits);
281
+
282
+ void decode_need_bytes();
283
+
284
+ enum
285
+ {
286
+ cNull,
287
+ cEncoding,
288
+ cDecoding
289
+ } m_mode;
290
+ };
291
+
292
+ // Optional macros for faster decompression. These macros implement the symbol_codec class's decode functionality.
293
+ // This is hard to debug (and just plain ugly), but using these macros eliminate function calls, and they place the most important
294
+ // member variables on the stack so they're hopefully put in registers (avoiding horrible load hit stores on some CPU's).
295
+ // The user must define the LZHAM_DECODE_NEEDS_BYTES macro, which is invoked when the decode buffer is exhausted.
296
+
297
+ #define LZHAM_SYMBOL_CODEC_DECODE_DECLARE(codec) \
298
+ uint arith_value = 0; \
299
+ uint arith_length = 0; \
300
+ symbol_codec::bit_buf_t bit_buf = 0; \
301
+ int bit_count = 0; \
302
+ const uint8* pDecode_buf_next = NULL;
303
+
304
+ #define LZHAM_SYMBOL_CODEC_DECODE_BEGIN(codec) \
305
+ arith_value = codec.m_arith_value; \
306
+ arith_length = codec.m_arith_length; \
307
+ bit_buf = codec.m_bit_buf; \
308
+ bit_count = codec.m_bit_count; \
309
+ pDecode_buf_next = codec.m_pDecode_buf_next;
310
+
311
+ #define LZHAM_SYMBOL_CODEC_DECODE_END(codec) \
312
+ codec.m_arith_value = arith_value; \
313
+ codec.m_arith_length = arith_length; \
314
+ codec.m_bit_buf = bit_buf; \
315
+ codec.m_bit_count = bit_count; \
316
+ codec.m_pDecode_buf_next = pDecode_buf_next;
317
+
318
+ // The user must declare the LZHAM_DECODE_NEEDS_BYTES macro.
319
+
320
+ #define LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, result, num_bits) \
321
+ { \
322
+ while (LZHAM_BUILTIN_EXPECT(bit_count < (int)(num_bits), 0)) \
323
+ { \
324
+ uint r; \
325
+ if (LZHAM_BUILTIN_EXPECT(pDecode_buf_next == codec.m_pDecode_buf_end, 0)) \
326
+ { \
327
+ if (LZHAM_BUILTIN_EXPECT(!codec.m_decode_buf_eof, 1)) \
328
+ { \
329
+ LZHAM_SYMBOL_CODEC_DECODE_END(codec) \
330
+ LZHAM_DECODE_NEEDS_BYTES \
331
+ LZHAM_SYMBOL_CODEC_DECODE_BEGIN(codec) \
332
+ } \
333
+ r = 0; \
334
+ if (LZHAM_BUILTIN_EXPECT(pDecode_buf_next < codec.m_pDecode_buf_end, 1)) r = *pDecode_buf_next++; \
335
+ } \
336
+ else \
337
+ r = *pDecode_buf_next++; \
338
+ bit_count += 8; \
339
+ bit_buf |= (static_cast<symbol_codec::bit_buf_t>(r) << (symbol_codec::cBitBufSize - bit_count)); \
340
+ } \
341
+ result = (num_bits) ? static_cast<uint>(bit_buf >> (symbol_codec::cBitBufSize - (num_bits))) : 0; \
342
+ bit_buf <<= (num_bits); \
343
+ bit_count -= (num_bits); \
344
+ }
345
+
346
+ #define LZHAM_SYMBOL_CODEC_DECODE_ARITH_BIT(codec, result, model) \
347
+ { \
348
+ adaptive_bit_model *pModel; \
349
+ pModel = &model; \
350
+ while (LZHAM_BUILTIN_EXPECT(arith_length < cSymbolCodecArithMinLen, 0)) \
351
+ { \
352
+ uint c; codec.m_pSaved_model = pModel; \
353
+ LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, c, 8); \
354
+ pModel = static_cast<adaptive_bit_model*>(codec.m_pSaved_model); \
355
+ arith_value = (arith_value << 8) | c; \
356
+ arith_length <<= 8; \
357
+ } \
358
+ uint x = pModel->m_bit_0_prob * (arith_length >> cSymbolCodecArithProbBits); \
359
+ result = (arith_value >= x); \
360
+ if (!result) \
361
+ { \
362
+ pModel->m_bit_0_prob += ((cSymbolCodecArithProbScale - pModel->m_bit_0_prob) >> cSymbolCodecArithProbMoveBits); \
363
+ arith_length = x; \
364
+ } \
365
+ else \
366
+ { \
367
+ pModel->m_bit_0_prob -= (pModel->m_bit_0_prob >> cSymbolCodecArithProbMoveBits); \
368
+ arith_value -= x; \
369
+ arith_length -= x; \
370
+ } \
371
+ }
372
+
373
+ #define LZHAM_SYMBOL_CODEC_DECODE_ADAPTIVE_ARITHMETIC(codec, result, model) \
374
+ { \
375
+ adaptive_arith_data_model *pArith_data_model; \
376
+ pArith_data_model = &model; \
377
+ uint node_index; \
378
+ node_index = 1; \
379
+ do \
380
+ { \
381
+ while (LZHAM_BUILTIN_EXPECT(arith_length < cSymbolCodecArithMinLen, 0)) \
382
+ { \
383
+ uint c; codec.m_saved_node_index = node_index; codec.m_pSaved_model = pArith_data_model; \
384
+ LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, c, 8); \
385
+ node_index = codec.m_saved_node_index; pArith_data_model = static_cast<adaptive_arith_data_model *>(codec.m_pSaved_model); \
386
+ arith_value = (arith_value << 8) | c; \
387
+ arith_length <<= 8; \
388
+ } \
389
+ adaptive_bit_model *pBit_model; pBit_model = &pArith_data_model->m_probs[node_index]; \
390
+ uint x = pBit_model->m_bit_0_prob * (arith_length >> cSymbolCodecArithProbBits); \
391
+ uint bit; bit = (arith_value >= x); \
392
+ if (!bit) \
393
+ { \
394
+ pBit_model->m_bit_0_prob += ((cSymbolCodecArithProbScale - pBit_model->m_bit_0_prob) >> cSymbolCodecArithProbMoveBits); \
395
+ arith_length = x; \
396
+ } \
397
+ else \
398
+ { \
399
+ pBit_model->m_bit_0_prob -= (pBit_model->m_bit_0_prob >> cSymbolCodecArithProbMoveBits); \
400
+ arith_value -= x; \
401
+ arith_length -= x; \
402
+ } \
403
+ node_index = (node_index << 1) + bit; \
404
+ } while (node_index < pArith_data_model->m_total_syms); \
405
+ result = node_index - pArith_data_model->m_total_syms; \
406
+ }
407
+
408
+ #if LZHAM_SYMBOL_CODEC_USE_64_BIT_BUFFER
409
+ #define LZHAM_SYMBOL_CODEC_DECODE_ADAPTIVE_HUFFMAN(codec, result, model) \
410
+ { \
411
+ quasi_adaptive_huffman_data_model* pModel; const prefix_coding::decoder_tables* pTables; \
412
+ pModel = &model; pTables = model.m_pDecode_tables; \
413
+ if (LZHAM_BUILTIN_EXPECT(bit_count < 24, 0)) \
414
+ { \
415
+ uint c; \
416
+ pDecode_buf_next += sizeof(uint32); \
417
+ if (LZHAM_BUILTIN_EXPECT(pDecode_buf_next >= codec.m_pDecode_buf_end, 0)) \
418
+ { \
419
+ pDecode_buf_next -= sizeof(uint32); \
420
+ while (bit_count < 24) \
421
+ { \
422
+ if (!codec.m_decode_buf_eof) \
423
+ { \
424
+ codec.m_pSaved_huff_model = pModel; \
425
+ LZHAM_SYMBOL_CODEC_DECODE_END(codec) \
426
+ LZHAM_DECODE_NEEDS_BYTES \
427
+ LZHAM_SYMBOL_CODEC_DECODE_BEGIN(codec) \
428
+ pModel = codec.m_pSaved_huff_model; pTables = pModel->m_pDecode_tables; \
429
+ } \
430
+ c = 0; if (pDecode_buf_next < codec.m_pDecode_buf_end) c = *pDecode_buf_next++; \
431
+ bit_count += 8; \
432
+ bit_buf |= (static_cast<symbol_codec::bit_buf_t>(c) << (symbol_codec::cBitBufSize - bit_count)); \
433
+ } \
434
+ } \
435
+ else \
436
+ { \
437
+ c = LZHAM_READ_BIG_ENDIAN_UINT32(pDecode_buf_next - sizeof(uint32)); \
438
+ bit_count += 32; \
439
+ bit_buf |= (static_cast<symbol_codec::bit_buf_t>(c) << (symbol_codec::cBitBufSize - bit_count)); \
440
+ } \
441
+ } \
442
+ uint k = static_cast<uint>((bit_buf >> (symbol_codec::cBitBufSize - 16)) + 1); \
443
+ uint len; \
444
+ if (LZHAM_BUILTIN_EXPECT(k <= pTables->m_table_max_code, 1)) \
445
+ { \
446
+ uint32 t = pTables->m_lookup[bit_buf >> (symbol_codec::cBitBufSize - pTables->m_table_bits)]; \
447
+ result = t & UINT16_MAX; \
448
+ len = t >> 16; \
449
+ } \
450
+ else \
451
+ { \
452
+ len = pTables->m_decode_start_code_size; \
453
+ for ( ; ; ) \
454
+ { \
455
+ if (LZHAM_BUILTIN_EXPECT(k <= pTables->m_max_codes[len - 1], 0)) \
456
+ break; \
457
+ len++; \
458
+ } \
459
+ int val_ptr = pTables->m_val_ptrs[len - 1] + static_cast<int>(bit_buf >> (symbol_codec::cBitBufSize - len)); \
460
+ if (((uint)val_ptr >= pModel->m_total_syms)) val_ptr = 0; \
461
+ result = pTables->m_sorted_symbol_order[val_ptr]; \
462
+ } \
463
+ bit_buf <<= len; \
464
+ bit_count -= len; \
465
+ uint freq = pModel->m_sym_freq[result]; \
466
+ freq++; \
467
+ pModel->m_sym_freq[result] = static_cast<uint16>(freq); \
468
+ LZHAM_ASSERT(freq <= UINT16_MAX); \
469
+ if (LZHAM_BUILTIN_EXPECT(--pModel->m_symbols_until_update == 0, 0)) \
470
+ { \
471
+ pModel->update_tables(); \
472
+ } \
473
+ }
474
+ #else
475
+ #define LZHAM_SYMBOL_CODEC_DECODE_ADAPTIVE_HUFFMAN(codec, result, model) \
476
+ { \
477
+ quasi_adaptive_huffman_data_model* pModel; const prefix_coding::decoder_tables* pTables; \
478
+ pModel = &model; pTables = model.m_pDecode_tables; \
479
+ while (LZHAM_BUILTIN_EXPECT(bit_count < (symbol_codec::cBitBufSize - 8), 1)) \
480
+ { \
481
+ uint c; \
482
+ if (LZHAM_BUILTIN_EXPECT(pDecode_buf_next == codec.m_pDecode_buf_end, 0)) \
483
+ { \
484
+ if (LZHAM_BUILTIN_EXPECT(!codec.m_decode_buf_eof, 1)) \
485
+ { \
486
+ codec.m_pSaved_huff_model = pModel; \
487
+ LZHAM_SYMBOL_CODEC_DECODE_END(codec) \
488
+ LZHAM_DECODE_NEEDS_BYTES \
489
+ LZHAM_SYMBOL_CODEC_DECODE_BEGIN(codec) \
490
+ pModel = codec.m_pSaved_huff_model; pTables = pModel->m_pDecode_tables; \
491
+ } \
492
+ c = 0; if (LZHAM_BUILTIN_EXPECT(pDecode_buf_next < codec.m_pDecode_buf_end, 1)) c = *pDecode_buf_next++; \
493
+ } \
494
+ else \
495
+ c = *pDecode_buf_next++; \
496
+ bit_count += 8; \
497
+ bit_buf |= (static_cast<symbol_codec::bit_buf_t>(c) << (symbol_codec::cBitBufSize - bit_count)); \
498
+ } \
499
+ uint k = static_cast<uint>((bit_buf >> (symbol_codec::cBitBufSize - 16)) + 1); \
500
+ uint len; \
501
+ if (LZHAM_BUILTIN_EXPECT(k <= pTables->m_table_max_code, 1)) \
502
+ { \
503
+ uint32 t = pTables->m_lookup[bit_buf >> (symbol_codec::cBitBufSize - pTables->m_table_bits)]; \
504
+ result = t & UINT16_MAX; \
505
+ len = t >> 16; \
506
+ } \
507
+ else \
508
+ { \
509
+ len = pTables->m_decode_start_code_size; \
510
+ for ( ; ; ) \
511
+ { \
512
+ if (LZHAM_BUILTIN_EXPECT(k <= pTables->m_max_codes[len - 1], 0)) \
513
+ break; \
514
+ len++; \
515
+ } \
516
+ int val_ptr = pTables->m_val_ptrs[len - 1] + static_cast<int>(bit_buf >> (symbol_codec::cBitBufSize - len)); \
517
+ if (LZHAM_BUILTIN_EXPECT(((uint)val_ptr >= pModel->m_total_syms), 0)) val_ptr = 0; \
518
+ result = pTables->m_sorted_symbol_order[val_ptr]; \
519
+ } \
520
+ bit_buf <<= len; \
521
+ bit_count -= len; \
522
+ uint freq = pModel->m_sym_freq[result]; \
523
+ freq++; \
524
+ pModel->m_sym_freq[result] = static_cast<uint16>(freq); \
525
+ LZHAM_ASSERT(freq <= UINT16_MAX); \
526
+ if (LZHAM_BUILTIN_EXPECT(--pModel->m_symbols_until_update == 0, 0)) \
527
+ { \
528
+ pModel->update_tables(); \
529
+ } \
530
+ }
531
+ #endif
532
+
533
+ #define LZHAM_SYMBOL_CODEC_DECODE_ALIGN_TO_BYTE(codec) if (bit_count & 7) { int dummy_result; LZHAM_NOTE_UNUSED(dummy_result); LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, dummy_result, bit_count & 7); }
534
+
535
+ #define LZHAM_SYMBOL_CODEC_DECODE_REMOVE_BYTE_FROM_BIT_BUF(codec, result) \
536
+ { \
537
+ result = -1; \
538
+ if (bit_count >= 8) \
539
+ { \
540
+ result = static_cast<int>(bit_buf >> (symbol_codec::cBitBufSize - 8)); \
541
+ bit_buf <<= 8; \
542
+ bit_count -= 8; \
543
+ } \
544
+ }
545
+
546
+ #define LZHAM_SYMBOL_CODEC_DECODE_ARITH_START(codec) \
547
+ { \
548
+ for ( arith_value = 0, arith_length = 0; arith_length < 4; ++arith_length ) \
549
+ { \
550
+ uint val; LZHAM_SYMBOL_CODEC_DECODE_GET_BITS(codec, val, 8); \
551
+ arith_value = (arith_value << 8) | val; \
552
+ } \
553
+ arith_length = cSymbolCodecArithMaxLen; \
554
+ }
555
+
556
+ } // namespace lzham