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
@@ -0,0 +1,131 @@
|
|
1
|
+
// LZ.InWindow
|
2
|
+
|
3
|
+
package SevenZip.Compression.LZ;
|
4
|
+
|
5
|
+
import java.io.IOException;
|
6
|
+
|
7
|
+
public class InWindow
|
8
|
+
{
|
9
|
+
public byte[] _bufferBase; // pointer to buffer with data
|
10
|
+
java.io.InputStream _stream;
|
11
|
+
int _posLimit; // offset (from _buffer) of first byte when new block reading must be done
|
12
|
+
boolean _streamEndWasReached; // if (true) then _streamPos shows real end of stream
|
13
|
+
|
14
|
+
int _pointerToLastSafePosition;
|
15
|
+
|
16
|
+
public int _bufferOffset;
|
17
|
+
|
18
|
+
public int _blockSize; // Size of Allocated memory block
|
19
|
+
public int _pos; // offset (from _buffer) of curent byte
|
20
|
+
int _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos
|
21
|
+
int _keepSizeAfter; // how many BYTEs must be kept buffer after _pos
|
22
|
+
public int _streamPos; // offset (from _buffer) of first not read byte from Stream
|
23
|
+
|
24
|
+
public void MoveBlock()
|
25
|
+
{
|
26
|
+
int offset = _bufferOffset + _pos - _keepSizeBefore;
|
27
|
+
// we need one additional byte, since MovePos moves on 1 byte.
|
28
|
+
if (offset > 0)
|
29
|
+
offset--;
|
30
|
+
|
31
|
+
int numBytes = _bufferOffset + _streamPos - offset;
|
32
|
+
|
33
|
+
// check negative offset ????
|
34
|
+
for (int i = 0; i < numBytes; i++)
|
35
|
+
_bufferBase[i] = _bufferBase[offset + i];
|
36
|
+
_bufferOffset -= offset;
|
37
|
+
}
|
38
|
+
|
39
|
+
public void ReadBlock() throws IOException
|
40
|
+
{
|
41
|
+
if (_streamEndWasReached)
|
42
|
+
return;
|
43
|
+
while (true)
|
44
|
+
{
|
45
|
+
int size = (0 - _bufferOffset) + _blockSize - _streamPos;
|
46
|
+
if (size == 0)
|
47
|
+
return;
|
48
|
+
int numReadBytes = _stream.read(_bufferBase, _bufferOffset + _streamPos, size);
|
49
|
+
if (numReadBytes == -1)
|
50
|
+
{
|
51
|
+
_posLimit = _streamPos;
|
52
|
+
int pointerToPostion = _bufferOffset + _posLimit;
|
53
|
+
if (pointerToPostion > _pointerToLastSafePosition)
|
54
|
+
_posLimit = _pointerToLastSafePosition - _bufferOffset;
|
55
|
+
|
56
|
+
_streamEndWasReached = true;
|
57
|
+
return;
|
58
|
+
}
|
59
|
+
_streamPos += numReadBytes;
|
60
|
+
if (_streamPos >= _pos + _keepSizeAfter)
|
61
|
+
_posLimit = _streamPos - _keepSizeAfter;
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
void Free() { _bufferBase = null; }
|
66
|
+
|
67
|
+
public void Create(int keepSizeBefore, int keepSizeAfter, int keepSizeReserv)
|
68
|
+
{
|
69
|
+
_keepSizeBefore = keepSizeBefore;
|
70
|
+
_keepSizeAfter = keepSizeAfter;
|
71
|
+
int blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv;
|
72
|
+
if (_bufferBase == null || _blockSize != blockSize)
|
73
|
+
{
|
74
|
+
Free();
|
75
|
+
_blockSize = blockSize;
|
76
|
+
_bufferBase = new byte[_blockSize];
|
77
|
+
}
|
78
|
+
_pointerToLastSafePosition = _blockSize - keepSizeAfter;
|
79
|
+
}
|
80
|
+
|
81
|
+
public void SetStream(java.io.InputStream stream) { _stream = stream; }
|
82
|
+
public void ReleaseStream() { _stream = null; }
|
83
|
+
|
84
|
+
public void Init() throws IOException
|
85
|
+
{
|
86
|
+
_bufferOffset = 0;
|
87
|
+
_pos = 0;
|
88
|
+
_streamPos = 0;
|
89
|
+
_streamEndWasReached = false;
|
90
|
+
ReadBlock();
|
91
|
+
}
|
92
|
+
|
93
|
+
public void MovePos() throws IOException
|
94
|
+
{
|
95
|
+
_pos++;
|
96
|
+
if (_pos > _posLimit)
|
97
|
+
{
|
98
|
+
int pointerToPostion = _bufferOffset + _pos;
|
99
|
+
if (pointerToPostion > _pointerToLastSafePosition)
|
100
|
+
MoveBlock();
|
101
|
+
ReadBlock();
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
public byte GetIndexByte(int index) { return _bufferBase[_bufferOffset + _pos + index]; }
|
106
|
+
|
107
|
+
// index + limit have not to exceed _keepSizeAfter;
|
108
|
+
public int GetMatchLen(int index, int distance, int limit)
|
109
|
+
{
|
110
|
+
if (_streamEndWasReached)
|
111
|
+
if ((_pos + index) + limit > _streamPos)
|
112
|
+
limit = _streamPos - (_pos + index);
|
113
|
+
distance++;
|
114
|
+
// Byte *pby = _buffer + (size_t)_pos + index;
|
115
|
+
int pby = _bufferOffset + _pos + index;
|
116
|
+
|
117
|
+
int i;
|
118
|
+
for (i = 0; i < limit && _bufferBase[pby + i] == _bufferBase[pby + i - distance]; i++);
|
119
|
+
return i;
|
120
|
+
}
|
121
|
+
|
122
|
+
public int GetNumAvailableBytes() { return _streamPos - _pos; }
|
123
|
+
|
124
|
+
public void ReduceOffsets(int subValue)
|
125
|
+
{
|
126
|
+
_bufferOffset += subValue;
|
127
|
+
_posLimit -= subValue;
|
128
|
+
_pos -= subValue;
|
129
|
+
_streamPos -= subValue;
|
130
|
+
}
|
131
|
+
}
|
@@ -0,0 +1,85 @@
|
|
1
|
+
// LZ.OutWindow
|
2
|
+
|
3
|
+
package SevenZip.Compression.LZ;
|
4
|
+
|
5
|
+
import java.io.IOException;
|
6
|
+
|
7
|
+
public class OutWindow
|
8
|
+
{
|
9
|
+
byte[] _buffer;
|
10
|
+
int _pos;
|
11
|
+
int _windowSize = 0;
|
12
|
+
int _streamPos;
|
13
|
+
java.io.OutputStream _stream;
|
14
|
+
|
15
|
+
public void Create(int windowSize)
|
16
|
+
{
|
17
|
+
if (_buffer == null || _windowSize != windowSize)
|
18
|
+
_buffer = new byte[windowSize];
|
19
|
+
_windowSize = windowSize;
|
20
|
+
_pos = 0;
|
21
|
+
_streamPos = 0;
|
22
|
+
}
|
23
|
+
|
24
|
+
public void SetStream(java.io.OutputStream stream) throws IOException
|
25
|
+
{
|
26
|
+
ReleaseStream();
|
27
|
+
_stream = stream;
|
28
|
+
}
|
29
|
+
|
30
|
+
public void ReleaseStream() throws IOException
|
31
|
+
{
|
32
|
+
Flush();
|
33
|
+
_stream = null;
|
34
|
+
}
|
35
|
+
|
36
|
+
public void Init(boolean solid)
|
37
|
+
{
|
38
|
+
if (!solid)
|
39
|
+
{
|
40
|
+
_streamPos = 0;
|
41
|
+
_pos = 0;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
public void Flush() throws IOException
|
46
|
+
{
|
47
|
+
int size = _pos - _streamPos;
|
48
|
+
if (size == 0)
|
49
|
+
return;
|
50
|
+
_stream.write(_buffer, _streamPos, size);
|
51
|
+
if (_pos >= _windowSize)
|
52
|
+
_pos = 0;
|
53
|
+
_streamPos = _pos;
|
54
|
+
}
|
55
|
+
|
56
|
+
public void CopyBlock(int distance, int len) throws IOException
|
57
|
+
{
|
58
|
+
int pos = _pos - distance - 1;
|
59
|
+
if (pos < 0)
|
60
|
+
pos += _windowSize;
|
61
|
+
for (; len != 0; len--)
|
62
|
+
{
|
63
|
+
if (pos >= _windowSize)
|
64
|
+
pos = 0;
|
65
|
+
_buffer[_pos++] = _buffer[pos++];
|
66
|
+
if (_pos >= _windowSize)
|
67
|
+
Flush();
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
public void PutByte(byte b) throws IOException
|
72
|
+
{
|
73
|
+
_buffer[_pos++] = b;
|
74
|
+
if (_pos >= _windowSize)
|
75
|
+
Flush();
|
76
|
+
}
|
77
|
+
|
78
|
+
public byte GetByte(int distance)
|
79
|
+
{
|
80
|
+
int pos = _pos - distance - 1;
|
81
|
+
if (pos < 0)
|
82
|
+
pos += _windowSize;
|
83
|
+
return _buffer[pos];
|
84
|
+
}
|
85
|
+
}
|
@@ -0,0 +1,88 @@
|
|
1
|
+
// Base.java
|
2
|
+
|
3
|
+
package SevenZip.Compression.LZMA;
|
4
|
+
|
5
|
+
public class Base
|
6
|
+
{
|
7
|
+
public static final int kNumRepDistances = 4;
|
8
|
+
public static final int kNumStates = 12;
|
9
|
+
|
10
|
+
public static final int StateInit()
|
11
|
+
{
|
12
|
+
return 0;
|
13
|
+
}
|
14
|
+
|
15
|
+
public static final int StateUpdateChar(int index)
|
16
|
+
{
|
17
|
+
if (index < 4)
|
18
|
+
return 0;
|
19
|
+
if (index < 10)
|
20
|
+
return index - 3;
|
21
|
+
return index - 6;
|
22
|
+
}
|
23
|
+
|
24
|
+
public static final int StateUpdateMatch(int index)
|
25
|
+
{
|
26
|
+
return (index < 7 ? 7 : 10);
|
27
|
+
}
|
28
|
+
|
29
|
+
public static final int StateUpdateRep(int index)
|
30
|
+
{
|
31
|
+
return (index < 7 ? 8 : 11);
|
32
|
+
}
|
33
|
+
|
34
|
+
public static final int StateUpdateShortRep(int index)
|
35
|
+
{
|
36
|
+
return (index < 7 ? 9 : 11);
|
37
|
+
}
|
38
|
+
|
39
|
+
public static final boolean StateIsCharState(int index)
|
40
|
+
{
|
41
|
+
return index < 7;
|
42
|
+
}
|
43
|
+
|
44
|
+
public static final int kNumPosSlotBits = 6;
|
45
|
+
public static final int kDicLogSizeMin = 0;
|
46
|
+
// public static final int kDicLogSizeMax = 28;
|
47
|
+
// public static final int kDistTableSizeMax = kDicLogSizeMax * 2;
|
48
|
+
|
49
|
+
public static final int kNumLenToPosStatesBits = 2; // it's for speed optimization
|
50
|
+
public static final int kNumLenToPosStates = 1 << kNumLenToPosStatesBits;
|
51
|
+
|
52
|
+
public static final int kMatchMinLen = 2;
|
53
|
+
|
54
|
+
public static final int GetLenToPosState(int len)
|
55
|
+
{
|
56
|
+
len -= kMatchMinLen;
|
57
|
+
if (len < kNumLenToPosStates)
|
58
|
+
return len;
|
59
|
+
return (int)(kNumLenToPosStates - 1);
|
60
|
+
}
|
61
|
+
|
62
|
+
public static final int kNumAlignBits = 4;
|
63
|
+
public static final int kAlignTableSize = 1 << kNumAlignBits;
|
64
|
+
public static final int kAlignMask = (kAlignTableSize - 1);
|
65
|
+
|
66
|
+
public static final int kStartPosModelIndex = 4;
|
67
|
+
public static final int kEndPosModelIndex = 14;
|
68
|
+
public static final int kNumPosModels = kEndPosModelIndex - kStartPosModelIndex;
|
69
|
+
|
70
|
+
public static final int kNumFullDistances = 1 << (kEndPosModelIndex / 2);
|
71
|
+
|
72
|
+
public static final int kNumLitPosStatesBitsEncodingMax = 4;
|
73
|
+
public static final int kNumLitContextBitsMax = 8;
|
74
|
+
|
75
|
+
public static final int kNumPosStatesBitsMax = 4;
|
76
|
+
public static final int kNumPosStatesMax = (1 << kNumPosStatesBitsMax);
|
77
|
+
public static final int kNumPosStatesBitsEncodingMax = 4;
|
78
|
+
public static final int kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax);
|
79
|
+
|
80
|
+
public static final int kNumLowLenBits = 3;
|
81
|
+
public static final int kNumMidLenBits = 3;
|
82
|
+
public static final int kNumHighLenBits = 8;
|
83
|
+
public static final int kNumLowLenSymbols = 1 << kNumLowLenBits;
|
84
|
+
public static final int kNumMidLenSymbols = 1 << kNumMidLenBits;
|
85
|
+
public static final int kNumLenSymbols = kNumLowLenSymbols + kNumMidLenSymbols +
|
86
|
+
(1 << kNumHighLenBits);
|
87
|
+
public static final int kMatchMaxLen = kMatchMinLen + kNumLenSymbols - 1;
|
88
|
+
}
|
@@ -0,0 +1,329 @@
|
|
1
|
+
package SevenZip.Compression.LZMA;
|
2
|
+
|
3
|
+
import SevenZip.Compression.RangeCoder.BitTreeDecoder;
|
4
|
+
import SevenZip.Compression.LZMA.Base;
|
5
|
+
import SevenZip.Compression.LZ.OutWindow;
|
6
|
+
import java.io.IOException;
|
7
|
+
|
8
|
+
public class Decoder
|
9
|
+
{
|
10
|
+
class LenDecoder
|
11
|
+
{
|
12
|
+
short[] m_Choice = new short[2];
|
13
|
+
BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
|
14
|
+
BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax];
|
15
|
+
BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits);
|
16
|
+
int m_NumPosStates = 0;
|
17
|
+
|
18
|
+
public void Create(int numPosStates)
|
19
|
+
{
|
20
|
+
for (; m_NumPosStates < numPosStates; m_NumPosStates++)
|
21
|
+
{
|
22
|
+
m_LowCoder[m_NumPosStates] = new BitTreeDecoder(Base.kNumLowLenBits);
|
23
|
+
m_MidCoder[m_NumPosStates] = new BitTreeDecoder(Base.kNumMidLenBits);
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
public void Init()
|
28
|
+
{
|
29
|
+
SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_Choice);
|
30
|
+
for (int posState = 0; posState < m_NumPosStates; posState++)
|
31
|
+
{
|
32
|
+
m_LowCoder[posState].Init();
|
33
|
+
m_MidCoder[posState].Init();
|
34
|
+
}
|
35
|
+
m_HighCoder.Init();
|
36
|
+
}
|
37
|
+
|
38
|
+
public int Decode(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, int posState) throws IOException
|
39
|
+
{
|
40
|
+
if (rangeDecoder.DecodeBit(m_Choice, 0) == 0)
|
41
|
+
return m_LowCoder[posState].Decode(rangeDecoder);
|
42
|
+
int symbol = Base.kNumLowLenSymbols;
|
43
|
+
if (rangeDecoder.DecodeBit(m_Choice, 1) == 0)
|
44
|
+
symbol += m_MidCoder[posState].Decode(rangeDecoder);
|
45
|
+
else
|
46
|
+
symbol += Base.kNumMidLenSymbols + m_HighCoder.Decode(rangeDecoder);
|
47
|
+
return symbol;
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
class LiteralDecoder
|
52
|
+
{
|
53
|
+
class Decoder2
|
54
|
+
{
|
55
|
+
short[] m_Decoders = new short[0x300];
|
56
|
+
|
57
|
+
public void Init()
|
58
|
+
{
|
59
|
+
SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_Decoders);
|
60
|
+
}
|
61
|
+
|
62
|
+
public byte DecodeNormal(SevenZip.Compression.RangeCoder.Decoder rangeDecoder) throws IOException
|
63
|
+
{
|
64
|
+
int symbol = 1;
|
65
|
+
do
|
66
|
+
symbol = (symbol << 1) | rangeDecoder.DecodeBit(m_Decoders, symbol);
|
67
|
+
while (symbol < 0x100);
|
68
|
+
return (byte)symbol;
|
69
|
+
}
|
70
|
+
|
71
|
+
public byte DecodeWithMatchByte(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, byte matchByte) throws IOException
|
72
|
+
{
|
73
|
+
int symbol = 1;
|
74
|
+
do
|
75
|
+
{
|
76
|
+
int matchBit = (matchByte >> 7) & 1;
|
77
|
+
matchByte <<= 1;
|
78
|
+
int bit = rangeDecoder.DecodeBit(m_Decoders, ((1 + matchBit) << 8) + symbol);
|
79
|
+
symbol = (symbol << 1) | bit;
|
80
|
+
if (matchBit != bit)
|
81
|
+
{
|
82
|
+
while (symbol < 0x100)
|
83
|
+
symbol = (symbol << 1) | rangeDecoder.DecodeBit(m_Decoders, symbol);
|
84
|
+
break;
|
85
|
+
}
|
86
|
+
}
|
87
|
+
while (symbol < 0x100);
|
88
|
+
return (byte)symbol;
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
Decoder2[] m_Coders;
|
93
|
+
int m_NumPrevBits;
|
94
|
+
int m_NumPosBits;
|
95
|
+
int m_PosMask;
|
96
|
+
|
97
|
+
public void Create(int numPosBits, int numPrevBits)
|
98
|
+
{
|
99
|
+
if (m_Coders != null && m_NumPrevBits == numPrevBits && m_NumPosBits == numPosBits)
|
100
|
+
return;
|
101
|
+
m_NumPosBits = numPosBits;
|
102
|
+
m_PosMask = (1 << numPosBits) - 1;
|
103
|
+
m_NumPrevBits = numPrevBits;
|
104
|
+
int numStates = 1 << (m_NumPrevBits + m_NumPosBits);
|
105
|
+
m_Coders = new Decoder2[numStates];
|
106
|
+
for (int i = 0; i < numStates; i++)
|
107
|
+
m_Coders[i] = new Decoder2();
|
108
|
+
}
|
109
|
+
|
110
|
+
public void Init()
|
111
|
+
{
|
112
|
+
int numStates = 1 << (m_NumPrevBits + m_NumPosBits);
|
113
|
+
for (int i = 0; i < numStates; i++)
|
114
|
+
m_Coders[i].Init();
|
115
|
+
}
|
116
|
+
|
117
|
+
Decoder2 GetDecoder(int pos, byte prevByte)
|
118
|
+
{
|
119
|
+
return m_Coders[((pos & m_PosMask) << m_NumPrevBits) + ((prevByte & 0xFF) >>> (8 - m_NumPrevBits))];
|
120
|
+
}
|
121
|
+
}
|
122
|
+
|
123
|
+
OutWindow m_OutWindow = new OutWindow();
|
124
|
+
SevenZip.Compression.RangeCoder.Decoder m_RangeDecoder = new SevenZip.Compression.RangeCoder.Decoder();
|
125
|
+
|
126
|
+
short[] m_IsMatchDecoders = new short[Base.kNumStates << Base.kNumPosStatesBitsMax];
|
127
|
+
short[] m_IsRepDecoders = new short[Base.kNumStates];
|
128
|
+
short[] m_IsRepG0Decoders = new short[Base.kNumStates];
|
129
|
+
short[] m_IsRepG1Decoders = new short[Base.kNumStates];
|
130
|
+
short[] m_IsRepG2Decoders = new short[Base.kNumStates];
|
131
|
+
short[] m_IsRep0LongDecoders = new short[Base.kNumStates << Base.kNumPosStatesBitsMax];
|
132
|
+
|
133
|
+
BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates];
|
134
|
+
short[] m_PosDecoders = new short[Base.kNumFullDistances - Base.kEndPosModelIndex];
|
135
|
+
|
136
|
+
BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumAlignBits);
|
137
|
+
|
138
|
+
LenDecoder m_LenDecoder = new LenDecoder();
|
139
|
+
LenDecoder m_RepLenDecoder = new LenDecoder();
|
140
|
+
|
141
|
+
LiteralDecoder m_LiteralDecoder = new LiteralDecoder();
|
142
|
+
|
143
|
+
int m_DictionarySize = -1;
|
144
|
+
int m_DictionarySizeCheck = -1;
|
145
|
+
|
146
|
+
int m_PosStateMask;
|
147
|
+
|
148
|
+
public Decoder()
|
149
|
+
{
|
150
|
+
for (int i = 0; i < Base.kNumLenToPosStates; i++)
|
151
|
+
m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits);
|
152
|
+
}
|
153
|
+
|
154
|
+
boolean SetDictionarySize(int dictionarySize)
|
155
|
+
{
|
156
|
+
if (dictionarySize < 0)
|
157
|
+
return false;
|
158
|
+
if (m_DictionarySize != dictionarySize)
|
159
|
+
{
|
160
|
+
m_DictionarySize = dictionarySize;
|
161
|
+
m_DictionarySizeCheck = Math.max(m_DictionarySize, 1);
|
162
|
+
m_OutWindow.Create(Math.max(m_DictionarySizeCheck, (1 << 12)));
|
163
|
+
}
|
164
|
+
return true;
|
165
|
+
}
|
166
|
+
|
167
|
+
boolean SetLcLpPb(int lc, int lp, int pb)
|
168
|
+
{
|
169
|
+
if (lc > Base.kNumLitContextBitsMax || lp > 4 || pb > Base.kNumPosStatesBitsMax)
|
170
|
+
return false;
|
171
|
+
m_LiteralDecoder.Create(lp, lc);
|
172
|
+
int numPosStates = 1 << pb;
|
173
|
+
m_LenDecoder.Create(numPosStates);
|
174
|
+
m_RepLenDecoder.Create(numPosStates);
|
175
|
+
m_PosStateMask = numPosStates - 1;
|
176
|
+
return true;
|
177
|
+
}
|
178
|
+
|
179
|
+
void Init() throws IOException
|
180
|
+
{
|
181
|
+
m_OutWindow.Init(false);
|
182
|
+
|
183
|
+
SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsMatchDecoders);
|
184
|
+
SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRep0LongDecoders);
|
185
|
+
SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepDecoders);
|
186
|
+
SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG0Decoders);
|
187
|
+
SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG1Decoders);
|
188
|
+
SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG2Decoders);
|
189
|
+
SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_PosDecoders);
|
190
|
+
|
191
|
+
m_LiteralDecoder.Init();
|
192
|
+
int i;
|
193
|
+
for (i = 0; i < Base.kNumLenToPosStates; i++)
|
194
|
+
m_PosSlotDecoder[i].Init();
|
195
|
+
m_LenDecoder.Init();
|
196
|
+
m_RepLenDecoder.Init();
|
197
|
+
m_PosAlignDecoder.Init();
|
198
|
+
m_RangeDecoder.Init();
|
199
|
+
}
|
200
|
+
|
201
|
+
public boolean Code(java.io.InputStream inStream, java.io.OutputStream outStream,
|
202
|
+
long outSize) throws IOException
|
203
|
+
{
|
204
|
+
m_RangeDecoder.SetStream(inStream);
|
205
|
+
m_OutWindow.SetStream(outStream);
|
206
|
+
Init();
|
207
|
+
|
208
|
+
int state = Base.StateInit();
|
209
|
+
int rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;
|
210
|
+
|
211
|
+
long nowPos64 = 0;
|
212
|
+
byte prevByte = 0;
|
213
|
+
while (outSize < 0 || nowPos64 < outSize)
|
214
|
+
{
|
215
|
+
int posState = (int)nowPos64 & m_PosStateMask;
|
216
|
+
if (m_RangeDecoder.DecodeBit(m_IsMatchDecoders, (state << Base.kNumPosStatesBitsMax) + posState) == 0)
|
217
|
+
{
|
218
|
+
LiteralDecoder.Decoder2 decoder2 = m_LiteralDecoder.GetDecoder((int)nowPos64, prevByte);
|
219
|
+
if (!Base.StateIsCharState(state))
|
220
|
+
prevByte = decoder2.DecodeWithMatchByte(m_RangeDecoder, m_OutWindow.GetByte(rep0));
|
221
|
+
else
|
222
|
+
prevByte = decoder2.DecodeNormal(m_RangeDecoder);
|
223
|
+
m_OutWindow.PutByte(prevByte);
|
224
|
+
state = Base.StateUpdateChar(state);
|
225
|
+
nowPos64++;
|
226
|
+
}
|
227
|
+
else
|
228
|
+
{
|
229
|
+
int len;
|
230
|
+
if (m_RangeDecoder.DecodeBit(m_IsRepDecoders, state) == 1)
|
231
|
+
{
|
232
|
+
len = 0;
|
233
|
+
if (m_RangeDecoder.DecodeBit(m_IsRepG0Decoders, state) == 0)
|
234
|
+
{
|
235
|
+
if (m_RangeDecoder.DecodeBit(m_IsRep0LongDecoders, (state << Base.kNumPosStatesBitsMax) + posState) == 0)
|
236
|
+
{
|
237
|
+
state = Base.StateUpdateShortRep(state);
|
238
|
+
len = 1;
|
239
|
+
}
|
240
|
+
}
|
241
|
+
else
|
242
|
+
{
|
243
|
+
int distance;
|
244
|
+
if (m_RangeDecoder.DecodeBit(m_IsRepG1Decoders, state) == 0)
|
245
|
+
distance = rep1;
|
246
|
+
else
|
247
|
+
{
|
248
|
+
if (m_RangeDecoder.DecodeBit(m_IsRepG2Decoders, state) == 0)
|
249
|
+
distance = rep2;
|
250
|
+
else
|
251
|
+
{
|
252
|
+
distance = rep3;
|
253
|
+
rep3 = rep2;
|
254
|
+
}
|
255
|
+
rep2 = rep1;
|
256
|
+
}
|
257
|
+
rep1 = rep0;
|
258
|
+
rep0 = distance;
|
259
|
+
}
|
260
|
+
if (len == 0)
|
261
|
+
{
|
262
|
+
len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen;
|
263
|
+
state = Base.StateUpdateRep(state);
|
264
|
+
}
|
265
|
+
}
|
266
|
+
else
|
267
|
+
{
|
268
|
+
rep3 = rep2;
|
269
|
+
rep2 = rep1;
|
270
|
+
rep1 = rep0;
|
271
|
+
len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState);
|
272
|
+
state = Base.StateUpdateMatch(state);
|
273
|
+
int posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder);
|
274
|
+
if (posSlot >= Base.kStartPosModelIndex)
|
275
|
+
{
|
276
|
+
int numDirectBits = (posSlot >> 1) - 1;
|
277
|
+
rep0 = ((2 | (posSlot & 1)) << numDirectBits);
|
278
|
+
if (posSlot < Base.kEndPosModelIndex)
|
279
|
+
rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders,
|
280
|
+
rep0 - posSlot - 1, m_RangeDecoder, numDirectBits);
|
281
|
+
else
|
282
|
+
{
|
283
|
+
rep0 += (m_RangeDecoder.DecodeDirectBits(
|
284
|
+
numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits);
|
285
|
+
rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder);
|
286
|
+
if (rep0 < 0)
|
287
|
+
{
|
288
|
+
if (rep0 == -1)
|
289
|
+
break;
|
290
|
+
return false;
|
291
|
+
}
|
292
|
+
}
|
293
|
+
}
|
294
|
+
else
|
295
|
+
rep0 = posSlot;
|
296
|
+
}
|
297
|
+
if (rep0 >= nowPos64 || rep0 >= m_DictionarySizeCheck)
|
298
|
+
{
|
299
|
+
// m_OutWindow.Flush();
|
300
|
+
return false;
|
301
|
+
}
|
302
|
+
m_OutWindow.CopyBlock(rep0, len);
|
303
|
+
nowPos64 += len;
|
304
|
+
prevByte = m_OutWindow.GetByte(0);
|
305
|
+
}
|
306
|
+
}
|
307
|
+
m_OutWindow.Flush();
|
308
|
+
m_OutWindow.ReleaseStream();
|
309
|
+
m_RangeDecoder.ReleaseStream();
|
310
|
+
return true;
|
311
|
+
}
|
312
|
+
|
313
|
+
public boolean SetDecoderProperties(byte[] properties)
|
314
|
+
{
|
315
|
+
if (properties.length < 5)
|
316
|
+
return false;
|
317
|
+
int val = properties[0] & 0xFF;
|
318
|
+
int lc = val % 9;
|
319
|
+
int remainder = val / 9;
|
320
|
+
int lp = remainder % 5;
|
321
|
+
int pb = remainder / 5;
|
322
|
+
int dictionarySize = 0;
|
323
|
+
for (int i = 0; i < 4; i++)
|
324
|
+
dictionarySize += ((int)(properties[1 + i]) & 0xFF) << (i * 8);
|
325
|
+
if (!SetLcLpPb(lc, lp, pb))
|
326
|
+
return false;
|
327
|
+
return SetDictionarySize(dictionarySize);
|
328
|
+
}
|
329
|
+
}
|