extlzham 0.0.1.PROTOTYPE3-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|