From 33740d43f099081d624decc3fda599120b5edaf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=F8=EDk?= Date: Wed, 19 Dec 2012 21:25:41 +0100 Subject: [PATCH] Support for LZMA compressed SWF files --- trunk/lib/LZMA.jar | Bin 0 -> 91326 bytes trunk/libsrc/LZMA/build.xml | 74 + trunk/libsrc/LZMA/manifest.mf | 3 + trunk/libsrc/LZMA/nbproject/build-impl.xml | 1053 ++++++++++++ .../libsrc/LZMA/nbproject/genfiles.properties | 8 + .../libsrc/LZMA/nbproject/project.properties | 71 + trunk/libsrc/LZMA/nbproject/project.xml | 15 + trunk/libsrc/LZMA/src/SevenZip/CRC.java | 52 + .../src/SevenZip/Compression/LZ/BinTree.java | 382 +++++ .../src/SevenZip/Compression/LZ/InWindow.java | 131 ++ .../SevenZip/Compression/LZ/OutWindow.java | 85 + .../src/SevenZip/Compression/LZMA/Base.java | 88 + .../SevenZip/Compression/LZMA/Decoder.java | 329 ++++ .../SevenZip/Compression/LZMA/Encoder.java | 1416 +++++++++++++++++ .../RangeCoder/BitTreeDecoder.java | 55 + .../RangeCoder/BitTreeEncoder.java | 99 ++ .../Compression/RangeCoder/Decoder.java | 88 + .../Compression/RangeCoder/Encoder.java | 151 ++ .../LZMA/src/SevenZip/ICodeProgress.java | 6 + trunk/libsrc/LZMA/src/SevenZip/LzmaAlone.java | 253 +++ trunk/libsrc/LZMA/src/SevenZip/LzmaBench.java | 392 +++++ trunk/src/com/jpexs/asdec/Main.java | 3 - trunk/src/com/jpexs/asdec/SWF.java | 74 +- 23 files changed, 4820 insertions(+), 8 deletions(-) create mode 100644 trunk/lib/LZMA.jar create mode 100644 trunk/libsrc/LZMA/build.xml create mode 100644 trunk/libsrc/LZMA/manifest.mf create mode 100644 trunk/libsrc/LZMA/nbproject/build-impl.xml create mode 100644 trunk/libsrc/LZMA/nbproject/genfiles.properties create mode 100644 trunk/libsrc/LZMA/nbproject/project.properties create mode 100644 trunk/libsrc/LZMA/nbproject/project.xml create mode 100644 trunk/libsrc/LZMA/src/SevenZip/CRC.java create mode 100644 trunk/libsrc/LZMA/src/SevenZip/Compression/LZ/BinTree.java create mode 100644 trunk/libsrc/LZMA/src/SevenZip/Compression/LZ/InWindow.java create mode 100644 trunk/libsrc/LZMA/src/SevenZip/Compression/LZ/OutWindow.java create mode 100644 trunk/libsrc/LZMA/src/SevenZip/Compression/LZMA/Base.java create mode 100644 trunk/libsrc/LZMA/src/SevenZip/Compression/LZMA/Decoder.java create mode 100644 trunk/libsrc/LZMA/src/SevenZip/Compression/LZMA/Encoder.java create mode 100644 trunk/libsrc/LZMA/src/SevenZip/Compression/RangeCoder/BitTreeDecoder.java create mode 100644 trunk/libsrc/LZMA/src/SevenZip/Compression/RangeCoder/BitTreeEncoder.java create mode 100644 trunk/libsrc/LZMA/src/SevenZip/Compression/RangeCoder/Decoder.java create mode 100644 trunk/libsrc/LZMA/src/SevenZip/Compression/RangeCoder/Encoder.java create mode 100644 trunk/libsrc/LZMA/src/SevenZip/ICodeProgress.java create mode 100644 trunk/libsrc/LZMA/src/SevenZip/LzmaAlone.java create mode 100644 trunk/libsrc/LZMA/src/SevenZip/LzmaBench.java diff --git a/trunk/lib/LZMA.jar b/trunk/lib/LZMA.jar new file mode 100644 index 0000000000000000000000000000000000000000..aa485ec25a2a4a9c8561682427858ea303600946 GIT binary patch literal 91326 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 udCq5UQ{^&EFD{j7kV_OoCo(_Y%trNe literal 0 HcmV?d00001 diff --git a/trunk/libsrc/LZMA/build.xml b/trunk/libsrc/LZMA/build.xml new file mode 100644 index 000000000..9228eac00 --- /dev/null +++ b/trunk/libsrc/LZMA/build.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + Builds, tests, and runs the project LZMA. + + + diff --git a/trunk/libsrc/LZMA/manifest.mf b/trunk/libsrc/LZMA/manifest.mf new file mode 100644 index 000000000..1574df4a2 --- /dev/null +++ b/trunk/libsrc/LZMA/manifest.mf @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +X-COMMENT: Main-Class will be added automatically by build + diff --git a/trunk/libsrc/LZMA/nbproject/build-impl.xml b/trunk/libsrc/LZMA/nbproject/build-impl.xml new file mode 100644 index 000000000..388d0fabe --- /dev/null +++ b/trunk/libsrc/LZMA/nbproject/build-impl.xml @@ -0,0 +1,1053 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + + + + + + java -cp "${run.classpath.with.dist.jar}" ${main.class} + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + + + + + + + + Must select one file in the IDE or set profile.class + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/trunk/libsrc/LZMA/nbproject/genfiles.properties b/trunk/libsrc/LZMA/nbproject/genfiles.properties new file mode 100644 index 000000000..91de430a2 --- /dev/null +++ b/trunk/libsrc/LZMA/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=cf8fb9e4 +build.xml.script.CRC32=b8fc23fa +build.xml.stylesheet.CRC32=28e38971@1.50.1.46 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=cf8fb9e4 +nbproject/build-impl.xml.script.CRC32=f883bccc +nbproject/build-impl.xml.stylesheet.CRC32=fcddb364@1.50.1.46 diff --git a/trunk/libsrc/LZMA/nbproject/project.properties b/trunk/libsrc/LZMA/nbproject/project.properties new file mode 100644 index 000000000..e53a17d18 --- /dev/null +++ b/trunk/libsrc/LZMA/nbproject/project.properties @@ -0,0 +1,71 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.processor.options= +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/LZMA.jar +dist.javadoc.dir=${dist.dir}/javadoc +excludes= +includes=** +jar.compress=false +javac.classpath= +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.6 +javac.target=1.6 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +main.class= +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project +# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value +# or test-sys-prop.name=value to set system properties for unit tests): +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/trunk/libsrc/LZMA/nbproject/project.xml b/trunk/libsrc/LZMA/nbproject/project.xml new file mode 100644 index 000000000..d34c5fea1 --- /dev/null +++ b/trunk/libsrc/LZMA/nbproject/project.xml @@ -0,0 +1,15 @@ + + + org.netbeans.modules.java.j2seproject + + + LZMA + + + + + + + + + diff --git a/trunk/libsrc/LZMA/src/SevenZip/CRC.java b/trunk/libsrc/LZMA/src/SevenZip/CRC.java new file mode 100644 index 000000000..f2f791f17 --- /dev/null +++ b/trunk/libsrc/LZMA/src/SevenZip/CRC.java @@ -0,0 +1,52 @@ +// SevenZip/CRC.java + +package SevenZip; + +public class CRC +{ + static public int[] Table = 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; + Table[i] = r; + } + } + + int _value = -1; + + public void Init() + { + _value = -1; + } + + public void Update(byte[] data, int offset, int size) + { + for (int i = 0; i < size; i++) + _value = Table[(_value ^ data[offset + i]) & 0xFF] ^ (_value >>> 8); + } + + public void Update(byte[] data) + { + int size = data.length; + for (int i = 0; i < size; i++) + _value = Table[(_value ^ data[i]) & 0xFF] ^ (_value >>> 8); + } + + public void UpdateByte(int b) + { + _value = Table[(_value ^ b) & 0xFF] ^ (_value >>> 8); + } + + public int GetDigest() + { + return _value ^ (-1); + } +} diff --git a/trunk/libsrc/LZMA/src/SevenZip/Compression/LZ/BinTree.java b/trunk/libsrc/LZMA/src/SevenZip/Compression/LZ/BinTree.java new file mode 100644 index 000000000..63d58c05a --- /dev/null +++ b/trunk/libsrc/LZMA/src/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/trunk/libsrc/LZMA/src/SevenZip/Compression/LZ/InWindow.java b/trunk/libsrc/LZMA/src/SevenZip/Compression/LZ/InWindow.java new file mode 100644 index 000000000..5f3f0b4d0 --- /dev/null +++ b/trunk/libsrc/LZMA/src/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/trunk/libsrc/LZMA/src/SevenZip/Compression/LZ/OutWindow.java b/trunk/libsrc/LZMA/src/SevenZip/Compression/LZ/OutWindow.java new file mode 100644 index 000000000..620cb41b4 --- /dev/null +++ b/trunk/libsrc/LZMA/src/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/trunk/libsrc/LZMA/src/SevenZip/Compression/LZMA/Base.java b/trunk/libsrc/LZMA/src/SevenZip/Compression/LZMA/Base.java new file mode 100644 index 000000000..18deed923 --- /dev/null +++ b/trunk/libsrc/LZMA/src/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/trunk/libsrc/LZMA/src/SevenZip/Compression/LZMA/Decoder.java b/trunk/libsrc/LZMA/src/SevenZip/Compression/LZMA/Decoder.java new file mode 100644 index 000000000..4ebd57110 --- /dev/null +++ b/trunk/libsrc/LZMA/src/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/trunk/libsrc/LZMA/src/SevenZip/Compression/LZMA/Encoder.java b/trunk/libsrc/LZMA/src/SevenZip/Compression/LZMA/Encoder.java new file mode 100644 index 000000000..771fb2194 --- /dev/null +++ b/trunk/libsrc/LZMA/src/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/trunk/libsrc/LZMA/src/SevenZip/Compression/RangeCoder/BitTreeDecoder.java b/trunk/libsrc/LZMA/src/SevenZip/Compression/RangeCoder/BitTreeDecoder.java new file mode 100644 index 000000000..6864c69ce --- /dev/null +++ b/trunk/libsrc/LZMA/src/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/trunk/libsrc/LZMA/src/SevenZip/Compression/RangeCoder/BitTreeEncoder.java b/trunk/libsrc/LZMA/src/SevenZip/Compression/RangeCoder/BitTreeEncoder.java new file mode 100644 index 000000000..b4c0a0721 --- /dev/null +++ b/trunk/libsrc/LZMA/src/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/trunk/libsrc/LZMA/src/SevenZip/Compression/RangeCoder/Decoder.java b/trunk/libsrc/LZMA/src/SevenZip/Compression/RangeCoder/Decoder.java new file mode 100644 index 000000000..745338348 --- /dev/null +++ b/trunk/libsrc/LZMA/src/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/trunk/libsrc/LZMA/src/SevenZip/Compression/RangeCoder/Encoder.java b/trunk/libsrc/LZMA/src/SevenZip/Compression/RangeCoder/Encoder.java new file mode 100644 index 000000000..2273e92e5 --- /dev/null +++ b/trunk/libsrc/LZMA/src/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]; + } +} diff --git a/trunk/libsrc/LZMA/src/SevenZip/ICodeProgress.java b/trunk/libsrc/LZMA/src/SevenZip/ICodeProgress.java new file mode 100644 index 000000000..290bd2d02 --- /dev/null +++ b/trunk/libsrc/LZMA/src/SevenZip/ICodeProgress.java @@ -0,0 +1,6 @@ +package SevenZip; + +public interface ICodeProgress +{ + public void SetProgress(long inSize, long outSize); +} diff --git a/trunk/libsrc/LZMA/src/SevenZip/LzmaAlone.java b/trunk/libsrc/LZMA/src/SevenZip/LzmaAlone.java new file mode 100644 index 000000000..de39a22cc --- /dev/null +++ b/trunk/libsrc/LZMA/src/SevenZip/LzmaAlone.java @@ -0,0 +1,253 @@ +package SevenZip; + +public class LzmaAlone +{ + static public class CommandLine + { + public static final int kEncode = 0; + public static final int kDecode = 1; + public static final int kBenchmak = 2; + + public int Command = -1; + public int NumBenchmarkPasses = 10; + + public int DictionarySize = 1 << 23; + public boolean DictionarySizeIsDefined = false; + + public int Lc = 3; + public int Lp = 0; + public int Pb = 2; + + public int Fb = 128; + public boolean FbIsDefined = false; + + public boolean Eos = false; + + public int Algorithm = 2; + public int MatchFinder = 1; + + public String InFile; + public String OutFile; + + boolean ParseSwitch(String s) + { + if (s.startsWith("d")) + { + DictionarySize = 1 << Integer.parseInt(s.substring(1)); + DictionarySizeIsDefined = true; + } + else if (s.startsWith("fb")) + { + Fb = Integer.parseInt(s.substring(2)); + FbIsDefined = true; + } + else if (s.startsWith("a")) + Algorithm = Integer.parseInt(s.substring(1)); + else if (s.startsWith("lc")) + Lc = Integer.parseInt(s.substring(2)); + else if (s.startsWith("lp")) + Lp = Integer.parseInt(s.substring(2)); + else if (s.startsWith("pb")) + Pb = Integer.parseInt(s.substring(2)); + else if (s.startsWith("eos")) + Eos = true; + else if (s.startsWith("mf")) + { + String mfs = s.substring(2); + if (mfs.equals("bt2")) + MatchFinder = 0; + else if (mfs.equals("bt4")) + MatchFinder = 1; + else if (mfs.equals("bt4b")) + MatchFinder = 2; + else + return false; + } + else + return false; + return true; + } + + public boolean Parse(String[] args) throws Exception + { + int pos = 0; + boolean switchMode = true; + for (int i = 0; i < args.length; i++) + { + String s = args[i]; + if (s.length() == 0) + return false; + if (switchMode) + { + if (s.compareTo("--") == 0) + { + switchMode = false; + continue; + } + if (s.charAt(0) == '-') + { + String sw = s.substring(1).toLowerCase(); + if (sw.length() == 0) + return false; + try + { + if (!ParseSwitch(sw)) + return false; + } + catch (NumberFormatException e) + { + return false; + } + continue; + } + } + if (pos == 0) + { + if (s.equalsIgnoreCase("e")) + Command = kEncode; + else if (s.equalsIgnoreCase("d")) + Command = kDecode; + else if (s.equalsIgnoreCase("b")) + Command = kBenchmak; + else + return false; + } + else if(pos == 1) + { + if (Command == kBenchmak) + { + try + { + NumBenchmarkPasses = Integer.parseInt(s); + if (NumBenchmarkPasses < 1) + return false; + } + catch (NumberFormatException e) + { + return false; + } + } + else + InFile = s; + } + else if(pos == 2) + OutFile = s; + else + return false; + pos++; + continue; + } + return true; + } + } + + + static void PrintHelp() + { + System.out.println( + "\nUsage: LZMA [...] inputFile outputFile\n" + + " e: encode file\n" + + " d: decode file\n" + + " b: Benchmark\n" + + "\n" + + // " -a{N}: set compression mode - [0, 1], default: 1 (max)\n" + + " -d{N}: set dictionary - [0,28], default: 23 (8MB)\n" + + " -fb{N}: set number of fast bytes - [5, 273], default: 128\n" + + " -lc{N}: set number of literal context bits - [0, 8], default: 3\n" + + " -lp{N}: set number of literal pos bits - [0, 4], default: 0\n" + + " -pb{N}: set number of pos bits - [0, 4], default: 2\n" + + " -mf{MF_ID}: set Match Finder: [bt2, bt4], default: bt4\n" + + " -eos: write End Of Stream marker\n" + ); + } + + public static void main(String[] args) throws Exception + { + System.out.println("\nLZMA (Java) 4.61 2008-11-23\n"); + + if (args.length < 1) + { + PrintHelp(); + return; + } + + CommandLine params = new CommandLine(); + if (!params.Parse(args)) + { + System.out.println("\nIncorrect command"); + return; + } + + if (params.Command == CommandLine.kBenchmak) + { + int dictionary = (1 << 21); + if (params.DictionarySizeIsDefined) + dictionary = params.DictionarySize; + if (params.MatchFinder > 1) + throw new Exception("Unsupported match finder"); + SevenZip.LzmaBench.LzmaBenchmark(params.NumBenchmarkPasses, dictionary); + } + else if (params.Command == CommandLine.kEncode || params.Command == CommandLine.kDecode) + { + java.io.File inFile = new java.io.File(params.InFile); + java.io.File outFile = new java.io.File(params.OutFile); + + java.io.BufferedInputStream inStream = new java.io.BufferedInputStream(new java.io.FileInputStream(inFile)); + java.io.BufferedOutputStream outStream = new java.io.BufferedOutputStream(new java.io.FileOutputStream(outFile)); + + boolean eos = false; + if (params.Eos) + eos = true; + if (params.Command == CommandLine.kEncode) + { + SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder(); + if (!encoder.SetAlgorithm(params.Algorithm)) + throw new Exception("Incorrect compression mode"); + if (!encoder.SetDictionarySize(params.DictionarySize)) + throw new Exception("Incorrect dictionary size"); + if (!encoder.SetNumFastBytes(params.Fb)) + throw new Exception("Incorrect -fb value"); + if (!encoder.SetMatchFinder(params.MatchFinder)) + throw new Exception("Incorrect -mf value"); + if (!encoder.SetLcLpPb(params.Lc, params.Lp, params.Pb)) + throw new Exception("Incorrect -lc or -lp or -pb value"); + encoder.SetEndMarkerMode(eos); + encoder.WriteCoderProperties(outStream); + long fileSize; + if (eos) + fileSize = -1; + else + fileSize = inFile.length(); + for (int i = 0; i < 8; i++) + outStream.write((int)(fileSize >>> (8 * i)) & 0xFF); + encoder.Code(inStream, outStream, -1, -1, null); + } + else + { + int propertiesSize = 5; + byte[] properties = new byte[propertiesSize]; + if (inStream.read(properties, 0, propertiesSize) != propertiesSize) + throw new Exception("input .lzma file is too short"); + SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder(); + if (!decoder.SetDecoderProperties(properties)) + throw new Exception("Incorrect stream properties"); + long outSize = 0; + for (int i = 0; i < 8; i++) + { + int v = inStream.read(); + if (v < 0) + throw new Exception("Can't read stream size"); + outSize |= ((long)v) << (8 * i); + } + if (!decoder.Code(inStream, outStream, outSize)) + throw new Exception("Error in data stream"); + } + outStream.flush(); + outStream.close(); + inStream.close(); + } + else + throw new Exception("Incorrect command"); + return; + } +} diff --git a/trunk/libsrc/LZMA/src/SevenZip/LzmaBench.java b/trunk/libsrc/LZMA/src/SevenZip/LzmaBench.java new file mode 100644 index 000000000..cceda24da --- /dev/null +++ b/trunk/libsrc/LZMA/src/SevenZip/LzmaBench.java @@ -0,0 +1,392 @@ +package SevenZip; + +import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; +import java.io.IOException; + +public class LzmaBench +{ + static final int kAdditionalSize = (1 << 21); + static final int kCompressedAdditionalSize = (1 << 10); + + static class CRandomGenerator + { + int A1; + int A2; + public CRandomGenerator() { Init(); } + public void Init() { A1 = 362436069; A2 = 521288629; } + public int GetRnd() + { + return + ((A1 = 36969 * (A1 & 0xffff) + (A1 >>> 16)) << 16) ^ + ((A2 = 18000 * (A2 & 0xffff) + (A2 >>> 16))); + } + }; + + static class CBitRandomGenerator + { + CRandomGenerator RG = new CRandomGenerator(); + int Value; + int NumBits; + public void Init() + { + Value = 0; + NumBits = 0; + } + public int GetRnd(int numBits) + { + int result; + if (NumBits > numBits) + { + result = Value & ((1 << numBits) - 1); + Value >>>= numBits; + NumBits -= numBits; + return result; + } + numBits -= NumBits; + result = (Value << numBits); + Value = RG.GetRnd(); + result |= Value & (((int)1 << numBits) - 1); + Value >>>= numBits; + NumBits = 32 - numBits; + return result; + } + }; + + static class CBenchRandomGenerator + { + CBitRandomGenerator RG = new CBitRandomGenerator(); + int Pos; + int Rep0; + + public int BufferSize; + public byte[] Buffer = null; + + public CBenchRandomGenerator() { } + public void Set(int bufferSize) + { + Buffer = new byte[bufferSize]; + Pos = 0; + BufferSize = bufferSize; + } + int GetRndBit() { return RG.GetRnd(1); } + int GetLogRandBits(int numBits) + { + int len = RG.GetRnd(numBits); + return RG.GetRnd((int)len); + } + int GetOffset() + { + if (GetRndBit() == 0) + return GetLogRandBits(4); + return (GetLogRandBits(4) << 10) | RG.GetRnd(10); + } + int GetLen1() { return RG.GetRnd(1 + (int)RG.GetRnd(2)); } + int GetLen2() { return RG.GetRnd(2 + (int)RG.GetRnd(2)); } + public void Generate() + { + RG.Init(); + Rep0 = 1; + while (Pos < BufferSize) + { + if (GetRndBit() == 0 || Pos < 1) + Buffer[Pos++] = (byte)(RG.GetRnd(8)); + else + { + int len; + if (RG.GetRnd(3) == 0) + len = 1 + GetLen1(); + else + { + do + Rep0 = GetOffset(); + while (Rep0 >= Pos); + Rep0++; + len = 2 + GetLen2(); + } + for (int i = 0; i < len && Pos < BufferSize; i++, Pos++) + Buffer[Pos] = Buffer[Pos - Rep0]; + } + } + } + }; + + static class CrcOutStream extends java.io.OutputStream + { + public CRC CRC = new CRC(); + + public void Init() + { + CRC.Init(); + } + public int GetDigest() + { + return CRC.GetDigest(); + } + public void write(byte[] b) + { + CRC.Update(b); + } + public void write(byte[] b, int off, int len) + { + CRC.Update(b, off, len); + } + public void write(int b) + { + CRC.UpdateByte(b); + } + }; + + static class MyOutputStream extends java.io.OutputStream + { + byte[] _buffer; + int _size; + int _pos; + + public MyOutputStream(byte[] buffer) + { + _buffer = buffer; + _size = _buffer.length; + } + + public void reset() + { + _pos = 0; + } + + public void write(int b) throws IOException + { + if (_pos >= _size) + throw new IOException("Error"); + _buffer[_pos++] = (byte)b; + } + + public int size() + { + return _pos; + } + }; + + static class MyInputStream extends java.io.InputStream + { + byte[] _buffer; + int _size; + int _pos; + + public MyInputStream(byte[] buffer, int size) + { + _buffer = buffer; + _size = size; + } + + public void reset() + { + _pos = 0; + } + + public int read() + { + if (_pos >= _size) + return -1; + return _buffer[_pos++] & 0xFF; + } + }; + + static class CProgressInfo implements ICodeProgress + { + public long ApprovedStart; + public long InSize; + public long Time; + public void Init() + { InSize = 0; } + public void SetProgress(long inSize, long outSize) + { + if (inSize >= ApprovedStart && InSize == 0) + { + Time = System.currentTimeMillis(); + InSize = inSize; + } + } + } + static final int kSubBits = 8; + + static int GetLogSize(int size) + { + for (int i = kSubBits; i < 32; i++) + for (int j = 0; j < (1 << kSubBits); j++) + if (size <= ((1) << i) + (j << (i - kSubBits))) + return (i << kSubBits) + j; + return (32 << kSubBits); + } + + static long MyMultDiv64(long value, long elapsedTime) + { + long freq = 1000; // ms + long elTime = elapsedTime; + while (freq > 1000000) + { + freq >>>= 1; + elTime >>>= 1; + } + if (elTime == 0) + elTime = 1; + return value * freq / elTime; + } + + static long GetCompressRating(int dictionarySize, long elapsedTime, long size) + { + long t = GetLogSize(dictionarySize) - (18 << kSubBits); + long numCommandsForOne = 1060 + ((t * t * 10) >> (2 * kSubBits)); + long numCommands = (long)(size) * numCommandsForOne; + return MyMultDiv64(numCommands, elapsedTime); + } + + static long GetDecompressRating(long elapsedTime, long outSize, long inSize) + { + long numCommands = inSize * 220 + outSize * 20; + return MyMultDiv64(numCommands, elapsedTime); + } + + static long GetTotalRating( + int dictionarySize, + long elapsedTimeEn, long sizeEn, + long elapsedTimeDe, + long inSizeDe, long outSizeDe) + { + return (GetCompressRating(dictionarySize, elapsedTimeEn, sizeEn) + + GetDecompressRating(elapsedTimeDe, inSizeDe, outSizeDe)) / 2; + } + + static void PrintValue(long v) + { + String s = ""; + s += v; + for (int i = 0; i + s.length() < 6; i++) + System.out.print(" "); + System.out.print(s); + } + + static void PrintRating(long rating) + { + PrintValue(rating / 1000000); + System.out.print(" MIPS"); + } + + static void PrintResults( + int dictionarySize, + long elapsedTime, + long size, + boolean decompressMode, long secondSize) + { + long speed = MyMultDiv64(size, elapsedTime); + PrintValue(speed / 1024); + System.out.print(" KB/s "); + long rating; + if (decompressMode) + rating = GetDecompressRating(elapsedTime, size, secondSize); + else + rating = GetCompressRating(dictionarySize, elapsedTime, size); + PrintRating(rating); + } + + static public int LzmaBenchmark(int numIterations, int dictionarySize) throws Exception + { + if (numIterations <= 0) + return 0; + if (dictionarySize < (1 << 18)) + { + System.out.println("\nError: dictionary size for benchmark must be >= 18 (256 KB)"); + return 1; + } + System.out.print("\n Compressing Decompressing\n\n"); + + SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder(); + SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder(); + + if (!encoder.SetDictionarySize(dictionarySize)) + throw new Exception("Incorrect dictionary size"); + + int kBufferSize = dictionarySize + kAdditionalSize; + int kCompressedBufferSize = (kBufferSize / 2) + kCompressedAdditionalSize; + + ByteArrayOutputStream propStream = new ByteArrayOutputStream(); + encoder.WriteCoderProperties(propStream); + byte[] propArray = propStream.toByteArray(); + decoder.SetDecoderProperties(propArray); + + CBenchRandomGenerator rg = new CBenchRandomGenerator(); + + rg.Set(kBufferSize); + rg.Generate(); + CRC crc = new CRC(); + crc.Init(); + crc.Update(rg.Buffer, 0, rg.BufferSize); + + CProgressInfo progressInfo = new CProgressInfo(); + progressInfo.ApprovedStart = dictionarySize; + + long totalBenchSize = 0; + long totalEncodeTime = 0; + long totalDecodeTime = 0; + long totalCompressedSize = 0; + + MyInputStream inStream = new MyInputStream(rg.Buffer, rg.BufferSize); + + byte[] compressedBuffer = new byte[kCompressedBufferSize]; + MyOutputStream compressedStream = new MyOutputStream(compressedBuffer); + CrcOutStream crcOutStream = new CrcOutStream(); + MyInputStream inputCompressedStream = null; + int compressedSize = 0; + for (int i = 0; i < numIterations; i++) + { + progressInfo.Init(); + inStream.reset(); + compressedStream.reset(); + encoder.Code(inStream, compressedStream, -1, -1, progressInfo); + long encodeTime = System.currentTimeMillis() - progressInfo.Time; + + if (i == 0) + { + compressedSize = compressedStream.size(); + inputCompressedStream = new MyInputStream(compressedBuffer, compressedSize); + } + else if (compressedSize != compressedStream.size()) + throw (new Exception("Encoding error")); + + if (progressInfo.InSize == 0) + throw (new Exception("Internal ERROR 1282")); + + long decodeTime = 0; + for (int j = 0; j < 2; j++) + { + inputCompressedStream.reset(); + crcOutStream.Init(); + + long outSize = kBufferSize; + long startTime = System.currentTimeMillis(); + if (!decoder.Code(inputCompressedStream, crcOutStream, outSize)) + throw (new Exception("Decoding Error"));; + decodeTime = System.currentTimeMillis() - startTime; + if (crcOutStream.GetDigest() != crc.GetDigest()) + throw (new Exception("CRC Error")); + } + long benchSize = kBufferSize - (long)progressInfo.InSize; + PrintResults(dictionarySize, encodeTime, benchSize, false, 0); + System.out.print(" "); + PrintResults(dictionarySize, decodeTime, kBufferSize, true, compressedSize); + System.out.println(); + + totalBenchSize += benchSize; + totalEncodeTime += encodeTime; + totalDecodeTime += decodeTime; + totalCompressedSize += compressedSize; + } + System.out.println("---------------------------------------------------"); + PrintResults(dictionarySize, totalEncodeTime, totalBenchSize, false, 0); + System.out.print(" "); + PrintResults(dictionarySize, totalDecodeTime, + kBufferSize * (long)numIterations, true, totalCompressedSize); + System.out.println(" Average"); + return 0; + } +} diff --git a/trunk/src/com/jpexs/asdec/Main.java b/trunk/src/com/jpexs/asdec/Main.java index 0b8e312a2..fbb764438 100644 --- a/trunk/src/com/jpexs/asdec/Main.java +++ b/trunk/src/com/jpexs/asdec/Main.java @@ -26,7 +26,6 @@ import com.jpexs.asdec.gui.View; import com.jpexs.asdec.gui.proxy.ProxyFrame; import com.jpexs.asdec.tags.DoABCTag; import com.jpexs.asdec.tags.Tag; -import com.jpexs.proxy.Replacement; import javax.swing.*; import javax.swing.filechooser.FileFilter; @@ -38,8 +37,6 @@ import java.awt.event.MouseEvent; import java.io.*; import java.util.ArrayList; import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/trunk/src/com/jpexs/asdec/SWF.java b/trunk/src/com/jpexs/asdec/SWF.java index 6f1aa4c81..aa48e99e6 100644 --- a/trunk/src/com/jpexs/asdec/SWF.java +++ b/trunk/src/com/jpexs/asdec/SWF.java @@ -17,9 +17,9 @@ package com.jpexs.asdec; +import SevenZip.Compression.LZMA.Encoder; import com.jpexs.asdec.tags.Tag; import com.jpexs.asdec.types.RECT; - import java.io.*; import java.util.ArrayList; import java.util.List; @@ -62,6 +62,23 @@ public class SWF { * Use compression */ public boolean compressed = false; + + /** + * Use LZMA compression + */ + public boolean lzma = true; + + /** + * Compressed size of the file (LZMA) + */ + public long compressedSize; + + /** + * LZMA Properties + */ + public byte lzmaProperties[]; + + /** * Gets all tags with specified id @@ -97,7 +114,9 @@ public class SWF { sos.writeTags(tags); sos.writeUI16(0); sos.close(); - if (compressed) { + if (compressed && lzma) { + os.write('Z'); + }else if(compressed){ os.write('C'); } else { os.write('F'); @@ -110,7 +129,32 @@ public class SWF { sos.writeUI32(data.length + 8); if (compressed) { - os = new DeflaterOutputStream(os); + if(lzma){ + Encoder enc=new Encoder(); + int val = lzmaProperties[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)(lzmaProperties[1 + i]) & 0xFF) << (i * 8); + enc.SetDictionarySize(dictionarySize); + enc.SetLcLpPb(lc, lp, pb); + baos = new ByteArrayOutputStream(); + enc.SetEndMarkerMode(true); + enc.Code(new ByteArrayInputStream(data), baos, -1, -1, null); + data = baos.toByteArray(); + byte udata[]=new byte[4]; + udata[0]=(byte)(data.length&0xFF); + udata[1]=(byte)((data.length>>8) & 0xFF); + udata[2]=(byte)((data.length>>16) & 0xFF); + udata[3]=(byte)((data.length>>24) & 0xFF); + os.write(udata); + os.write(lzmaProperties); + }else{ + os = new DeflaterOutputStream(os); + } } os.write(data); } @@ -131,7 +175,7 @@ public class SWF { byte hdr[] = new byte[3]; is.read(hdr); String shdr = new String(hdr); - if ((!shdr.equals("FWS")) && (!shdr.equals("CWS"))) { + if ((!shdr.equals("FWS")) && (!shdr.equals("CWS")) && (!shdr.equals("ZWS"))) { throw new IOException("Invalid SWF file"); } version = is.read(); @@ -142,6 +186,26 @@ public class SWF { sis = new SWFInputStream(new InflaterInputStream(is), version, 8); compressed = true; } + + if (hdr[0] == 'Z') { + ByteArrayOutputStream baos=new ByteArrayOutputStream(); + long outSize = sis.readUI32(); + int propertiesSize = 5; + lzmaProperties = new byte[propertiesSize]; + if (sis.read(lzmaProperties, 0, propertiesSize) != propertiesSize) + throw new IOException("LZMA:input .lzma file is too short"); + SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder(); + if (!decoder.SetDecoderProperties(lzmaProperties)) + throw new IOException("LZMA:Incorrect stream properties"); + + if (!decoder.Code(sis, baos, fileSize-8)) + throw new IOException("LZMA:Error in data stream"); + sis = new SWFInputStream(new ByteArrayInputStream(baos.toByteArray()), version, 8); + compressed = true; + lzma = true; + } + + displayRect = sis.readRECT(); @@ -216,5 +280,5 @@ public class SWF { return false; } return true; - } + } }