ruby-lzma 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/README.markdown +15 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/ext/Alloc.cpp +118 -0
- data/ext/Alloc.h +29 -0
- data/ext/BinTree.h +55 -0
- data/ext/BinTree2.h +12 -0
- data/ext/BinTree3.h +16 -0
- data/ext/BinTree3Z.h +16 -0
- data/ext/BinTree4.h +18 -0
- data/ext/BinTree4b.h +20 -0
- data/ext/BinTreeMain.h +444 -0
- data/ext/BranchX86.c +101 -0
- data/ext/BranchX86.h +19 -0
- data/ext/CRC.cpp +61 -0
- data/ext/CRC.h +36 -0
- data/ext/C_FileIO.h +45 -0
- data/ext/CommandLineParser.h +82 -0
- data/ext/Defs.h +20 -0
- data/ext/FileStreams.h +98 -0
- data/ext/HC.h +55 -0
- data/ext/HC2.h +13 -0
- data/ext/HC3.h +17 -0
- data/ext/HC4.h +19 -0
- data/ext/HC4b.h +21 -0
- data/ext/HCMain.h +350 -0
- data/ext/ICoder.h +156 -0
- data/ext/IMatchFinder.h +63 -0
- data/ext/IStream.h +62 -0
- data/ext/InBuffer.cpp +80 -0
- data/ext/InBuffer.h +76 -0
- data/ext/LZInWindow.cpp +102 -0
- data/ext/LZInWindow.h +84 -0
- data/ext/LZMA.h +82 -0
- data/ext/LZMADecoder.h +248 -0
- data/ext/LZMAEncoder.cpp +1504 -0
- data/ext/LZMAEncoder.h +416 -0
- data/ext/LZOutWindow.cpp +17 -0
- data/ext/LZOutWindow.h +66 -0
- data/ext/LzmaBench.h +11 -0
- data/ext/LzmaDecode.c +588 -0
- data/ext/LzmaDecode.h +131 -0
- data/ext/LzmaRam.cpp +228 -0
- data/ext/LzmaRam.h +46 -0
- data/ext/LzmaRamDecode.c +79 -0
- data/ext/LzmaRamDecode.h +55 -0
- data/ext/MyCom.h +203 -0
- data/ext/MyGuidDef.h +54 -0
- data/ext/MyInitGuid.h +13 -0
- data/ext/MyString.h +631 -0
- data/ext/MyUnknown.h +24 -0
- data/ext/MyWindows.h +183 -0
- data/ext/OutBuffer.cpp +117 -0
- data/ext/OutBuffer.h +64 -0
- data/ext/Pat.h +318 -0
- data/ext/Pat2.h +22 -0
- data/ext/Pat2H.h +24 -0
- data/ext/Pat2R.h +20 -0
- data/ext/Pat3H.h +24 -0
- data/ext/Pat4H.h +24 -0
- data/ext/PatMain.h +989 -0
- data/ext/RangeCoder.h +205 -0
- data/ext/RangeCoderBit.cpp +80 -0
- data/ext/RangeCoderBit.h +120 -0
- data/ext/RangeCoderBitTree.h +161 -0
- data/ext/RangeCoderOpt.h +31 -0
- data/ext/StdAfx.h +8 -0
- data/ext/StreamUtils.cpp +44 -0
- data/ext/StreamUtils.h +11 -0
- data/ext/StringConvert.h +71 -0
- data/ext/StringToInt.h +17 -0
- data/ext/Types.h +19 -0
- data/ext/Vector.h +211 -0
- data/ext/extconf.rb +7 -0
- data/ext/lzma_ruby.cpp +51 -0
- data/ext/lzmalib.h +64 -0
- data/ext/mylib.cpp +81 -0
- data/java/SevenZip/CRC.java +52 -0
- data/java/SevenZip/Compression/LZ/BinTree.java +382 -0
- data/java/SevenZip/Compression/LZ/InWindow.java +131 -0
- data/java/SevenZip/Compression/LZ/OutWindow.java +85 -0
- data/java/SevenZip/Compression/LZMA/Base.java +88 -0
- data/java/SevenZip/Compression/LZMA/Decoder.java +329 -0
- data/java/SevenZip/Compression/LZMA/Encoder.java +1415 -0
- data/java/SevenZip/Compression/RangeCoder/BitTreeDecoder.java +55 -0
- data/java/SevenZip/Compression/RangeCoder/BitTreeEncoder.java +99 -0
- data/java/SevenZip/Compression/RangeCoder/Decoder.java +88 -0
- data/java/SevenZip/Compression/RangeCoder/Encoder.java +151 -0
- data/java/SevenZip/ICodeProgress.java +6 -0
- data/java/SevenZip/LzmaAlone.java +253 -0
- data/java/SevenZip/LzmaBench.java +391 -0
- data/java/com/ephemeronindustries/lzma/LZMA.java +104 -0
- data/lib/lzma.rb +32 -0
- data/ruby-lzma.gemspec +136 -0
- data/test/test_lzma.rb +42 -0
- metadata +157 -0
data/ext/RangeCoder.h
ADDED
@@ -0,0 +1,205 @@
|
|
1
|
+
// Compress/RangeCoder/RangeCoder.h
|
2
|
+
|
3
|
+
#ifndef __COMPRESS_RANGECODER_H
|
4
|
+
#define __COMPRESS_RANGECODER_H
|
5
|
+
|
6
|
+
#include "InBuffer.h"
|
7
|
+
#include "OutBuffer.h"
|
8
|
+
|
9
|
+
namespace NCompress {
|
10
|
+
namespace NRangeCoder {
|
11
|
+
|
12
|
+
const int kNumTopBits = 24;
|
13
|
+
const UInt32 kTopValue = (1 << kNumTopBits);
|
14
|
+
|
15
|
+
class CEncoder
|
16
|
+
{
|
17
|
+
UInt32 _cacheSize;
|
18
|
+
Byte _cache;
|
19
|
+
public:
|
20
|
+
UInt64 Low;
|
21
|
+
UInt32 Range;
|
22
|
+
COutBuffer Stream;
|
23
|
+
bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
|
24
|
+
|
25
|
+
void SetStream(ISequentialOutStream *stream) { Stream.SetStream(stream); }
|
26
|
+
void Init()
|
27
|
+
{
|
28
|
+
Stream.Init();
|
29
|
+
Low = 0;
|
30
|
+
Range = 0xFFFFFFFF;
|
31
|
+
_cacheSize = 1;
|
32
|
+
_cache = 0;
|
33
|
+
}
|
34
|
+
|
35
|
+
void FlushData()
|
36
|
+
{
|
37
|
+
// Low += 1;
|
38
|
+
for(int i = 0; i < 5; i++)
|
39
|
+
ShiftLow();
|
40
|
+
}
|
41
|
+
|
42
|
+
HRESULT FlushStream() { return Stream.Flush(); }
|
43
|
+
|
44
|
+
void ReleaseStream() { Stream.ReleaseStream(); }
|
45
|
+
|
46
|
+
void Encode(UInt32 start, UInt32 size, UInt32 total)
|
47
|
+
{
|
48
|
+
Low += start * (Range /= total);
|
49
|
+
Range *= size;
|
50
|
+
while (Range < kTopValue)
|
51
|
+
{
|
52
|
+
Range <<= 8;
|
53
|
+
ShiftLow();
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
void ShiftLow()
|
58
|
+
{
|
59
|
+
if ((UInt32)Low < (UInt32)0xFF000000 || (int)(Low >> 32) != 0)
|
60
|
+
{
|
61
|
+
Byte temp = _cache;
|
62
|
+
do
|
63
|
+
{
|
64
|
+
Stream.WriteByte((Byte)(temp + (Byte)(Low >> 32)));
|
65
|
+
temp = 0xFF;
|
66
|
+
}
|
67
|
+
while(--_cacheSize != 0);
|
68
|
+
_cache = (Byte)((UInt32)Low >> 24);
|
69
|
+
}
|
70
|
+
_cacheSize++;
|
71
|
+
Low = (UInt32)Low << 8;
|
72
|
+
}
|
73
|
+
|
74
|
+
void EncodeDirectBits(UInt32 value, int numTotalBits)
|
75
|
+
{
|
76
|
+
for (int i = numTotalBits - 1; i >= 0; i--)
|
77
|
+
{
|
78
|
+
Range >>= 1;
|
79
|
+
if (((value >> i) & 1) == 1)
|
80
|
+
Low += Range;
|
81
|
+
if (Range < kTopValue)
|
82
|
+
{
|
83
|
+
Range <<= 8;
|
84
|
+
ShiftLow();
|
85
|
+
}
|
86
|
+
}
|
87
|
+
}
|
88
|
+
|
89
|
+
void EncodeBit(UInt32 size0, UInt32 numTotalBits, UInt32 symbol)
|
90
|
+
{
|
91
|
+
UInt32 newBound = (Range >> numTotalBits) * size0;
|
92
|
+
if (symbol == 0)
|
93
|
+
Range = newBound;
|
94
|
+
else
|
95
|
+
{
|
96
|
+
Low += newBound;
|
97
|
+
Range -= newBound;
|
98
|
+
}
|
99
|
+
while (Range < kTopValue)
|
100
|
+
{
|
101
|
+
Range <<= 8;
|
102
|
+
ShiftLow();
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
UInt64 GetProcessedSize() { return Stream.GetProcessedSize() + _cacheSize + 4; }
|
107
|
+
};
|
108
|
+
|
109
|
+
class CDecoder
|
110
|
+
{
|
111
|
+
public:
|
112
|
+
CInBuffer Stream;
|
113
|
+
UInt32 Range;
|
114
|
+
UInt32 Code;
|
115
|
+
bool Create(UInt32 bufferSize) { return Stream.Create(bufferSize); }
|
116
|
+
|
117
|
+
void Normalize()
|
118
|
+
{
|
119
|
+
while (Range < kTopValue)
|
120
|
+
{
|
121
|
+
Code = (Code << 8) | Stream.ReadByte();
|
122
|
+
Range <<= 8;
|
123
|
+
}
|
124
|
+
}
|
125
|
+
|
126
|
+
void SetStream(ISequentialInStream *stream) { Stream.SetStream(stream); }
|
127
|
+
void Init()
|
128
|
+
{
|
129
|
+
Stream.Init();
|
130
|
+
Code = 0;
|
131
|
+
Range = 0xFFFFFFFF;
|
132
|
+
for(int i = 0; i < 5; i++)
|
133
|
+
Code = (Code << 8) | Stream.ReadByte();
|
134
|
+
}
|
135
|
+
|
136
|
+
void ReleaseStream() { Stream.ReleaseStream(); }
|
137
|
+
|
138
|
+
UInt32 GetThreshold(UInt32 total)
|
139
|
+
{
|
140
|
+
return (Code) / ( Range /= total);
|
141
|
+
}
|
142
|
+
|
143
|
+
void Decode(UInt32 start, UInt32 size)
|
144
|
+
{
|
145
|
+
Code -= start * Range;
|
146
|
+
Range *= size;
|
147
|
+
Normalize();
|
148
|
+
}
|
149
|
+
|
150
|
+
UInt32 DecodeDirectBits(int numTotalBits)
|
151
|
+
{
|
152
|
+
UInt32 range = Range;
|
153
|
+
UInt32 code = Code;
|
154
|
+
UInt32 result = 0;
|
155
|
+
for (int i = numTotalBits; i != 0; i--)
|
156
|
+
{
|
157
|
+
range >>= 1;
|
158
|
+
/*
|
159
|
+
result <<= 1;
|
160
|
+
if (code >= range)
|
161
|
+
{
|
162
|
+
code -= range;
|
163
|
+
result |= 1;
|
164
|
+
}
|
165
|
+
*/
|
166
|
+
UInt32 t = (code - range) >> 31;
|
167
|
+
code -= range & (t - 1);
|
168
|
+
result = (result << 1) | (1 - t);
|
169
|
+
|
170
|
+
if (range < kTopValue)
|
171
|
+
{
|
172
|
+
code = (code << 8) | Stream.ReadByte();
|
173
|
+
range <<= 8;
|
174
|
+
}
|
175
|
+
}
|
176
|
+
Range = range;
|
177
|
+
Code = code;
|
178
|
+
return result;
|
179
|
+
}
|
180
|
+
|
181
|
+
UInt32 DecodeBit(UInt32 size0, UInt32 numTotalBits)
|
182
|
+
{
|
183
|
+
UInt32 newBound = (Range >> numTotalBits) * size0;
|
184
|
+
UInt32 symbol;
|
185
|
+
if (Code < newBound)
|
186
|
+
{
|
187
|
+
symbol = 0;
|
188
|
+
Range = newBound;
|
189
|
+
}
|
190
|
+
else
|
191
|
+
{
|
192
|
+
symbol = 1;
|
193
|
+
Code -= newBound;
|
194
|
+
Range -= newBound;
|
195
|
+
}
|
196
|
+
Normalize();
|
197
|
+
return symbol;
|
198
|
+
}
|
199
|
+
|
200
|
+
UInt64 GetProcessedSize() {return Stream.GetProcessedSize(); }
|
201
|
+
};
|
202
|
+
|
203
|
+
}}
|
204
|
+
|
205
|
+
#endif
|
@@ -0,0 +1,80 @@
|
|
1
|
+
// Compress/RangeCoder/RangeCoderBit.cpp
|
2
|
+
|
3
|
+
#include "StdAfx.h"
|
4
|
+
|
5
|
+
#include "RangeCoderBit.h"
|
6
|
+
|
7
|
+
namespace NCompress {
|
8
|
+
namespace NRangeCoder {
|
9
|
+
|
10
|
+
UInt32 CPriceTables::ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
|
11
|
+
static CPriceTables g_PriceTables;
|
12
|
+
|
13
|
+
CPriceTables::CPriceTables() { Init(); }
|
14
|
+
|
15
|
+
void CPriceTables::Init()
|
16
|
+
{
|
17
|
+
const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
|
18
|
+
for(int i = kNumBits - 1; i >= 0; i--)
|
19
|
+
{
|
20
|
+
UInt32 start = 1 << (kNumBits - i - 1);
|
21
|
+
UInt32 end = 1 << (kNumBits - i);
|
22
|
+
for (UInt32 j = start; j < end; j++)
|
23
|
+
ProbPrices[j] = (i << kNumBitPriceShiftBits) +
|
24
|
+
(((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1));
|
25
|
+
}
|
26
|
+
|
27
|
+
/*
|
28
|
+
// simplest: bad solution
|
29
|
+
for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
|
30
|
+
ProbPrices[i] = kBitPrice;
|
31
|
+
*/
|
32
|
+
|
33
|
+
/*
|
34
|
+
const double kDummyMultMid = (1.0 / kBitPrice) / 2;
|
35
|
+
const double kDummyMultMid = 0;
|
36
|
+
// float solution
|
37
|
+
double ln2 = log(double(2));
|
38
|
+
double lnAll = log(double(kBitModelTotal >> kNumMoveReducingBits));
|
39
|
+
for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
|
40
|
+
ProbPrices[i] = UInt32((fabs(lnAll - log(double(i))) / ln2 + kDummyMultMid) * kBitPrice);
|
41
|
+
*/
|
42
|
+
|
43
|
+
/*
|
44
|
+
// experimental, slow, solution:
|
45
|
+
for(UInt32 i = 1; i < (kBitModelTotal >> kNumMoveReducingBits) - 1; i++)
|
46
|
+
{
|
47
|
+
const int kCyclesBits = 5;
|
48
|
+
const UInt32 kCycles = (1 << kCyclesBits);
|
49
|
+
|
50
|
+
UInt32 range = UInt32(-1);
|
51
|
+
UInt32 bitCount = 0;
|
52
|
+
for (UInt32 j = 0; j < kCycles; j++)
|
53
|
+
{
|
54
|
+
range >>= (kNumBitModelTotalBits - kNumMoveReducingBits);
|
55
|
+
range *= i;
|
56
|
+
while(range < (1 << 31))
|
57
|
+
{
|
58
|
+
range <<= 1;
|
59
|
+
bitCount++;
|
60
|
+
}
|
61
|
+
}
|
62
|
+
bitCount <<= kNumBitPriceShiftBits;
|
63
|
+
range -= (1 << 31);
|
64
|
+
for (int k = kNumBitPriceShiftBits - 1; k >= 0; k--)
|
65
|
+
{
|
66
|
+
range <<= 1;
|
67
|
+
if (range > (1 << 31))
|
68
|
+
{
|
69
|
+
bitCount += (1 << k);
|
70
|
+
range -= (1 << 31);
|
71
|
+
}
|
72
|
+
}
|
73
|
+
ProbPrices[i] = (bitCount
|
74
|
+
// + (1 << (kCyclesBits - 1))
|
75
|
+
) >> kCyclesBits;
|
76
|
+
}
|
77
|
+
*/
|
78
|
+
}
|
79
|
+
|
80
|
+
}}
|
data/ext/RangeCoderBit.h
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
// Compress/RangeCoder/RangeCoderBit.h
|
2
|
+
|
3
|
+
#ifndef __COMPRESS_RANGECODER_BIT_H
|
4
|
+
#define __COMPRESS_RANGECODER_BIT_H
|
5
|
+
|
6
|
+
#include "RangeCoder.h"
|
7
|
+
|
8
|
+
namespace NCompress {
|
9
|
+
namespace NRangeCoder {
|
10
|
+
|
11
|
+
const int kNumBitModelTotalBits = 11;
|
12
|
+
const UInt32 kBitModelTotal = (1 << kNumBitModelTotalBits);
|
13
|
+
|
14
|
+
const int kNumMoveReducingBits = 2;
|
15
|
+
|
16
|
+
const int kNumBitPriceShiftBits = 6;
|
17
|
+
const UInt32 kBitPrice = 1 << kNumBitPriceShiftBits;
|
18
|
+
|
19
|
+
class CPriceTables
|
20
|
+
{
|
21
|
+
public:
|
22
|
+
static UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
|
23
|
+
static void Init();
|
24
|
+
CPriceTables();
|
25
|
+
};
|
26
|
+
|
27
|
+
template <int numMoveBits>
|
28
|
+
class CBitModel
|
29
|
+
{
|
30
|
+
public:
|
31
|
+
UInt32 Prob;
|
32
|
+
void UpdateModel(UInt32 symbol)
|
33
|
+
{
|
34
|
+
/*
|
35
|
+
Prob -= (Prob + ((symbol - 1) & ((1 << numMoveBits) - 1))) >> numMoveBits;
|
36
|
+
Prob += (1 - symbol) << (kNumBitModelTotalBits - numMoveBits);
|
37
|
+
*/
|
38
|
+
if (symbol == 0)
|
39
|
+
Prob += (kBitModelTotal - Prob) >> numMoveBits;
|
40
|
+
else
|
41
|
+
Prob -= (Prob) >> numMoveBits;
|
42
|
+
}
|
43
|
+
public:
|
44
|
+
void Init() { Prob = kBitModelTotal / 2; }
|
45
|
+
};
|
46
|
+
|
47
|
+
template <int numMoveBits>
|
48
|
+
class CBitEncoder: public CBitModel<numMoveBits>
|
49
|
+
{
|
50
|
+
public:
|
51
|
+
void Encode(CEncoder *encoder, UInt32 symbol)
|
52
|
+
{
|
53
|
+
/*
|
54
|
+
encoder->EncodeBit(this->Prob, kNumBitModelTotalBits, symbol);
|
55
|
+
this->UpdateModel(symbol);
|
56
|
+
*/
|
57
|
+
UInt32 newBound = (encoder->Range >> kNumBitModelTotalBits) * this->Prob;
|
58
|
+
if (symbol == 0)
|
59
|
+
{
|
60
|
+
encoder->Range = newBound;
|
61
|
+
this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
|
62
|
+
}
|
63
|
+
else
|
64
|
+
{
|
65
|
+
encoder->Low += newBound;
|
66
|
+
encoder->Range -= newBound;
|
67
|
+
this->Prob -= (this->Prob) >> numMoveBits;
|
68
|
+
}
|
69
|
+
if (encoder->Range < kTopValue)
|
70
|
+
{
|
71
|
+
encoder->Range <<= 8;
|
72
|
+
encoder->ShiftLow();
|
73
|
+
}
|
74
|
+
}
|
75
|
+
UInt32 GetPrice(UInt32 symbol) const
|
76
|
+
{
|
77
|
+
return CPriceTables::ProbPrices[
|
78
|
+
(((this->Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits];
|
79
|
+
}
|
80
|
+
UInt32 GetPrice0() const { return CPriceTables::ProbPrices[this->Prob >> kNumMoveReducingBits]; }
|
81
|
+
UInt32 GetPrice1() const { return CPriceTables::ProbPrices[(kBitModelTotal - this->Prob) >> kNumMoveReducingBits]; }
|
82
|
+
};
|
83
|
+
|
84
|
+
|
85
|
+
template <int numMoveBits>
|
86
|
+
class CBitDecoder: public CBitModel<numMoveBits>
|
87
|
+
{
|
88
|
+
public:
|
89
|
+
UInt32 Decode(CDecoder *decoder)
|
90
|
+
{
|
91
|
+
UInt32 newBound = (decoder->Range >> kNumBitModelTotalBits) * this->Prob;
|
92
|
+
if (decoder->Code < newBound)
|
93
|
+
{
|
94
|
+
decoder->Range = newBound;
|
95
|
+
this->Prob += (kBitModelTotal - this->Prob) >> numMoveBits;
|
96
|
+
if (decoder->Range < kTopValue)
|
97
|
+
{
|
98
|
+
decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
|
99
|
+
decoder->Range <<= 8;
|
100
|
+
}
|
101
|
+
return 0;
|
102
|
+
}
|
103
|
+
else
|
104
|
+
{
|
105
|
+
decoder->Range -= newBound;
|
106
|
+
decoder->Code -= newBound;
|
107
|
+
this->Prob -= (this->Prob) >> numMoveBits;
|
108
|
+
if (decoder->Range < kTopValue)
|
109
|
+
{
|
110
|
+
decoder->Code = (decoder->Code << 8) | decoder->Stream.ReadByte();
|
111
|
+
decoder->Range <<= 8;
|
112
|
+
}
|
113
|
+
return 1;
|
114
|
+
}
|
115
|
+
}
|
116
|
+
};
|
117
|
+
|
118
|
+
}}
|
119
|
+
|
120
|
+
#endif
|
@@ -0,0 +1,161 @@
|
|
1
|
+
// Compress/RangeCoder/RangeCoderBitTree.h
|
2
|
+
|
3
|
+
#ifndef __COMPRESS_RANGECODER_BIT_TREE_H
|
4
|
+
#define __COMPRESS_RANGECODER_BIT_TREE_H
|
5
|
+
|
6
|
+
#include "RangeCoderBit.h"
|
7
|
+
#include "RangeCoderOpt.h"
|
8
|
+
|
9
|
+
namespace NCompress {
|
10
|
+
namespace NRangeCoder {
|
11
|
+
|
12
|
+
template <int numMoveBits, int NumBitLevels>
|
13
|
+
class CBitTreeEncoder
|
14
|
+
{
|
15
|
+
CBitEncoder<numMoveBits> Models[1 << NumBitLevels];
|
16
|
+
public:
|
17
|
+
void Init()
|
18
|
+
{
|
19
|
+
for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
|
20
|
+
Models[i].Init();
|
21
|
+
}
|
22
|
+
void Encode(CEncoder *rangeEncoder, UInt32 symbol)
|
23
|
+
{
|
24
|
+
UInt32 modelIndex = 1;
|
25
|
+
for (int bitIndex = NumBitLevels; bitIndex != 0 ;)
|
26
|
+
{
|
27
|
+
bitIndex--;
|
28
|
+
UInt32 bit = (symbol >> bitIndex) & 1;
|
29
|
+
Models[modelIndex].Encode(rangeEncoder, bit);
|
30
|
+
modelIndex = (modelIndex << 1) | bit;
|
31
|
+
}
|
32
|
+
};
|
33
|
+
void ReverseEncode(CEncoder *rangeEncoder, UInt32 symbol)
|
34
|
+
{
|
35
|
+
UInt32 modelIndex = 1;
|
36
|
+
for (int i = 0; i < NumBitLevels; i++)
|
37
|
+
{
|
38
|
+
UInt32 bit = symbol & 1;
|
39
|
+
Models[modelIndex].Encode(rangeEncoder, bit);
|
40
|
+
modelIndex = (modelIndex << 1) | bit;
|
41
|
+
symbol >>= 1;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
UInt32 GetPrice(UInt32 symbol) const
|
45
|
+
{
|
46
|
+
symbol |= (1 << NumBitLevels);
|
47
|
+
UInt32 price = 0;
|
48
|
+
while (symbol != 1)
|
49
|
+
{
|
50
|
+
price += Models[symbol >> 1].GetPrice(symbol & 1);
|
51
|
+
symbol >>= 1;
|
52
|
+
}
|
53
|
+
return price;
|
54
|
+
}
|
55
|
+
UInt32 ReverseGetPrice(UInt32 symbol) const
|
56
|
+
{
|
57
|
+
UInt32 price = 0;
|
58
|
+
UInt32 modelIndex = 1;
|
59
|
+
for (int i = NumBitLevels; i != 0; i--)
|
60
|
+
{
|
61
|
+
UInt32 bit = symbol & 1;
|
62
|
+
symbol >>= 1;
|
63
|
+
price += Models[modelIndex].GetPrice(bit);
|
64
|
+
modelIndex = (modelIndex << 1) | bit;
|
65
|
+
}
|
66
|
+
return price;
|
67
|
+
}
|
68
|
+
};
|
69
|
+
|
70
|
+
template <int numMoveBits, int NumBitLevels>
|
71
|
+
class CBitTreeDecoder
|
72
|
+
{
|
73
|
+
CBitDecoder<numMoveBits> Models[1 << NumBitLevels];
|
74
|
+
public:
|
75
|
+
void Init()
|
76
|
+
{
|
77
|
+
for(UInt32 i = 1; i < (1 << NumBitLevels); i++)
|
78
|
+
Models[i].Init();
|
79
|
+
}
|
80
|
+
UInt32 Decode(CDecoder *rangeDecoder)
|
81
|
+
{
|
82
|
+
UInt32 modelIndex = 1;
|
83
|
+
RC_INIT_VAR
|
84
|
+
for(int bitIndex = NumBitLevels; bitIndex != 0; bitIndex--)
|
85
|
+
{
|
86
|
+
// modelIndex = (modelIndex << 1) + Models[modelIndex].Decode(rangeDecoder);
|
87
|
+
RC_GETBIT(numMoveBits, Models[modelIndex].Prob, modelIndex)
|
88
|
+
}
|
89
|
+
RC_FLUSH_VAR
|
90
|
+
return modelIndex - (1 << NumBitLevels);
|
91
|
+
};
|
92
|
+
UInt32 ReverseDecode(CDecoder *rangeDecoder)
|
93
|
+
{
|
94
|
+
UInt32 modelIndex = 1;
|
95
|
+
UInt32 symbol = 0;
|
96
|
+
RC_INIT_VAR
|
97
|
+
for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
|
98
|
+
{
|
99
|
+
// UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
|
100
|
+
// modelIndex <<= 1;
|
101
|
+
// modelIndex += bit;
|
102
|
+
// symbol |= (bit << bitIndex);
|
103
|
+
RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
|
104
|
+
}
|
105
|
+
RC_FLUSH_VAR
|
106
|
+
return symbol;
|
107
|
+
}
|
108
|
+
};
|
109
|
+
|
110
|
+
template <int numMoveBits>
|
111
|
+
void ReverseBitTreeEncode(CBitEncoder<numMoveBits> *Models,
|
112
|
+
CEncoder *rangeEncoder, int NumBitLevels, UInt32 symbol)
|
113
|
+
{
|
114
|
+
UInt32 modelIndex = 1;
|
115
|
+
for (int i = 0; i < NumBitLevels; i++)
|
116
|
+
{
|
117
|
+
UInt32 bit = symbol & 1;
|
118
|
+
Models[modelIndex].Encode(rangeEncoder, bit);
|
119
|
+
modelIndex = (modelIndex << 1) | bit;
|
120
|
+
symbol >>= 1;
|
121
|
+
}
|
122
|
+
}
|
123
|
+
|
124
|
+
template <int numMoveBits>
|
125
|
+
UInt32 ReverseBitTreeGetPrice(CBitEncoder<numMoveBits> *Models,
|
126
|
+
UInt32 NumBitLevels, UInt32 symbol)
|
127
|
+
{
|
128
|
+
UInt32 price = 0;
|
129
|
+
UInt32 modelIndex = 1;
|
130
|
+
for (int i = NumBitLevels; i != 0; i--)
|
131
|
+
{
|
132
|
+
UInt32 bit = symbol & 1;
|
133
|
+
symbol >>= 1;
|
134
|
+
price += Models[modelIndex].GetPrice(bit);
|
135
|
+
modelIndex = (modelIndex << 1) | bit;
|
136
|
+
}
|
137
|
+
return price;
|
138
|
+
}
|
139
|
+
|
140
|
+
template <int numMoveBits>
|
141
|
+
UInt32 ReverseBitTreeDecode(CBitDecoder<numMoveBits> *Models,
|
142
|
+
CDecoder *rangeDecoder, int NumBitLevels)
|
143
|
+
{
|
144
|
+
UInt32 modelIndex = 1;
|
145
|
+
UInt32 symbol = 0;
|
146
|
+
RC_INIT_VAR
|
147
|
+
for(int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++)
|
148
|
+
{
|
149
|
+
// UInt32 bit = Models[modelIndex].Decode(rangeDecoder);
|
150
|
+
// modelIndex <<= 1;
|
151
|
+
// modelIndex += bit;
|
152
|
+
// symbol |= (bit << bitIndex);
|
153
|
+
RC_GETBIT2(numMoveBits, Models[modelIndex].Prob, modelIndex, ; , symbol |= (1 << bitIndex))
|
154
|
+
}
|
155
|
+
RC_FLUSH_VAR
|
156
|
+
return symbol;
|
157
|
+
}
|
158
|
+
|
159
|
+
}}
|
160
|
+
|
161
|
+
#endif
|