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.
- checksums.yaml +7 -0
- data/LICENSE.md +27 -0
- data/README.md +74 -0
- data/Rakefile +152 -0
- data/contrib/lzham/LICENSE +22 -0
- data/contrib/lzham/README.md +209 -0
- data/contrib/lzham/include/lzham.h +781 -0
- data/contrib/lzham/lzhamcomp/lzham_comp.h +38 -0
- data/contrib/lzham/lzhamcomp/lzham_lzbase.cpp +244 -0
- data/contrib/lzham/lzhamcomp/lzham_lzbase.h +45 -0
- data/contrib/lzham/lzhamcomp/lzham_lzcomp.cpp +608 -0
- data/contrib/lzham/lzhamcomp/lzham_lzcomp_internal.cpp +1966 -0
- data/contrib/lzham/lzhamcomp/lzham_lzcomp_internal.h +472 -0
- data/contrib/lzham/lzhamcomp/lzham_lzcomp_state.cpp +1413 -0
- data/contrib/lzham/lzhamcomp/lzham_match_accel.cpp +562 -0
- data/contrib/lzham/lzhamcomp/lzham_match_accel.h +146 -0
- data/contrib/lzham/lzhamcomp/lzham_null_threading.h +97 -0
- data/contrib/lzham/lzhamcomp/lzham_pthreads_threading.cpp +229 -0
- data/contrib/lzham/lzhamcomp/lzham_pthreads_threading.h +520 -0
- data/contrib/lzham/lzhamcomp/lzham_threading.h +12 -0
- data/contrib/lzham/lzhamcomp/lzham_win32_threading.cpp +220 -0
- data/contrib/lzham/lzhamcomp/lzham_win32_threading.h +368 -0
- data/contrib/lzham/lzhamdecomp/lzham_assert.cpp +66 -0
- data/contrib/lzham/lzhamdecomp/lzham_assert.h +40 -0
- data/contrib/lzham/lzhamdecomp/lzham_checksum.cpp +73 -0
- data/contrib/lzham/lzhamdecomp/lzham_checksum.h +13 -0
- data/contrib/lzham/lzhamdecomp/lzham_config.h +23 -0
- data/contrib/lzham/lzhamdecomp/lzham_core.h +264 -0
- data/contrib/lzham/lzhamdecomp/lzham_decomp.h +37 -0
- data/contrib/lzham/lzhamdecomp/lzham_helpers.h +54 -0
- data/contrib/lzham/lzhamdecomp/lzham_huffman_codes.cpp +262 -0
- data/contrib/lzham/lzhamdecomp/lzham_huffman_codes.h +14 -0
- data/contrib/lzham/lzhamdecomp/lzham_lzdecomp.cpp +1527 -0
- data/contrib/lzham/lzhamdecomp/lzham_lzdecompbase.cpp +131 -0
- data/contrib/lzham/lzhamdecomp/lzham_lzdecompbase.h +89 -0
- data/contrib/lzham/lzhamdecomp/lzham_math.h +142 -0
- data/contrib/lzham/lzhamdecomp/lzham_mem.cpp +284 -0
- data/contrib/lzham/lzhamdecomp/lzham_mem.h +112 -0
- data/contrib/lzham/lzhamdecomp/lzham_platform.cpp +157 -0
- data/contrib/lzham/lzhamdecomp/lzham_platform.h +284 -0
- data/contrib/lzham/lzhamdecomp/lzham_prefix_coding.cpp +351 -0
- data/contrib/lzham/lzhamdecomp/lzham_prefix_coding.h +146 -0
- data/contrib/lzham/lzhamdecomp/lzham_symbol_codec.cpp +1484 -0
- data/contrib/lzham/lzhamdecomp/lzham_symbol_codec.h +556 -0
- data/contrib/lzham/lzhamdecomp/lzham_timer.cpp +147 -0
- data/contrib/lzham/lzhamdecomp/lzham_timer.h +99 -0
- data/contrib/lzham/lzhamdecomp/lzham_traits.h +141 -0
- data/contrib/lzham/lzhamdecomp/lzham_types.h +97 -0
- data/contrib/lzham/lzhamdecomp/lzham_utils.h +58 -0
- data/contrib/lzham/lzhamdecomp/lzham_vector.cpp +75 -0
- data/contrib/lzham/lzhamdecomp/lzham_vector.h +588 -0
- data/contrib/lzham/lzhamlib/lzham_lib.cpp +179 -0
- data/examples/basic.rb +48 -0
- data/ext/constants.c +64 -0
- data/ext/decoder.c +313 -0
- data/ext/depend +5 -0
- data/ext/encoder.c +372 -0
- data/ext/error.c +80 -0
- data/ext/extconf.rb +29 -0
- data/ext/extlzham.c +34 -0
- data/ext/extlzham.h +62 -0
- data/gemstub.rb +22 -0
- data/lib/2.0/extlzham.so +0 -0
- data/lib/2.1/extlzham.so +0 -0
- data/lib/2.2/extlzham.so +0 -0
- data/lib/extlzham.rb +158 -0
- data/lib/extlzham/version.rb +5 -0
- data/test/test_extlzham.rb +35 -0
- 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
|
+
|