extlzham 0.0.1.PROTOTYPE

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.md +27 -0
  3. data/README.md +21 -0
  4. data/Rakefile +143 -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/extconf.rb +26 -0
  55. data/ext/extlzham.c +741 -0
  56. data/gemstub.rb +22 -0
  57. data/lib/extlzham/version.rb +5 -0
  58. data/lib/extlzham.rb +153 -0
  59. metadata +135 -0
@@ -0,0 +1,131 @@
1
+ // File: lzham_lzdecompbase.cpp
2
+ // See Copyright Notice and license at the end of include/lzham.h
3
+ #include "lzham_core.h"
4
+ #include "lzham_lzdecompbase.h"
5
+
6
+ namespace lzham
7
+ {
8
+ // Keep in sync with LZHAM_DEFAULT_ADAPT_RATE, and LZHAM_DEFAULT_TABLE_UPDATE_RATE, etc.
9
+ table_update_settings g_table_update_settings[] =
10
+ {
11
+ { 4, 32 }, // crazy slow!
12
+ { 5, 33 },
13
+ { 6, 34 },
14
+ { 7, 35 },
15
+ { 8, 36 },
16
+
17
+ { 16, 48 },
18
+ { 32, 72 },
19
+ { 64, 64 }, // codec's internal default
20
+ { 98, 80 },
21
+ { 128, 96 },
22
+
23
+ { 192, 112 },
24
+ { 256, 128 },
25
+ { 512, 128+16*2 },
26
+ { 1024, 128+16*4 },
27
+ { 2048, 128+16*6 },
28
+
29
+ { 2048, 128+16*8 },
30
+ { 2048, 128+16*10 },
31
+ { 2048, 128+16*12 },
32
+ { 2048, 128+16*14 },
33
+ { 2048, 128+16*16 }
34
+ };
35
+
36
+ uint CLZDecompBase::m_lzx_position_base[CLZDecompBase::cLZXMaxPositionSlots] =
37
+ {
38
+ 0x0, 0x1, 0x2, 0x3, 0x4, 0x6, 0x8, 0xC, 0x10, 0x18, 0x20, 0x30, 0x40, 0x60, 0x80, 0xC0,
39
+ 0x100, 0x180, 0x200, 0x300, 0x400, 0x600, 0x800, 0xC00, 0x1000, 0x1800, 0x2000, 0x3000, 0x4000, 0x6000, 0x8000, 0xC000,
40
+ 0x10000, 0x18000, 0x20000, 0x30000, 0x40000, 0x60000, 0x80000, 0xC0000, 0x100000, 0x180000, 0x200000, 0x300000, 0x400000, 0x600000, 0x800000, 0xC00000,
41
+ 0x1000000, 0x1800000, 0x2000000, 0x3000000, 0x4000000, 0x6000000, 0x8000000, 0xA000000, 0xC000000, 0xE000000, 0x10000000, 0x12000000, 0x14000000, 0x16000000, 0x18000000, 0x1A000000,
42
+ 0x1C000000, 0x1E000000, 0x20000000, 0x22000000, 0x24000000, 0x26000000, 0x28000000, 0x2A000000, 0x2C000000, 0x2E000000, 0x30000000, 0x32000000, 0x34000000, 0x36000000, 0x38000000, 0x3A000000,
43
+ 0x3C000000, 0x3E000000, 0x40000000, 0x42000000, 0x44000000, 0x46000000, 0x48000000, 0x4A000000, 0x4C000000, 0x4E000000, 0x50000000, 0x52000000, 0x54000000, 0x56000000, 0x58000000, 0x5A000000,
44
+ 0x5C000000, 0x5E000000, 0x60000000, 0x62000000, 0x64000000, 0x66000000, 0x68000000, 0x6A000000, 0x6C000000, 0x6E000000, 0x70000000, 0x72000000, 0x74000000, 0x76000000, 0x78000000, 0x7A000000,
45
+ 0x7C000000, 0x7E000000, 0x80000000, 0x82000000, 0x84000000, 0x86000000, 0x88000000, 0x8A000000, 0x8C000000, 0x8E000000, 0x90000000, 0x92000000, 0x94000000, 0x96000000, 0x98000000, 0x9A000000,
46
+ };
47
+
48
+ uint CLZDecompBase::m_lzx_position_extra_mask[CLZDecompBase::cLZXMaxPositionSlots] =
49
+ {
50
+ 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x3, 0x3, 0x7, 0x7, 0xF, 0xF, 0x1F, 0x1F, 0x3F, 0x3F,
51
+ 0x7F, 0x7F, 0xFF, 0xFF, 0x1FF, 0x1FF, 0x3FF, 0x3FF, 0x7FF, 0x7FF, 0xFFF, 0xFFF, 0x1FFF, 0x1FFF, 0x3FFF, 0x3FFF,
52
+ 0x7FFF, 0x7FFF, 0xFFFF, 0xFFFF, 0x1FFFF, 0x1FFFF, 0x3FFFF, 0x3FFFF, 0x7FFFF, 0x7FFFF, 0xFFFFF, 0xFFFFF, 0x1FFFFF, 0x1FFFFF, 0x3FFFFF, 0x3FFFFF,
53
+ 0x7FFFFF, 0x7FFFFF, 0xFFFFFF, 0xFFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF,
54
+ 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF,
55
+ 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF,
56
+ 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF,
57
+ 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF, 0x1FFFFFF
58
+ };
59
+
60
+ uint8 CLZDecompBase::m_lzx_position_extra_bits[CLZDecompBase::cLZXMaxPositionSlots] =
61
+ {
62
+ 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x2, 0x2, 0x3, 0x3, 0x4, 0x4, 0x5, 0x5, 0x6, 0x6,
63
+ 0x7, 0x7, 0x8, 0x8, 0x9, 0x9, 0xA, 0xA, 0xB, 0xB, 0xC, 0xC, 0xD, 0xD, 0xE, 0xE,
64
+ 0xF, 0xF, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14, 0x15, 0x15, 0x16, 0x16,
65
+ 0x17, 0x17, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
66
+ 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
67
+ 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
68
+ 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
69
+ 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19
70
+ };
71
+
72
+ static const uint8 g_num_lzx_position_slots[] = { 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 58, 66 };
73
+
74
+ void CLZDecompBase::init_position_slots(uint dict_size_log2)
75
+ {
76
+ LZHAM_ASSERT(dict_size_log2 >= LZHAM_MIN_DICT_SIZE_LOG2);
77
+ LZHAM_ASSERT(dict_size_log2 <= LZHAM_MAX_DICT_SIZE_LOG2_X64);
78
+ LZHAM_ASSERT((sizeof(g_table_update_settings) / sizeof(g_table_update_settings[0])) == LZHAM_FASTEST_TABLE_UPDATE_RATE);
79
+
80
+ //for (dict_size_log2 = LZHAM_MIN_DICT_SIZE_LOG2; dict_size_log2 <= LZHAM_MAX_DICT_SIZE_LOG2_X64; dict_size_log2++) {
81
+
82
+ m_dict_size_log2 = dict_size_log2;
83
+ m_dict_size = 1U << dict_size_log2;
84
+ m_num_lzx_slots = g_num_lzx_position_slots[dict_size_log2 - LZHAM_MIN_DICT_SIZE_LOG2];
85
+
86
+ #if 0
87
+ int i, j;
88
+ for (i = 0, j = 0; i < cLZXMaxPositionSlots; i += 2)
89
+ {
90
+ m_lzx_position_extra_bits[i] = (uint8)j;
91
+ m_lzx_position_extra_bits[i + 1] = (uint8)j;
92
+
93
+ if ((i != 0) && (j < 25))
94
+ j++;
95
+ }
96
+
97
+ for (i = 0, j = 0; i < cLZXMaxPositionSlots; i++)
98
+ {
99
+ m_lzx_position_base[i] = j;
100
+ m_lzx_position_extra_mask[i] = (1 << m_lzx_position_extra_bits[i]) - 1;
101
+ j += (1 << m_lzx_position_extra_bits[i]);
102
+ }
103
+
104
+ for (uint i = 0; i < cLZXMaxPositionSlots; i++)
105
+ {
106
+ printf("0x%X, ", m_lzx_position_base[i]);
107
+ if ((i & 15) == 15) printf("\n");
108
+ }
109
+ #endif
110
+
111
+ #if 0
112
+ m_num_lzx_slots = 0;
113
+
114
+ const uint largest_dist = m_dict_size - 1;
115
+ for (i = 0; i < cLZXMaxPositionSlots; i++)
116
+ {
117
+ if ( (largest_dist >= m_lzx_position_base[i]) &&
118
+ (largest_dist < (m_lzx_position_base[i] + (1 << m_lzx_position_extra_bits[i])) ) )
119
+ {
120
+ m_num_lzx_slots = i + 1;
121
+ break;
122
+ }
123
+ }
124
+
125
+ LZHAM_VERIFY(m_num_lzx_slots);
126
+ #endif
127
+
128
+ //printf("%u, ", m_num_lzx_slots); }
129
+ }
130
+
131
+ } //namespace lzham
@@ -0,0 +1,89 @@
1
+ // File: lzham_lzdecompbase.h
2
+ // See Copyright Notice and license at the end of include/lzham.h
3
+ #pragma once
4
+
5
+ //#define LZHAM_LZDEBUG
6
+
7
+ #define LZHAM_IS_MATCH_MODEL_INDEX(cur_state) (cur_state)
8
+
9
+ namespace lzham
10
+ {
11
+ struct table_update_settings
12
+ {
13
+ uint16 m_max_update_interval;
14
+ uint16 m_slow_rate;
15
+ };
16
+ extern table_update_settings g_table_update_settings[];
17
+
18
+ struct CLZDecompBase
19
+ {
20
+ enum
21
+ {
22
+ cMinMatchLen = 2U,
23
+ cMaxMatchLen = 257U,
24
+
25
+ cMaxHugeMatchLen = 65536,
26
+
27
+ cMinDictSizeLog2 = 15,
28
+ cMaxDictSizeLog2 = 29,
29
+
30
+ cMatchHistSize = 4,
31
+ cMaxLen2MatchDist = 2047
32
+ };
33
+
34
+ enum
35
+ {
36
+ cLZXNumSecondaryLengths = 249,
37
+
38
+ cNumHugeMatchCodes = 1,
39
+ cMaxHugeMatchCodeBits = 16,
40
+
41
+ cLZXNumSpecialLengths = 2,
42
+
43
+ cLZXLowestUsableMatchSlot = 1,
44
+ cLZXMaxPositionSlots = 128
45
+ };
46
+
47
+ enum
48
+ {
49
+ cLZXSpecialCodeEndOfBlockCode = 0,
50
+ cLZXSpecialCodePartialStateReset = 1
51
+ };
52
+
53
+ enum
54
+ {
55
+ cLZHAMDebugSyncMarkerValue = 666,
56
+ cLZHAMDebugSyncMarkerBits = 12
57
+ };
58
+
59
+ enum
60
+ {
61
+ cBlockHeaderBits = 2,
62
+ cBlockCheckBits = 4,
63
+ cBlockFlushTypeBits = 2,
64
+
65
+ cSyncBlock = 0,
66
+ cCompBlock = 1,
67
+ cRawBlock = 2,
68
+ cEOFBlock = 3
69
+ };
70
+
71
+ enum
72
+ {
73
+ cNumStates = 12,
74
+ cNumLitStates = 7,
75
+ };
76
+
77
+ uint m_dict_size_log2;
78
+ uint m_dict_size;
79
+
80
+ uint m_num_lzx_slots;
81
+
82
+ static uint m_lzx_position_base[cLZXMaxPositionSlots];
83
+ static uint m_lzx_position_extra_mask[cLZXMaxPositionSlots];
84
+ static uint8 m_lzx_position_extra_bits[cLZXMaxPositionSlots];
85
+
86
+ void init_position_slots(uint dict_size_log2);
87
+ };
88
+
89
+ } // namespace lzham
@@ -0,0 +1,142 @@
1
+ // File: lzham_math.h
2
+ // See Copyright Notice and license at the end of include/lzham.h
3
+ #pragma once
4
+
5
+ #if defined(LZHAM_USE_MSVC_INTRINSICS) && !defined(__MINGW32__)
6
+ #include <intrin.h>
7
+ #if defined(_MSC_VER)
8
+ #pragma intrinsic(_BitScanReverse)
9
+ #endif
10
+ #endif
11
+
12
+ namespace lzham
13
+ {
14
+ namespace math
15
+ {
16
+ // Yes I know these should probably be pass by ref, not val:
17
+ // http://www.stepanovpapers.com/notes.pdf
18
+ // Just don't use them on non-simple (non built-in) types!
19
+ template<typename T> inline T minimum(T a, T b) { return (a < b) ? a : b; }
20
+
21
+ template<typename T> inline T minimum(T a, T b, T c) { return minimum(minimum(a, b), c); }
22
+
23
+ template<typename T> inline T maximum(T a, T b) { return (a > b) ? a : b; }
24
+
25
+ template<typename T> inline T maximum(T a, T b, T c) { return maximum(maximum(a, b), c); }
26
+
27
+ template<typename T> inline T clamp(T value, T low, T high) { return (value < low) ? low : ((value > high) ? high : value); }
28
+
29
+ inline bool is_power_of_2(uint32 x) { return x && ((x & (x - 1U)) == 0U); }
30
+ inline bool is_power_of_2(uint64 x) { return x && ((x & (x - 1U)) == 0U); }
31
+
32
+ template<typename T> inline T align_up_pointer(T p, uint alignment)
33
+ {
34
+ LZHAM_ASSERT(is_power_of_2(alignment));
35
+ ptr_bits_t q = reinterpret_cast<ptr_bits_t>(p);
36
+ q = (q + alignment - 1) & (~((uint_ptr)alignment - 1));
37
+ return reinterpret_cast<T>(q);
38
+ }
39
+
40
+ // From "Hackers Delight"
41
+ // val remains unchanged if it is already a power of 2.
42
+ inline uint32 next_pow2(uint32 val)
43
+ {
44
+ val--;
45
+ val |= val >> 16;
46
+ val |= val >> 8;
47
+ val |= val >> 4;
48
+ val |= val >> 2;
49
+ val |= val >> 1;
50
+ return val + 1;
51
+ }
52
+
53
+ // val remains unchanged if it is already a power of 2.
54
+ inline uint64 next_pow2(uint64 val)
55
+ {
56
+ val--;
57
+ val |= val >> 32;
58
+ val |= val >> 16;
59
+ val |= val >> 8;
60
+ val |= val >> 4;
61
+ val |= val >> 2;
62
+ val |= val >> 1;
63
+ return val + 1;
64
+ }
65
+
66
+ inline uint floor_log2i(uint v)
67
+ {
68
+ uint l = 0;
69
+ while (v > 1U)
70
+ {
71
+ v >>= 1;
72
+ l++;
73
+ }
74
+ return l;
75
+ }
76
+
77
+ inline uint ceil_log2i(uint v)
78
+ {
79
+ uint l = floor_log2i(v);
80
+ if ((l != cIntBits) && (v > (1U << l)))
81
+ l++;
82
+ return l;
83
+ }
84
+
85
+ // Returns the total number of bits needed to encode v.
86
+ inline uint total_bits(uint v)
87
+ {
88
+ unsigned long l = 0;
89
+ #if defined(__MINGW32__)
90
+ if (v)
91
+ {
92
+ l = 32 -__builtin_clz(v);
93
+ }
94
+ #elif defined(LZHAM_USE_MSVC_INTRINSICS)
95
+ if (_BitScanReverse(&l, v))
96
+ {
97
+ l++;
98
+ }
99
+ else
100
+ {
101
+ l = 0;
102
+ }
103
+ #else
104
+ while (v > 0U)
105
+ {
106
+ v >>= 1;
107
+ l++;
108
+ }
109
+ #endif
110
+ return static_cast<uint>(l);
111
+ }
112
+
113
+ inline uint compute_mask_size(uint x)
114
+ {
115
+ uint l = 0;
116
+ while (x)
117
+ {
118
+ x &= (x - 1);
119
+ l++;
120
+ }
121
+ return l;
122
+ }
123
+
124
+ inline uint compute_mask_shift(uint x)
125
+ {
126
+ if (!x)
127
+ return 0;
128
+
129
+ uint l = 0;
130
+ while ((x & 1) == 0)
131
+ {
132
+ x >>= 1;
133
+ l++;
134
+ }
135
+
136
+ return l;
137
+ }
138
+
139
+ }
140
+
141
+ } // namespace lzham
142
+
@@ -0,0 +1,284 @@
1
+ // File: lzham_mem.cpp
2
+ // See Copyright Notice and license at the end of include/lzham.h
3
+ #include "lzham_core.h"
4
+
5
+ #ifdef __APPLE__
6
+ #include <malloc/malloc.h>
7
+ #elif defined(__FreeBSD__) || defined(__NetBSD__)
8
+ #include <malloc_np.h>
9
+ #if defined(__FreeBSD__)
10
+ #define malloc(size) aligned_alloc((LZHAM_MIN_ALLOC_ALIGNMENT), (size))
11
+ #endif
12
+ #else
13
+ #include <malloc.h>
14
+ #endif
15
+
16
+ using namespace lzham;
17
+
18
+ #define LZHAM_MEM_STATS 0
19
+
20
+ #ifndef LZHAM_USE_WIN32_API
21
+ #ifndef __APPLE__
22
+ #define _msize malloc_usable_size
23
+ #else
24
+ #define _msize malloc_size
25
+ #endif
26
+ #endif
27
+
28
+ namespace lzham
29
+ {
30
+ #if LZHAM_64BIT_POINTERS
31
+ const uint64 MAX_POSSIBLE_BLOCK_SIZE = 0x400000000ULL;
32
+ #else
33
+ const uint32 MAX_POSSIBLE_BLOCK_SIZE = 0x7FFF0000U;
34
+ #endif
35
+
36
+ #if LZHAM_MEM_STATS
37
+ #if LZHAM_64BIT_POINTERS
38
+ typedef atomic64_t mem_stat_t;
39
+ #define LZHAM_MEM_COMPARE_EXCHANGE atomic_compare_exchange64
40
+ #else
41
+ typedef atomic32_t mem_stat_t;
42
+ #define LZHAM_MEM_COMPARE_EXCHANGE atomic_compare_exchange32
43
+ #endif
44
+
45
+ static volatile atomic32_t g_total_blocks;
46
+ static volatile mem_stat_t g_total_allocated;
47
+ static volatile mem_stat_t g_max_allocated;
48
+
49
+ static mem_stat_t update_total_allocated(int block_delta, mem_stat_t byte_delta)
50
+ {
51
+ atomic32_t cur_total_blocks;
52
+ for ( ; ; )
53
+ {
54
+ cur_total_blocks = g_total_blocks;
55
+ atomic32_t new_total_blocks = static_cast<atomic32_t>(cur_total_blocks + block_delta);
56
+ LZHAM_ASSERT(new_total_blocks >= 0);
57
+ if (atomic_compare_exchange32(&g_total_blocks, new_total_blocks, cur_total_blocks) == cur_total_blocks)
58
+ break;
59
+ }
60
+
61
+ mem_stat_t cur_total_allocated, new_total_allocated;
62
+ for ( ; ; )
63
+ {
64
+ cur_total_allocated = g_total_allocated;
65
+ new_total_allocated = static_cast<mem_stat_t>(cur_total_allocated + byte_delta);
66
+ LZHAM_ASSERT(new_total_allocated >= 0);
67
+ if (LZHAM_MEM_COMPARE_EXCHANGE(&g_total_allocated, new_total_allocated, cur_total_allocated) == cur_total_allocated)
68
+ break;
69
+ }
70
+ for ( ; ; )
71
+ {
72
+ mem_stat_t cur_max_allocated = g_max_allocated;
73
+ mem_stat_t new_max_allocated = LZHAM_MAX(new_total_allocated, cur_max_allocated);
74
+ if (LZHAM_MEM_COMPARE_EXCHANGE(&g_max_allocated, new_max_allocated, cur_max_allocated) == cur_max_allocated)
75
+ break;
76
+ }
77
+ return new_total_allocated;
78
+ }
79
+ #endif // LZHAM_MEM_STATS
80
+
81
+ static void* lzham_default_realloc(void* p, size_t size, size_t* pActual_size, lzham_bool movable, void* pUser_data)
82
+ {
83
+ LZHAM_NOTE_UNUSED(pUser_data);
84
+
85
+ void* p_new;
86
+
87
+ if (!p)
88
+ {
89
+ p_new = malloc(size);
90
+ LZHAM_ASSERT( (reinterpret_cast<ptr_bits_t>(p_new) & (LZHAM_MIN_ALLOC_ALIGNMENT - 1)) == 0 );
91
+
92
+ if (pActual_size)
93
+ *pActual_size = p_new ? _msize(p_new) : 0;
94
+ }
95
+ else if (!size)
96
+ {
97
+ free(p);
98
+ p_new = NULL;
99
+
100
+ if (pActual_size)
101
+ *pActual_size = 0;
102
+ }
103
+ else
104
+ {
105
+ void* p_final_block = p;
106
+ #ifdef WIN32
107
+ p_new = _expand(p, size);
108
+ #else
109
+
110
+ p_new = NULL;
111
+ #endif
112
+
113
+ if (p_new)
114
+ {
115
+ LZHAM_ASSERT( (reinterpret_cast<ptr_bits_t>(p_new) & (LZHAM_MIN_ALLOC_ALIGNMENT - 1)) == 0 );
116
+ p_final_block = p_new;
117
+ }
118
+ else if (movable)
119
+ {
120
+ p_new = realloc(p, size);
121
+
122
+ if (p_new)
123
+ {
124
+ LZHAM_ASSERT( (reinterpret_cast<ptr_bits_t>(p_new) & (LZHAM_MIN_ALLOC_ALIGNMENT - 1)) == 0 );
125
+ p_final_block = p_new;
126
+ }
127
+ }
128
+
129
+ if (pActual_size)
130
+ *pActual_size = _msize(p_final_block);
131
+ }
132
+
133
+ return p_new;
134
+ }
135
+
136
+ static size_t lzham_default_msize(void* p, void* pUser_data)
137
+ {
138
+ LZHAM_NOTE_UNUSED(pUser_data);
139
+ return p ? _msize(p) : 0;
140
+ }
141
+
142
+ static lzham_realloc_func g_pRealloc = lzham_default_realloc;
143
+ static lzham_msize_func g_pMSize = lzham_default_msize;
144
+ static void* g_pUser_data;
145
+
146
+ static inline void lzham_mem_error(const char* p_msg)
147
+ {
148
+ lzham_assert(p_msg, __FILE__, __LINE__);
149
+ }
150
+
151
+ void* lzham_malloc(size_t size, size_t* pActual_size)
152
+ {
153
+ size = (size + sizeof(uint32) - 1U) & ~(sizeof(uint32) - 1U);
154
+ if (!size)
155
+ size = sizeof(uint32);
156
+
157
+ if (size > MAX_POSSIBLE_BLOCK_SIZE)
158
+ {
159
+ lzham_mem_error("lzham_malloc: size too big");
160
+ return NULL;
161
+ }
162
+
163
+ size_t actual_size = size;
164
+ uint8* p_new = static_cast<uint8*>((*g_pRealloc)(NULL, size, &actual_size, true, g_pUser_data));
165
+
166
+ if (pActual_size)
167
+ *pActual_size = actual_size;
168
+
169
+ if ((!p_new) || (actual_size < size))
170
+ {
171
+ lzham_mem_error("lzham_malloc: out of memory");
172
+ return NULL;
173
+ }
174
+
175
+ LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(p_new) & (LZHAM_MIN_ALLOC_ALIGNMENT - 1)) == 0);
176
+
177
+ #if LZHAM_MEM_STATS
178
+ update_total_allocated(1, static_cast<mem_stat_t>(actual_size));
179
+ #endif
180
+
181
+ return p_new;
182
+ }
183
+
184
+ void* lzham_realloc(void* p, size_t size, size_t* pActual_size, bool movable)
185
+ {
186
+ if ((ptr_bits_t)p & (LZHAM_MIN_ALLOC_ALIGNMENT - 1))
187
+ {
188
+ lzham_mem_error("lzham_realloc: bad ptr");
189
+ return NULL;
190
+ }
191
+
192
+ if (size > MAX_POSSIBLE_BLOCK_SIZE)
193
+ {
194
+ lzham_mem_error("lzham_malloc: size too big");
195
+ return NULL;
196
+ }
197
+
198
+ #if LZHAM_MEM_STATS
199
+ size_t cur_size = p ? (*g_pMSize)(p, g_pUser_data) : 0;
200
+ #endif
201
+
202
+ size_t actual_size = size;
203
+ void* p_new = (*g_pRealloc)(p, size, &actual_size, movable, g_pUser_data);
204
+
205
+ if (pActual_size)
206
+ *pActual_size = actual_size;
207
+
208
+ LZHAM_ASSERT((reinterpret_cast<ptr_bits_t>(p_new) & (LZHAM_MIN_ALLOC_ALIGNMENT - 1)) == 0);
209
+
210
+ #if LZHAM_MEM_STATS
211
+ int num_new_blocks = 0;
212
+ if (p)
213
+ {
214
+ if (!p_new)
215
+ num_new_blocks = -1;
216
+ }
217
+ else if (p_new)
218
+ {
219
+ num_new_blocks = 1;
220
+ }
221
+ update_total_allocated(num_new_blocks, static_cast<mem_stat_t>(actual_size) - static_cast<mem_stat_t>(cur_size));
222
+ #endif
223
+
224
+ return p_new;
225
+ }
226
+
227
+ void lzham_free(void* p)
228
+ {
229
+ if (!p)
230
+ return;
231
+
232
+ if (reinterpret_cast<ptr_bits_t>(p) & (LZHAM_MIN_ALLOC_ALIGNMENT - 1))
233
+ {
234
+ lzham_mem_error("lzham_free: bad ptr");
235
+ return;
236
+ }
237
+
238
+ #if LZHAM_MEM_STATS
239
+ size_t cur_size = (*g_pMSize)(p, g_pUser_data);
240
+ update_total_allocated(-1, -static_cast<mem_stat_t>(cur_size));
241
+ #endif
242
+
243
+ (*g_pRealloc)(p, 0, NULL, true, g_pUser_data);
244
+ }
245
+
246
+ size_t lzham_msize(void* p)
247
+ {
248
+ if (!p)
249
+ return 0;
250
+
251
+ if (reinterpret_cast<ptr_bits_t>(p) & (LZHAM_MIN_ALLOC_ALIGNMENT - 1))
252
+ {
253
+ lzham_mem_error("lzham_msize: bad ptr");
254
+ return 0;
255
+ }
256
+
257
+ return (*g_pMSize)(p, g_pUser_data);
258
+ }
259
+
260
+ void LZHAM_CDECL lzham_lib_set_memory_callbacks(lzham_realloc_func pRealloc, lzham_msize_func pMSize, void* pUser_data)
261
+ {
262
+ if ((!pRealloc) || (!pMSize))
263
+ {
264
+ g_pRealloc = lzham_default_realloc;
265
+ g_pMSize = lzham_default_msize;
266
+ g_pUser_data = NULL;
267
+ }
268
+ else
269
+ {
270
+ g_pRealloc = pRealloc;
271
+ g_pMSize = pMSize;
272
+ g_pUser_data = pUser_data;
273
+ }
274
+ }
275
+
276
+ void lzham_print_mem_stats()
277
+ {
278
+ #if LZHAM_MEM_STATS
279
+ printf("Current blocks: %u, allocated: %I64u, max ever allocated: %I64i\n", g_total_blocks, (int64)g_total_allocated, (int64)g_max_allocated);
280
+ #endif
281
+ }
282
+
283
+ } // namespace lzham
284
+