From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- .../src/Java/SevenZip/Compression/LZ/BinTree.java | 382 ++++++ .../src/Java/SevenZip/Compression/LZ/InWindow.java | 131 ++ .../Java/SevenZip/Compression/LZ/OutWindow.java | 85 ++ .../src/Java/SevenZip/Compression/LZMA/Base.java | 88 ++ .../Java/SevenZip/Compression/LZMA/Decoder.java | 329 +++++ .../Java/SevenZip/Compression/LZMA/Encoder.java | 1416 ++++++++++++++++++++ .../Compression/RangeCoder/BitTreeDecoder.java | 55 + .../Compression/RangeCoder/BitTreeEncoder.java | 99 ++ .../SevenZip/Compression/RangeCoder/Decoder.java | 88 ++ .../SevenZip/Compression/RangeCoder/Encoder.java | 151 +++ 10 files changed, 2824 insertions(+) create mode 100644 other-licenses/7zstub/src/Java/SevenZip/Compression/LZ/BinTree.java create mode 100644 other-licenses/7zstub/src/Java/SevenZip/Compression/LZ/InWindow.java create mode 100644 other-licenses/7zstub/src/Java/SevenZip/Compression/LZ/OutWindow.java create mode 100644 other-licenses/7zstub/src/Java/SevenZip/Compression/LZMA/Base.java create mode 100644 other-licenses/7zstub/src/Java/SevenZip/Compression/LZMA/Decoder.java create mode 100644 other-licenses/7zstub/src/Java/SevenZip/Compression/LZMA/Encoder.java create mode 100644 other-licenses/7zstub/src/Java/SevenZip/Compression/RangeCoder/BitTreeDecoder.java create mode 100644 other-licenses/7zstub/src/Java/SevenZip/Compression/RangeCoder/BitTreeEncoder.java create mode 100644 other-licenses/7zstub/src/Java/SevenZip/Compression/RangeCoder/Decoder.java create mode 100644 other-licenses/7zstub/src/Java/SevenZip/Compression/RangeCoder/Encoder.java (limited to 'other-licenses/7zstub/src/Java/SevenZip/Compression') diff --git a/other-licenses/7zstub/src/Java/SevenZip/Compression/LZ/BinTree.java b/other-licenses/7zstub/src/Java/SevenZip/Compression/LZ/BinTree.java new file mode 100644 index 0000000000..63d58c05a0 --- /dev/null +++ b/other-licenses/7zstub/src/Java/SevenZip/Compression/LZ/BinTree.java @@ -0,0 +1,382 @@ +// LZ.BinTree + +package SevenZip.Compression.LZ; +import java.io.IOException; + + +public class BinTree extends InWindow +{ + int _cyclicBufferPos; + int _cyclicBufferSize = 0; + int _matchMaxLen; + + int[] _son; + int[] _hash; + + int _cutValue = 0xFF; + int _hashMask; + int _hashSizeSum = 0; + + boolean HASH_ARRAY = true; + + static final int kHash2Size = 1 << 10; + static final int kHash3Size = 1 << 16; + static final int kBT2HashSize = 1 << 16; + static final int kStartMaxLen = 1; + static final int kHash3Offset = kHash2Size; + static final int kEmptyHashValue = 0; + static final int kMaxValForNormalize = (1 << 30) - 1; + + int kNumHashDirectBytes = 0; + int kMinMatchCheck = 4; + int kFixHashSize = kHash2Size + kHash3Size; + + public void SetType(int numHashBytes) + { + HASH_ARRAY = (numHashBytes > 2); + if (HASH_ARRAY) + { + kNumHashDirectBytes = 0; + kMinMatchCheck = 4; + kFixHashSize = kHash2Size + kHash3Size; + } + else + { + kNumHashDirectBytes = 2; + kMinMatchCheck = 2 + 1; + kFixHashSize = 0; + } + } + + + + + public void Init() throws IOException + { + super.Init(); + for (int i = 0; i < _hashSizeSum; i++) + _hash[i] = kEmptyHashValue; + _cyclicBufferPos = 0; + ReduceOffsets(-1); + } + + public void MovePos() throws IOException + { + if (++_cyclicBufferPos >= _cyclicBufferSize) + _cyclicBufferPos = 0; + super.MovePos(); + if (_pos == kMaxValForNormalize) + Normalize(); + } + + + + + + + + + public boolean Create(int historySize, int keepAddBufferBefore, + int matchMaxLen, int keepAddBufferAfter) + { + if (historySize > kMaxValForNormalize - 256) + return false; + _cutValue = 16 + (matchMaxLen >> 1); + + int windowReservSize = (historySize + keepAddBufferBefore + + matchMaxLen + keepAddBufferAfter) / 2 + 256; + + super.Create(historySize + keepAddBufferBefore, matchMaxLen + keepAddBufferAfter, windowReservSize); + + _matchMaxLen = matchMaxLen; + + int cyclicBufferSize = historySize + 1; + if (_cyclicBufferSize != cyclicBufferSize) + _son = new int[(_cyclicBufferSize = cyclicBufferSize) * 2]; + + int hs = kBT2HashSize; + + if (HASH_ARRAY) + { + hs = historySize - 1; + hs |= (hs >> 1); + hs |= (hs >> 2); + hs |= (hs >> 4); + hs |= (hs >> 8); + hs >>= 1; + hs |= 0xFFFF; + if (hs > (1 << 24)) + hs >>= 1; + _hashMask = hs; + hs++; + hs += kFixHashSize; + } + if (hs != _hashSizeSum) + _hash = new int [_hashSizeSum = hs]; + return true; + } + public int GetMatches(int[] distances) throws IOException + { + int lenLimit; + if (_pos + _matchMaxLen <= _streamPos) + lenLimit = _matchMaxLen; + else + { + lenLimit = _streamPos - _pos; + if (lenLimit < kMinMatchCheck) + { + MovePos(); + return 0; + } + } + + int offset = 0; + int matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0; + int cur = _bufferOffset + _pos; + int maxLen = kStartMaxLen; // to avoid items for len < hashSize; + int hashValue, hash2Value = 0, hash3Value = 0; + + if (HASH_ARRAY) + { + int temp = CrcTable[_bufferBase[cur] & 0xFF] ^ (_bufferBase[cur + 1] & 0xFF); + hash2Value = temp & (kHash2Size - 1); + temp ^= ((int)(_bufferBase[cur + 2] & 0xFF) << 8); + hash3Value = temp & (kHash3Size - 1); + hashValue = (temp ^ (CrcTable[_bufferBase[cur + 3] & 0xFF] << 5)) & _hashMask; + } + else + hashValue = ((_bufferBase[cur] & 0xFF) ^ ((int)(_bufferBase[cur + 1] & 0xFF) << 8)); + + int curMatch = _hash[kFixHashSize + hashValue]; + if (HASH_ARRAY) + { + int curMatch2 = _hash[hash2Value]; + int curMatch3 = _hash[kHash3Offset + hash3Value]; + _hash[hash2Value] = _pos; + _hash[kHash3Offset + hash3Value] = _pos; + if (curMatch2 > matchMinPos) + if (_bufferBase[_bufferOffset + curMatch2] == _bufferBase[cur]) + { + distances[offset++] = maxLen = 2; + distances[offset++] = _pos - curMatch2 - 1; + } + if (curMatch3 > matchMinPos) + if (_bufferBase[_bufferOffset + curMatch3] == _bufferBase[cur]) + { + if (curMatch3 == curMatch2) + offset -= 2; + distances[offset++] = maxLen = 3; + distances[offset++] = _pos - curMatch3 - 1; + curMatch2 = curMatch3; + } + if (offset != 0 && curMatch2 == curMatch) + { + offset -= 2; + maxLen = kStartMaxLen; + } + } + + _hash[kFixHashSize + hashValue] = _pos; + + int ptr0 = (_cyclicBufferPos << 1) + 1; + int ptr1 = (_cyclicBufferPos << 1); + + int len0, len1; + len0 = len1 = kNumHashDirectBytes; + + if (kNumHashDirectBytes != 0) + { + if (curMatch > matchMinPos) + { + if (_bufferBase[_bufferOffset + curMatch + kNumHashDirectBytes] != + _bufferBase[cur + kNumHashDirectBytes]) + { + distances[offset++] = maxLen = kNumHashDirectBytes; + distances[offset++] = _pos - curMatch - 1; + } + } + } + + int count = _cutValue; + + while (true) + { + if (curMatch <= matchMinPos || count-- == 0) + { + _son[ptr0] = _son[ptr1] = kEmptyHashValue; + break; + } + int delta = _pos - curMatch; + int cyclicPos = ((delta <= _cyclicBufferPos) ? + (_cyclicBufferPos - delta) : + (_cyclicBufferPos - delta + _cyclicBufferSize)) << 1; + + int pby1 = _bufferOffset + curMatch; + int len = Math.min(len0, len1); + if (_bufferBase[pby1 + len] == _bufferBase[cur + len]) + { + while(++len != lenLimit) + if (_bufferBase[pby1 + len] != _bufferBase[cur + len]) + break; + if (maxLen < len) + { + distances[offset++] = maxLen = len; + distances[offset++] = delta - 1; + if (len == lenLimit) + { + _son[ptr1] = _son[cyclicPos]; + _son[ptr0] = _son[cyclicPos + 1]; + break; + } + } + } + if ((_bufferBase[pby1 + len] & 0xFF) < (_bufferBase[cur + len] & 0xFF)) + { + _son[ptr1] = curMatch; + ptr1 = cyclicPos + 1; + curMatch = _son[ptr1]; + len1 = len; + } + else + { + _son[ptr0] = curMatch; + ptr0 = cyclicPos; + curMatch = _son[ptr0]; + len0 = len; + } + } + MovePos(); + return offset; + } + + public void Skip(int num) throws IOException + { + do + { + int lenLimit; + if (_pos + _matchMaxLen <= _streamPos) + lenLimit = _matchMaxLen; + else + { + lenLimit = _streamPos - _pos; + if (lenLimit < kMinMatchCheck) + { + MovePos(); + continue; + } + } + + int matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0; + int cur = _bufferOffset + _pos; + + int hashValue; + + if (HASH_ARRAY) + { + int temp = CrcTable[_bufferBase[cur] & 0xFF] ^ (_bufferBase[cur + 1] & 0xFF); + int hash2Value = temp & (kHash2Size - 1); + _hash[hash2Value] = _pos; + temp ^= ((int)(_bufferBase[cur + 2] & 0xFF) << 8); + int hash3Value = temp & (kHash3Size - 1); + _hash[kHash3Offset + hash3Value] = _pos; + hashValue = (temp ^ (CrcTable[_bufferBase[cur + 3] & 0xFF] << 5)) & _hashMask; + } + else + hashValue = ((_bufferBase[cur] & 0xFF) ^ ((int)(_bufferBase[cur + 1] & 0xFF) << 8)); + + int curMatch = _hash[kFixHashSize + hashValue]; + _hash[kFixHashSize + hashValue] = _pos; + + int ptr0 = (_cyclicBufferPos << 1) + 1; + int ptr1 = (_cyclicBufferPos << 1); + + int len0, len1; + len0 = len1 = kNumHashDirectBytes; + + int count = _cutValue; + while (true) + { + if (curMatch <= matchMinPos || count-- == 0) + { + _son[ptr0] = _son[ptr1] = kEmptyHashValue; + break; + } + + int delta = _pos - curMatch; + int cyclicPos = ((delta <= _cyclicBufferPos) ? + (_cyclicBufferPos - delta) : + (_cyclicBufferPos - delta + _cyclicBufferSize)) << 1; + + int pby1 = _bufferOffset + curMatch; + int len = Math.min(len0, len1); + if (_bufferBase[pby1 + len] == _bufferBase[cur + len]) + { + while (++len != lenLimit) + if (_bufferBase[pby1 + len] != _bufferBase[cur + len]) + break; + if (len == lenLimit) + { + _son[ptr1] = _son[cyclicPos]; + _son[ptr0] = _son[cyclicPos + 1]; + break; + } + } + if ((_bufferBase[pby1 + len] & 0xFF) < (_bufferBase[cur + len] & 0xFF)) + { + _son[ptr1] = curMatch; + ptr1 = cyclicPos + 1; + curMatch = _son[ptr1]; + len1 = len; + } + else + { + _son[ptr0] = curMatch; + ptr0 = cyclicPos; + curMatch = _son[ptr0]; + len0 = len; + } + } + MovePos(); + } + while (--num != 0); + } + + void NormalizeLinks(int[] items, int numItems, int subValue) + { + for (int i = 0; i < numItems; i++) + { + int value = items[i]; + if (value <= subValue) + value = kEmptyHashValue; + else + value -= subValue; + items[i] = value; + } + } + + void Normalize() + { + int subValue = _pos - _cyclicBufferSize; + NormalizeLinks(_son, _cyclicBufferSize * 2, subValue); + NormalizeLinks(_hash, _hashSizeSum, subValue); + ReduceOffsets(subValue); + } + + public void SetCutValue(int cutValue) { _cutValue = cutValue; } + + private static final int[] CrcTable = new int[256]; + + static + { + for (int i = 0; i < 256; i++) + { + int r = i; + for (int j = 0; j < 8; j++) + if ((r & 1) != 0) + r = (r >>> 1) ^ 0xEDB88320; + else + r >>>= 1; + CrcTable[i] = r; + } + } +} diff --git a/other-licenses/7zstub/src/Java/SevenZip/Compression/LZ/InWindow.java b/other-licenses/7zstub/src/Java/SevenZip/Compression/LZ/InWindow.java new file mode 100644 index 0000000000..5f3f0b4d09 --- /dev/null +++ b/other-licenses/7zstub/src/Java/SevenZip/Compression/LZ/InWindow.java @@ -0,0 +1,131 @@ +// LZ.InWindow + +package SevenZip.Compression.LZ; + +import java.io.IOException; + +public class InWindow +{ + public byte[] _bufferBase; // pointer to buffer with data + java.io.InputStream _stream; + int _posLimit; // offset (from _buffer) of first byte when new block reading must be done + boolean _streamEndWasReached; // if (true) then _streamPos shows real end of stream + + int _pointerToLastSafePosition; + + public int _bufferOffset; + + public int _blockSize; // Size of Allocated memory block + public int _pos; // offset (from _buffer) of curent byte + int _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos + int _keepSizeAfter; // how many BYTEs must be kept buffer after _pos + public int _streamPos; // offset (from _buffer) of first not read byte from Stream + + public void MoveBlock() + { + int offset = _bufferOffset + _pos - _keepSizeBefore; + // we need one additional byte, since MovePos moves on 1 byte. + if (offset > 0) + offset--; + + int numBytes = _bufferOffset + _streamPos - offset; + + // check negative offset ???? + for (int i = 0; i < numBytes; i++) + _bufferBase[i] = _bufferBase[offset + i]; + _bufferOffset -= offset; + } + + public void ReadBlock() throws IOException + { + if (_streamEndWasReached) + return; + while (true) + { + int size = (0 - _bufferOffset) + _blockSize - _streamPos; + if (size == 0) + return; + int numReadBytes = _stream.read(_bufferBase, _bufferOffset + _streamPos, size); + if (numReadBytes == -1) + { + _posLimit = _streamPos; + int pointerToPostion = _bufferOffset + _posLimit; + if (pointerToPostion > _pointerToLastSafePosition) + _posLimit = _pointerToLastSafePosition - _bufferOffset; + + _streamEndWasReached = true; + return; + } + _streamPos += numReadBytes; + if (_streamPos >= _pos + _keepSizeAfter) + _posLimit = _streamPos - _keepSizeAfter; + } + } + + void Free() { _bufferBase = null; } + + public void Create(int keepSizeBefore, int keepSizeAfter, int keepSizeReserv) + { + _keepSizeBefore = keepSizeBefore; + _keepSizeAfter = keepSizeAfter; + int blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv; + if (_bufferBase == null || _blockSize != blockSize) + { + Free(); + _blockSize = blockSize; + _bufferBase = new byte[_blockSize]; + } + _pointerToLastSafePosition = _blockSize - keepSizeAfter; + } + + public void SetStream(java.io.InputStream stream) { _stream = stream; } + public void ReleaseStream() { _stream = null; } + + public void Init() throws IOException + { + _bufferOffset = 0; + _pos = 0; + _streamPos = 0; + _streamEndWasReached = false; + ReadBlock(); + } + + public void MovePos() throws IOException + { + _pos++; + if (_pos > _posLimit) + { + int pointerToPostion = _bufferOffset + _pos; + if (pointerToPostion > _pointerToLastSafePosition) + MoveBlock(); + ReadBlock(); + } + } + + public byte GetIndexByte(int index) { return _bufferBase[_bufferOffset + _pos + index]; } + + // index + limit have not to exceed _keepSizeAfter; + public int GetMatchLen(int index, int distance, int limit) + { + if (_streamEndWasReached) + if ((_pos + index) + limit > _streamPos) + limit = _streamPos - (_pos + index); + distance++; + // Byte *pby = _buffer + (size_t)_pos + index; + int pby = _bufferOffset + _pos + index; + + int i; + for (i = 0; i < limit && _bufferBase[pby + i] == _bufferBase[pby + i - distance]; i++); + return i; + } + + public int GetNumAvailableBytes() { return _streamPos - _pos; } + + public void ReduceOffsets(int subValue) + { + _bufferOffset += subValue; + _posLimit -= subValue; + _pos -= subValue; + _streamPos -= subValue; + } +} diff --git a/other-licenses/7zstub/src/Java/SevenZip/Compression/LZ/OutWindow.java b/other-licenses/7zstub/src/Java/SevenZip/Compression/LZ/OutWindow.java new file mode 100644 index 0000000000..620cb41b47 --- /dev/null +++ b/other-licenses/7zstub/src/Java/SevenZip/Compression/LZ/OutWindow.java @@ -0,0 +1,85 @@ +// LZ.OutWindow + +package SevenZip.Compression.LZ; + +import java.io.IOException; + +public class OutWindow +{ + byte[] _buffer; + int _pos; + int _windowSize = 0; + int _streamPos; + java.io.OutputStream _stream; + + public void Create(int windowSize) + { + if (_buffer == null || _windowSize != windowSize) + _buffer = new byte[windowSize]; + _windowSize = windowSize; + _pos = 0; + _streamPos = 0; + } + + public void SetStream(java.io.OutputStream stream) throws IOException + { + ReleaseStream(); + _stream = stream; + } + + public void ReleaseStream() throws IOException + { + Flush(); + _stream = null; + } + + public void Init(boolean solid) + { + if (!solid) + { + _streamPos = 0; + _pos = 0; + } + } + + public void Flush() throws IOException + { + int size = _pos - _streamPos; + if (size == 0) + return; + _stream.write(_buffer, _streamPos, size); + if (_pos >= _windowSize) + _pos = 0; + _streamPos = _pos; + } + + public void CopyBlock(int distance, int len) throws IOException + { + int pos = _pos - distance - 1; + if (pos < 0) + pos += _windowSize; + for (; len != 0; len--) + { + if (pos >= _windowSize) + pos = 0; + _buffer[_pos++] = _buffer[pos++]; + if (_pos >= _windowSize) + Flush(); + } + } + + public void PutByte(byte b) throws IOException + { + _buffer[_pos++] = b; + if (_pos >= _windowSize) + Flush(); + } + + public byte GetByte(int distance) + { + int pos = _pos - distance - 1; + if (pos < 0) + pos += _windowSize; + return _buffer[pos]; + } +} diff --git a/other-licenses/7zstub/src/Java/SevenZip/Compression/LZMA/Base.java b/other-licenses/7zstub/src/Java/SevenZip/Compression/LZMA/Base.java new file mode 100644 index 0000000000..18deed9232 --- /dev/null +++ b/other-licenses/7zstub/src/Java/SevenZip/Compression/LZMA/Base.java @@ -0,0 +1,88 @@ +// Base.java + +package SevenZip.Compression.LZMA; + +public class Base +{ + public static final int kNumRepDistances = 4; + public static final int kNumStates = 12; + + public static final int StateInit() + { + return 0; + } + + public static final int StateUpdateChar(int index) + { + if (index < 4) + return 0; + if (index < 10) + return index - 3; + return index - 6; + } + + public static final int StateUpdateMatch(int index) + { + return (index < 7 ? 7 : 10); + } + + public static final int StateUpdateRep(int index) + { + return (index < 7 ? 8 : 11); + } + + public static final int StateUpdateShortRep(int index) + { + return (index < 7 ? 9 : 11); + } + + public static final boolean StateIsCharState(int index) + { + return index < 7; + } + + public static final int kNumPosSlotBits = 6; + public static final int kDicLogSizeMin = 0; + // public static final int kDicLogSizeMax = 28; + // public static final int kDistTableSizeMax = kDicLogSizeMax * 2; + + public static final int kNumLenToPosStatesBits = 2; // it's for speed optimization + public static final int kNumLenToPosStates = 1 << kNumLenToPosStatesBits; + + public static final int kMatchMinLen = 2; + + public static final int GetLenToPosState(int len) + { + len -= kMatchMinLen; + if (len < kNumLenToPosStates) + return len; + return (int)(kNumLenToPosStates - 1); + } + + public static final int kNumAlignBits = 4; + public static final int kAlignTableSize = 1 << kNumAlignBits; + public static final int kAlignMask = (kAlignTableSize - 1); + + public static final int kStartPosModelIndex = 4; + public static final int kEndPosModelIndex = 14; + public static final int kNumPosModels = kEndPosModelIndex - kStartPosModelIndex; + + public static final int kNumFullDistances = 1 << (kEndPosModelIndex / 2); + + public static final int kNumLitPosStatesBitsEncodingMax = 4; + public static final int kNumLitContextBitsMax = 8; + + public static final int kNumPosStatesBitsMax = 4; + public static final int kNumPosStatesMax = (1 << kNumPosStatesBitsMax); + public static final int kNumPosStatesBitsEncodingMax = 4; + public static final int kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax); + + public static final int kNumLowLenBits = 3; + public static final int kNumMidLenBits = 3; + public static final int kNumHighLenBits = 8; + public static final int kNumLowLenSymbols = 1 << kNumLowLenBits; + public static final int kNumMidLenSymbols = 1 << kNumMidLenBits; + public static final int kNumLenSymbols = kNumLowLenSymbols + kNumMidLenSymbols + + (1 << kNumHighLenBits); + public static final int kMatchMaxLen = kMatchMinLen + kNumLenSymbols - 1; +} diff --git a/other-licenses/7zstub/src/Java/SevenZip/Compression/LZMA/Decoder.java b/other-licenses/7zstub/src/Java/SevenZip/Compression/LZMA/Decoder.java new file mode 100644 index 0000000000..4ebd571106 --- /dev/null +++ b/other-licenses/7zstub/src/Java/SevenZip/Compression/LZMA/Decoder.java @@ -0,0 +1,329 @@ +package SevenZip.Compression.LZMA; + +import SevenZip.Compression.RangeCoder.BitTreeDecoder; +import SevenZip.Compression.LZMA.Base; +import SevenZip.Compression.LZ.OutWindow; +import java.io.IOException; + +public class Decoder +{ + class LenDecoder + { + short[] m_Choice = new short[2]; + BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax]; + BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax]; + BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits); + int m_NumPosStates = 0; + + public void Create(int numPosStates) + { + for (; m_NumPosStates < numPosStates; m_NumPosStates++) + { + m_LowCoder[m_NumPosStates] = new BitTreeDecoder(Base.kNumLowLenBits); + m_MidCoder[m_NumPosStates] = new BitTreeDecoder(Base.kNumMidLenBits); + } + } + + public void Init() + { + SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_Choice); + for (int posState = 0; posState < m_NumPosStates; posState++) + { + m_LowCoder[posState].Init(); + m_MidCoder[posState].Init(); + } + m_HighCoder.Init(); + } + + public int Decode(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, int posState) throws IOException + { + if (rangeDecoder.DecodeBit(m_Choice, 0) == 0) + return m_LowCoder[posState].Decode(rangeDecoder); + int symbol = Base.kNumLowLenSymbols; + if (rangeDecoder.DecodeBit(m_Choice, 1) == 0) + symbol += m_MidCoder[posState].Decode(rangeDecoder); + else + symbol += Base.kNumMidLenSymbols + m_HighCoder.Decode(rangeDecoder); + return symbol; + } + } + + class LiteralDecoder + { + class Decoder2 + { + short[] m_Decoders = new short[0x300]; + + public void Init() + { + SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_Decoders); + } + + public byte DecodeNormal(SevenZip.Compression.RangeCoder.Decoder rangeDecoder) throws IOException + { + int symbol = 1; + do + symbol = (symbol << 1) | rangeDecoder.DecodeBit(m_Decoders, symbol); + while (symbol < 0x100); + return (byte)symbol; + } + + public byte DecodeWithMatchByte(SevenZip.Compression.RangeCoder.Decoder rangeDecoder, byte matchByte) throws IOException + { + int symbol = 1; + do + { + int matchBit = (matchByte >> 7) & 1; + matchByte <<= 1; + int bit = rangeDecoder.DecodeBit(m_Decoders, ((1 + matchBit) << 8) + symbol); + symbol = (symbol << 1) | bit; + if (matchBit != bit) + { + while (symbol < 0x100) + symbol = (symbol << 1) | rangeDecoder.DecodeBit(m_Decoders, symbol); + break; + } + } + while (symbol < 0x100); + return (byte)symbol; + } + } + + Decoder2[] m_Coders; + int m_NumPrevBits; + int m_NumPosBits; + int m_PosMask; + + public void Create(int numPosBits, int numPrevBits) + { + if (m_Coders != null && m_NumPrevBits == numPrevBits && m_NumPosBits == numPosBits) + return; + m_NumPosBits = numPosBits; + m_PosMask = (1 << numPosBits) - 1; + m_NumPrevBits = numPrevBits; + int numStates = 1 << (m_NumPrevBits + m_NumPosBits); + m_Coders = new Decoder2[numStates]; + for (int i = 0; i < numStates; i++) + m_Coders[i] = new Decoder2(); + } + + public void Init() + { + int numStates = 1 << (m_NumPrevBits + m_NumPosBits); + for (int i = 0; i < numStates; i++) + m_Coders[i].Init(); + } + + Decoder2 GetDecoder(int pos, byte prevByte) + { + return m_Coders[((pos & m_PosMask) << m_NumPrevBits) + ((prevByte & 0xFF) >>> (8 - m_NumPrevBits))]; + } + } + + OutWindow m_OutWindow = new OutWindow(); + SevenZip.Compression.RangeCoder.Decoder m_RangeDecoder = new SevenZip.Compression.RangeCoder.Decoder(); + + short[] m_IsMatchDecoders = new short[Base.kNumStates << Base.kNumPosStatesBitsMax]; + short[] m_IsRepDecoders = new short[Base.kNumStates]; + short[] m_IsRepG0Decoders = new short[Base.kNumStates]; + short[] m_IsRepG1Decoders = new short[Base.kNumStates]; + short[] m_IsRepG2Decoders = new short[Base.kNumStates]; + short[] m_IsRep0LongDecoders = new short[Base.kNumStates << Base.kNumPosStatesBitsMax]; + + BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates]; + short[] m_PosDecoders = new short[Base.kNumFullDistances - Base.kEndPosModelIndex]; + + BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumAlignBits); + + LenDecoder m_LenDecoder = new LenDecoder(); + LenDecoder m_RepLenDecoder = new LenDecoder(); + + LiteralDecoder m_LiteralDecoder = new LiteralDecoder(); + + int m_DictionarySize = -1; + int m_DictionarySizeCheck = -1; + + int m_PosStateMask; + + public Decoder() + { + for (int i = 0; i < Base.kNumLenToPosStates; i++) + m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits); + } + + boolean SetDictionarySize(int dictionarySize) + { + if (dictionarySize < 0) + return false; + if (m_DictionarySize != dictionarySize) + { + m_DictionarySize = dictionarySize; + m_DictionarySizeCheck = Math.max(m_DictionarySize, 1); + m_OutWindow.Create(Math.max(m_DictionarySizeCheck, (1 << 12))); + } + return true; + } + + boolean SetLcLpPb(int lc, int lp, int pb) + { + if (lc > Base.kNumLitContextBitsMax || lp > 4 || pb > Base.kNumPosStatesBitsMax) + return false; + m_LiteralDecoder.Create(lp, lc); + int numPosStates = 1 << pb; + m_LenDecoder.Create(numPosStates); + m_RepLenDecoder.Create(numPosStates); + m_PosStateMask = numPosStates - 1; + return true; + } + + void Init() throws IOException + { + m_OutWindow.Init(false); + + SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsMatchDecoders); + SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRep0LongDecoders); + SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepDecoders); + SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG0Decoders); + SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG1Decoders); + SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_IsRepG2Decoders); + SevenZip.Compression.RangeCoder.Decoder.InitBitModels(m_PosDecoders); + + m_LiteralDecoder.Init(); + int i; + for (i = 0; i < Base.kNumLenToPosStates; i++) + m_PosSlotDecoder[i].Init(); + m_LenDecoder.Init(); + m_RepLenDecoder.Init(); + m_PosAlignDecoder.Init(); + m_RangeDecoder.Init(); + } + + public boolean Code(java.io.InputStream inStream, java.io.OutputStream outStream, + long outSize) throws IOException + { + m_RangeDecoder.SetStream(inStream); + m_OutWindow.SetStream(outStream); + Init(); + + int state = Base.StateInit(); + int rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0; + + long nowPos64 = 0; + byte prevByte = 0; + while (outSize < 0 || nowPos64 < outSize) + { + int posState = (int)nowPos64 & m_PosStateMask; + if (m_RangeDecoder.DecodeBit(m_IsMatchDecoders, (state << Base.kNumPosStatesBitsMax) + posState) == 0) + { + LiteralDecoder.Decoder2 decoder2 = m_LiteralDecoder.GetDecoder((int)nowPos64, prevByte); + if (!Base.StateIsCharState(state)) + prevByte = decoder2.DecodeWithMatchByte(m_RangeDecoder, m_OutWindow.GetByte(rep0)); + else + prevByte = decoder2.DecodeNormal(m_RangeDecoder); + m_OutWindow.PutByte(prevByte); + state = Base.StateUpdateChar(state); + nowPos64++; + } + else + { + int len; + if (m_RangeDecoder.DecodeBit(m_IsRepDecoders, state) == 1) + { + len = 0; + if (m_RangeDecoder.DecodeBit(m_IsRepG0Decoders, state) == 0) + { + if (m_RangeDecoder.DecodeBit(m_IsRep0LongDecoders, (state << Base.kNumPosStatesBitsMax) + posState) == 0) + { + state = Base.StateUpdateShortRep(state); + len = 1; + } + } + else + { + int distance; + if (m_RangeDecoder.DecodeBit(m_IsRepG1Decoders, state) == 0) + distance = rep1; + else + { + if (m_RangeDecoder.DecodeBit(m_IsRepG2Decoders, state) == 0) + distance = rep2; + else + { + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + if (len == 0) + { + len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen; + state = Base.StateUpdateRep(state); + } + } + else + { + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState); + state = Base.StateUpdateMatch(state); + int posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder); + if (posSlot >= Base.kStartPosModelIndex) + { + int numDirectBits = (posSlot >> 1) - 1; + rep0 = ((2 | (posSlot & 1)) << numDirectBits); + if (posSlot < Base.kEndPosModelIndex) + rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders, + rep0 - posSlot - 1, m_RangeDecoder, numDirectBits); + else + { + rep0 += (m_RangeDecoder.DecodeDirectBits( + numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits); + rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder); + if (rep0 < 0) + { + if (rep0 == -1) + break; + return false; + } + } + } + else + rep0 = posSlot; + } + if (rep0 >= nowPos64 || rep0 >= m_DictionarySizeCheck) + { + // m_OutWindow.Flush(); + return false; + } + m_OutWindow.CopyBlock(rep0, len); + nowPos64 += len; + prevByte = m_OutWindow.GetByte(0); + } + } + m_OutWindow.Flush(); + m_OutWindow.ReleaseStream(); + m_RangeDecoder.ReleaseStream(); + return true; + } + + public boolean SetDecoderProperties(byte[] properties) + { + if (properties.length < 5) + return false; + int val = properties[0] & 0xFF; + int lc = val % 9; + int remainder = val / 9; + int lp = remainder % 5; + int pb = remainder / 5; + int dictionarySize = 0; + for (int i = 0; i < 4; i++) + dictionarySize += ((int)(properties[1 + i]) & 0xFF) << (i * 8); + if (!SetLcLpPb(lc, lp, pb)) + return false; + return SetDictionarySize(dictionarySize); + } +} diff --git a/other-licenses/7zstub/src/Java/SevenZip/Compression/LZMA/Encoder.java b/other-licenses/7zstub/src/Java/SevenZip/Compression/LZMA/Encoder.java new file mode 100644 index 0000000000..771fb21946 --- /dev/null +++ b/other-licenses/7zstub/src/Java/SevenZip/Compression/LZMA/Encoder.java @@ -0,0 +1,1416 @@ +package SevenZip.Compression.LZMA; + +import SevenZip.Compression.RangeCoder.BitTreeEncoder; +import SevenZip.Compression.LZMA.Base; +import SevenZip.Compression.LZ.BinTree; +import SevenZip.ICodeProgress; +import java.io.IOException; + +public class Encoder +{ + public static final int EMatchFinderTypeBT2 = 0; + public static final int EMatchFinderTypeBT4 = 1; + + + + + static final int kIfinityPrice = 0xFFFFFFF; + + static byte[] g_FastPos = new byte[1 << 11]; + + static + { + int kFastSlots = 22; + int c = 2; + g_FastPos[0] = 0; + g_FastPos[1] = 1; + for (int slotFast = 2; slotFast < kFastSlots; slotFast++) + { + int k = (1 << ((slotFast >> 1) - 1)); + for (int j = 0; j < k; j++, c++) + g_FastPos[c] = (byte)slotFast; + } + } + + static int GetPosSlot(int pos) + { + if (pos < (1 << 11)) + return g_FastPos[pos]; + if (pos < (1 << 21)) + return (g_FastPos[pos >> 10] + 20); + return (g_FastPos[pos >> 20] + 40); + } + + static int GetPosSlot2(int pos) + { + if (pos < (1 << 17)) + return (g_FastPos[pos >> 6] + 12); + if (pos < (1 << 27)) + return (g_FastPos[pos >> 16] + 32); + return (g_FastPos[pos >> 26] + 52); + } + + int _state = Base.StateInit(); + byte _previousByte; + int[] _repDistances = new int[Base.kNumRepDistances]; + + void BaseInit() + { + _state = Base.StateInit(); + _previousByte = 0; + for (int i = 0; i < Base.kNumRepDistances; i++) + _repDistances[i] = 0; + } + + static final int kDefaultDictionaryLogSize = 22; + static final int kNumFastBytesDefault = 0x20; + + class LiteralEncoder + { + class Encoder2 + { + short[] m_Encoders = new short[0x300]; + + public void Init() { SevenZip.Compression.RangeCoder.Encoder.InitBitModels(m_Encoders); } + + + + public void Encode(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, byte symbol) throws IOException + { + int context = 1; + for (int i = 7; i >= 0; i--) + { + int bit = ((symbol >> i) & 1); + rangeEncoder.Encode(m_Encoders, context, bit); + context = (context << 1) | bit; + } + } + + public void EncodeMatched(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, byte matchByte, byte symbol) throws IOException + { + int context = 1; + boolean same = true; + for (int i = 7; i >= 0; i--) + { + int bit = ((symbol >> i) & 1); + int state = context; + if (same) + { + int matchBit = ((matchByte >> i) & 1); + state += ((1 + matchBit) << 8); + same = (matchBit == bit); + } + rangeEncoder.Encode(m_Encoders, state, bit); + context = (context << 1) | bit; + } + } + + public int GetPrice(boolean matchMode, byte matchByte, byte symbol) + { + int price = 0; + int context = 1; + int i = 7; + if (matchMode) + { + for (; i >= 0; i--) + { + int matchBit = (matchByte >> i) & 1; + int bit = (symbol >> i) & 1; + price += SevenZip.Compression.RangeCoder.Encoder.GetPrice(m_Encoders[((1 + matchBit) << 8) + context], bit); + context = (context << 1) | bit; + if (matchBit != bit) + { + i--; + break; + } + } + } + for (; i >= 0; i--) + { + int bit = (symbol >> i) & 1; + price += SevenZip.Compression.RangeCoder.Encoder.GetPrice(m_Encoders[context], bit); + context = (context << 1) | bit; + } + return price; + } + } + + Encoder2[] m_Coders; + int m_NumPrevBits; + int m_NumPosBits; + int m_PosMask; + + public void Create(int numPosBits, int numPrevBits) + { + if (m_Coders != null && m_NumPrevBits == numPrevBits && m_NumPosBits == numPosBits) + return; + m_NumPosBits = numPosBits; + m_PosMask = (1 << numPosBits) - 1; + m_NumPrevBits = numPrevBits; + int numStates = 1 << (m_NumPrevBits + m_NumPosBits); + m_Coders = new Encoder2[numStates]; + for (int i = 0; i < numStates; i++) + m_Coders[i] = new Encoder2(); + } + + public void Init() + { + int numStates = 1 << (m_NumPrevBits + m_NumPosBits); + for (int i = 0; i < numStates; i++) + m_Coders[i].Init(); + } + + public Encoder2 GetSubCoder(int pos, byte prevByte) + { return m_Coders[((pos & m_PosMask) << m_NumPrevBits) + ((prevByte & 0xFF) >>> (8 - m_NumPrevBits))]; } + } + + class LenEncoder + { + short[] _choice = new short[2]; + BitTreeEncoder[] _lowCoder = new BitTreeEncoder[Base.kNumPosStatesEncodingMax]; + BitTreeEncoder[] _midCoder = new BitTreeEncoder[Base.kNumPosStatesEncodingMax]; + BitTreeEncoder _highCoder = new BitTreeEncoder(Base.kNumHighLenBits); + + + public LenEncoder() + { + for (int posState = 0; posState < Base.kNumPosStatesEncodingMax; posState++) + { + _lowCoder[posState] = new BitTreeEncoder(Base.kNumLowLenBits); + _midCoder[posState] = new BitTreeEncoder(Base.kNumMidLenBits); + } + } + + public void Init(int numPosStates) + { + SevenZip.Compression.RangeCoder.Encoder.InitBitModels(_choice); + + for (int posState = 0; posState < numPosStates; posState++) + { + _lowCoder[posState].Init(); + _midCoder[posState].Init(); + } + _highCoder.Init(); + } + + public void Encode(SevenZip.Compression.RangeCoder.Encoder rangeEncoder, int symbol, int posState) throws IOException + { + if (symbol < Base.kNumLowLenSymbols) + { + rangeEncoder.Encode(_choice, 0, 0); + _lowCoder[posState].Encode(rangeEncoder, symbol); + } + else + { + symbol -= Base.kNumLowLenSymbols; + rangeEncoder.Encode(_choice, 0, 1); + if (symbol < Base.kNumMidLenSymbols) + { + rangeEncoder.Encode(_choice, 1, 0); + _midCoder[posState].Encode(rangeEncoder, symbol); + } + else + { + rangeEncoder.Encode(_choice, 1, 1); + _highCoder.Encode(rangeEncoder, symbol - Base.kNumMidLenSymbols); + } + } + } + + public void SetPrices(int posState, int numSymbols, int[] prices, int st) + { + int a0 = SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_choice[0]); + int a1 = SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_choice[0]); + int b0 = a1 + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_choice[1]); + int b1 = a1 + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_choice[1]); + int i = 0; + for (i = 0; i < Base.kNumLowLenSymbols; i++) + { + if (i >= numSymbols) + return; + prices[st + i] = a0 + _lowCoder[posState].GetPrice(i); + } + for (; i < Base.kNumLowLenSymbols + Base.kNumMidLenSymbols; i++) + { + if (i >= numSymbols) + return; + prices[st + i] = b0 + _midCoder[posState].GetPrice(i - Base.kNumLowLenSymbols); + } + for (; i < numSymbols; i++) + prices[st + i] = b1 + _highCoder.GetPrice(i - Base.kNumLowLenSymbols - Base.kNumMidLenSymbols); + } + }; + + public static final int kNumLenSpecSymbols = Base.kNumLowLenSymbols + Base.kNumMidLenSymbols; + + class LenPriceTableEncoder extends LenEncoder + { + int[] _prices = new int[Base.kNumLenSymbols< 0) + { + lenRes = _matchDistances[_numDistancePairs - 2]; + if (lenRes == _numFastBytes) + lenRes += _matchFinder.GetMatchLen((int)lenRes - 1, _matchDistances[_numDistancePairs - 1], + Base.kMatchMaxLen - lenRes); + } + _additionalOffset++; + return lenRes; + } + + void MovePos(int num) throws java.io.IOException + { + if (num > 0) + { + _matchFinder.Skip(num); + _additionalOffset += num; + } + } + + int GetRepLen1Price(int state, int posState) + { + return SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRepG0[state]) + + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRep0Long[(state << Base.kNumPosStatesBitsMax) + posState]); + } + + int GetPureRepPrice(int repIndex, int state, int posState) + { + int price; + if (repIndex == 0) + { + price = SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRepG0[state]); + price += SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep0Long[(state << Base.kNumPosStatesBitsMax) + posState]); + } + else + { + price = SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRepG0[state]); + if (repIndex == 1) + price += SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRepG1[state]); + else + { + price += SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRepG1[state]); + price += SevenZip.Compression.RangeCoder.Encoder.GetPrice(_isRepG2[state], repIndex - 2); + } + } + return price; + } + + int GetRepPrice(int repIndex, int len, int state, int posState) + { + int price = _repMatchLenEncoder.GetPrice(len - Base.kMatchMinLen, posState); + return price + GetPureRepPrice(repIndex, state, posState); + } + + int GetPosLenPrice(int pos, int len, int posState) + { + int price; + int lenToPosState = Base.GetLenToPosState(len); + if (pos < Base.kNumFullDistances) + price = _distancesPrices[(lenToPosState * Base.kNumFullDistances) + pos]; + else + price = _posSlotPrices[(lenToPosState << Base.kNumPosSlotBits) + GetPosSlot2(pos)] + + _alignPrices[pos & Base.kAlignMask]; + return price + _lenEncoder.GetPrice(len - Base.kMatchMinLen, posState); + } + + int Backward(int cur) + { + _optimumEndIndex = cur; + int posMem = _optimum[cur].PosPrev; + int backMem = _optimum[cur].BackPrev; + do + { + if (_optimum[cur].Prev1IsChar) + { + _optimum[posMem].MakeAsChar(); + _optimum[posMem].PosPrev = posMem - 1; + if (_optimum[cur].Prev2) + { + _optimum[posMem - 1].Prev1IsChar = false; + _optimum[posMem - 1].PosPrev = _optimum[cur].PosPrev2; + _optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2; + } + } + int posPrev = posMem; + int backCur = backMem; + + backMem = _optimum[posPrev].BackPrev; + posMem = _optimum[posPrev].PosPrev; + + _optimum[posPrev].BackPrev = backCur; + _optimum[posPrev].PosPrev = cur; + cur = posPrev; + } + while (cur > 0); + backRes = _optimum[0].BackPrev; + _optimumCurrentIndex = _optimum[0].PosPrev; + return _optimumCurrentIndex; + } + + int[] reps = new int[Base.kNumRepDistances]; + int[] repLens = new int[Base.kNumRepDistances]; + int backRes; + + int GetOptimum(int position) throws IOException + { + if (_optimumEndIndex != _optimumCurrentIndex) + { + int lenRes = _optimum[_optimumCurrentIndex].PosPrev - _optimumCurrentIndex; + backRes = _optimum[_optimumCurrentIndex].BackPrev; + _optimumCurrentIndex = _optimum[_optimumCurrentIndex].PosPrev; + return lenRes; + } + _optimumCurrentIndex = _optimumEndIndex = 0; + + int lenMain, numDistancePairs; + if (!_longestMatchWasFound) + { + lenMain = ReadMatchDistances(); + } + else + { + lenMain = _longestMatchLength; + _longestMatchWasFound = false; + } + numDistancePairs = _numDistancePairs; + + int numAvailableBytes = _matchFinder.GetNumAvailableBytes() + 1; + if (numAvailableBytes < 2) + { + backRes = -1; + return 1; + } + if (numAvailableBytes > Base.kMatchMaxLen) + numAvailableBytes = Base.kMatchMaxLen; + + int repMaxIndex = 0; + int i; + for (i = 0; i < Base.kNumRepDistances; i++) + { + reps[i] = _repDistances[i]; + repLens[i] = _matchFinder.GetMatchLen(0 - 1, reps[i], Base.kMatchMaxLen); + if (repLens[i] > repLens[repMaxIndex]) + repMaxIndex = i; + } + if (repLens[repMaxIndex] >= _numFastBytes) + { + backRes = repMaxIndex; + int lenRes = repLens[repMaxIndex]; + MovePos(lenRes - 1); + return lenRes; + } + + if (lenMain >= _numFastBytes) + { + backRes = _matchDistances[numDistancePairs - 1] + Base.kNumRepDistances; + MovePos(lenMain - 1); + return lenMain; + } + + byte currentByte = _matchFinder.GetIndexByte(0 - 1); + byte matchByte = _matchFinder.GetIndexByte(0 - _repDistances[0] - 1 - 1); + + if (lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2) + { + backRes = -1; + return 1; + } + + _optimum[0].State = _state; + + int posState = (position & _posStateMask); + + _optimum[1].Price = SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(_state << Base.kNumPosStatesBitsMax) + posState]) + + _literalEncoder.GetSubCoder(position, _previousByte).GetPrice(!Base.StateIsCharState(_state), matchByte, currentByte); + _optimum[1].MakeAsChar(); + + int matchPrice = SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(_state << Base.kNumPosStatesBitsMax) + posState]); + int repMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[_state]); + + if (matchByte == currentByte) + { + int shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState); + if (shortRepPrice < _optimum[1].Price) + { + _optimum[1].Price = shortRepPrice; + _optimum[1].MakeAsShortRep(); + } + } + + int lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]); + + if (lenEnd < 2) + { + backRes = _optimum[1].BackPrev; + return 1; + } + + _optimum[1].PosPrev = 0; + + _optimum[0].Backs0 = reps[0]; + _optimum[0].Backs1 = reps[1]; + _optimum[0].Backs2 = reps[2]; + _optimum[0].Backs3 = reps[3]; + + int len = lenEnd; + do + _optimum[len--].Price = kIfinityPrice; + while (len >= 2); + + for (i = 0; i < Base.kNumRepDistances; i++) + { + int repLen = repLens[i]; + if (repLen < 2) + continue; + int price = repMatchPrice + GetPureRepPrice(i, _state, posState); + do + { + int curAndLenPrice = price + _repMatchLenEncoder.GetPrice(repLen - 2, posState); + Optimal optimum = _optimum[repLen]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = 0; + optimum.BackPrev = i; + optimum.Prev1IsChar = false; + } + } + while (--repLen >= 2); + } + + int normalMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRep[_state]); + + len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); + if (len <= lenMain) + { + int offs = 0; + while (len > _matchDistances[offs]) + offs += 2; + for (; ; len++) + { + int distance = _matchDistances[offs + 1]; + int curAndLenPrice = normalMatchPrice + GetPosLenPrice(distance, len, posState); + Optimal optimum = _optimum[len]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = 0; + optimum.BackPrev = distance + Base.kNumRepDistances; + optimum.Prev1IsChar = false; + } + if (len == _matchDistances[offs]) + { + offs += 2; + if (offs == numDistancePairs) + break; + } + } + } + + int cur = 0; + + while (true) + { + cur++; + if (cur == lenEnd) + return Backward(cur); + int newLen = ReadMatchDistances(); + numDistancePairs = _numDistancePairs; + if (newLen >= _numFastBytes) + { + + _longestMatchLength = newLen; + _longestMatchWasFound = true; + return Backward(cur); + } + position++; + int posPrev = _optimum[cur].PosPrev; + int state; + if (_optimum[cur].Prev1IsChar) + { + posPrev--; + if (_optimum[cur].Prev2) + { + state = _optimum[_optimum[cur].PosPrev2].State; + if (_optimum[cur].BackPrev2 < Base.kNumRepDistances) + state = Base.StateUpdateRep(state); + else + state = Base.StateUpdateMatch(state); + } + else + state = _optimum[posPrev].State; + state = Base.StateUpdateChar(state); + } + else + state = _optimum[posPrev].State; + if (posPrev == cur - 1) + { + if (_optimum[cur].IsShortRep()) + state = Base.StateUpdateShortRep(state); + else + state = Base.StateUpdateChar(state); + } + else + { + int pos; + if (_optimum[cur].Prev1IsChar && _optimum[cur].Prev2) + { + posPrev = _optimum[cur].PosPrev2; + pos = _optimum[cur].BackPrev2; + state = Base.StateUpdateRep(state); + } + else + { + pos = _optimum[cur].BackPrev; + if (pos < Base.kNumRepDistances) + state = Base.StateUpdateRep(state); + else + state = Base.StateUpdateMatch(state); + } + Optimal opt = _optimum[posPrev]; + if (pos < Base.kNumRepDistances) + { + if (pos == 0) + { + reps[0] = opt.Backs0; + reps[1] = opt.Backs1; + reps[2] = opt.Backs2; + reps[3] = opt.Backs3; + } + else if (pos == 1) + { + reps[0] = opt.Backs1; + reps[1] = opt.Backs0; + reps[2] = opt.Backs2; + reps[3] = opt.Backs3; + } + else if (pos == 2) + { + reps[0] = opt.Backs2; + reps[1] = opt.Backs0; + reps[2] = opt.Backs1; + reps[3] = opt.Backs3; + } + else + { + reps[0] = opt.Backs3; + reps[1] = opt.Backs0; + reps[2] = opt.Backs1; + reps[3] = opt.Backs2; + } + } + else + { + reps[0] = (pos - Base.kNumRepDistances); + reps[1] = opt.Backs0; + reps[2] = opt.Backs1; + reps[3] = opt.Backs2; + } + } + _optimum[cur].State = state; + _optimum[cur].Backs0 = reps[0]; + _optimum[cur].Backs1 = reps[1]; + _optimum[cur].Backs2 = reps[2]; + _optimum[cur].Backs3 = reps[3]; + int curPrice = _optimum[cur].Price; + + currentByte = _matchFinder.GetIndexByte(0 - 1); + matchByte = _matchFinder.GetIndexByte(0 - reps[0] - 1 - 1); + + posState = (position & _posStateMask); + + int curAnd1Price = curPrice + + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(state << Base.kNumPosStatesBitsMax) + posState]) + + _literalEncoder.GetSubCoder(position, _matchFinder.GetIndexByte(0 - 2)). + GetPrice(!Base.StateIsCharState(state), matchByte, currentByte); + + Optimal nextOptimum = _optimum[cur + 1]; + + boolean nextIsChar = false; + if (curAnd1Price < nextOptimum.Price) + { + nextOptimum.Price = curAnd1Price; + nextOptimum.PosPrev = cur; + nextOptimum.MakeAsChar(); + nextIsChar = true; + } + + matchPrice = curPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state << Base.kNumPosStatesBitsMax) + posState]); + repMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state]); + + if (matchByte == currentByte && + !(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0)) + { + int shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState); + if (shortRepPrice <= nextOptimum.Price) + { + nextOptimum.Price = shortRepPrice; + nextOptimum.PosPrev = cur; + nextOptimum.MakeAsShortRep(); + nextIsChar = true; + } + } + + int numAvailableBytesFull = _matchFinder.GetNumAvailableBytes() + 1; + numAvailableBytesFull = Math.min(kNumOpts - 1 - cur, numAvailableBytesFull); + numAvailableBytes = numAvailableBytesFull; + + if (numAvailableBytes < 2) + continue; + if (numAvailableBytes > _numFastBytes) + numAvailableBytes = _numFastBytes; + if (!nextIsChar && matchByte != currentByte) + { + // try Literal + rep0 + int t = Math.min(numAvailableBytesFull - 1, _numFastBytes); + int lenTest2 = _matchFinder.GetMatchLen(0, reps[0], t); + if (lenTest2 >= 2) + { + int state2 = Base.StateUpdateChar(state); + + int posStateNext = (position + 1) & _posStateMask; + int nextRepMatchPrice = curAnd1Price + + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]) + + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state2]); + { + int offset = cur + 1 + lenTest2; + while (lenEnd < offset) + _optimum[++lenEnd].Price = kIfinityPrice; + int curAndLenPrice = nextRepMatchPrice + GetRepPrice( + 0, lenTest2, state2, posStateNext); + Optimal optimum = _optimum[offset]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = cur + 1; + optimum.BackPrev = 0; + optimum.Prev1IsChar = true; + optimum.Prev2 = false; + } + } + } + } + + int startLen = 2; // speed optimization + + for (int repIndex = 0; repIndex < Base.kNumRepDistances; repIndex++) + { + int lenTest = _matchFinder.GetMatchLen(0 - 1, reps[repIndex], numAvailableBytes); + if (lenTest < 2) + continue; + int lenTestTemp = lenTest; + do + { + while (lenEnd < cur + lenTest) + _optimum[++lenEnd].Price = kIfinityPrice; + int curAndLenPrice = repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState); + Optimal optimum = _optimum[cur + lenTest]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = cur; + optimum.BackPrev = repIndex; + optimum.Prev1IsChar = false; + } + } + while (--lenTest >= 2); + lenTest = lenTestTemp; + + if (repIndex == 0) + startLen = lenTest + 1; + + // if (_maxMode) + if (lenTest < numAvailableBytesFull) + { + int t = Math.min(numAvailableBytesFull - 1 - lenTest, _numFastBytes); + int lenTest2 = _matchFinder.GetMatchLen(lenTest, reps[repIndex], t); + if (lenTest2 >= 2) + { + int state2 = Base.StateUpdateRep(state); + + int posStateNext = (position + lenTest) & _posStateMask; + int curAndLenCharPrice = + repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState) + + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]) + + _literalEncoder.GetSubCoder(position + lenTest, + _matchFinder.GetIndexByte(lenTest - 1 - 1)).GetPrice(true, + _matchFinder.GetIndexByte(lenTest - 1 - (reps[repIndex] + 1)), + _matchFinder.GetIndexByte(lenTest - 1)); + state2 = Base.StateUpdateChar(state2); + posStateNext = (position + lenTest + 1) & _posStateMask; + int nextMatchPrice = curAndLenCharPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]); + int nextRepMatchPrice = nextMatchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state2]); + + // for(; lenTest2 >= 2; lenTest2--) + { + int offset = lenTest + 1 + lenTest2; + while (lenEnd < cur + offset) + _optimum[++lenEnd].Price = kIfinityPrice; + int curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext); + Optimal optimum = _optimum[cur + offset]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = cur + lenTest + 1; + optimum.BackPrev = 0; + optimum.Prev1IsChar = true; + optimum.Prev2 = true; + optimum.PosPrev2 = cur; + optimum.BackPrev2 = repIndex; + } + } + } + } + } + + if (newLen > numAvailableBytes) + { + newLen = numAvailableBytes; + for (numDistancePairs = 0; newLen > _matchDistances[numDistancePairs]; numDistancePairs += 2) ; + _matchDistances[numDistancePairs] = newLen; + numDistancePairs += 2; + } + if (newLen >= startLen) + { + normalMatchPrice = matchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isRep[state]); + while (lenEnd < cur + newLen) + _optimum[++lenEnd].Price = kIfinityPrice; + + int offs = 0; + while (startLen > _matchDistances[offs]) + offs += 2; + + for (int lenTest = startLen; ; lenTest++) + { + int curBack = _matchDistances[offs + 1]; + int curAndLenPrice = normalMatchPrice + GetPosLenPrice(curBack, lenTest, posState); + Optimal optimum = _optimum[cur + lenTest]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = cur; + optimum.BackPrev = curBack + Base.kNumRepDistances; + optimum.Prev1IsChar = false; + } + + if (lenTest == _matchDistances[offs]) + { + if (lenTest < numAvailableBytesFull) + { + int t = Math.min(numAvailableBytesFull - 1 - lenTest, _numFastBytes); + int lenTest2 = _matchFinder.GetMatchLen(lenTest, curBack, t); + if (lenTest2 >= 2) + { + int state2 = Base.StateUpdateMatch(state); + + int posStateNext = (position + lenTest) & _posStateMask; + int curAndLenCharPrice = curAndLenPrice + + SevenZip.Compression.RangeCoder.Encoder.GetPrice0(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]) + + _literalEncoder.GetSubCoder(position + lenTest, + _matchFinder.GetIndexByte(lenTest - 1 - 1)). + GetPrice(true, + _matchFinder.GetIndexByte(lenTest - (curBack + 1) - 1), + _matchFinder.GetIndexByte(lenTest - 1)); + state2 = Base.StateUpdateChar(state2); + posStateNext = (position + lenTest + 1) & _posStateMask; + int nextMatchPrice = curAndLenCharPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isMatch[(state2 << Base.kNumPosStatesBitsMax) + posStateNext]); + int nextRepMatchPrice = nextMatchPrice + SevenZip.Compression.RangeCoder.Encoder.GetPrice1(_isRep[state2]); + + int offset = lenTest + 1 + lenTest2; + while (lenEnd < cur + offset) + _optimum[++lenEnd].Price = kIfinityPrice; + curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext); + optimum = _optimum[cur + offset]; + if (curAndLenPrice < optimum.Price) + { + optimum.Price = curAndLenPrice; + optimum.PosPrev = cur + lenTest + 1; + optimum.BackPrev = 0; + optimum.Prev1IsChar = true; + optimum.Prev2 = true; + optimum.PosPrev2 = cur; + optimum.BackPrev2 = curBack + Base.kNumRepDistances; + } + } + } + offs += 2; + if (offs == numDistancePairs) + break; + } + } + } + } + } + + boolean ChangePair(int smallDist, int bigDist) + { + int kDif = 7; + return (smallDist < (1 << (32 - kDif)) && bigDist >= (smallDist << kDif)); + } + + void WriteEndMarker(int posState) throws IOException + { + if (!_writeEndMark) + return; + + _rangeEncoder.Encode(_isMatch, (_state << Base.kNumPosStatesBitsMax) + posState, 1); + _rangeEncoder.Encode(_isRep, _state, 0); + _state = Base.StateUpdateMatch(_state); + int len = Base.kMatchMinLen; + _lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState); + int posSlot = (1 << Base.kNumPosSlotBits) - 1; + int lenToPosState = Base.GetLenToPosState(len); + _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot); + int footerBits = 30; + int posReduced = (1 << footerBits) - 1; + _rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits); + _posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask); + } + + void Flush(int nowPos) throws IOException + { + ReleaseMFStream(); + WriteEndMarker(nowPos & _posStateMask); + _rangeEncoder.FlushData(); + _rangeEncoder.FlushStream(); + } + + public void CodeOneBlock(long[] inSize, long[] outSize, boolean[] finished) throws IOException + { + inSize[0] = 0; + outSize[0] = 0; + finished[0] = true; + + if (_inStream != null) + { + _matchFinder.SetStream(_inStream); + _matchFinder.Init(); + _needReleaseMFStream = true; + _inStream = null; + } + + if (_finished) + return; + _finished = true; + + + long progressPosValuePrev = nowPos64; + if (nowPos64 == 0) + { + if (_matchFinder.GetNumAvailableBytes() == 0) + { + Flush((int)nowPos64); + return; + } + + ReadMatchDistances(); + int posState = (int)(nowPos64) & _posStateMask; + _rangeEncoder.Encode(_isMatch, (_state << Base.kNumPosStatesBitsMax) + posState, 0); + _state = Base.StateUpdateChar(_state); + byte curByte = _matchFinder.GetIndexByte(0 - _additionalOffset); + _literalEncoder.GetSubCoder((int)(nowPos64), _previousByte).Encode(_rangeEncoder, curByte); + _previousByte = curByte; + _additionalOffset--; + nowPos64++; + } + if (_matchFinder.GetNumAvailableBytes() == 0) + { + Flush((int)nowPos64); + return; + } + while (true) + { + + int len = GetOptimum((int)nowPos64); + int pos = backRes; + int posState = ((int)nowPos64) & _posStateMask; + int complexState = (_state << Base.kNumPosStatesBitsMax) + posState; + if (len == 1 && pos == -1) + { + _rangeEncoder.Encode(_isMatch, complexState, 0); + byte curByte = _matchFinder.GetIndexByte((int)(0 - _additionalOffset)); + LiteralEncoder.Encoder2 subCoder = _literalEncoder.GetSubCoder((int)nowPos64, _previousByte); + if (!Base.StateIsCharState(_state)) + { + byte matchByte = _matchFinder.GetIndexByte((int)(0 - _repDistances[0] - 1 - _additionalOffset)); + subCoder.EncodeMatched(_rangeEncoder, matchByte, curByte); + } + else + subCoder.Encode(_rangeEncoder, curByte); + _previousByte = curByte; + _state = Base.StateUpdateChar(_state); + } + else + { + _rangeEncoder.Encode(_isMatch, complexState, 1); + if (pos < Base.kNumRepDistances) + { + _rangeEncoder.Encode(_isRep, _state, 1); + if (pos == 0) + { + _rangeEncoder.Encode(_isRepG0, _state, 0); + if (len == 1) + _rangeEncoder.Encode(_isRep0Long, complexState, 0); + else + _rangeEncoder.Encode(_isRep0Long, complexState, 1); + } + else + { + _rangeEncoder.Encode(_isRepG0, _state, 1); + if (pos == 1) + _rangeEncoder.Encode(_isRepG1, _state, 0); + else + { + _rangeEncoder.Encode(_isRepG1, _state, 1); + _rangeEncoder.Encode(_isRepG2, _state, pos - 2); + } + } + if (len == 1) + _state = Base.StateUpdateShortRep(_state); + else + { + _repMatchLenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState); + _state = Base.StateUpdateRep(_state); + } + int distance = _repDistances[pos]; + if (pos != 0) + { + for (int i = pos; i >= 1; i--) + _repDistances[i] = _repDistances[i - 1]; + _repDistances[0] = distance; + } + } + else + { + _rangeEncoder.Encode(_isRep, _state, 0); + _state = Base.StateUpdateMatch(_state); + _lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState); + pos -= Base.kNumRepDistances; + int posSlot = GetPosSlot(pos); + int lenToPosState = Base.GetLenToPosState(len); + _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot); + + if (posSlot >= Base.kStartPosModelIndex) + { + int footerBits = (int)((posSlot >> 1) - 1); + int baseVal = ((2 | (posSlot & 1)) << footerBits); + int posReduced = pos - baseVal; + + if (posSlot < Base.kEndPosModelIndex) + BitTreeEncoder.ReverseEncode(_posEncoders, + baseVal - posSlot - 1, _rangeEncoder, footerBits, posReduced); + else + { + _rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits); + _posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask); + _alignPriceCount++; + } + } + int distance = pos; + for (int i = Base.kNumRepDistances - 1; i >= 1; i--) + _repDistances[i] = _repDistances[i - 1]; + _repDistances[0] = distance; + _matchPriceCount++; + } + _previousByte = _matchFinder.GetIndexByte(len - 1 - _additionalOffset); + } + _additionalOffset -= len; + nowPos64 += len; + if (_additionalOffset == 0) + { + // if (!_fastMode) + if (_matchPriceCount >= (1 << 7)) + FillDistancesPrices(); + if (_alignPriceCount >= Base.kAlignTableSize) + FillAlignPrices(); + inSize[0] = nowPos64; + outSize[0] = _rangeEncoder.GetProcessedSizeAdd(); + if (_matchFinder.GetNumAvailableBytes() == 0) + { + Flush((int)nowPos64); + return; + } + + if (nowPos64 - progressPosValuePrev >= (1 << 12)) + { + _finished = false; + finished[0] = false; + return; + } + } + } + } + + void ReleaseMFStream() + { + if (_matchFinder != null && _needReleaseMFStream) + { + _matchFinder.ReleaseStream(); + _needReleaseMFStream = false; + } + } + + void SetOutStream(java.io.OutputStream outStream) + { _rangeEncoder.SetStream(outStream); } + void ReleaseOutStream() + { _rangeEncoder.ReleaseStream(); } + + void ReleaseStreams() + { + ReleaseMFStream(); + ReleaseOutStream(); + } + + void SetStreams(java.io.InputStream inStream, java.io.OutputStream outStream, + long inSize, long outSize) + { + _inStream = inStream; + _finished = false; + Create(); + SetOutStream(outStream); + Init(); + + // if (!_fastMode) + { + FillDistancesPrices(); + FillAlignPrices(); + } + + _lenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen); + _lenEncoder.UpdateTables(1 << _posStateBits); + _repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen); + _repMatchLenEncoder.UpdateTables(1 << _posStateBits); + + nowPos64 = 0; + } + + long[] processedInSize = new long[1]; long[] processedOutSize = new long[1]; boolean[] finished = new boolean[1]; + public void Code(java.io.InputStream inStream, java.io.OutputStream outStream, + long inSize, long outSize, ICodeProgress progress) throws IOException + { + _needReleaseMFStream = false; + try + { + SetStreams(inStream, outStream, inSize, outSize); + while (true) + { + + + + CodeOneBlock(processedInSize, processedOutSize, finished); + if (finished[0]) + return; + if (progress != null) + { + progress.SetProgress(processedInSize[0], processedOutSize[0]); + } + } + } + finally + { + ReleaseStreams(); + } + } + + public static final int kPropSize = 5; + byte[] properties = new byte[kPropSize]; + + public void WriteCoderProperties(java.io.OutputStream outStream) throws IOException + { + properties[0] = (byte)((_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits); + for (int i = 0; i < 4; i++) + properties[1 + i] = (byte)(_dictionarySize >> (8 * i)); + outStream.write(properties, 0, kPropSize); + } + + int[] tempPrices = new int[Base.kNumFullDistances]; + int _matchPriceCount; + + void FillDistancesPrices() + { + for (int i = Base.kStartPosModelIndex; i < Base.kNumFullDistances; i++) + { + int posSlot = GetPosSlot(i); + int footerBits = (int)((posSlot >> 1) - 1); + int baseVal = ((2 | (posSlot & 1)) << footerBits); + tempPrices[i] = BitTreeEncoder.ReverseGetPrice(_posEncoders, + baseVal - posSlot - 1, footerBits, i - baseVal); + } + + for (int lenToPosState = 0; lenToPosState < Base.kNumLenToPosStates; lenToPosState++) + { + int posSlot; + BitTreeEncoder encoder = _posSlotEncoder[lenToPosState]; + + int st = (lenToPosState << Base.kNumPosSlotBits); + for (posSlot = 0; posSlot < _distTableSize; posSlot++) + _posSlotPrices[st + posSlot] = encoder.GetPrice(posSlot); + for (posSlot = Base.kEndPosModelIndex; posSlot < _distTableSize; posSlot++) + _posSlotPrices[st + posSlot] += ((((posSlot >> 1) - 1) - Base.kNumAlignBits) << SevenZip.Compression.RangeCoder.Encoder.kNumBitPriceShiftBits); + + int st2 = lenToPosState * Base.kNumFullDistances; + int i; + for (i = 0; i < Base.kStartPosModelIndex; i++) + _distancesPrices[st2 + i] = _posSlotPrices[st + i]; + for (; i < Base.kNumFullDistances; i++) + _distancesPrices[st2 + i] = _posSlotPrices[st + GetPosSlot(i)] + tempPrices[i]; + } + _matchPriceCount = 0; + } + + void FillAlignPrices() + { + for (int i = 0; i < Base.kAlignTableSize; i++) + _alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i); + _alignPriceCount = 0; + } + + + public boolean SetAlgorithm(int algorithm) + { + /* + _fastMode = (algorithm == 0); + _maxMode = (algorithm >= 2); + */ + return true; + } + + public boolean SetDictionarySize(int dictionarySize) + { + int kDicLogSizeMaxCompress = 29; + if (dictionarySize < (1 << Base.kDicLogSizeMin) || dictionarySize > (1 << kDicLogSizeMaxCompress)) + return false; + _dictionarySize = dictionarySize; + int dicLogSize; + for (dicLogSize = 0; dictionarySize > (1 << dicLogSize); dicLogSize++) ; + _distTableSize = dicLogSize * 2; + return true; + } + + public boolean SetNumFastBytes(int numFastBytes) + { + if (numFastBytes < 5 || numFastBytes > Base.kMatchMaxLen) + return false; + _numFastBytes = numFastBytes; + return true; + } + + public boolean SetMatchFinder(int matchFinderIndex) + { + if (matchFinderIndex < 0 || matchFinderIndex > 2) + return false; + int matchFinderIndexPrev = _matchFinderType; + _matchFinderType = matchFinderIndex; + if (_matchFinder != null && matchFinderIndexPrev != _matchFinderType) + { + _dictionarySizePrev = -1; + _matchFinder = null; + } + return true; + } + + public boolean SetLcLpPb(int lc, int lp, int pb) + { + if ( + lp < 0 || lp > Base.kNumLitPosStatesBitsEncodingMax || + lc < 0 || lc > Base.kNumLitContextBitsMax || + pb < 0 || pb > Base.kNumPosStatesBitsEncodingMax) + return false; + _numLiteralPosStateBits = lp; + _numLiteralContextBits = lc; + _posStateBits = pb; + _posStateMask = ((1) << _posStateBits) - 1; + return true; + } + + public void SetEndMarkerMode(boolean endMarkerMode) + { + _writeEndMark = endMarkerMode; + } +} + diff --git a/other-licenses/7zstub/src/Java/SevenZip/Compression/RangeCoder/BitTreeDecoder.java b/other-licenses/7zstub/src/Java/SevenZip/Compression/RangeCoder/BitTreeDecoder.java new file mode 100644 index 0000000000..6864c69cef --- /dev/null +++ b/other-licenses/7zstub/src/Java/SevenZip/Compression/RangeCoder/BitTreeDecoder.java @@ -0,0 +1,55 @@ +package SevenZip.Compression.RangeCoder; + +public class BitTreeDecoder +{ + short[] Models; + int NumBitLevels; + + public BitTreeDecoder(int numBitLevels) + { + NumBitLevels = numBitLevels; + Models = new short[1 << numBitLevels]; + } + + public void Init() + { + Decoder.InitBitModels(Models); + } + + public int Decode(Decoder rangeDecoder) throws java.io.IOException + { + int m = 1; + for (int bitIndex = NumBitLevels; bitIndex != 0; bitIndex--) + m = (m << 1) + rangeDecoder.DecodeBit(Models, m); + return m - (1 << NumBitLevels); + } + + public int ReverseDecode(Decoder rangeDecoder) throws java.io.IOException + { + int m = 1; + int symbol = 0; + for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++) + { + int bit = rangeDecoder.DecodeBit(Models, m); + m <<= 1; + m += bit; + symbol |= (bit << bitIndex); + } + return symbol; + } + + public static int ReverseDecode(short[] Models, int startIndex, + Decoder rangeDecoder, int NumBitLevels) throws java.io.IOException + { + int m = 1; + int symbol = 0; + for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++) + { + int bit = rangeDecoder.DecodeBit(Models, startIndex + m); + m <<= 1; + m += bit; + symbol |= (bit << bitIndex); + } + return symbol; + } +} diff --git a/other-licenses/7zstub/src/Java/SevenZip/Compression/RangeCoder/BitTreeEncoder.java b/other-licenses/7zstub/src/Java/SevenZip/Compression/RangeCoder/BitTreeEncoder.java new file mode 100644 index 0000000000..b4c0a0721d --- /dev/null +++ b/other-licenses/7zstub/src/Java/SevenZip/Compression/RangeCoder/BitTreeEncoder.java @@ -0,0 +1,99 @@ +package SevenZip.Compression.RangeCoder; +import java.io.IOException; + +public class BitTreeEncoder +{ + short[] Models; + int NumBitLevels; + + public BitTreeEncoder(int numBitLevels) + { + NumBitLevels = numBitLevels; + Models = new short[1 << numBitLevels]; + } + + public void Init() + { + Decoder.InitBitModels(Models); + } + + public void Encode(Encoder rangeEncoder, int symbol) throws IOException + { + int m = 1; + for (int bitIndex = NumBitLevels; bitIndex != 0; ) + { + bitIndex--; + int bit = (symbol >>> bitIndex) & 1; + rangeEncoder.Encode(Models, m, bit); + m = (m << 1) | bit; + } + } + + public void ReverseEncode(Encoder rangeEncoder, int symbol) throws IOException + { + int m = 1; + for (int i = 0; i < NumBitLevels; i++) + { + int bit = symbol & 1; + rangeEncoder.Encode(Models, m, bit); + m = (m << 1) | bit; + symbol >>= 1; + } + } + + public int GetPrice(int symbol) + { + int price = 0; + int m = 1; + for (int bitIndex = NumBitLevels; bitIndex != 0; ) + { + bitIndex--; + int bit = (symbol >>> bitIndex) & 1; + price += Encoder.GetPrice(Models[m], bit); + m = (m << 1) + bit; + } + return price; + } + + public int ReverseGetPrice(int symbol) + { + int price = 0; + int m = 1; + for (int i = NumBitLevels; i != 0; i--) + { + int bit = symbol & 1; + symbol >>>= 1; + price += Encoder.GetPrice(Models[m], bit); + m = (m << 1) | bit; + } + return price; + } + + public static int ReverseGetPrice(short[] Models, int startIndex, + int NumBitLevels, int symbol) + { + int price = 0; + int m = 1; + for (int i = NumBitLevels; i != 0; i--) + { + int bit = symbol & 1; + symbol >>>= 1; + price += Encoder.GetPrice(Models[startIndex + m], bit); + m = (m << 1) | bit; + } + return price; + } + + public static void ReverseEncode(short[] Models, int startIndex, + Encoder rangeEncoder, int NumBitLevels, int symbol) throws IOException + { + int m = 1; + for (int i = 0; i < NumBitLevels; i++) + { + int bit = symbol & 1; + rangeEncoder.Encode(Models, startIndex + m, bit); + m = (m << 1) | bit; + symbol >>= 1; + } + } +} diff --git a/other-licenses/7zstub/src/Java/SevenZip/Compression/RangeCoder/Decoder.java b/other-licenses/7zstub/src/Java/SevenZip/Compression/RangeCoder/Decoder.java new file mode 100644 index 0000000000..7453383483 --- /dev/null +++ b/other-licenses/7zstub/src/Java/SevenZip/Compression/RangeCoder/Decoder.java @@ -0,0 +1,88 @@ +package SevenZip.Compression.RangeCoder; +import java.io.IOException; + +public class Decoder +{ + static final int kTopMask = ~((1 << 24) - 1); + + static final int kNumBitModelTotalBits = 11; + static final int kBitModelTotal = (1 << kNumBitModelTotalBits); + static final int kNumMoveBits = 5; + + int Range; + int Code; + + java.io.InputStream Stream; + + public final void SetStream(java.io.InputStream stream) + { + Stream = stream; + } + + public final void ReleaseStream() + { + Stream = null; + } + + public final void Init() throws IOException + { + Code = 0; + Range = -1; + for (int i = 0; i < 5; i++) + Code = (Code << 8) | Stream.read(); + } + + public final int DecodeDirectBits(int numTotalBits) throws IOException + { + int result = 0; + for (int i = numTotalBits; i != 0; i--) + { + Range >>>= 1; + int t = ((Code - Range) >>> 31); + Code -= Range & (t - 1); + result = (result << 1) | (1 - t); + + if ((Range & kTopMask) == 0) + { + Code = (Code << 8) | Stream.read(); + Range <<= 8; + } + } + return result; + } + + public int DecodeBit(short []probs, int index) throws IOException + { + int prob = probs[index]; + int newBound = (Range >>> kNumBitModelTotalBits) * prob; + if ((Code ^ 0x80000000) < (newBound ^ 0x80000000)) + { + Range = newBound; + probs[index] = (short)(prob + ((kBitModelTotal - prob) >>> kNumMoveBits)); + if ((Range & kTopMask) == 0) + { + Code = (Code << 8) | Stream.read(); + Range <<= 8; + } + return 0; + } + else + { + Range -= newBound; + Code -= newBound; + probs[index] = (short)(prob - ((prob) >>> kNumMoveBits)); + if ((Range & kTopMask) == 0) + { + Code = (Code << 8) | Stream.read(); + Range <<= 8; + } + return 1; + } + } + + public static void InitBitModels(short []probs) + { + for (int i = 0; i < probs.length; i++) + probs[i] = (kBitModelTotal >>> 1); + } +} diff --git a/other-licenses/7zstub/src/Java/SevenZip/Compression/RangeCoder/Encoder.java b/other-licenses/7zstub/src/Java/SevenZip/Compression/RangeCoder/Encoder.java new file mode 100644 index 0000000000..2273e92e50 --- /dev/null +++ b/other-licenses/7zstub/src/Java/SevenZip/Compression/RangeCoder/Encoder.java @@ -0,0 +1,151 @@ +package SevenZip.Compression.RangeCoder; +import java.io.IOException; + +public class Encoder +{ + static final int kTopMask = ~((1 << 24) - 1); + + static final int kNumBitModelTotalBits = 11; + static final int kBitModelTotal = (1 << kNumBitModelTotalBits); + static final int kNumMoveBits = 5; + + java.io.OutputStream Stream; + + long Low; + int Range; + int _cacheSize; + int _cache; + + long _position; + + public void SetStream(java.io.OutputStream stream) + { + Stream = stream; + } + + public void ReleaseStream() + { + Stream = null; + } + + public void Init() + { + _position = 0; + Low = 0; + Range = -1; + _cacheSize = 1; + _cache = 0; + } + + public void FlushData() throws IOException + { + for (int i = 0; i < 5; i++) + ShiftLow(); + } + + public void FlushStream() throws IOException + { + Stream.flush(); + } + + public void ShiftLow() throws IOException + { + int LowHi = (int)(Low >>> 32); + if (LowHi != 0 || Low < 0xFF000000L) + { + _position += _cacheSize; + int temp = _cache; + do + { + Stream.write(temp + LowHi); + temp = 0xFF; + } + while(--_cacheSize != 0); + _cache = (((int)Low) >>> 24); + } + _cacheSize++; + Low = (Low & 0xFFFFFF) << 8; + } + + public void EncodeDirectBits(int v, int numTotalBits) throws IOException + { + for (int i = numTotalBits - 1; i >= 0; i--) + { + Range >>>= 1; + if (((v >>> i) & 1) == 1) + Low += Range; + if ((Range & Encoder.kTopMask) == 0) + { + Range <<= 8; + ShiftLow(); + } + } + } + + + public long GetProcessedSizeAdd() + { + return _cacheSize + _position + 4; + } + + + + static final int kNumMoveReducingBits = 2; + public static final int kNumBitPriceShiftBits = 6; + + public static void InitBitModels(short []probs) + { + for (int i = 0; i < probs.length; i++) + probs[i] = (kBitModelTotal >>> 1); + } + + public void Encode(short []probs, int index, int symbol) throws IOException + { + int prob = probs[index]; + int newBound = (Range >>> kNumBitModelTotalBits) * prob; + if (symbol == 0) + { + Range = newBound; + probs[index] = (short)(prob + ((kBitModelTotal - prob) >>> kNumMoveBits)); + } + else + { + Low += (newBound & 0xFFFFFFFFL); + Range -= newBound; + probs[index] = (short)(prob - ((prob) >>> kNumMoveBits)); + } + if ((Range & kTopMask) == 0) + { + Range <<= 8; + ShiftLow(); + } + } + + private static int[] ProbPrices = new int[kBitModelTotal >>> kNumMoveReducingBits]; + + static + { + int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits); + for (int i = kNumBits - 1; i >= 0; i--) + { + int start = 1 << (kNumBits - i - 1); + int end = 1 << (kNumBits - i); + for (int j = start; j < end; j++) + ProbPrices[j] = (i << kNumBitPriceShiftBits) + + (((end - j) << kNumBitPriceShiftBits) >>> (kNumBits - i - 1)); + } + } + + static public int GetPrice(int Prob, int symbol) + { + return ProbPrices[(((Prob - symbol) ^ ((-symbol))) & (kBitModelTotal - 1)) >>> kNumMoveReducingBits]; + } + static public int GetPrice0(int Prob) + { + return ProbPrices[Prob >>> kNumMoveReducingBits]; + } + static public int GetPrice1(int Prob) + { + return ProbPrices[(kBitModelTotal - Prob) >>> kNumMoveReducingBits]; + } +} -- cgit v1.2.3