ruby-lzma 0.4.1
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.
- 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
|
+
}
|