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,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
+