├── dumpsc ├── App.config ├── LZMA.cs ├── 7zip │ ├── Compress │ │ ├── LZ │ │ │ ├── IMatchFinder.cs │ │ │ ├── LzOutWindow.cs │ │ │ ├── LzInWindow.cs │ │ │ └── LzBinTree.cs │ │ ├── LZMA │ │ │ ├── LzmaBase.cs │ │ │ ├── LzmaDecoder.cs │ │ │ └── LzmaEncoder.cs │ │ └── RangeCoder │ │ │ ├── RangeCoderBit.cs │ │ │ ├── RangeCoderBitTree.cs │ │ │ └── RangeCoder.cs │ ├── Common │ │ ├── OutBuffer.cs │ │ ├── CRC.cs │ │ ├── InBuffer.cs │ │ └── CommandLineParser.cs │ ├── ICoder.cs │ └── FileStreamCoder.cs ├── Properties │ └── AssemblyInfo.cs ├── dumpsc.csproj └── Program.cs ├── README.md ├── dumpsc.sln ├── .gitattributes └── .gitignore /dumpsc/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /dumpsc/LZMA.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using SevenZip.Compression; 3 | 4 | namespace dumpsc 5 | { 6 | class LZMA 7 | { 8 | public static byte[] Decompress(byte[] inputBytes) 9 | { 10 | byte[] result; 11 | 12 | using(LZMACoder coder = new LZMACoder()) 13 | using (MemoryStream input = new MemoryStream(inputBytes)) 14 | using (MemoryStream output = new MemoryStream()) 15 | { 16 | coder.Decompress(input, output); 17 | 18 | result = output.ToArray(); 19 | } 20 | 21 | return result; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /dumpsc/7zip/Compress/LZ/IMatchFinder.cs: -------------------------------------------------------------------------------- 1 | // IMatchFinder.cs 2 | 3 | using System; 4 | 5 | namespace SevenZip.Compression.LZ 6 | { 7 | interface IInWindowStream 8 | { 9 | void SetStream(System.IO.Stream inStream); 10 | void Init(); 11 | void ReleaseStream(); 12 | Byte GetIndexByte(Int32 index); 13 | UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit); 14 | UInt32 GetNumAvailableBytes(); 15 | } 16 | 17 | interface IMatchFinder : IInWindowStream 18 | { 19 | void Create(UInt32 historySize, UInt32 keepAddBufferBefore, 20 | UInt32 matchMaxLen, UInt32 keepAddBufferAfter); 21 | UInt32 GetMatches(UInt32[] distances); 22 | void Skip(UInt32 num); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dumpsc 2 | Port of https://github.com/123456abcdef/cr-sc-dump in CSharp. 3 | 4 | Extract Images From '_tex.sc' Files 5 | 6 | **IMPORTANT: THIS TOOL IS NOT WORKING ANYMORE FOR NEW COC VERSION, SADLY I DON'T REMIND THE SUPPORTED VERSION OF COC BY THIS TOOL :(** 7 | 8 | 9 | **IMPORTANT2: MY BAD ENGLISH SKILLS MAY CAUSE EYE CANCER :D** 10 | 11 | ## How to use 12 | * After compile, put .exe to empty folder and run 13 | * Program generates two folder named as 'input' and 'output' 14 | * Open clash royal apk file with WinRAR or 7Zip, Goto assets\sc folder and pickup any _tex.sc files 15 | * Put _tex.sc files to input folder and run .exe 16 | * Wait a minute 17 | * DONE 18 | 19 | ## TODO 20 | * Ability To Reverse Back 21 | * Fix Todo #1 at Program.cs 22 | -------------------------------------------------------------------------------- /dumpsc.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25123.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dumpsc", "dumpsc\dumpsc.csproj", "{3806DAFA-4DCF-4D7F-A60F-8ED4ACB415EA}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {3806DAFA-4DCF-4D7F-A60F-8ED4ACB415EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {3806DAFA-4DCF-4D7F-A60F-8ED4ACB415EA}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {3806DAFA-4DCF-4D7F-A60F-8ED4ACB415EA}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {3806DAFA-4DCF-4D7F-A60F-8ED4ACB415EA}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /dumpsc/7zip/Common/OutBuffer.cs: -------------------------------------------------------------------------------- 1 | // OutBuffer.cs 2 | 3 | namespace SevenZip.Buffer 4 | { 5 | public class OutBuffer 6 | { 7 | byte[] m_Buffer; 8 | uint m_Pos; 9 | uint m_BufferSize; 10 | System.IO.Stream m_Stream; 11 | ulong m_ProcessedSize; 12 | 13 | public OutBuffer(uint bufferSize) 14 | { 15 | m_Buffer = new byte[bufferSize]; 16 | m_BufferSize = bufferSize; 17 | } 18 | 19 | public void SetStream(System.IO.Stream stream) { m_Stream = stream; } 20 | public void FlushStream() { m_Stream.Flush(); } 21 | public void CloseStream() { m_Stream.Close(); } 22 | public void ReleaseStream() { m_Stream = null; } 23 | 24 | public void Init() 25 | { 26 | m_ProcessedSize = 0; 27 | m_Pos = 0; 28 | } 29 | 30 | public void WriteByte(byte b) 31 | { 32 | m_Buffer[m_Pos++] = b; 33 | if (m_Pos >= m_BufferSize) 34 | FlushData(); 35 | } 36 | 37 | public void FlushData() 38 | { 39 | if (m_Pos == 0) 40 | return; 41 | m_Stream.Write(m_Buffer, 0, (int)m_Pos); 42 | m_Pos = 0; 43 | } 44 | 45 | public ulong GetProcessedSize() { return m_ProcessedSize + m_Pos; } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /dumpsc/7zip/Common/CRC.cs: -------------------------------------------------------------------------------- 1 | // Common/CRC.cs 2 | 3 | namespace SevenZip 4 | { 5 | class CRC 6 | { 7 | public static readonly uint[] Table; 8 | 9 | static CRC() 10 | { 11 | Table = new uint[256]; 12 | const uint kPoly = 0xEDB88320; 13 | for (uint i = 0; i < 256; i++) 14 | { 15 | uint r = i; 16 | for (int j = 0; j < 8; j++) 17 | if ((r & 1) != 0) 18 | r = (r >> 1) ^ kPoly; 19 | else 20 | r >>= 1; 21 | Table[i] = r; 22 | } 23 | } 24 | 25 | uint _value = 0xFFFFFFFF; 26 | 27 | public void Init() { _value = 0xFFFFFFFF; } 28 | 29 | public void UpdateByte(byte b) 30 | { 31 | _value = Table[(((byte)(_value)) ^ b)] ^ (_value >> 8); 32 | } 33 | 34 | public void Update(byte[] data, uint offset, uint size) 35 | { 36 | for (uint i = 0; i < size; i++) 37 | _value = Table[(((byte)(_value)) ^ data[offset + i])] ^ (_value >> 8); 38 | } 39 | 40 | public uint GetDigest() { return _value ^ 0xFFFFFFFF; } 41 | 42 | static uint CalculateDigest(byte[] data, uint offset, uint size) 43 | { 44 | CRC crc = new CRC(); 45 | // crc.Init(); 46 | crc.Update(data, offset, size); 47 | return crc.GetDigest(); 48 | } 49 | 50 | static bool VerifyDigest(uint digest, byte[] data, uint offset, uint size) 51 | { 52 | return (CalculateDigest(data, offset, size) == digest); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /dumpsc/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("dumpsc")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("dumpsc")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("3806dafa-4dcf-4d7f-a60f-8ed4acb415ea")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /dumpsc/7zip/Common/InBuffer.cs: -------------------------------------------------------------------------------- 1 | // InBuffer.cs 2 | 3 | namespace SevenZip.Buffer 4 | { 5 | public class InBuffer 6 | { 7 | byte[] m_Buffer; 8 | uint m_Pos; 9 | uint m_Limit; 10 | uint m_BufferSize; 11 | System.IO.Stream m_Stream; 12 | bool m_StreamWasExhausted; 13 | ulong m_ProcessedSize; 14 | 15 | public InBuffer(uint bufferSize) 16 | { 17 | m_Buffer = new byte[bufferSize]; 18 | m_BufferSize = bufferSize; 19 | } 20 | 21 | public void Init(System.IO.Stream stream) 22 | { 23 | m_Stream = stream; 24 | m_ProcessedSize = 0; 25 | m_Limit = 0; 26 | m_Pos = 0; 27 | m_StreamWasExhausted = false; 28 | } 29 | 30 | public bool ReadBlock() 31 | { 32 | if (m_StreamWasExhausted) 33 | return false; 34 | m_ProcessedSize += m_Pos; 35 | int aNumProcessedBytes = m_Stream.Read(m_Buffer, 0, (int)m_BufferSize); 36 | m_Pos = 0; 37 | m_Limit = (uint)aNumProcessedBytes; 38 | m_StreamWasExhausted = (aNumProcessedBytes == 0); 39 | return (!m_StreamWasExhausted); 40 | } 41 | 42 | 43 | public void ReleaseStream() 44 | { 45 | // m_Stream.Close(); 46 | m_Stream = null; 47 | } 48 | 49 | public bool ReadByte(byte b) // check it 50 | { 51 | if (m_Pos >= m_Limit) 52 | if (!ReadBlock()) 53 | return false; 54 | b = m_Buffer[m_Pos++]; 55 | return true; 56 | } 57 | 58 | public byte ReadByte() 59 | { 60 | // return (byte)m_Stream.ReadByte(); 61 | if (m_Pos >= m_Limit) 62 | if (!ReadBlock()) 63 | return 0xFF; 64 | return m_Buffer[m_Pos++]; 65 | } 66 | 67 | public ulong GetProcessedSize() 68 | { 69 | return m_ProcessedSize + m_Pos; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /dumpsc/7zip/Compress/LZ/LzOutWindow.cs: -------------------------------------------------------------------------------- 1 | // LzOutWindow.cs 2 | 3 | namespace SevenZip.Compression.LZ 4 | { 5 | public class OutWindow 6 | { 7 | byte[] _buffer = null; 8 | uint _pos; 9 | uint _windowSize = 0; 10 | uint _streamPos; 11 | System.IO.Stream _stream; 12 | 13 | public uint TrainSize = 0; 14 | 15 | public void Create(uint windowSize) 16 | { 17 | if (_windowSize != windowSize) 18 | { 19 | // System.GC.Collect(); 20 | _buffer = new byte[windowSize]; 21 | } 22 | _windowSize = windowSize; 23 | _pos = 0; 24 | _streamPos = 0; 25 | } 26 | 27 | public void Init(System.IO.Stream stream, bool solid) 28 | { 29 | ReleaseStream(); 30 | _stream = stream; 31 | if (!solid) 32 | { 33 | _streamPos = 0; 34 | _pos = 0; 35 | TrainSize = 0; 36 | } 37 | } 38 | 39 | public bool Train(System.IO.Stream stream) 40 | { 41 | long len = stream.Length; 42 | uint size = (len < _windowSize) ? (uint)len : _windowSize; 43 | TrainSize = size; 44 | stream.Position = len - size; 45 | _streamPos = _pos = 0; 46 | while (size > 0) 47 | { 48 | uint curSize = _windowSize - _pos; 49 | if (size < curSize) 50 | curSize = size; 51 | int numReadBytes = stream.Read(_buffer, (int)_pos, (int)curSize); 52 | if (numReadBytes == 0) 53 | return false; 54 | size -= (uint)numReadBytes; 55 | _pos += (uint)numReadBytes; 56 | _streamPos += (uint)numReadBytes; 57 | if (_pos == _windowSize) 58 | _streamPos = _pos = 0; 59 | } 60 | return true; 61 | } 62 | 63 | public void ReleaseStream() 64 | { 65 | Flush(); 66 | _stream = null; 67 | } 68 | 69 | public void Flush() 70 | { 71 | uint size = _pos - _streamPos; 72 | if (size == 0) 73 | return; 74 | _stream.Write(_buffer, (int)_streamPos, (int)size); 75 | if (_pos >= _windowSize) 76 | _pos = 0; 77 | _streamPos = _pos; 78 | } 79 | 80 | public void CopyBlock(uint distance, uint len) 81 | { 82 | uint pos = _pos - distance - 1; 83 | if (pos >= _windowSize) 84 | pos += _windowSize; 85 | for (; len > 0; len--) 86 | { 87 | if (pos >= _windowSize) 88 | pos = 0; 89 | _buffer[_pos++] = _buffer[pos++]; 90 | if (_pos >= _windowSize) 91 | Flush(); 92 | } 93 | } 94 | 95 | public void PutByte(byte b) 96 | { 97 | _buffer[_pos++] = b; 98 | if (_pos >= _windowSize) 99 | Flush(); 100 | } 101 | 102 | public byte GetByte(uint distance) 103 | { 104 | uint pos = _pos - distance - 1; 105 | if (pos >= _windowSize) 106 | pos += _windowSize; 107 | return _buffer[pos]; 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /dumpsc/7zip/Compress/LZMA/LzmaBase.cs: -------------------------------------------------------------------------------- 1 | // LzmaBase.cs 2 | 3 | namespace SevenZip.Compression.LZMA 4 | { 5 | internal abstract class Base 6 | { 7 | public const uint kNumRepDistances = 4; 8 | public const uint kNumStates = 12; 9 | 10 | // static byte []kLiteralNextStates = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; 11 | // static byte []kMatchNextStates = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; 12 | // static byte []kRepNextStates = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; 13 | // static byte []kShortRepNextStates = {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; 14 | 15 | public struct State 16 | { 17 | public uint Index; 18 | public void Init() { Index = 0; } 19 | public void UpdateChar() 20 | { 21 | if (Index < 4) Index = 0; 22 | else if (Index < 10) Index -= 3; 23 | else Index -= 6; 24 | } 25 | public void UpdateMatch() { Index = (uint)(Index < 7 ? 7 : 10); } 26 | public void UpdateRep() { Index = (uint)(Index < 7 ? 8 : 11); } 27 | public void UpdateShortRep() { Index = (uint)(Index < 7 ? 9 : 11); } 28 | public bool IsCharState() { return Index < 7; } 29 | } 30 | 31 | public const int kNumPosSlotBits = 6; 32 | public const int kDicLogSizeMin = 0; 33 | // public const int kDicLogSizeMax = 30; 34 | // public const uint kDistTableSizeMax = kDicLogSizeMax * 2; 35 | 36 | public const int kNumLenToPosStatesBits = 2; // it's for speed optimization 37 | public const uint kNumLenToPosStates = 1 << kNumLenToPosStatesBits; 38 | 39 | public const uint kMatchMinLen = 2; 40 | 41 | public static uint GetLenToPosState(uint len) 42 | { 43 | len -= kMatchMinLen; 44 | if (len < kNumLenToPosStates) 45 | return len; 46 | return (uint)(kNumLenToPosStates - 1); 47 | } 48 | 49 | public const int kNumAlignBits = 4; 50 | public const uint kAlignTableSize = 1 << kNumAlignBits; 51 | public const uint kAlignMask = (kAlignTableSize - 1); 52 | 53 | public const uint kStartPosModelIndex = 4; 54 | public const uint kEndPosModelIndex = 14; 55 | public const uint kNumPosModels = kEndPosModelIndex - kStartPosModelIndex; 56 | 57 | public const uint kNumFullDistances = 1 << ((int)kEndPosModelIndex / 2); 58 | 59 | public const uint kNumLitPosStatesBitsEncodingMax = 4; 60 | public const uint kNumLitContextBitsMax = 8; 61 | 62 | public const int kNumPosStatesBitsMax = 4; 63 | public const uint kNumPosStatesMax = (1 << kNumPosStatesBitsMax); 64 | public const int kNumPosStatesBitsEncodingMax = 4; 65 | public const uint kNumPosStatesEncodingMax = (1 << kNumPosStatesBitsEncodingMax); 66 | 67 | public const int kNumLowLenBits = 3; 68 | public const int kNumMidLenBits = 3; 69 | public const int kNumHighLenBits = 8; 70 | public const uint kNumLowLenSymbols = 1 << kNumLowLenBits; 71 | public const uint kNumMidLenSymbols = 1 << kNumMidLenBits; 72 | public const uint kNumLenSymbols = kNumLowLenSymbols + kNumMidLenSymbols + 73 | (1 << kNumHighLenBits); 74 | public const uint kMatchMaxLen = kMatchMinLen + kNumLenSymbols - 1; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /dumpsc/7zip/Compress/RangeCoder/RangeCoderBit.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SevenZip.Compression.RangeCoder 4 | { 5 | struct BitEncoder 6 | { 7 | public const int kNumBitModelTotalBits = 11; 8 | public const uint kBitModelTotal = (1 << kNumBitModelTotalBits); 9 | const int kNumMoveBits = 5; 10 | const int kNumMoveReducingBits = 2; 11 | public const int kNumBitPriceShiftBits = 6; 12 | 13 | uint Prob; 14 | 15 | public void Init() { Prob = kBitModelTotal >> 1; } 16 | 17 | public void UpdateModel(uint symbol) 18 | { 19 | if (symbol == 0) 20 | Prob += (kBitModelTotal - Prob) >> kNumMoveBits; 21 | else 22 | Prob -= (Prob) >> kNumMoveBits; 23 | } 24 | 25 | public void Encode(Encoder encoder, uint symbol) 26 | { 27 | // encoder.EncodeBit(Prob, kNumBitModelTotalBits, symbol); 28 | // UpdateModel(symbol); 29 | uint newBound = (encoder.Range >> kNumBitModelTotalBits) * Prob; 30 | if (symbol == 0) 31 | { 32 | encoder.Range = newBound; 33 | Prob += (kBitModelTotal - Prob) >> kNumMoveBits; 34 | } 35 | else 36 | { 37 | encoder.Low += newBound; 38 | encoder.Range -= newBound; 39 | Prob -= (Prob) >> kNumMoveBits; 40 | } 41 | if (encoder.Range < Encoder.kTopValue) 42 | { 43 | encoder.Range <<= 8; 44 | encoder.ShiftLow(); 45 | } 46 | } 47 | 48 | private static UInt32[] ProbPrices = new UInt32[kBitModelTotal >> kNumMoveReducingBits]; 49 | 50 | static BitEncoder() 51 | { 52 | const int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits); 53 | for (int i = kNumBits - 1; i >= 0; i--) 54 | { 55 | UInt32 start = (UInt32)1 << (kNumBits - i - 1); 56 | UInt32 end = (UInt32)1 << (kNumBits - i); 57 | for (UInt32 j = start; j < end; j++) 58 | ProbPrices[j] = ((UInt32)i << kNumBitPriceShiftBits) + 59 | (((end - j) << kNumBitPriceShiftBits) >> (kNumBits - i - 1)); 60 | } 61 | } 62 | 63 | public uint GetPrice(uint symbol) 64 | { 65 | return ProbPrices[(((Prob - symbol) ^ ((-(int)symbol))) & (kBitModelTotal - 1)) >> kNumMoveReducingBits]; 66 | } 67 | public uint GetPrice0() { return ProbPrices[Prob >> kNumMoveReducingBits]; } 68 | public uint GetPrice1() { return ProbPrices[(kBitModelTotal - Prob) >> kNumMoveReducingBits]; } 69 | } 70 | 71 | struct BitDecoder 72 | { 73 | public const int kNumBitModelTotalBits = 11; 74 | public const uint kBitModelTotal = (1 << kNumBitModelTotalBits); 75 | const int kNumMoveBits = 5; 76 | 77 | uint Prob; 78 | 79 | public void UpdateModel(int numMoveBits, uint symbol) 80 | { 81 | if (symbol == 0) 82 | Prob += (kBitModelTotal - Prob) >> numMoveBits; 83 | else 84 | Prob -= (Prob) >> numMoveBits; 85 | } 86 | 87 | public void Init() { Prob = kBitModelTotal >> 1; } 88 | 89 | public uint Decode(RangeCoder.Decoder rangeDecoder) 90 | { 91 | uint newBound = (uint)(rangeDecoder.Range >> kNumBitModelTotalBits) * (uint)Prob; 92 | if (rangeDecoder.Code < newBound) 93 | { 94 | rangeDecoder.Range = newBound; 95 | Prob += (kBitModelTotal - Prob) >> kNumMoveBits; 96 | if (rangeDecoder.Range < Decoder.kTopValue) 97 | { 98 | rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte(); 99 | rangeDecoder.Range <<= 8; 100 | } 101 | return 0; 102 | } 103 | else 104 | { 105 | rangeDecoder.Range -= newBound; 106 | rangeDecoder.Code -= newBound; 107 | Prob -= (Prob) >> kNumMoveBits; 108 | if (rangeDecoder.Range < Decoder.kTopValue) 109 | { 110 | rangeDecoder.Code = (rangeDecoder.Code << 8) | (byte)rangeDecoder.Stream.ReadByte(); 111 | rangeDecoder.Range <<= 8; 112 | } 113 | return 1; 114 | } 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /dumpsc/dumpsc.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {3806DAFA-4DCF-4D7F-A60F-8ED4ACB415EA} 8 | Exe 9 | Properties 10 | dumpsc 11 | dumpsc 12 | v4.5 13 | 512 14 | true 15 | 16 | 17 | 18 | AnyCPU 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 79 | -------------------------------------------------------------------------------- /dumpsc/7zip/Compress/RangeCoder/RangeCoderBitTree.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SevenZip.Compression.RangeCoder 4 | { 5 | struct BitTreeEncoder 6 | { 7 | BitEncoder[] Models; 8 | int NumBitLevels; 9 | 10 | public BitTreeEncoder(int numBitLevels) 11 | { 12 | NumBitLevels = numBitLevels; 13 | Models = new BitEncoder[1 << numBitLevels]; 14 | } 15 | 16 | public void Init() 17 | { 18 | for (uint i = 1; i < (1 << NumBitLevels); i++) 19 | Models[i].Init(); 20 | } 21 | 22 | public void Encode(Encoder rangeEncoder, UInt32 symbol) 23 | { 24 | UInt32 m = 1; 25 | for (int bitIndex = NumBitLevels; bitIndex > 0; ) 26 | { 27 | bitIndex--; 28 | UInt32 bit = (symbol >> bitIndex) & 1; 29 | Models[m].Encode(rangeEncoder, bit); 30 | m = (m << 1) | bit; 31 | } 32 | } 33 | 34 | public void ReverseEncode(Encoder rangeEncoder, UInt32 symbol) 35 | { 36 | UInt32 m = 1; 37 | for (UInt32 i = 0; i < NumBitLevels; i++) 38 | { 39 | UInt32 bit = symbol & 1; 40 | Models[m].Encode(rangeEncoder, bit); 41 | m = (m << 1) | bit; 42 | symbol >>= 1; 43 | } 44 | } 45 | 46 | public UInt32 GetPrice(UInt32 symbol) 47 | { 48 | UInt32 price = 0; 49 | UInt32 m = 1; 50 | for (int bitIndex = NumBitLevels; bitIndex > 0; ) 51 | { 52 | bitIndex--; 53 | UInt32 bit = (symbol >> bitIndex) & 1; 54 | price += Models[m].GetPrice(bit); 55 | m = (m << 1) + bit; 56 | } 57 | return price; 58 | } 59 | 60 | public UInt32 ReverseGetPrice(UInt32 symbol) 61 | { 62 | UInt32 price = 0; 63 | UInt32 m = 1; 64 | for (int i = NumBitLevels; i > 0; i--) 65 | { 66 | UInt32 bit = symbol & 1; 67 | symbol >>= 1; 68 | price += Models[m].GetPrice(bit); 69 | m = (m << 1) | bit; 70 | } 71 | return price; 72 | } 73 | 74 | public static UInt32 ReverseGetPrice(BitEncoder[] Models, UInt32 startIndex, 75 | int NumBitLevels, UInt32 symbol) 76 | { 77 | UInt32 price = 0; 78 | UInt32 m = 1; 79 | for (int i = NumBitLevels; i > 0; i--) 80 | { 81 | UInt32 bit = symbol & 1; 82 | symbol >>= 1; 83 | price += Models[startIndex + m].GetPrice(bit); 84 | m = (m << 1) | bit; 85 | } 86 | return price; 87 | } 88 | 89 | public static void ReverseEncode(BitEncoder[] Models, UInt32 startIndex, 90 | Encoder rangeEncoder, int NumBitLevels, UInt32 symbol) 91 | { 92 | UInt32 m = 1; 93 | for (int i = 0; i < NumBitLevels; i++) 94 | { 95 | UInt32 bit = symbol & 1; 96 | Models[startIndex + m].Encode(rangeEncoder, bit); 97 | m = (m << 1) | bit; 98 | symbol >>= 1; 99 | } 100 | } 101 | } 102 | 103 | struct BitTreeDecoder 104 | { 105 | BitDecoder[] Models; 106 | int NumBitLevels; 107 | 108 | public BitTreeDecoder(int numBitLevels) 109 | { 110 | NumBitLevels = numBitLevels; 111 | Models = new BitDecoder[1 << numBitLevels]; 112 | } 113 | 114 | public void Init() 115 | { 116 | for (uint i = 1; i < (1 << NumBitLevels); i++) 117 | Models[i].Init(); 118 | } 119 | 120 | public uint Decode(RangeCoder.Decoder rangeDecoder) 121 | { 122 | uint m = 1; 123 | for (int bitIndex = NumBitLevels; bitIndex > 0; bitIndex--) 124 | m = (m << 1) + Models[m].Decode(rangeDecoder); 125 | return m - ((uint)1 << NumBitLevels); 126 | } 127 | 128 | public uint ReverseDecode(RangeCoder.Decoder rangeDecoder) 129 | { 130 | uint m = 1; 131 | uint symbol = 0; 132 | for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++) 133 | { 134 | uint bit = Models[m].Decode(rangeDecoder); 135 | m <<= 1; 136 | m += bit; 137 | symbol |= (bit << bitIndex); 138 | } 139 | return symbol; 140 | } 141 | 142 | public static uint ReverseDecode(BitDecoder[] Models, UInt32 startIndex, 143 | RangeCoder.Decoder rangeDecoder, int NumBitLevels) 144 | { 145 | uint m = 1; 146 | uint symbol = 0; 147 | for (int bitIndex = 0; bitIndex < NumBitLevels; bitIndex++) 148 | { 149 | uint bit = Models[startIndex + m].Decode(rangeDecoder); 150 | m <<= 1; 151 | m += bit; 152 | symbol |= (bit << bitIndex); 153 | } 154 | return symbol; 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /dumpsc/7zip/ICoder.cs: -------------------------------------------------------------------------------- 1 | // ICoder.h 2 | 3 | using System; 4 | 5 | namespace SevenZip 6 | { 7 | /// 8 | /// The exception that is thrown when an error in input stream occurs during decoding. 9 | /// 10 | class DataErrorException : ApplicationException 11 | { 12 | public DataErrorException(): base("Data Error") { } 13 | } 14 | 15 | /// 16 | /// The exception that is thrown when the value of an argument is outside the allowable range. 17 | /// 18 | class InvalidParamException : ApplicationException 19 | { 20 | public InvalidParamException(): base("Invalid Parameter") { } 21 | } 22 | 23 | public interface ICodeProgress 24 | { 25 | /// 26 | /// Callback progress. 27 | /// 28 | /// 29 | /// input size. -1 if unknown. 30 | /// 31 | /// 32 | /// output size. -1 if unknown. 33 | /// 34 | void SetProgress(Int64 inSize, Int64 outSize); 35 | }; 36 | 37 | public interface ICoder 38 | { 39 | /// 40 | /// Codes streams. 41 | /// 42 | /// 43 | /// input Stream. 44 | /// 45 | /// 46 | /// output Stream. 47 | /// 48 | /// 49 | /// input Size. -1 if unknown. 50 | /// 51 | /// 52 | /// output Size. -1 if unknown. 53 | /// 54 | /// 55 | /// callback progress reference. 56 | /// 57 | /// 58 | /// if input stream is not valid 59 | /// 60 | void Code(System.IO.Stream inStream, System.IO.Stream outStream, 61 | Int64 inSize, Int64 outSize, ICodeProgress progress); 62 | }; 63 | 64 | /* 65 | public interface ICoder2 66 | { 67 | void Code(ISequentialInStream []inStreams, 68 | const UInt64 []inSizes, 69 | ISequentialOutStream []outStreams, 70 | UInt64 []outSizes, 71 | ICodeProgress progress); 72 | }; 73 | */ 74 | 75 | /// 76 | /// Provides the fields that represent properties idenitifiers for compressing. 77 | /// 78 | public enum CoderPropID 79 | { 80 | /// 81 | /// Specifies default property. 82 | /// 83 | DefaultProp = 0, 84 | /// 85 | /// Specifies size of dictionary. 86 | /// 87 | DictionarySize, 88 | /// 89 | /// Specifies size of memory for PPM*. 90 | /// 91 | UsedMemorySize, 92 | /// 93 | /// Specifies order for PPM methods. 94 | /// 95 | Order, 96 | /// 97 | /// Specifies Block Size. 98 | /// 99 | BlockSize, 100 | /// 101 | /// Specifies number of postion state bits for LZMA (0 <= x <= 4). 102 | /// 103 | PosStateBits, 104 | /// 105 | /// Specifies number of literal context bits for LZMA (0 <= x <= 8). 106 | /// 107 | LitContextBits, 108 | /// 109 | /// Specifies number of literal position bits for LZMA (0 <= x <= 4). 110 | /// 111 | LitPosBits, 112 | /// 113 | /// Specifies number of fast bytes for LZ*. 114 | /// 115 | NumFastBytes, 116 | /// 117 | /// Specifies match finder. LZMA: "BT2", "BT4" or "BT4B". 118 | /// 119 | MatchFinder, 120 | /// 121 | /// Specifies the number of match finder cyckes. 122 | /// 123 | MatchFinderCycles, 124 | /// 125 | /// Specifies number of passes. 126 | /// 127 | NumPasses, 128 | /// 129 | /// Specifies number of algorithm. 130 | /// 131 | Algorithm, 132 | /// 133 | /// Specifies the number of threads. 134 | /// 135 | NumThreads, 136 | /// 137 | /// Specifies mode with end marker. 138 | /// 139 | EndMarker 140 | }; 141 | 142 | 143 | public interface ISetCoderProperties 144 | { 145 | void SetCoderProperties(CoderPropID[] propIDs, object[] properties); 146 | }; 147 | 148 | public interface IWriteCoderProperties 149 | { 150 | void WriteCoderProperties(System.IO.Stream outStream); 151 | } 152 | 153 | public interface ISetDecoderProperties 154 | { 155 | void SetDecoderProperties(byte[] properties); 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /dumpsc/7zip/Compress/LZ/LzInWindow.cs: -------------------------------------------------------------------------------- 1 | // LzInWindow.cs 2 | 3 | using System; 4 | 5 | namespace SevenZip.Compression.LZ 6 | { 7 | public class InWindow 8 | { 9 | public Byte[] _bufferBase = null; // pointer to buffer with data 10 | System.IO.Stream _stream; 11 | UInt32 _posLimit; // offset (from _buffer) of first byte when new block reading must be done 12 | bool _streamEndWasReached; // if (true) then _streamPos shows real end of stream 13 | 14 | UInt32 _pointerToLastSafePosition; 15 | 16 | public UInt32 _bufferOffset; 17 | 18 | public UInt32 _blockSize; // Size of Allocated memory block 19 | public UInt32 _pos; // offset (from _buffer) of curent byte 20 | UInt32 _keepSizeBefore; // how many BYTEs must be kept in buffer before _pos 21 | UInt32 _keepSizeAfter; // how many BYTEs must be kept buffer after _pos 22 | public UInt32 _streamPos; // offset (from _buffer) of first not read byte from Stream 23 | 24 | public void MoveBlock() 25 | { 26 | UInt32 offset = (UInt32)(_bufferOffset) + _pos - _keepSizeBefore; 27 | // we need one additional byte, since MovePos moves on 1 byte. 28 | if (offset > 0) 29 | offset--; 30 | 31 | UInt32 numBytes = (UInt32)(_bufferOffset) + _streamPos - offset; 32 | 33 | // check negative offset ???? 34 | for (UInt32 i = 0; i < numBytes; i++) 35 | _bufferBase[i] = _bufferBase[offset + i]; 36 | _bufferOffset -= offset; 37 | } 38 | 39 | public virtual void ReadBlock() 40 | { 41 | if (_streamEndWasReached) 42 | return; 43 | while (true) 44 | { 45 | int size = (int)((0 - _bufferOffset) + _blockSize - _streamPos); 46 | if (size == 0) 47 | return; 48 | int numReadBytes = _stream.Read(_bufferBase, (int)(_bufferOffset + _streamPos), size); 49 | if (numReadBytes == 0) 50 | { 51 | _posLimit = _streamPos; 52 | UInt32 pointerToPostion = _bufferOffset + _posLimit; 53 | if (pointerToPostion > _pointerToLastSafePosition) 54 | _posLimit = (UInt32)(_pointerToLastSafePosition - _bufferOffset); 55 | 56 | _streamEndWasReached = true; 57 | return; 58 | } 59 | _streamPos += (UInt32)numReadBytes; 60 | if (_streamPos >= _pos + _keepSizeAfter) 61 | _posLimit = _streamPos - _keepSizeAfter; 62 | } 63 | } 64 | 65 | void Free() { _bufferBase = null; } 66 | 67 | public void Create(UInt32 keepSizeBefore, UInt32 keepSizeAfter, UInt32 keepSizeReserv) 68 | { 69 | _keepSizeBefore = keepSizeBefore; 70 | _keepSizeAfter = keepSizeAfter; 71 | UInt32 blockSize = keepSizeBefore + keepSizeAfter + keepSizeReserv; 72 | if (_bufferBase == null || _blockSize != blockSize) 73 | { 74 | Free(); 75 | _blockSize = blockSize; 76 | _bufferBase = new Byte[_blockSize]; 77 | } 78 | _pointerToLastSafePosition = _blockSize - keepSizeAfter; 79 | } 80 | 81 | public void SetStream(System.IO.Stream stream) { _stream = stream; } 82 | public void ReleaseStream() { _stream = null; } 83 | 84 | public void Init() 85 | { 86 | _bufferOffset = 0; 87 | _pos = 0; 88 | _streamPos = 0; 89 | _streamEndWasReached = false; 90 | ReadBlock(); 91 | } 92 | 93 | public void MovePos() 94 | { 95 | _pos++; 96 | if (_pos > _posLimit) 97 | { 98 | UInt32 pointerToPostion = _bufferOffset + _pos; 99 | if (pointerToPostion > _pointerToLastSafePosition) 100 | MoveBlock(); 101 | ReadBlock(); 102 | } 103 | } 104 | 105 | public Byte GetIndexByte(Int32 index) { return _bufferBase[_bufferOffset + _pos + index]; } 106 | 107 | // index + limit have not to exceed _keepSizeAfter; 108 | public UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit) 109 | { 110 | if (_streamEndWasReached) 111 | if ((_pos + index) + limit > _streamPos) 112 | limit = _streamPos - (UInt32)(_pos + index); 113 | distance++; 114 | // Byte *pby = _buffer + (size_t)_pos + index; 115 | UInt32 pby = _bufferOffset + _pos + (UInt32)index; 116 | 117 | UInt32 i; 118 | for (i = 0; i < limit && _bufferBase[pby + i] == _bufferBase[pby + i - distance]; i++); 119 | return i; 120 | } 121 | 122 | public UInt32 GetNumAvailableBytes() { return _streamPos - _pos; } 123 | 124 | public void ReduceOffsets(Int32 subValue) 125 | { 126 | _bufferOffset += (UInt32)subValue; 127 | _posLimit -= (UInt32)subValue; 128 | _pos -= (UInt32)subValue; 129 | _streamPos -= (UInt32)subValue; 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /dumpsc/7zip/FileStreamCoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using SevenZip; 4 | using SevenZip.Compression; 5 | 6 | namespace SevenZip.Compression 7 | { 8 | public class LZMACoder : IDisposable 9 | { 10 | private bool isDisposed = false; 11 | 12 | private static Int32 dictionary = 1 << 21; //No dictionary 13 | private static Int32 posStateBits = 2; 14 | private static Int32 litContextBits = 3; // for normal files // UInt32 litContextBits = 0; // for 32-bit data 15 | private static Int32 litPosBits = 0; // UInt32 litPosBits = 2; // for 32-bit data 16 | private static Int32 algorithm = 2; 17 | private static Int32 numFastBytes = 128; 18 | private static bool eos = false; 19 | private static string mf = "bt4"; 20 | 21 | private static CoderPropID[] propIDs = 22 | { 23 | CoderPropID.DictionarySize, 24 | CoderPropID.PosStateBits, 25 | CoderPropID.LitContextBits, 26 | CoderPropID.LitPosBits, 27 | CoderPropID.Algorithm, 28 | CoderPropID.NumFastBytes, 29 | CoderPropID.MatchFinder, 30 | CoderPropID.EndMarker 31 | }; 32 | 33 | private static object[] properties = 34 | { 35 | (Int32)(dictionary), 36 | (Int32)(posStateBits), 37 | (Int32)(litContextBits), 38 | (Int32)(litPosBits), 39 | (Int32)(algorithm), 40 | (Int32)(numFastBytes), 41 | mf, 42 | eos 43 | }; 44 | 45 | public LZMACoder() 46 | { 47 | if (BitConverter.IsLittleEndian == false) 48 | { 49 | Dispose(); 50 | throw new Exception("Not implemented"); 51 | } 52 | } 53 | 54 | public void Decompress(Stream inStream, Stream outStream) 55 | { 56 | Decompress(inStream, outStream, false); 57 | } 58 | 59 | public void Decompress(Stream inStream, Stream outStream, bool closeInStream) 60 | { 61 | inStream.Position = 0; 62 | 63 | byte[] properties = new byte[5]; 64 | if (inStream.Read(properties, 0, 5) != 5) 65 | throw (new Exception("input .lzma is too short")); 66 | 67 | SevenZip.Compression.LZMA.Decoder decoder = new SevenZip.Compression.LZMA.Decoder(); 68 | decoder.SetDecoderProperties(properties); 69 | 70 | long outSize = 0; 71 | 72 | if (BitConverter.IsLittleEndian) 73 | { 74 | for (int i = 0; i < 8; i++) 75 | { 76 | int v = inStream.ReadByte(); 77 | if (v < 0) 78 | throw (new Exception("Can't Read 1")); 79 | 80 | outSize |= ((long)(byte)v) << (8 * i); 81 | } 82 | } 83 | 84 | long compressedSize = inStream.Length - inStream.Position; 85 | decoder.Code(inStream, outStream, compressedSize, outSize, null); 86 | 87 | if (closeInStream) 88 | inStream.Close(); 89 | } 90 | 91 | public void Compress(Stream inStream, Stream outStream) 92 | { 93 | Compress(inStream, outStream, false); 94 | } 95 | 96 | public void Compress(Stream inStream, Stream outStream, bool closeInStream) 97 | { 98 | inStream.Position = 0; 99 | Int64 fileSize = inStream.Length; 100 | 101 | SevenZip.Compression.LZMA.Encoder encoder = new SevenZip.Compression.LZMA.Encoder(); 102 | encoder.SetCoderProperties(propIDs, properties); 103 | encoder.WriteCoderProperties(outStream); 104 | 105 | if (BitConverter.IsLittleEndian) 106 | { 107 | byte[] LengthHeader = BitConverter.GetBytes(fileSize); 108 | outStream.Write(LengthHeader, 0, LengthHeader.Length); 109 | } 110 | 111 | encoder.Code(inStream, outStream, -1, -1, null); 112 | 113 | if (closeInStream) 114 | inStream.Close(); 115 | } 116 | 117 | ~LZMACoder() 118 | { 119 | Dispose(); 120 | } 121 | 122 | public void Dispose() 123 | { 124 | Dispose(true); 125 | GC.SuppressFinalize(this); 126 | } 127 | 128 | private void Dispose(bool disposing) 129 | { 130 | if (this.isDisposed == false) 131 | { 132 | if (disposing) 133 | { 134 | GC.SuppressFinalize(this); 135 | } 136 | } 137 | 138 | this.isDisposed = true; 139 | } 140 | } 141 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Microsoft Azure ApplicationInsights config file 170 | ApplicationInsights.config 171 | 172 | # Windows Store app package directory 173 | AppPackages/ 174 | BundleArtifacts/ 175 | 176 | # Visual Studio cache files 177 | # files ending in .cache can be ignored 178 | *.[Cc]ache 179 | # but keep track of directories ending in .cache 180 | !*.[Cc]ache/ 181 | 182 | # Others 183 | ClientBin/ 184 | [Ss]tyle[Cc]op.* 185 | ~$* 186 | *~ 187 | *.dbmdl 188 | *.dbproj.schemaview 189 | *.pfx 190 | *.publishsettings 191 | node_modules/ 192 | orleans.codegen.cs 193 | 194 | # RIA/Silverlight projects 195 | Generated_Code/ 196 | 197 | # Backup & report files from converting an old project file 198 | # to a newer Visual Studio version. Backup files are not needed, 199 | # because we have git ;-) 200 | _UpgradeReport_Files/ 201 | Backup*/ 202 | UpgradeLog*.XML 203 | UpgradeLog*.htm 204 | 205 | # SQL Server files 206 | *.mdf 207 | *.ldf 208 | 209 | # Business Intelligence projects 210 | *.rdl.data 211 | *.bim.layout 212 | *.bim_*.settings 213 | 214 | # Microsoft Fakes 215 | FakesAssemblies/ 216 | 217 | # GhostDoc plugin setting file 218 | *.GhostDoc.xml 219 | 220 | # Node.js Tools for Visual Studio 221 | .ntvs_analysis.dat 222 | 223 | # Visual Studio 6 build log 224 | *.plg 225 | 226 | # Visual Studio 6 workspace options file 227 | *.opt 228 | 229 | # Visual Studio LightSwitch build output 230 | **/*.HTMLClient/GeneratedArtifacts 231 | **/*.DesktopClient/GeneratedArtifacts 232 | **/*.DesktopClient/ModelManifest.xml 233 | **/*.Server/GeneratedArtifacts 234 | **/*.Server/ModelManifest.xml 235 | _Pvt_Extensions 236 | 237 | # LightSwitch generated files 238 | GeneratedArtifacts/ 239 | ModelManifest.xml 240 | 241 | # Paket dependency manager 242 | .paket/paket.exe 243 | 244 | # FAKE - F# Make 245 | .fake/ -------------------------------------------------------------------------------- /dumpsc/7zip/Compress/RangeCoder/RangeCoder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SevenZip.Compression.RangeCoder 4 | { 5 | class Encoder 6 | { 7 | public const uint kTopValue = (1 << 24); 8 | 9 | System.IO.Stream Stream; 10 | 11 | public UInt64 Low; 12 | public uint Range; 13 | uint _cacheSize; 14 | byte _cache; 15 | 16 | long StartPosition; 17 | 18 | public void SetStream(System.IO.Stream stream) 19 | { 20 | Stream = stream; 21 | } 22 | 23 | public void ReleaseStream() 24 | { 25 | Stream = null; 26 | } 27 | 28 | public void Init() 29 | { 30 | StartPosition = Stream.Position; 31 | 32 | Low = 0; 33 | Range = 0xFFFFFFFF; 34 | _cacheSize = 1; 35 | _cache = 0; 36 | } 37 | 38 | public void FlushData() 39 | { 40 | for (int i = 0; i < 5; i++) 41 | ShiftLow(); 42 | } 43 | 44 | public void FlushStream() 45 | { 46 | Stream.Flush(); 47 | } 48 | 49 | public void CloseStream() 50 | { 51 | Stream.Close(); 52 | } 53 | 54 | public void Encode(uint start, uint size, uint total) 55 | { 56 | Low += start * (Range /= total); 57 | Range *= size; 58 | while (Range < kTopValue) 59 | { 60 | Range <<= 8; 61 | ShiftLow(); 62 | } 63 | } 64 | 65 | public void ShiftLow() 66 | { 67 | if ((uint)Low < (uint)0xFF000000 || (uint)(Low >> 32) == 1) 68 | { 69 | byte temp = _cache; 70 | do 71 | { 72 | Stream.WriteByte((byte)(temp + (Low >> 32))); 73 | temp = 0xFF; 74 | } 75 | while (--_cacheSize != 0); 76 | _cache = (byte)(((uint)Low) >> 24); 77 | } 78 | _cacheSize++; 79 | Low = ((uint)Low) << 8; 80 | } 81 | 82 | public void EncodeDirectBits(uint v, int numTotalBits) 83 | { 84 | for (int i = numTotalBits - 1; i >= 0; i--) 85 | { 86 | Range >>= 1; 87 | if (((v >> i) & 1) == 1) 88 | Low += Range; 89 | if (Range < kTopValue) 90 | { 91 | Range <<= 8; 92 | ShiftLow(); 93 | } 94 | } 95 | } 96 | 97 | public void EncodeBit(uint size0, int numTotalBits, uint symbol) 98 | { 99 | uint newBound = (Range >> numTotalBits) * size0; 100 | if (symbol == 0) 101 | Range = newBound; 102 | else 103 | { 104 | Low += newBound; 105 | Range -= newBound; 106 | } 107 | while (Range < kTopValue) 108 | { 109 | Range <<= 8; 110 | ShiftLow(); 111 | } 112 | } 113 | 114 | public long GetProcessedSizeAdd() 115 | { 116 | return _cacheSize + 117 | Stream.Position - StartPosition + 4; 118 | // (long)Stream.GetProcessedSize(); 119 | } 120 | } 121 | 122 | class Decoder 123 | { 124 | public const uint kTopValue = (1 << 24); 125 | public uint Range; 126 | public uint Code; 127 | // public Buffer.InBuffer Stream = new Buffer.InBuffer(1 << 16); 128 | public System.IO.Stream Stream; 129 | 130 | public void Init(System.IO.Stream stream) 131 | { 132 | // Stream.Init(stream); 133 | Stream = stream; 134 | 135 | Code = 0; 136 | Range = 0xFFFFFFFF; 137 | for (int i = 0; i < 5; i++) 138 | Code = (Code << 8) | (byte)Stream.ReadByte(); 139 | } 140 | 141 | public void ReleaseStream() 142 | { 143 | // Stream.ReleaseStream(); 144 | Stream = null; 145 | } 146 | 147 | public void CloseStream() 148 | { 149 | Stream.Close(); 150 | } 151 | 152 | public void Normalize() 153 | { 154 | while (Range < kTopValue) 155 | { 156 | Code = (Code << 8) | (byte)Stream.ReadByte(); 157 | Range <<= 8; 158 | } 159 | } 160 | 161 | public void Normalize2() 162 | { 163 | if (Range < kTopValue) 164 | { 165 | Code = (Code << 8) | (byte)Stream.ReadByte(); 166 | Range <<= 8; 167 | } 168 | } 169 | 170 | public uint GetThreshold(uint total) 171 | { 172 | return Code / (Range /= total); 173 | } 174 | 175 | public void Decode(uint start, uint size, uint total) 176 | { 177 | Code -= start * Range; 178 | Range *= size; 179 | Normalize(); 180 | } 181 | 182 | public uint DecodeDirectBits(int numTotalBits) 183 | { 184 | uint range = Range; 185 | uint code = Code; 186 | uint result = 0; 187 | for (int i = numTotalBits; i > 0; i--) 188 | { 189 | range >>= 1; 190 | /* 191 | result <<= 1; 192 | if (code >= range) 193 | { 194 | code -= range; 195 | result |= 1; 196 | } 197 | */ 198 | uint t = (code - range) >> 31; 199 | code -= range & (t - 1); 200 | result = (result << 1) | (1 - t); 201 | 202 | if (range < kTopValue) 203 | { 204 | code = (code << 8) | (byte)Stream.ReadByte(); 205 | range <<= 8; 206 | } 207 | } 208 | Range = range; 209 | Code = code; 210 | return result; 211 | } 212 | 213 | public uint DecodeBit(uint size0, int numTotalBits) 214 | { 215 | uint newBound = (Range >> numTotalBits) * size0; 216 | uint symbol; 217 | if (Code < newBound) 218 | { 219 | symbol = 0; 220 | Range = newBound; 221 | } 222 | else 223 | { 224 | symbol = 1; 225 | Code -= newBound; 226 | Range -= newBound; 227 | } 228 | Normalize(); 229 | return symbol; 230 | } 231 | 232 | // ulong GetProcessedSize() {return Stream.GetProcessedSize(); } 233 | } 234 | } 235 | -------------------------------------------------------------------------------- /dumpsc/7zip/Common/CommandLineParser.cs: -------------------------------------------------------------------------------- 1 | // CommandLineParser.cs 2 | 3 | using System; 4 | using System.Collections; 5 | 6 | namespace SevenZip.CommandLineParser 7 | { 8 | public enum SwitchType 9 | { 10 | Simple, 11 | PostMinus, 12 | LimitedPostString, 13 | UnLimitedPostString, 14 | PostChar 15 | } 16 | 17 | public class SwitchForm 18 | { 19 | public string IDString; 20 | public SwitchType Type; 21 | public bool Multi; 22 | public int MinLen; 23 | public int MaxLen; 24 | public string PostCharSet; 25 | 26 | public SwitchForm(string idString, SwitchType type, bool multi, 27 | int minLen, int maxLen, string postCharSet) 28 | { 29 | IDString = idString; 30 | Type = type; 31 | Multi = multi; 32 | MinLen = minLen; 33 | MaxLen = maxLen; 34 | PostCharSet = postCharSet; 35 | } 36 | public SwitchForm(string idString, SwitchType type, bool multi, int minLen): 37 | this(idString, type, multi, minLen, 0, "") 38 | { 39 | } 40 | public SwitchForm(string idString, SwitchType type, bool multi): 41 | this(idString, type, multi, 0) 42 | { 43 | } 44 | } 45 | 46 | public class SwitchResult 47 | { 48 | public bool ThereIs; 49 | public bool WithMinus; 50 | public ArrayList PostStrings = new ArrayList(); 51 | public int PostCharIndex; 52 | public SwitchResult() 53 | { 54 | ThereIs = false; 55 | } 56 | } 57 | 58 | public class Parser 59 | { 60 | public ArrayList NonSwitchStrings = new ArrayList(); 61 | SwitchResult[] _switches; 62 | 63 | public Parser(int numSwitches) 64 | { 65 | _switches = new SwitchResult[numSwitches]; 66 | for (int i = 0; i < numSwitches; i++) 67 | _switches[i] = new SwitchResult(); 68 | } 69 | 70 | bool ParseString(string srcString, SwitchForm[] switchForms) 71 | { 72 | int len = srcString.Length; 73 | if (len == 0) 74 | return false; 75 | int pos = 0; 76 | if (!IsItSwitchChar(srcString[pos])) 77 | return false; 78 | while (pos < len) 79 | { 80 | if (IsItSwitchChar(srcString[pos])) 81 | pos++; 82 | const int kNoLen = -1; 83 | int matchedSwitchIndex = 0; 84 | int maxLen = kNoLen; 85 | for (int switchIndex = 0; switchIndex < _switches.Length; switchIndex++) 86 | { 87 | int switchLen = switchForms[switchIndex].IDString.Length; 88 | if (switchLen <= maxLen || pos + switchLen > len) 89 | continue; 90 | if (String.Compare(switchForms[switchIndex].IDString, 0, 91 | srcString, pos, switchLen, true) == 0) 92 | { 93 | matchedSwitchIndex = switchIndex; 94 | maxLen = switchLen; 95 | } 96 | } 97 | if (maxLen == kNoLen) 98 | throw new Exception("maxLen == kNoLen"); 99 | SwitchResult matchedSwitch = _switches[matchedSwitchIndex]; 100 | SwitchForm switchForm = switchForms[matchedSwitchIndex]; 101 | if ((!switchForm.Multi) && matchedSwitch.ThereIs) 102 | throw new Exception("switch must be single"); 103 | matchedSwitch.ThereIs = true; 104 | pos += maxLen; 105 | int tailSize = len - pos; 106 | SwitchType type = switchForm.Type; 107 | switch (type) 108 | { 109 | case SwitchType.PostMinus: 110 | { 111 | if (tailSize == 0) 112 | matchedSwitch.WithMinus = false; 113 | else 114 | { 115 | matchedSwitch.WithMinus = (srcString[pos] == kSwitchMinus); 116 | if (matchedSwitch.WithMinus) 117 | pos++; 118 | } 119 | break; 120 | } 121 | case SwitchType.PostChar: 122 | { 123 | if (tailSize < switchForm.MinLen) 124 | throw new Exception("switch is not full"); 125 | string charSet = switchForm.PostCharSet; 126 | const int kEmptyCharValue = -1; 127 | if (tailSize == 0) 128 | matchedSwitch.PostCharIndex = kEmptyCharValue; 129 | else 130 | { 131 | int index = charSet.IndexOf(srcString[pos]); 132 | if (index < 0) 133 | matchedSwitch.PostCharIndex = kEmptyCharValue; 134 | else 135 | { 136 | matchedSwitch.PostCharIndex = index; 137 | pos++; 138 | } 139 | } 140 | break; 141 | } 142 | case SwitchType.LimitedPostString: 143 | case SwitchType.UnLimitedPostString: 144 | { 145 | int minLen = switchForm.MinLen; 146 | if (tailSize < minLen) 147 | throw new Exception("switch is not full"); 148 | if (type == SwitchType.UnLimitedPostString) 149 | { 150 | matchedSwitch.PostStrings.Add(srcString.Substring(pos)); 151 | return true; 152 | } 153 | String stringSwitch = srcString.Substring(pos, minLen); 154 | pos += minLen; 155 | for (int i = minLen; i < switchForm.MaxLen && pos < len; i++, pos++) 156 | { 157 | char c = srcString[pos]; 158 | if (IsItSwitchChar(c)) 159 | break; 160 | stringSwitch += c; 161 | } 162 | matchedSwitch.PostStrings.Add(stringSwitch); 163 | break; 164 | } 165 | } 166 | } 167 | return true; 168 | 169 | } 170 | 171 | public void ParseStrings(SwitchForm[] switchForms, string[] commandStrings) 172 | { 173 | int numCommandStrings = commandStrings.Length; 174 | bool stopSwitch = false; 175 | for (int i = 0; i < numCommandStrings; i++) 176 | { 177 | string s = commandStrings[i]; 178 | if (stopSwitch) 179 | NonSwitchStrings.Add(s); 180 | else 181 | if (s == kStopSwitchParsing) 182 | stopSwitch = true; 183 | else 184 | if (!ParseString(s, switchForms)) 185 | NonSwitchStrings.Add(s); 186 | } 187 | } 188 | 189 | public SwitchResult this[int index] { get { return _switches[index]; } } 190 | 191 | public static int ParseCommand(CommandForm[] commandForms, string commandString, 192 | out string postString) 193 | { 194 | for (int i = 0; i < commandForms.Length; i++) 195 | { 196 | string id = commandForms[i].IDString; 197 | if (commandForms[i].PostStringMode) 198 | { 199 | if (commandString.IndexOf(id) == 0) 200 | { 201 | postString = commandString.Substring(id.Length); 202 | return i; 203 | } 204 | } 205 | else 206 | if (commandString == id) 207 | { 208 | postString = ""; 209 | return i; 210 | } 211 | } 212 | postString = ""; 213 | return -1; 214 | } 215 | 216 | static bool ParseSubCharsCommand(int numForms, CommandSubCharsSet[] forms, 217 | string commandString, ArrayList indices) 218 | { 219 | indices.Clear(); 220 | int numUsedChars = 0; 221 | for (int i = 0; i < numForms; i++) 222 | { 223 | CommandSubCharsSet charsSet = forms[i]; 224 | int currentIndex = -1; 225 | int len = charsSet.Chars.Length; 226 | for (int j = 0; j < len; j++) 227 | { 228 | char c = charsSet.Chars[j]; 229 | int newIndex = commandString.IndexOf(c); 230 | if (newIndex >= 0) 231 | { 232 | if (currentIndex >= 0) 233 | return false; 234 | if (commandString.IndexOf(c, newIndex + 1) >= 0) 235 | return false; 236 | currentIndex = j; 237 | numUsedChars++; 238 | } 239 | } 240 | if (currentIndex == -1 && !charsSet.EmptyAllowed) 241 | return false; 242 | indices.Add(currentIndex); 243 | } 244 | return (numUsedChars == commandString.Length); 245 | } 246 | const char kSwitchID1 = '-'; 247 | const char kSwitchID2 = '/'; 248 | 249 | const char kSwitchMinus = '-'; 250 | const string kStopSwitchParsing = "--"; 251 | 252 | static bool IsItSwitchChar(char c) 253 | { 254 | return (c == kSwitchID1 || c == kSwitchID2); 255 | } 256 | } 257 | 258 | public class CommandForm 259 | { 260 | public string IDString = ""; 261 | public bool PostStringMode = false; 262 | public CommandForm(string idString, bool postStringMode) 263 | { 264 | IDString = idString; 265 | PostStringMode = postStringMode; 266 | } 267 | } 268 | 269 | class CommandSubCharsSet 270 | { 271 | public string Chars = ""; 272 | public bool EmptyAllowed = false; 273 | } 274 | } 275 | -------------------------------------------------------------------------------- /dumpsc/7zip/Compress/LZ/LzBinTree.cs: -------------------------------------------------------------------------------- 1 | // LzBinTree.cs 2 | 3 | using System; 4 | 5 | namespace SevenZip.Compression.LZ 6 | { 7 | public class BinTree : InWindow, IMatchFinder 8 | { 9 | UInt32 _cyclicBufferPos; 10 | UInt32 _cyclicBufferSize = 0; 11 | UInt32 _matchMaxLen; 12 | 13 | UInt32[] _son; 14 | UInt32[] _hash; 15 | 16 | UInt32 _cutValue = 0xFF; 17 | UInt32 _hashMask; 18 | UInt32 _hashSizeSum = 0; 19 | 20 | bool HASH_ARRAY = true; 21 | 22 | const UInt32 kHash2Size = 1 << 10; 23 | const UInt32 kHash3Size = 1 << 16; 24 | const UInt32 kBT2HashSize = 1 << 16; 25 | const UInt32 kStartMaxLen = 1; 26 | const UInt32 kHash3Offset = kHash2Size; 27 | const UInt32 kEmptyHashValue = 0; 28 | const UInt32 kMaxValForNormalize = ((UInt32)1 << 31) - 1; 29 | 30 | UInt32 kNumHashDirectBytes = 0; 31 | UInt32 kMinMatchCheck = 4; 32 | UInt32 kFixHashSize = kHash2Size + kHash3Size; 33 | 34 | public void SetType(int numHashBytes) 35 | { 36 | HASH_ARRAY = (numHashBytes > 2); 37 | if (HASH_ARRAY) 38 | { 39 | kNumHashDirectBytes = 0; 40 | kMinMatchCheck = 4; 41 | kFixHashSize = kHash2Size + kHash3Size; 42 | } 43 | else 44 | { 45 | kNumHashDirectBytes = 2; 46 | kMinMatchCheck = 2 + 1; 47 | kFixHashSize = 0; 48 | } 49 | } 50 | 51 | public new void SetStream(System.IO.Stream stream) { base.SetStream(stream); } 52 | public new void ReleaseStream() { base.ReleaseStream(); } 53 | 54 | public new void Init() 55 | { 56 | base.Init(); 57 | for (UInt32 i = 0; i < _hashSizeSum; i++) 58 | _hash[i] = kEmptyHashValue; 59 | _cyclicBufferPos = 0; 60 | ReduceOffsets(-1); 61 | } 62 | 63 | public new void MovePos() 64 | { 65 | if (++_cyclicBufferPos >= _cyclicBufferSize) 66 | _cyclicBufferPos = 0; 67 | base.MovePos(); 68 | if (_pos == kMaxValForNormalize) 69 | Normalize(); 70 | } 71 | 72 | public new Byte GetIndexByte(Int32 index) { return base.GetIndexByte(index); } 73 | 74 | public new UInt32 GetMatchLen(Int32 index, UInt32 distance, UInt32 limit) 75 | { return base.GetMatchLen(index, distance, limit); } 76 | 77 | public new UInt32 GetNumAvailableBytes() { return base.GetNumAvailableBytes(); } 78 | 79 | public void Create(UInt32 historySize, UInt32 keepAddBufferBefore, 80 | UInt32 matchMaxLen, UInt32 keepAddBufferAfter) 81 | { 82 | if (historySize > kMaxValForNormalize - 256) 83 | throw new Exception(); 84 | _cutValue = 16 + (matchMaxLen >> 1); 85 | 86 | UInt32 windowReservSize = (historySize + keepAddBufferBefore + 87 | matchMaxLen + keepAddBufferAfter) / 2 + 256; 88 | 89 | base.Create(historySize + keepAddBufferBefore, matchMaxLen + keepAddBufferAfter, windowReservSize); 90 | 91 | _matchMaxLen = matchMaxLen; 92 | 93 | UInt32 cyclicBufferSize = historySize + 1; 94 | if (_cyclicBufferSize != cyclicBufferSize) 95 | _son = new UInt32[(_cyclicBufferSize = cyclicBufferSize) * 2]; 96 | 97 | UInt32 hs = kBT2HashSize; 98 | 99 | if (HASH_ARRAY) 100 | { 101 | hs = historySize - 1; 102 | hs |= (hs >> 1); 103 | hs |= (hs >> 2); 104 | hs |= (hs >> 4); 105 | hs |= (hs >> 8); 106 | hs >>= 1; 107 | hs |= 0xFFFF; 108 | if (hs > (1 << 24)) 109 | hs >>= 1; 110 | _hashMask = hs; 111 | hs++; 112 | hs += kFixHashSize; 113 | } 114 | if (hs != _hashSizeSum) 115 | _hash = new UInt32[_hashSizeSum = hs]; 116 | } 117 | 118 | public UInt32 GetMatches(UInt32[] distances) 119 | { 120 | UInt32 lenLimit; 121 | if (_pos + _matchMaxLen <= _streamPos) 122 | lenLimit = _matchMaxLen; 123 | else 124 | { 125 | lenLimit = _streamPos - _pos; 126 | if (lenLimit < kMinMatchCheck) 127 | { 128 | MovePos(); 129 | return 0; 130 | } 131 | } 132 | 133 | UInt32 offset = 0; 134 | UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0; 135 | UInt32 cur = _bufferOffset + _pos; 136 | UInt32 maxLen = kStartMaxLen; // to avoid items for len < hashSize; 137 | UInt32 hashValue, hash2Value = 0, hash3Value = 0; 138 | 139 | if (HASH_ARRAY) 140 | { 141 | UInt32 temp = CRC.Table[_bufferBase[cur]] ^ _bufferBase[cur + 1]; 142 | hash2Value = temp & (kHash2Size - 1); 143 | temp ^= ((UInt32)(_bufferBase[cur + 2]) << 8); 144 | hash3Value = temp & (kHash3Size - 1); 145 | hashValue = (temp ^ (CRC.Table[_bufferBase[cur + 3]] << 5)) & _hashMask; 146 | } 147 | else 148 | hashValue = _bufferBase[cur] ^ ((UInt32)(_bufferBase[cur + 1]) << 8); 149 | 150 | UInt32 curMatch = _hash[kFixHashSize + hashValue]; 151 | if (HASH_ARRAY) 152 | { 153 | UInt32 curMatch2 = _hash[hash2Value]; 154 | UInt32 curMatch3 = _hash[kHash3Offset + hash3Value]; 155 | _hash[hash2Value] = _pos; 156 | _hash[kHash3Offset + hash3Value] = _pos; 157 | if (curMatch2 > matchMinPos) 158 | if (_bufferBase[_bufferOffset + curMatch2] == _bufferBase[cur]) 159 | { 160 | distances[offset++] = maxLen = 2; 161 | distances[offset++] = _pos - curMatch2 - 1; 162 | } 163 | if (curMatch3 > matchMinPos) 164 | if (_bufferBase[_bufferOffset + curMatch3] == _bufferBase[cur]) 165 | { 166 | if (curMatch3 == curMatch2) 167 | offset -= 2; 168 | distances[offset++] = maxLen = 3; 169 | distances[offset++] = _pos - curMatch3 - 1; 170 | curMatch2 = curMatch3; 171 | } 172 | if (offset != 0 && curMatch2 == curMatch) 173 | { 174 | offset -= 2; 175 | maxLen = kStartMaxLen; 176 | } 177 | } 178 | 179 | _hash[kFixHashSize + hashValue] = _pos; 180 | 181 | UInt32 ptr0 = (_cyclicBufferPos << 1) + 1; 182 | UInt32 ptr1 = (_cyclicBufferPos << 1); 183 | 184 | UInt32 len0, len1; 185 | len0 = len1 = kNumHashDirectBytes; 186 | 187 | if (kNumHashDirectBytes != 0) 188 | { 189 | if (curMatch > matchMinPos) 190 | { 191 | if (_bufferBase[_bufferOffset + curMatch + kNumHashDirectBytes] != 192 | _bufferBase[cur + kNumHashDirectBytes]) 193 | { 194 | distances[offset++] = maxLen = kNumHashDirectBytes; 195 | distances[offset++] = _pos - curMatch - 1; 196 | } 197 | } 198 | } 199 | 200 | UInt32 count = _cutValue; 201 | 202 | while(true) 203 | { 204 | if(curMatch <= matchMinPos || count-- == 0) 205 | { 206 | _son[ptr0] = _son[ptr1] = kEmptyHashValue; 207 | break; 208 | } 209 | UInt32 delta = _pos - curMatch; 210 | UInt32 cyclicPos = ((delta <= _cyclicBufferPos) ? 211 | (_cyclicBufferPos - delta) : 212 | (_cyclicBufferPos - delta + _cyclicBufferSize)) << 1; 213 | 214 | UInt32 pby1 = _bufferOffset + curMatch; 215 | UInt32 len = Math.Min(len0, len1); 216 | if (_bufferBase[pby1 + len] == _bufferBase[cur + len]) 217 | { 218 | while(++len != lenLimit) 219 | if (_bufferBase[pby1 + len] != _bufferBase[cur + len]) 220 | break; 221 | if (maxLen < len) 222 | { 223 | distances[offset++] = maxLen = len; 224 | distances[offset++] = delta - 1; 225 | if (len == lenLimit) 226 | { 227 | _son[ptr1] = _son[cyclicPos]; 228 | _son[ptr0] = _son[cyclicPos + 1]; 229 | break; 230 | } 231 | } 232 | } 233 | if (_bufferBase[pby1 + len] < _bufferBase[cur + len]) 234 | { 235 | _son[ptr1] = curMatch; 236 | ptr1 = cyclicPos + 1; 237 | curMatch = _son[ptr1]; 238 | len1 = len; 239 | } 240 | else 241 | { 242 | _son[ptr0] = curMatch; 243 | ptr0 = cyclicPos; 244 | curMatch = _son[ptr0]; 245 | len0 = len; 246 | } 247 | } 248 | MovePos(); 249 | return offset; 250 | } 251 | 252 | public void Skip(UInt32 num) 253 | { 254 | do 255 | { 256 | UInt32 lenLimit; 257 | if (_pos + _matchMaxLen <= _streamPos) 258 | lenLimit = _matchMaxLen; 259 | else 260 | { 261 | lenLimit = _streamPos - _pos; 262 | if (lenLimit < kMinMatchCheck) 263 | { 264 | MovePos(); 265 | continue; 266 | } 267 | } 268 | 269 | UInt32 matchMinPos = (_pos > _cyclicBufferSize) ? (_pos - _cyclicBufferSize) : 0; 270 | UInt32 cur = _bufferOffset + _pos; 271 | 272 | UInt32 hashValue; 273 | 274 | if (HASH_ARRAY) 275 | { 276 | UInt32 temp = CRC.Table[_bufferBase[cur]] ^ _bufferBase[cur + 1]; 277 | UInt32 hash2Value = temp & (kHash2Size - 1); 278 | _hash[hash2Value] = _pos; 279 | temp ^= ((UInt32)(_bufferBase[cur + 2]) << 8); 280 | UInt32 hash3Value = temp & (kHash3Size - 1); 281 | _hash[kHash3Offset + hash3Value] = _pos; 282 | hashValue = (temp ^ (CRC.Table[_bufferBase[cur + 3]] << 5)) & _hashMask; 283 | } 284 | else 285 | hashValue = _bufferBase[cur] ^ ((UInt32)(_bufferBase[cur + 1]) << 8); 286 | 287 | UInt32 curMatch = _hash[kFixHashSize + hashValue]; 288 | _hash[kFixHashSize + hashValue] = _pos; 289 | 290 | UInt32 ptr0 = (_cyclicBufferPos << 1) + 1; 291 | UInt32 ptr1 = (_cyclicBufferPos << 1); 292 | 293 | UInt32 len0, len1; 294 | len0 = len1 = kNumHashDirectBytes; 295 | 296 | UInt32 count = _cutValue; 297 | while (true) 298 | { 299 | if (curMatch <= matchMinPos || count-- == 0) 300 | { 301 | _son[ptr0] = _son[ptr1] = kEmptyHashValue; 302 | break; 303 | } 304 | 305 | UInt32 delta = _pos - curMatch; 306 | UInt32 cyclicPos = ((delta <= _cyclicBufferPos) ? 307 | (_cyclicBufferPos - delta) : 308 | (_cyclicBufferPos - delta + _cyclicBufferSize)) << 1; 309 | 310 | UInt32 pby1 = _bufferOffset + curMatch; 311 | UInt32 len = Math.Min(len0, len1); 312 | if (_bufferBase[pby1 + len] == _bufferBase[cur + len]) 313 | { 314 | while (++len != lenLimit) 315 | if (_bufferBase[pby1 + len] != _bufferBase[cur + len]) 316 | break; 317 | if (len == lenLimit) 318 | { 319 | _son[ptr1] = _son[cyclicPos]; 320 | _son[ptr0] = _son[cyclicPos + 1]; 321 | break; 322 | } 323 | } 324 | if (_bufferBase[pby1 + len] < _bufferBase[cur + len]) 325 | { 326 | _son[ptr1] = curMatch; 327 | ptr1 = cyclicPos + 1; 328 | curMatch = _son[ptr1]; 329 | len1 = len; 330 | } 331 | else 332 | { 333 | _son[ptr0] = curMatch; 334 | ptr0 = cyclicPos; 335 | curMatch = _son[ptr0]; 336 | len0 = len; 337 | } 338 | } 339 | MovePos(); 340 | } 341 | while (--num != 0); 342 | } 343 | 344 | void NormalizeLinks(UInt32[] items, UInt32 numItems, UInt32 subValue) 345 | { 346 | for (UInt32 i = 0; i < numItems; i++) 347 | { 348 | UInt32 value = items[i]; 349 | if (value <= subValue) 350 | value = kEmptyHashValue; 351 | else 352 | value -= subValue; 353 | items[i] = value; 354 | } 355 | } 356 | 357 | void Normalize() 358 | { 359 | UInt32 subValue = _pos - _cyclicBufferSize; 360 | NormalizeLinks(_son, _cyclicBufferSize * 2, subValue); 361 | NormalizeLinks(_hash, _hashSizeSum, subValue); 362 | ReduceOffsets((Int32)subValue); 363 | } 364 | 365 | public void SetCutValue(UInt32 cutValue) { _cutValue = cutValue; } 366 | } 367 | } 368 | -------------------------------------------------------------------------------- /dumpsc/Program.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Project : SC Extractor for Clash Royal 3 | * Author : Moien007 (https://github.com/moien007) 4 | * 5 | * Description : Port https://github.com/123456abcdef/cr-sc-dump to C# 6 | * 7 | * TODO : 8 | * [-] Reverse Code for Edit _tex.sc files 9 | * [-] Fix TODO #1 10 | */ 11 | 12 | using System; 13 | using System.Collections.Generic; 14 | using System.Linq; 15 | //using System.Text; 16 | //using System.Threading.Tasks; 17 | using System.IO; 18 | using System.Drawing.Imaging; 19 | using System.Drawing; 20 | using System.Diagnostics; 21 | 22 | /* 23 | * How to use : 24 | * after compile, but .exe to empty folder and run 25 | * program generates two folder named as 'input' and 'output' 26 | * open clash royal apk file with WinRAR or 7Zip, goto assets\sc folder and pickup any _tex.sc files 27 | * put _tex.sc files to input folder and run .exe 28 | * wait a minute 29 | * open output folder 30 | * DONE!!! 31 | */ 32 | 33 | namespace dumpsc 34 | { 35 | class Program 36 | { 37 | public const string InputFolder = "input"; 38 | public const string OutputFolder = "output"; 39 | 40 | static void Main(string[] args) 41 | { 42 | // create input and output directories 43 | Directory.CreateDirectory(InputFolder); 44 | Directory.CreateDirectory(OutputFolder); 45 | 46 | long elapsedMilliseconds = 0; 47 | 48 | // for each file in input folder 49 | foreach (string fileName in Directory.GetFiles(InputFolder)) 50 | { 51 | // create stop for calculate execution time 52 | Stopwatch watch = Stopwatch.StartNew(); 53 | watch.Start(); 54 | 55 | Console.WriteLine("Processing {0}", fileName); 56 | Console.WriteLine("\tDecompressing..."); 57 | byte[] decodedBytes = Decompress(fileName); // load and decompress file 58 | 59 | Console.WriteLine("\tDecoding..."); 60 | Bitmap[] images = Decode(decodedBytes); 61 | 62 | Console.WriteLine("\tSaving Images..."); 63 | 64 | string savePath = string.Format("{0}\\{1}", OutputFolder, Path.GetFileNameWithoutExtension(fileName)); 65 | 66 | for (int i = 0; i < images.Length; i++) 67 | { 68 | using (FileStream fileStream = new FileStream(string.Format("\\{0}.png", savePath, i), FileMode.Create)) 69 | { 70 | // save bitmap with png image format to file 71 | images[i].Save(fileStream, ImageFormat.Png); 72 | } 73 | } 74 | 75 | watch.Stop(); 76 | Console.WriteLine("\tDone in {0}ms", watch.ElapsedMilliseconds); 77 | 78 | elapsedMilliseconds += watch.ElapsedMilliseconds; 79 | } 80 | 81 | Console.WriteLine("\nFinished in {0}ms", elapsedMilliseconds); 82 | Console.WriteLine("Press any key to close..."); 83 | Console.ReadKey(); 84 | } 85 | 86 | public static Bitmap[] Decode(byte[] decodedBytes) 87 | { 88 | // textures in sc files 89 | List images = new List(); 90 | 91 | using (MemoryStream memory = new MemoryStream(decodedBytes)) 92 | using (BinaryReader binaryReader = new BinaryReader(memory)) 93 | { 94 | while (memory.Length - memory.Position > 5) 95 | { 96 | // read sc header 97 | SCHeader scHeader = ReadSCHeader(binaryReader); 98 | 99 | Console.WriteLine("\t FileType: {0}, FileSize: {1}, SubType: {2}, Width: {3}, Height: {4}", 100 | scHeader.FileType, scHeader.FileSize, scHeader.SubType, scHeader.Width, scHeader.Height); 101 | int pixelSize; 102 | 103 | switch(scHeader.SubType) 104 | { 105 | case 0: 106 | pixelSize = 4; 107 | break; 108 | case 2: 109 | case 4: 110 | case 6: 111 | pixelSize = 2; 112 | break; 113 | case 10: 114 | pixelSize = 1; 115 | break; 116 | default: 117 | throw new Exception("Unknown pixel type " + scHeader.SubType.ToString()); 118 | } 119 | 120 | // create bitmap image using width and height from sc header 121 | Bitmap bmp = new Bitmap(scHeader.Width, scHeader.Height, PixelFormat.Format32bppArgb); 122 | 123 | // we should lock bitmap ? 124 | 125 | List pixels = new List(); 126 | 127 | for (int x = 0; x < bmp.Width; x++) 128 | { 129 | for (int y = 0; y < bmp.Height; y++) 130 | { 131 | // get pixel from bytes 132 | Color pixel = ConvertToPixelColor(binaryReader.ReadBytes(pixelSize), scHeader.SubType); 133 | 134 | // add it to list 135 | pixels.Add(pixel); 136 | 137 | // and set it to bitmap 138 | bmp.SetPixel(x, y, pixel); 139 | } 140 | } 141 | 142 | // from this part all of codes just converted to csharp with comments 143 | if(scHeader.FileType == 27 || scHeader.FileType == 28) 144 | { 145 | int iSrcPix = 0; 146 | 147 | for (int l = 0; l < Math.Floor((decimal)scHeader.Height / 32); l++) //block of 32 lines 148 | { 149 | // normal 32-pixels blocks 150 | for (int k = 0; k < Math.Floor((decimal)scHeader.Width / 32); k++) // 32-pixels blocks in a line 151 | { 152 | for (int j = 0; j < 32; j++) // line in a multi line block 153 | { 154 | for (int h = 0; h < 32; h++) // pixels in a block 155 | { 156 | bmp.SetPixel((h + (k * 32)), (j + (l * 32)), pixels[iSrcPix]); 157 | 158 | iSrcPix++; 159 | } 160 | } 161 | } 162 | 163 | // line end blocks 164 | for (int j = 0; j < 32; j++) 165 | { 166 | for (int h = 0; h < scHeader.Width % 32; h++) 167 | { 168 | bmp.SetPixel((h + (scHeader.Width - (scHeader.Width % 32))), (j + (l * 32)), pixels[iSrcPix]); 169 | iSrcPix++; 170 | } 171 | } 172 | } 173 | 174 | // final lines 175 | for (int k = 0; k < Math.Floor((decimal)scHeader.Width / 32); k++) // 32-pixels blocks in a line 176 | { 177 | for (int j = 0; j < (scHeader.Height % 32); j++) // line in a multi line block 178 | { 179 | for (int h = 0; h < 32; h++) // pixels in a 32-pixels-block 180 | { 181 | bmp.SetPixel((h + (k * 32)), (j + (scHeader.Height - (scHeader.Height % 32))), pixels[iSrcPix]); 182 | iSrcPix++; 183 | } 184 | } 185 | } 186 | 187 | // line end blocks 188 | /* for (int j = 0; j < (scHeader.Height % 32); j++) // TODO #1 we got error here about at runtime, i will working on it 189 | { 190 | for (int h = 0; h < (scHeader.Width & 32); h++) 191 | { 192 | bmp.SetPixel((h + (scHeader.Width - (scHeader.Width % 32))), (j + (scHeader.Height - (scHeader.Height % 32))), pixels[iSrcPix]); 193 | iSrcPix++; 194 | } 195 | } */ 196 | } 197 | 198 | images.Add(bmp); 199 | } 200 | } 201 | 202 | return images.ToArray(); 203 | } 204 | 205 | 206 | public static byte[] Decompress(string filePath) 207 | { 208 | // read file bytes, then skip first 26 bytes (idk why) 209 | byte[] fileBytes = File.ReadAllBytes(filePath).Skip(26).ToArray(); 210 | 211 | byte[] decompressed; 212 | 213 | using (MemoryStream memory = new MemoryStream()) 214 | using (BinaryWriter binaryWriter = new BinaryWriter(memory)) 215 | { 216 | // add first 9 bytes 217 | binaryWriter.Write(fileBytes, 0, 9); 218 | 219 | // add four zero bytes (fix header) 220 | binaryWriter.Write(new byte[] { 0x00, 0x00, 0x00, 0x00 }); 221 | 222 | // add another bytes 223 | binaryWriter.Write(fileBytes, 9, fileBytes.Length - 9); 224 | 225 | // get bytes from memory and then decompress using LZMA 226 | decompressed = LZMA.Decompress(memory.ToArray()); 227 | } 228 | 229 | return decompressed; 230 | } 231 | 232 | // just for saving time :D 233 | public static SCHeader ReadSCHeader(BinaryReader reader) 234 | { 235 | return new SCHeader 236 | { 237 | FileType = reader.ReadByte(), 238 | FileSize = reader.ReadUInt32(), 239 | SubType = reader.ReadByte(), 240 | Width = reader.ReadUInt16(), 241 | Height = reader.ReadUInt16(), 242 | }; 243 | } 244 | 245 | public static Color ConvertToPixelColor(byte[] pixel, byte subType) 246 | { 247 | ushort pix; 248 | 249 | switch (subType) // this part just converted to csharp 250 | { 251 | case 0: // RGB8888 252 | return Color.FromArgb((int)BitConverter.ToUInt32(pixel, 0)); 253 | case 2: // RGB4444 254 | pix = BitConverter.ToUInt16(pixel, 0); 255 | return Color.FromArgb(((pix >> 12) & 0xF) << 4, ((pix >> 8) & 0xF) << 4, ((pix >> 4) & 0xF) << 4, ((pix >> 0) & 0xF) << 4); 256 | case 4: // RGB565 257 | pix = BitConverter.ToUInt16(pixel, 0); 258 | return Color.FromArgb(((pix >> 11) & 0x1F) << 3, ((pix >> 5) & 0x3F) << 2, (pix & 0x1F) << 3); 259 | case 6: // LA88 260 | pix = BitConverter.ToUInt16(pixel, 0); 261 | return Color.FromArgb((pix >> 8), (pix >> 8), (pix >> 8), (pix & 0xFF)); 262 | case 10: //L8 263 | pix = pixel.FirstOrDefault(); 264 | return Color.FromArgb(pix,pix,pix); 265 | } 266 | 267 | throw new Exception("Unknown pixel color " + subType.ToString()); 268 | } 269 | } 270 | 271 | public class SCHeader 272 | { 273 | public byte FileType { get; set; } 274 | public uint FileSize { get; set; } 275 | public byte SubType { get; set; } 276 | public ushort Width { get; set; } 277 | public ushort Height { get; set; } 278 | } 279 | } 280 | -------------------------------------------------------------------------------- /dumpsc/7zip/Compress/LZMA/LzmaDecoder.cs: -------------------------------------------------------------------------------- 1 | // LzmaDecoder.cs 2 | 3 | using System; 4 | 5 | namespace SevenZip.Compression.LZMA 6 | { 7 | using RangeCoder; 8 | 9 | public class Decoder : ICoder, ISetDecoderProperties // ,System.IO.Stream 10 | { 11 | class LenDecoder 12 | { 13 | BitDecoder m_Choice = new BitDecoder(); 14 | BitDecoder m_Choice2 = new BitDecoder(); 15 | BitTreeDecoder[] m_LowCoder = new BitTreeDecoder[Base.kNumPosStatesMax]; 16 | BitTreeDecoder[] m_MidCoder = new BitTreeDecoder[Base.kNumPosStatesMax]; 17 | BitTreeDecoder m_HighCoder = new BitTreeDecoder(Base.kNumHighLenBits); 18 | uint m_NumPosStates = 0; 19 | 20 | public void Create(uint numPosStates) 21 | { 22 | for (uint posState = m_NumPosStates; posState < numPosStates; posState++) 23 | { 24 | m_LowCoder[posState] = new BitTreeDecoder(Base.kNumLowLenBits); 25 | m_MidCoder[posState] = new BitTreeDecoder(Base.kNumMidLenBits); 26 | } 27 | m_NumPosStates = numPosStates; 28 | } 29 | 30 | public void Init() 31 | { 32 | m_Choice.Init(); 33 | for (uint posState = 0; posState < m_NumPosStates; posState++) 34 | { 35 | m_LowCoder[posState].Init(); 36 | m_MidCoder[posState].Init(); 37 | } 38 | m_Choice2.Init(); 39 | m_HighCoder.Init(); 40 | } 41 | 42 | public uint Decode(RangeCoder.Decoder rangeDecoder, uint posState) 43 | { 44 | if (m_Choice.Decode(rangeDecoder) == 0) 45 | return m_LowCoder[posState].Decode(rangeDecoder); 46 | else 47 | { 48 | uint symbol = Base.kNumLowLenSymbols; 49 | if (m_Choice2.Decode(rangeDecoder) == 0) 50 | symbol += m_MidCoder[posState].Decode(rangeDecoder); 51 | else 52 | { 53 | symbol += Base.kNumMidLenSymbols; 54 | symbol += m_HighCoder.Decode(rangeDecoder); 55 | } 56 | return symbol; 57 | } 58 | } 59 | } 60 | 61 | class LiteralDecoder 62 | { 63 | struct Decoder2 64 | { 65 | BitDecoder[] m_Decoders; 66 | public void Create() { m_Decoders = new BitDecoder[0x300]; } 67 | public void Init() { for (int i = 0; i < 0x300; i++) m_Decoders[i].Init(); } 68 | 69 | public byte DecodeNormal(RangeCoder.Decoder rangeDecoder) 70 | { 71 | uint symbol = 1; 72 | do 73 | symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder); 74 | while (symbol < 0x100); 75 | return (byte)symbol; 76 | } 77 | 78 | public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, byte matchByte) 79 | { 80 | uint symbol = 1; 81 | do 82 | { 83 | uint matchBit = (uint)(matchByte >> 7) & 1; 84 | matchByte <<= 1; 85 | uint bit = m_Decoders[((1 + matchBit) << 8) + symbol].Decode(rangeDecoder); 86 | symbol = (symbol << 1) | bit; 87 | if (matchBit != bit) 88 | { 89 | while (symbol < 0x100) 90 | symbol = (symbol << 1) | m_Decoders[symbol].Decode(rangeDecoder); 91 | break; 92 | } 93 | } 94 | while (symbol < 0x100); 95 | return (byte)symbol; 96 | } 97 | } 98 | 99 | Decoder2[] m_Coders; 100 | int m_NumPrevBits; 101 | int m_NumPosBits; 102 | uint m_PosMask; 103 | 104 | public void Create(int numPosBits, int numPrevBits) 105 | { 106 | if (m_Coders != null && m_NumPrevBits == numPrevBits && 107 | m_NumPosBits == numPosBits) 108 | return; 109 | m_NumPosBits = numPosBits; 110 | m_PosMask = ((uint)1 << numPosBits) - 1; 111 | m_NumPrevBits = numPrevBits; 112 | uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits); 113 | m_Coders = new Decoder2[numStates]; 114 | for (uint i = 0; i < numStates; i++) 115 | m_Coders[i].Create(); 116 | } 117 | 118 | public void Init() 119 | { 120 | uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits); 121 | for (uint i = 0; i < numStates; i++) 122 | m_Coders[i].Init(); 123 | } 124 | 125 | uint GetState(uint pos, byte prevByte) 126 | { return ((pos & m_PosMask) << m_NumPrevBits) + (uint)(prevByte >> (8 - m_NumPrevBits)); } 127 | 128 | public byte DecodeNormal(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte) 129 | { return m_Coders[GetState(pos, prevByte)].DecodeNormal(rangeDecoder); } 130 | 131 | public byte DecodeWithMatchByte(RangeCoder.Decoder rangeDecoder, uint pos, byte prevByte, byte matchByte) 132 | { return m_Coders[GetState(pos, prevByte)].DecodeWithMatchByte(rangeDecoder, matchByte); } 133 | }; 134 | 135 | LZ.OutWindow m_OutWindow = new LZ.OutWindow(); 136 | RangeCoder.Decoder m_RangeDecoder = new RangeCoder.Decoder(); 137 | 138 | BitDecoder[] m_IsMatchDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax]; 139 | BitDecoder[] m_IsRepDecoders = new BitDecoder[Base.kNumStates]; 140 | BitDecoder[] m_IsRepG0Decoders = new BitDecoder[Base.kNumStates]; 141 | BitDecoder[] m_IsRepG1Decoders = new BitDecoder[Base.kNumStates]; 142 | BitDecoder[] m_IsRepG2Decoders = new BitDecoder[Base.kNumStates]; 143 | BitDecoder[] m_IsRep0LongDecoders = new BitDecoder[Base.kNumStates << Base.kNumPosStatesBitsMax]; 144 | 145 | BitTreeDecoder[] m_PosSlotDecoder = new BitTreeDecoder[Base.kNumLenToPosStates]; 146 | BitDecoder[] m_PosDecoders = new BitDecoder[Base.kNumFullDistances - Base.kEndPosModelIndex]; 147 | 148 | BitTreeDecoder m_PosAlignDecoder = new BitTreeDecoder(Base.kNumAlignBits); 149 | 150 | LenDecoder m_LenDecoder = new LenDecoder(); 151 | LenDecoder m_RepLenDecoder = new LenDecoder(); 152 | 153 | LiteralDecoder m_LiteralDecoder = new LiteralDecoder(); 154 | 155 | uint m_DictionarySize; 156 | uint m_DictionarySizeCheck; 157 | 158 | uint m_PosStateMask; 159 | 160 | public Decoder() 161 | { 162 | m_DictionarySize = 0xFFFFFFFF; 163 | for (int i = 0; i < Base.kNumLenToPosStates; i++) 164 | m_PosSlotDecoder[i] = new BitTreeDecoder(Base.kNumPosSlotBits); 165 | } 166 | 167 | void SetDictionarySize(uint dictionarySize) 168 | { 169 | if (m_DictionarySize != dictionarySize) 170 | { 171 | m_DictionarySize = dictionarySize; 172 | m_DictionarySizeCheck = Math.Max(m_DictionarySize, 1); 173 | uint blockSize = Math.Max(m_DictionarySizeCheck, (1 << 12)); 174 | m_OutWindow.Create(blockSize); 175 | } 176 | } 177 | 178 | void SetLiteralProperties(int lp, int lc) 179 | { 180 | if (lp > 8) 181 | throw new InvalidParamException(); 182 | if (lc > 8) 183 | throw new InvalidParamException(); 184 | m_LiteralDecoder.Create(lp, lc); 185 | } 186 | 187 | void SetPosBitsProperties(int pb) 188 | { 189 | if (pb > Base.kNumPosStatesBitsMax) 190 | throw new InvalidParamException(); 191 | uint numPosStates = (uint)1 << pb; 192 | m_LenDecoder.Create(numPosStates); 193 | m_RepLenDecoder.Create(numPosStates); 194 | m_PosStateMask = numPosStates - 1; 195 | } 196 | 197 | bool _solid = false; 198 | void Init(System.IO.Stream inStream, System.IO.Stream outStream) 199 | { 200 | m_RangeDecoder.Init(inStream); 201 | m_OutWindow.Init(outStream, _solid); 202 | 203 | uint i; 204 | for (i = 0; i < Base.kNumStates; i++) 205 | { 206 | for (uint j = 0; j <= m_PosStateMask; j++) 207 | { 208 | uint index = (i << Base.kNumPosStatesBitsMax) + j; 209 | m_IsMatchDecoders[index].Init(); 210 | m_IsRep0LongDecoders[index].Init(); 211 | } 212 | m_IsRepDecoders[i].Init(); 213 | m_IsRepG0Decoders[i].Init(); 214 | m_IsRepG1Decoders[i].Init(); 215 | m_IsRepG2Decoders[i].Init(); 216 | } 217 | 218 | m_LiteralDecoder.Init(); 219 | for (i = 0; i < Base.kNumLenToPosStates; i++) 220 | m_PosSlotDecoder[i].Init(); 221 | // m_PosSpecDecoder.Init(); 222 | for (i = 0; i < Base.kNumFullDistances - Base.kEndPosModelIndex; i++) 223 | m_PosDecoders[i].Init(); 224 | 225 | m_LenDecoder.Init(); 226 | m_RepLenDecoder.Init(); 227 | m_PosAlignDecoder.Init(); 228 | } 229 | 230 | public void Code(System.IO.Stream inStream, System.IO.Stream outStream, 231 | Int64 inSize, Int64 outSize, ICodeProgress progress) 232 | { 233 | Init(inStream, outStream); 234 | 235 | Base.State state = new Base.State(); 236 | state.Init(); 237 | uint rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0; 238 | 239 | UInt64 nowPos64 = 0; 240 | UInt64 outSize64 = (UInt64)outSize; 241 | if (nowPos64 < outSize64) 242 | { 243 | if (m_IsMatchDecoders[state.Index << Base.kNumPosStatesBitsMax].Decode(m_RangeDecoder) != 0) 244 | throw new DataErrorException(); 245 | state.UpdateChar(); 246 | byte b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, 0, 0); 247 | m_OutWindow.PutByte(b); 248 | nowPos64++; 249 | } 250 | while (nowPos64 < outSize64) 251 | { 252 | // UInt64 next = Math.Min(nowPos64 + (1 << 18), outSize64); 253 | // while(nowPos64 < next) 254 | { 255 | uint posState = (uint)nowPos64 & m_PosStateMask; 256 | if (m_IsMatchDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0) 257 | { 258 | byte b; 259 | byte prevByte = m_OutWindow.GetByte(0); 260 | if (!state.IsCharState()) 261 | b = m_LiteralDecoder.DecodeWithMatchByte(m_RangeDecoder, 262 | (uint)nowPos64, prevByte, m_OutWindow.GetByte(rep0)); 263 | else 264 | b = m_LiteralDecoder.DecodeNormal(m_RangeDecoder, (uint)nowPos64, prevByte); 265 | m_OutWindow.PutByte(b); 266 | state.UpdateChar(); 267 | nowPos64++; 268 | } 269 | else 270 | { 271 | uint len; 272 | if (m_IsRepDecoders[state.Index].Decode(m_RangeDecoder) == 1) 273 | { 274 | if (m_IsRepG0Decoders[state.Index].Decode(m_RangeDecoder) == 0) 275 | { 276 | if (m_IsRep0LongDecoders[(state.Index << Base.kNumPosStatesBitsMax) + posState].Decode(m_RangeDecoder) == 0) 277 | { 278 | state.UpdateShortRep(); 279 | m_OutWindow.PutByte(m_OutWindow.GetByte(rep0)); 280 | nowPos64++; 281 | continue; 282 | } 283 | } 284 | else 285 | { 286 | UInt32 distance; 287 | if (m_IsRepG1Decoders[state.Index].Decode(m_RangeDecoder) == 0) 288 | { 289 | distance = rep1; 290 | } 291 | else 292 | { 293 | if (m_IsRepG2Decoders[state.Index].Decode(m_RangeDecoder) == 0) 294 | distance = rep2; 295 | else 296 | { 297 | distance = rep3; 298 | rep3 = rep2; 299 | } 300 | rep2 = rep1; 301 | } 302 | rep1 = rep0; 303 | rep0 = distance; 304 | } 305 | len = m_RepLenDecoder.Decode(m_RangeDecoder, posState) + Base.kMatchMinLen; 306 | state.UpdateRep(); 307 | } 308 | else 309 | { 310 | rep3 = rep2; 311 | rep2 = rep1; 312 | rep1 = rep0; 313 | len = Base.kMatchMinLen + m_LenDecoder.Decode(m_RangeDecoder, posState); 314 | state.UpdateMatch(); 315 | uint posSlot = m_PosSlotDecoder[Base.GetLenToPosState(len)].Decode(m_RangeDecoder); 316 | if (posSlot >= Base.kStartPosModelIndex) 317 | { 318 | int numDirectBits = (int)((posSlot >> 1) - 1); 319 | rep0 = ((2 | (posSlot & 1)) << numDirectBits); 320 | if (posSlot < Base.kEndPosModelIndex) 321 | rep0 += BitTreeDecoder.ReverseDecode(m_PosDecoders, 322 | rep0 - posSlot - 1, m_RangeDecoder, numDirectBits); 323 | else 324 | { 325 | rep0 += (m_RangeDecoder.DecodeDirectBits( 326 | numDirectBits - Base.kNumAlignBits) << Base.kNumAlignBits); 327 | rep0 += m_PosAlignDecoder.ReverseDecode(m_RangeDecoder); 328 | } 329 | } 330 | else 331 | rep0 = posSlot; 332 | } 333 | if (rep0 >= m_OutWindow.TrainSize + nowPos64 || rep0 >= m_DictionarySizeCheck) 334 | { 335 | if (rep0 == 0xFFFFFFFF) 336 | break; 337 | throw new DataErrorException(); 338 | } 339 | m_OutWindow.CopyBlock(rep0, len); 340 | nowPos64 += len; 341 | } 342 | } 343 | } 344 | m_OutWindow.Flush(); 345 | m_OutWindow.ReleaseStream(); 346 | m_RangeDecoder.ReleaseStream(); 347 | } 348 | 349 | public void SetDecoderProperties(byte[] properties) 350 | { 351 | if (properties.Length < 5) 352 | throw new InvalidParamException(); 353 | int lc = properties[0] % 9; 354 | int remainder = properties[0] / 9; 355 | int lp = remainder % 5; 356 | int pb = remainder / 5; 357 | if (pb > Base.kNumPosStatesBitsMax) 358 | throw new InvalidParamException(); 359 | UInt32 dictionarySize = 0; 360 | for (int i = 0; i < 4; i++) 361 | dictionarySize += ((UInt32)(properties[1 + i])) << (i * 8); 362 | SetDictionarySize(dictionarySize); 363 | SetLiteralProperties(lp, lc); 364 | SetPosBitsProperties(pb); 365 | } 366 | 367 | public bool Train(System.IO.Stream stream) 368 | { 369 | _solid = true; 370 | return m_OutWindow.Train(stream); 371 | } 372 | 373 | /* 374 | public override bool CanRead { get { return true; }} 375 | public override bool CanWrite { get { return true; }} 376 | public override bool CanSeek { get { return true; }} 377 | public override long Length { get { return 0; }} 378 | public override long Position 379 | { 380 | get { return 0; } 381 | set { } 382 | } 383 | public override void Flush() { } 384 | public override int Read(byte[] buffer, int offset, int count) 385 | { 386 | return 0; 387 | } 388 | public override void Write(byte[] buffer, int offset, int count) 389 | { 390 | } 391 | public override long Seek(long offset, System.IO.SeekOrigin origin) 392 | { 393 | return 0; 394 | } 395 | public override void SetLength(long value) {} 396 | */ 397 | } 398 | } 399 | -------------------------------------------------------------------------------- /dumpsc/7zip/Compress/LZMA/LzmaEncoder.cs: -------------------------------------------------------------------------------- 1 | // LzmaEncoder.cs 2 | 3 | using System; 4 | 5 | namespace SevenZip.Compression.LZMA 6 | { 7 | using RangeCoder; 8 | 9 | public class Encoder : ICoder, ISetCoderProperties, IWriteCoderProperties 10 | { 11 | enum EMatchFinderType 12 | { 13 | BT2, 14 | BT4, 15 | }; 16 | 17 | const UInt32 kIfinityPrice = 0xFFFFFFF; 18 | 19 | static Byte[] g_FastPos = new Byte[1 << 11]; 20 | 21 | static Encoder() 22 | { 23 | const Byte kFastSlots = 22; 24 | int c = 2; 25 | g_FastPos[0] = 0; 26 | g_FastPos[1] = 1; 27 | for (Byte slotFast = 2; slotFast < kFastSlots; slotFast++) 28 | { 29 | UInt32 k = ((UInt32)1 << ((slotFast >> 1) - 1)); 30 | for (UInt32 j = 0; j < k; j++, c++) 31 | g_FastPos[c] = slotFast; 32 | } 33 | } 34 | 35 | static UInt32 GetPosSlot(UInt32 pos) 36 | { 37 | if (pos < (1 << 11)) 38 | return g_FastPos[pos]; 39 | if (pos < (1 << 21)) 40 | return (UInt32)(g_FastPos[pos >> 10] + 20); 41 | return (UInt32)(g_FastPos[pos >> 20] + 40); 42 | } 43 | 44 | static UInt32 GetPosSlot2(UInt32 pos) 45 | { 46 | if (pos < (1 << 17)) 47 | return (UInt32)(g_FastPos[pos >> 6] + 12); 48 | if (pos < (1 << 27)) 49 | return (UInt32)(g_FastPos[pos >> 16] + 32); 50 | return (UInt32)(g_FastPos[pos >> 26] + 52); 51 | } 52 | 53 | Base.State _state = new Base.State(); 54 | Byte _previousByte; 55 | UInt32[] _repDistances = new UInt32[Base.kNumRepDistances]; 56 | 57 | void BaseInit() 58 | { 59 | _state.Init(); 60 | _previousByte = 0; 61 | for (UInt32 i = 0; i < Base.kNumRepDistances; i++) 62 | _repDistances[i] = 0; 63 | } 64 | 65 | const int kDefaultDictionaryLogSize = 22; 66 | const UInt32 kNumFastBytesDefault = 0x20; 67 | 68 | class LiteralEncoder 69 | { 70 | public struct Encoder2 71 | { 72 | BitEncoder[] m_Encoders; 73 | 74 | public void Create() { m_Encoders = new BitEncoder[0x300]; } 75 | 76 | public void Init() { for (int i = 0; i < 0x300; i++) m_Encoders[i].Init(); } 77 | 78 | public void Encode(RangeCoder.Encoder rangeEncoder, byte symbol) 79 | { 80 | uint context = 1; 81 | for (int i = 7; i >= 0; i--) 82 | { 83 | uint bit = (uint)((symbol >> i) & 1); 84 | m_Encoders[context].Encode(rangeEncoder, bit); 85 | context = (context << 1) | bit; 86 | } 87 | } 88 | 89 | public void EncodeMatched(RangeCoder.Encoder rangeEncoder, byte matchByte, byte symbol) 90 | { 91 | uint context = 1; 92 | bool same = true; 93 | for (int i = 7; i >= 0; i--) 94 | { 95 | uint bit = (uint)((symbol >> i) & 1); 96 | uint state = context; 97 | if (same) 98 | { 99 | uint matchBit = (uint)((matchByte >> i) & 1); 100 | state += ((1 + matchBit) << 8); 101 | same = (matchBit == bit); 102 | } 103 | m_Encoders[state].Encode(rangeEncoder, bit); 104 | context = (context << 1) | bit; 105 | } 106 | } 107 | 108 | public uint GetPrice(bool matchMode, byte matchByte, byte symbol) 109 | { 110 | uint price = 0; 111 | uint context = 1; 112 | int i = 7; 113 | if (matchMode) 114 | { 115 | for (; i >= 0; i--) 116 | { 117 | uint matchBit = (uint)(matchByte >> i) & 1; 118 | uint bit = (uint)(symbol >> i) & 1; 119 | price += m_Encoders[((1 + matchBit) << 8) + context].GetPrice(bit); 120 | context = (context << 1) | bit; 121 | if (matchBit != bit) 122 | { 123 | i--; 124 | break; 125 | } 126 | } 127 | } 128 | for (; i >= 0; i--) 129 | { 130 | uint bit = (uint)(symbol >> i) & 1; 131 | price += m_Encoders[context].GetPrice(bit); 132 | context = (context << 1) | bit; 133 | } 134 | return price; 135 | } 136 | } 137 | 138 | Encoder2[] m_Coders; 139 | int m_NumPrevBits; 140 | int m_NumPosBits; 141 | uint m_PosMask; 142 | 143 | public void Create(int numPosBits, int numPrevBits) 144 | { 145 | if (m_Coders != null && m_NumPrevBits == numPrevBits && m_NumPosBits == numPosBits) 146 | return; 147 | m_NumPosBits = numPosBits; 148 | m_PosMask = ((uint)1 << numPosBits) - 1; 149 | m_NumPrevBits = numPrevBits; 150 | uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits); 151 | m_Coders = new Encoder2[numStates]; 152 | for (uint i = 0; i < numStates; i++) 153 | m_Coders[i].Create(); 154 | } 155 | 156 | public void Init() 157 | { 158 | uint numStates = (uint)1 << (m_NumPrevBits + m_NumPosBits); 159 | for (uint i = 0; i < numStates; i++) 160 | m_Coders[i].Init(); 161 | } 162 | 163 | public Encoder2 GetSubCoder(UInt32 pos, Byte prevByte) 164 | { return m_Coders[((pos & m_PosMask) << m_NumPrevBits) + (uint)(prevByte >> (8 - m_NumPrevBits))]; } 165 | } 166 | 167 | class LenEncoder 168 | { 169 | RangeCoder.BitEncoder _choice = new RangeCoder.BitEncoder(); 170 | RangeCoder.BitEncoder _choice2 = new RangeCoder.BitEncoder(); 171 | RangeCoder.BitTreeEncoder[] _lowCoder = new RangeCoder.BitTreeEncoder[Base.kNumPosStatesEncodingMax]; 172 | RangeCoder.BitTreeEncoder[] _midCoder = new RangeCoder.BitTreeEncoder[Base.kNumPosStatesEncodingMax]; 173 | RangeCoder.BitTreeEncoder _highCoder = new RangeCoder.BitTreeEncoder(Base.kNumHighLenBits); 174 | 175 | public LenEncoder() 176 | { 177 | for (UInt32 posState = 0; posState < Base.kNumPosStatesEncodingMax; posState++) 178 | { 179 | _lowCoder[posState] = new RangeCoder.BitTreeEncoder(Base.kNumLowLenBits); 180 | _midCoder[posState] = new RangeCoder.BitTreeEncoder(Base.kNumMidLenBits); 181 | } 182 | } 183 | 184 | public void Init(UInt32 numPosStates) 185 | { 186 | _choice.Init(); 187 | _choice2.Init(); 188 | for (UInt32 posState = 0; posState < numPosStates; posState++) 189 | { 190 | _lowCoder[posState].Init(); 191 | _midCoder[posState].Init(); 192 | } 193 | _highCoder.Init(); 194 | } 195 | 196 | public void Encode(RangeCoder.Encoder rangeEncoder, UInt32 symbol, UInt32 posState) 197 | { 198 | if (symbol < Base.kNumLowLenSymbols) 199 | { 200 | _choice.Encode(rangeEncoder, 0); 201 | _lowCoder[posState].Encode(rangeEncoder, symbol); 202 | } 203 | else 204 | { 205 | symbol -= Base.kNumLowLenSymbols; 206 | _choice.Encode(rangeEncoder, 1); 207 | if (symbol < Base.kNumMidLenSymbols) 208 | { 209 | _choice2.Encode(rangeEncoder, 0); 210 | _midCoder[posState].Encode(rangeEncoder, symbol); 211 | } 212 | else 213 | { 214 | _choice2.Encode(rangeEncoder, 1); 215 | _highCoder.Encode(rangeEncoder, symbol - Base.kNumMidLenSymbols); 216 | } 217 | } 218 | } 219 | 220 | public void SetPrices(UInt32 posState, UInt32 numSymbols, UInt32[] prices, UInt32 st) 221 | { 222 | UInt32 a0 = _choice.GetPrice0(); 223 | UInt32 a1 = _choice.GetPrice1(); 224 | UInt32 b0 = a1 + _choice2.GetPrice0(); 225 | UInt32 b1 = a1 + _choice2.GetPrice1(); 226 | UInt32 i = 0; 227 | for (i = 0; i < Base.kNumLowLenSymbols; i++) 228 | { 229 | if (i >= numSymbols) 230 | return; 231 | prices[st + i] = a0 + _lowCoder[posState].GetPrice(i); 232 | } 233 | for (; i < Base.kNumLowLenSymbols + Base.kNumMidLenSymbols; i++) 234 | { 235 | if (i >= numSymbols) 236 | return; 237 | prices[st + i] = b0 + _midCoder[posState].GetPrice(i - Base.kNumLowLenSymbols); 238 | } 239 | for (; i < numSymbols; i++) 240 | prices[st + i] = b1 + _highCoder.GetPrice(i - Base.kNumLowLenSymbols - Base.kNumMidLenSymbols); 241 | } 242 | }; 243 | 244 | const UInt32 kNumLenSpecSymbols = Base.kNumLowLenSymbols + Base.kNumMidLenSymbols; 245 | 246 | class LenPriceTableEncoder : LenEncoder 247 | { 248 | UInt32[] _prices = new UInt32[Base.kNumLenSymbols << Base.kNumPosStatesBitsEncodingMax]; 249 | UInt32 _tableSize; 250 | UInt32[] _counters = new UInt32[Base.kNumPosStatesEncodingMax]; 251 | 252 | public void SetTableSize(UInt32 tableSize) { _tableSize = tableSize; } 253 | 254 | public UInt32 GetPrice(UInt32 symbol, UInt32 posState) 255 | { 256 | return _prices[posState * Base.kNumLenSymbols + symbol]; 257 | } 258 | 259 | void UpdateTable(UInt32 posState) 260 | { 261 | SetPrices(posState, _tableSize, _prices, posState * Base.kNumLenSymbols); 262 | _counters[posState] = _tableSize; 263 | } 264 | 265 | public void UpdateTables(UInt32 numPosStates) 266 | { 267 | for (UInt32 posState = 0; posState < numPosStates; posState++) 268 | UpdateTable(posState); 269 | } 270 | 271 | public new void Encode(RangeCoder.Encoder rangeEncoder, UInt32 symbol, UInt32 posState) 272 | { 273 | base.Encode(rangeEncoder, symbol, posState); 274 | if (--_counters[posState] == 0) 275 | UpdateTable(posState); 276 | } 277 | } 278 | 279 | const UInt32 kNumOpts = 1 << 12; 280 | class Optimal 281 | { 282 | public Base.State State; 283 | 284 | public bool Prev1IsChar; 285 | public bool Prev2; 286 | 287 | public UInt32 PosPrev2; 288 | public UInt32 BackPrev2; 289 | 290 | public UInt32 Price; 291 | public UInt32 PosPrev; 292 | public UInt32 BackPrev; 293 | 294 | public UInt32 Backs0; 295 | public UInt32 Backs1; 296 | public UInt32 Backs2; 297 | public UInt32 Backs3; 298 | 299 | public void MakeAsChar() { BackPrev = 0xFFFFFFFF; Prev1IsChar = false; } 300 | public void MakeAsShortRep() { BackPrev = 0; ; Prev1IsChar = false; } 301 | public bool IsShortRep() { return (BackPrev == 0); } 302 | }; 303 | Optimal[] _optimum = new Optimal[kNumOpts]; 304 | LZ.IMatchFinder _matchFinder = null; 305 | RangeCoder.Encoder _rangeEncoder = new RangeCoder.Encoder(); 306 | 307 | RangeCoder.BitEncoder[] _isMatch = new RangeCoder.BitEncoder[Base.kNumStates << Base.kNumPosStatesBitsMax]; 308 | RangeCoder.BitEncoder[] _isRep = new RangeCoder.BitEncoder[Base.kNumStates]; 309 | RangeCoder.BitEncoder[] _isRepG0 = new RangeCoder.BitEncoder[Base.kNumStates]; 310 | RangeCoder.BitEncoder[] _isRepG1 = new RangeCoder.BitEncoder[Base.kNumStates]; 311 | RangeCoder.BitEncoder[] _isRepG2 = new RangeCoder.BitEncoder[Base.kNumStates]; 312 | RangeCoder.BitEncoder[] _isRep0Long = new RangeCoder.BitEncoder[Base.kNumStates << Base.kNumPosStatesBitsMax]; 313 | 314 | RangeCoder.BitTreeEncoder[] _posSlotEncoder = new RangeCoder.BitTreeEncoder[Base.kNumLenToPosStates]; 315 | 316 | RangeCoder.BitEncoder[] _posEncoders = new RangeCoder.BitEncoder[Base.kNumFullDistances - Base.kEndPosModelIndex]; 317 | RangeCoder.BitTreeEncoder _posAlignEncoder = new RangeCoder.BitTreeEncoder(Base.kNumAlignBits); 318 | 319 | LenPriceTableEncoder _lenEncoder = new LenPriceTableEncoder(); 320 | LenPriceTableEncoder _repMatchLenEncoder = new LenPriceTableEncoder(); 321 | 322 | LiteralEncoder _literalEncoder = new LiteralEncoder(); 323 | 324 | UInt32[] _matchDistances = new UInt32[Base.kMatchMaxLen * 2 + 2]; 325 | 326 | UInt32 _numFastBytes = kNumFastBytesDefault; 327 | UInt32 _longestMatchLength; 328 | UInt32 _numDistancePairs; 329 | 330 | UInt32 _additionalOffset; 331 | 332 | UInt32 _optimumEndIndex; 333 | UInt32 _optimumCurrentIndex; 334 | 335 | bool _longestMatchWasFound; 336 | 337 | UInt32[] _posSlotPrices = new UInt32[1 << (Base.kNumPosSlotBits + Base.kNumLenToPosStatesBits)]; 338 | UInt32[] _distancesPrices = new UInt32[Base.kNumFullDistances << Base.kNumLenToPosStatesBits]; 339 | UInt32[] _alignPrices = new UInt32[Base.kAlignTableSize]; 340 | UInt32 _alignPriceCount; 341 | 342 | UInt32 _distTableSize = (kDefaultDictionaryLogSize * 2); 343 | 344 | int _posStateBits = 2; 345 | UInt32 _posStateMask = (4 - 1); 346 | int _numLiteralPosStateBits = 0; 347 | int _numLiteralContextBits = 3; 348 | 349 | UInt32 _dictionarySize = (1 << kDefaultDictionaryLogSize); 350 | UInt32 _dictionarySizePrev = 0xFFFFFFFF; 351 | UInt32 _numFastBytesPrev = 0xFFFFFFFF; 352 | 353 | Int64 nowPos64; 354 | bool _finished; 355 | System.IO.Stream _inStream; 356 | 357 | EMatchFinderType _matchFinderType = EMatchFinderType.BT4; 358 | bool _writeEndMark = false; 359 | 360 | bool _needReleaseMFStream; 361 | 362 | void Create() 363 | { 364 | if (_matchFinder == null) 365 | { 366 | LZ.BinTree bt = new LZ.BinTree(); 367 | int numHashBytes = 4; 368 | if (_matchFinderType == EMatchFinderType.BT2) 369 | numHashBytes = 2; 370 | bt.SetType(numHashBytes); 371 | _matchFinder = bt; 372 | } 373 | _literalEncoder.Create(_numLiteralPosStateBits, _numLiteralContextBits); 374 | 375 | if (_dictionarySize == _dictionarySizePrev && _numFastBytesPrev == _numFastBytes) 376 | return; 377 | _matchFinder.Create(_dictionarySize, kNumOpts, _numFastBytes, Base.kMatchMaxLen + 1); 378 | _dictionarySizePrev = _dictionarySize; 379 | _numFastBytesPrev = _numFastBytes; 380 | } 381 | 382 | public Encoder() 383 | { 384 | for (int i = 0; i < kNumOpts; i++) 385 | _optimum[i] = new Optimal(); 386 | for (int i = 0; i < Base.kNumLenToPosStates; i++) 387 | _posSlotEncoder[i] = new RangeCoder.BitTreeEncoder(Base.kNumPosSlotBits); 388 | } 389 | 390 | void SetWriteEndMarkerMode(bool writeEndMarker) 391 | { 392 | _writeEndMark = writeEndMarker; 393 | } 394 | 395 | void Init() 396 | { 397 | BaseInit(); 398 | _rangeEncoder.Init(); 399 | 400 | uint i; 401 | for (i = 0; i < Base.kNumStates; i++) 402 | { 403 | for (uint j = 0; j <= _posStateMask; j++) 404 | { 405 | uint complexState = (i << Base.kNumPosStatesBitsMax) + j; 406 | _isMatch[complexState].Init(); 407 | _isRep0Long[complexState].Init(); 408 | } 409 | _isRep[i].Init(); 410 | _isRepG0[i].Init(); 411 | _isRepG1[i].Init(); 412 | _isRepG2[i].Init(); 413 | } 414 | _literalEncoder.Init(); 415 | for (i = 0; i < Base.kNumLenToPosStates; i++) 416 | _posSlotEncoder[i].Init(); 417 | for (i = 0; i < Base.kNumFullDistances - Base.kEndPosModelIndex; i++) 418 | _posEncoders[i].Init(); 419 | 420 | _lenEncoder.Init((UInt32)1 << _posStateBits); 421 | _repMatchLenEncoder.Init((UInt32)1 << _posStateBits); 422 | 423 | _posAlignEncoder.Init(); 424 | 425 | _longestMatchWasFound = false; 426 | _optimumEndIndex = 0; 427 | _optimumCurrentIndex = 0; 428 | _additionalOffset = 0; 429 | } 430 | 431 | void ReadMatchDistances(out UInt32 lenRes, out UInt32 numDistancePairs) 432 | { 433 | lenRes = 0; 434 | numDistancePairs = _matchFinder.GetMatches(_matchDistances); 435 | if (numDistancePairs > 0) 436 | { 437 | lenRes = _matchDistances[numDistancePairs - 2]; 438 | if (lenRes == _numFastBytes) 439 | lenRes += _matchFinder.GetMatchLen((int)lenRes - 1, _matchDistances[numDistancePairs - 1], 440 | Base.kMatchMaxLen - lenRes); 441 | } 442 | _additionalOffset++; 443 | } 444 | 445 | 446 | void MovePos(UInt32 num) 447 | { 448 | if (num > 0) 449 | { 450 | _matchFinder.Skip(num); 451 | _additionalOffset += num; 452 | } 453 | } 454 | 455 | UInt32 GetRepLen1Price(Base.State state, UInt32 posState) 456 | { 457 | return _isRepG0[state.Index].GetPrice0() + 458 | _isRep0Long[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice0(); 459 | } 460 | 461 | UInt32 GetPureRepPrice(UInt32 repIndex, Base.State state, UInt32 posState) 462 | { 463 | UInt32 price; 464 | if (repIndex == 0) 465 | { 466 | price = _isRepG0[state.Index].GetPrice0(); 467 | price += _isRep0Long[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice1(); 468 | } 469 | else 470 | { 471 | price = _isRepG0[state.Index].GetPrice1(); 472 | if (repIndex == 1) 473 | price += _isRepG1[state.Index].GetPrice0(); 474 | else 475 | { 476 | price += _isRepG1[state.Index].GetPrice1(); 477 | price += _isRepG2[state.Index].GetPrice(repIndex - 2); 478 | } 479 | } 480 | return price; 481 | } 482 | 483 | UInt32 GetRepPrice(UInt32 repIndex, UInt32 len, Base.State state, UInt32 posState) 484 | { 485 | UInt32 price = _repMatchLenEncoder.GetPrice(len - Base.kMatchMinLen, posState); 486 | return price + GetPureRepPrice(repIndex, state, posState); 487 | } 488 | 489 | UInt32 GetPosLenPrice(UInt32 pos, UInt32 len, UInt32 posState) 490 | { 491 | UInt32 price; 492 | UInt32 lenToPosState = Base.GetLenToPosState(len); 493 | if (pos < Base.kNumFullDistances) 494 | price = _distancesPrices[(lenToPosState * Base.kNumFullDistances) + pos]; 495 | else 496 | price = _posSlotPrices[(lenToPosState << Base.kNumPosSlotBits) + GetPosSlot2(pos)] + 497 | _alignPrices[pos & Base.kAlignMask]; 498 | return price + _lenEncoder.GetPrice(len - Base.kMatchMinLen, posState); 499 | } 500 | 501 | UInt32 Backward(out UInt32 backRes, UInt32 cur) 502 | { 503 | _optimumEndIndex = cur; 504 | UInt32 posMem = _optimum[cur].PosPrev; 505 | UInt32 backMem = _optimum[cur].BackPrev; 506 | do 507 | { 508 | if (_optimum[cur].Prev1IsChar) 509 | { 510 | _optimum[posMem].MakeAsChar(); 511 | _optimum[posMem].PosPrev = posMem - 1; 512 | if (_optimum[cur].Prev2) 513 | { 514 | _optimum[posMem - 1].Prev1IsChar = false; 515 | _optimum[posMem - 1].PosPrev = _optimum[cur].PosPrev2; 516 | _optimum[posMem - 1].BackPrev = _optimum[cur].BackPrev2; 517 | } 518 | } 519 | UInt32 posPrev = posMem; 520 | UInt32 backCur = backMem; 521 | 522 | backMem = _optimum[posPrev].BackPrev; 523 | posMem = _optimum[posPrev].PosPrev; 524 | 525 | _optimum[posPrev].BackPrev = backCur; 526 | _optimum[posPrev].PosPrev = cur; 527 | cur = posPrev; 528 | } 529 | while (cur > 0); 530 | backRes = _optimum[0].BackPrev; 531 | _optimumCurrentIndex = _optimum[0].PosPrev; 532 | return _optimumCurrentIndex; 533 | } 534 | 535 | UInt32[] reps = new UInt32[Base.kNumRepDistances]; 536 | UInt32[] repLens = new UInt32[Base.kNumRepDistances]; 537 | 538 | 539 | UInt32 GetOptimum(UInt32 position, out UInt32 backRes) 540 | { 541 | if (_optimumEndIndex != _optimumCurrentIndex) 542 | { 543 | UInt32 lenRes = _optimum[_optimumCurrentIndex].PosPrev - _optimumCurrentIndex; 544 | backRes = _optimum[_optimumCurrentIndex].BackPrev; 545 | _optimumCurrentIndex = _optimum[_optimumCurrentIndex].PosPrev; 546 | return lenRes; 547 | } 548 | _optimumCurrentIndex = _optimumEndIndex = 0; 549 | 550 | UInt32 lenMain, numDistancePairs; 551 | if (!_longestMatchWasFound) 552 | { 553 | ReadMatchDistances(out lenMain, out numDistancePairs); 554 | } 555 | else 556 | { 557 | lenMain = _longestMatchLength; 558 | numDistancePairs = _numDistancePairs; 559 | _longestMatchWasFound = false; 560 | } 561 | 562 | UInt32 numAvailableBytes = _matchFinder.GetNumAvailableBytes() + 1; 563 | if (numAvailableBytes < 2) 564 | { 565 | backRes = 0xFFFFFFFF; 566 | return 1; 567 | } 568 | if (numAvailableBytes > Base.kMatchMaxLen) 569 | numAvailableBytes = Base.kMatchMaxLen; 570 | 571 | UInt32 repMaxIndex = 0; 572 | UInt32 i; 573 | for (i = 0; i < Base.kNumRepDistances; i++) 574 | { 575 | reps[i] = _repDistances[i]; 576 | repLens[i] = _matchFinder.GetMatchLen(0 - 1, reps[i], Base.kMatchMaxLen); 577 | if (repLens[i] > repLens[repMaxIndex]) 578 | repMaxIndex = i; 579 | } 580 | if (repLens[repMaxIndex] >= _numFastBytes) 581 | { 582 | backRes = repMaxIndex; 583 | UInt32 lenRes = repLens[repMaxIndex]; 584 | MovePos(lenRes - 1); 585 | return lenRes; 586 | } 587 | 588 | if (lenMain >= _numFastBytes) 589 | { 590 | backRes = _matchDistances[numDistancePairs - 1] + Base.kNumRepDistances; 591 | MovePos(lenMain - 1); 592 | return lenMain; 593 | } 594 | 595 | Byte currentByte = _matchFinder.GetIndexByte(0 - 1); 596 | Byte matchByte = _matchFinder.GetIndexByte((Int32)(0 - _repDistances[0] - 1 - 1)); 597 | 598 | if (lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2) 599 | { 600 | backRes = (UInt32)0xFFFFFFFF; 601 | return 1; 602 | } 603 | 604 | _optimum[0].State = _state; 605 | 606 | UInt32 posState = (position & _posStateMask); 607 | 608 | _optimum[1].Price = _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice0() + 609 | _literalEncoder.GetSubCoder(position, _previousByte).GetPrice(!_state.IsCharState(), matchByte, currentByte); 610 | _optimum[1].MakeAsChar(); 611 | 612 | UInt32 matchPrice = _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice1(); 613 | UInt32 repMatchPrice = matchPrice + _isRep[_state.Index].GetPrice1(); 614 | 615 | if (matchByte == currentByte) 616 | { 617 | UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(_state, posState); 618 | if (shortRepPrice < _optimum[1].Price) 619 | { 620 | _optimum[1].Price = shortRepPrice; 621 | _optimum[1].MakeAsShortRep(); 622 | } 623 | } 624 | 625 | UInt32 lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]); 626 | 627 | if(lenEnd < 2) 628 | { 629 | backRes = _optimum[1].BackPrev; 630 | return 1; 631 | } 632 | 633 | _optimum[1].PosPrev = 0; 634 | 635 | _optimum[0].Backs0 = reps[0]; 636 | _optimum[0].Backs1 = reps[1]; 637 | _optimum[0].Backs2 = reps[2]; 638 | _optimum[0].Backs3 = reps[3]; 639 | 640 | UInt32 len = lenEnd; 641 | do 642 | _optimum[len--].Price = kIfinityPrice; 643 | while (len >= 2); 644 | 645 | for (i = 0; i < Base.kNumRepDistances; i++) 646 | { 647 | UInt32 repLen = repLens[i]; 648 | if (repLen < 2) 649 | continue; 650 | UInt32 price = repMatchPrice + GetPureRepPrice(i, _state, posState); 651 | do 652 | { 653 | UInt32 curAndLenPrice = price + _repMatchLenEncoder.GetPrice(repLen - 2, posState); 654 | Optimal optimum = _optimum[repLen]; 655 | if (curAndLenPrice < optimum.Price) 656 | { 657 | optimum.Price = curAndLenPrice; 658 | optimum.PosPrev = 0; 659 | optimum.BackPrev = i; 660 | optimum.Prev1IsChar = false; 661 | } 662 | } 663 | while (--repLen >= 2); 664 | } 665 | 666 | UInt32 normalMatchPrice = matchPrice + _isRep[_state.Index].GetPrice0(); 667 | 668 | len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); 669 | if (len <= lenMain) 670 | { 671 | UInt32 offs = 0; 672 | while (len > _matchDistances[offs]) 673 | offs += 2; 674 | for (; ; len++) 675 | { 676 | UInt32 distance = _matchDistances[offs + 1]; 677 | UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(distance, len, posState); 678 | Optimal optimum = _optimum[len]; 679 | if (curAndLenPrice < optimum.Price) 680 | { 681 | optimum.Price = curAndLenPrice; 682 | optimum.PosPrev = 0; 683 | optimum.BackPrev = distance + Base.kNumRepDistances; 684 | optimum.Prev1IsChar = false; 685 | } 686 | if (len == _matchDistances[offs]) 687 | { 688 | offs += 2; 689 | if (offs == numDistancePairs) 690 | break; 691 | } 692 | } 693 | } 694 | 695 | UInt32 cur = 0; 696 | 697 | while (true) 698 | { 699 | cur++; 700 | if (cur == lenEnd) 701 | return Backward(out backRes, cur); 702 | UInt32 newLen; 703 | ReadMatchDistances(out newLen, out numDistancePairs); 704 | if (newLen >= _numFastBytes) 705 | { 706 | _numDistancePairs = numDistancePairs; 707 | _longestMatchLength = newLen; 708 | _longestMatchWasFound = true; 709 | return Backward(out backRes, cur); 710 | } 711 | position++; 712 | UInt32 posPrev = _optimum[cur].PosPrev; 713 | Base.State state; 714 | if (_optimum[cur].Prev1IsChar) 715 | { 716 | posPrev--; 717 | if (_optimum[cur].Prev2) 718 | { 719 | state = _optimum[_optimum[cur].PosPrev2].State; 720 | if (_optimum[cur].BackPrev2 < Base.kNumRepDistances) 721 | state.UpdateRep(); 722 | else 723 | state.UpdateMatch(); 724 | } 725 | else 726 | state = _optimum[posPrev].State; 727 | state.UpdateChar(); 728 | } 729 | else 730 | state = _optimum[posPrev].State; 731 | if (posPrev == cur - 1) 732 | { 733 | if (_optimum[cur].IsShortRep()) 734 | state.UpdateShortRep(); 735 | else 736 | state.UpdateChar(); 737 | } 738 | else 739 | { 740 | UInt32 pos; 741 | if (_optimum[cur].Prev1IsChar && _optimum[cur].Prev2) 742 | { 743 | posPrev = _optimum[cur].PosPrev2; 744 | pos = _optimum[cur].BackPrev2; 745 | state.UpdateRep(); 746 | } 747 | else 748 | { 749 | pos = _optimum[cur].BackPrev; 750 | if (pos < Base.kNumRepDistances) 751 | state.UpdateRep(); 752 | else 753 | state.UpdateMatch(); 754 | } 755 | Optimal opt = _optimum[posPrev]; 756 | if (pos < Base.kNumRepDistances) 757 | { 758 | if (pos == 0) 759 | { 760 | reps[0] = opt.Backs0; 761 | reps[1] = opt.Backs1; 762 | reps[2] = opt.Backs2; 763 | reps[3] = opt.Backs3; 764 | } 765 | else if (pos == 1) 766 | { 767 | reps[0] = opt.Backs1; 768 | reps[1] = opt.Backs0; 769 | reps[2] = opt.Backs2; 770 | reps[3] = opt.Backs3; 771 | } 772 | else if (pos == 2) 773 | { 774 | reps[0] = opt.Backs2; 775 | reps[1] = opt.Backs0; 776 | reps[2] = opt.Backs1; 777 | reps[3] = opt.Backs3; 778 | } 779 | else 780 | { 781 | reps[0] = opt.Backs3; 782 | reps[1] = opt.Backs0; 783 | reps[2] = opt.Backs1; 784 | reps[3] = opt.Backs2; 785 | } 786 | } 787 | else 788 | { 789 | reps[0] = (pos - Base.kNumRepDistances); 790 | reps[1] = opt.Backs0; 791 | reps[2] = opt.Backs1; 792 | reps[3] = opt.Backs2; 793 | } 794 | } 795 | _optimum[cur].State = state; 796 | _optimum[cur].Backs0 = reps[0]; 797 | _optimum[cur].Backs1 = reps[1]; 798 | _optimum[cur].Backs2 = reps[2]; 799 | _optimum[cur].Backs3 = reps[3]; 800 | UInt32 curPrice = _optimum[cur].Price; 801 | 802 | currentByte = _matchFinder.GetIndexByte(0 - 1); 803 | matchByte = _matchFinder.GetIndexByte((Int32)(0 - reps[0] - 1 - 1)); 804 | 805 | posState = (position & _posStateMask); 806 | 807 | UInt32 curAnd1Price = curPrice + 808 | _isMatch[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice0() + 809 | _literalEncoder.GetSubCoder(position, _matchFinder.GetIndexByte(0 - 2)). 810 | GetPrice(!state.IsCharState(), matchByte, currentByte); 811 | 812 | Optimal nextOptimum = _optimum[cur + 1]; 813 | 814 | bool nextIsChar = false; 815 | if (curAnd1Price < nextOptimum.Price) 816 | { 817 | nextOptimum.Price = curAnd1Price; 818 | nextOptimum.PosPrev = cur; 819 | nextOptimum.MakeAsChar(); 820 | nextIsChar = true; 821 | } 822 | 823 | matchPrice = curPrice + _isMatch[(state.Index << Base.kNumPosStatesBitsMax) + posState].GetPrice1(); 824 | repMatchPrice = matchPrice + _isRep[state.Index].GetPrice1(); 825 | 826 | if (matchByte == currentByte && 827 | !(nextOptimum.PosPrev < cur && nextOptimum.BackPrev == 0)) 828 | { 829 | UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(state, posState); 830 | if (shortRepPrice <= nextOptimum.Price) 831 | { 832 | nextOptimum.Price = shortRepPrice; 833 | nextOptimum.PosPrev = cur; 834 | nextOptimum.MakeAsShortRep(); 835 | nextIsChar = true; 836 | } 837 | } 838 | 839 | UInt32 numAvailableBytesFull = _matchFinder.GetNumAvailableBytes() + 1; 840 | numAvailableBytesFull = Math.Min(kNumOpts - 1 - cur, numAvailableBytesFull); 841 | numAvailableBytes = numAvailableBytesFull; 842 | 843 | if (numAvailableBytes < 2) 844 | continue; 845 | if (numAvailableBytes > _numFastBytes) 846 | numAvailableBytes = _numFastBytes; 847 | if (!nextIsChar && matchByte != currentByte) 848 | { 849 | // try Literal + rep0 850 | UInt32 t = Math.Min(numAvailableBytesFull - 1, _numFastBytes); 851 | UInt32 lenTest2 = _matchFinder.GetMatchLen(0, reps[0], t); 852 | if (lenTest2 >= 2) 853 | { 854 | Base.State state2 = state; 855 | state2.UpdateChar(); 856 | UInt32 posStateNext = (position + 1) & _posStateMask; 857 | UInt32 nextRepMatchPrice = curAnd1Price + 858 | _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice1() + 859 | _isRep[state2.Index].GetPrice1(); 860 | { 861 | UInt32 offset = cur + 1 + lenTest2; 862 | while (lenEnd < offset) 863 | _optimum[++lenEnd].Price = kIfinityPrice; 864 | UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice( 865 | 0, lenTest2, state2, posStateNext); 866 | Optimal optimum = _optimum[offset]; 867 | if (curAndLenPrice < optimum.Price) 868 | { 869 | optimum.Price = curAndLenPrice; 870 | optimum.PosPrev = cur + 1; 871 | optimum.BackPrev = 0; 872 | optimum.Prev1IsChar = true; 873 | optimum.Prev2 = false; 874 | } 875 | } 876 | } 877 | } 878 | 879 | UInt32 startLen = 2; // speed optimization 880 | 881 | for (UInt32 repIndex = 0; repIndex < Base.kNumRepDistances; repIndex++) 882 | { 883 | UInt32 lenTest = _matchFinder.GetMatchLen(0 - 1, reps[repIndex], numAvailableBytes); 884 | if (lenTest < 2) 885 | continue; 886 | UInt32 lenTestTemp = lenTest; 887 | do 888 | { 889 | while (lenEnd < cur + lenTest) 890 | _optimum[++lenEnd].Price = kIfinityPrice; 891 | UInt32 curAndLenPrice = repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState); 892 | Optimal optimum = _optimum[cur + lenTest]; 893 | if (curAndLenPrice < optimum.Price) 894 | { 895 | optimum.Price = curAndLenPrice; 896 | optimum.PosPrev = cur; 897 | optimum.BackPrev = repIndex; 898 | optimum.Prev1IsChar = false; 899 | } 900 | } 901 | while(--lenTest >= 2); 902 | lenTest = lenTestTemp; 903 | 904 | if (repIndex == 0) 905 | startLen = lenTest + 1; 906 | 907 | // if (_maxMode) 908 | if (lenTest < numAvailableBytesFull) 909 | { 910 | UInt32 t = Math.Min(numAvailableBytesFull - 1 - lenTest, _numFastBytes); 911 | UInt32 lenTest2 = _matchFinder.GetMatchLen((Int32)lenTest, reps[repIndex], t); 912 | if (lenTest2 >= 2) 913 | { 914 | Base.State state2 = state; 915 | state2.UpdateRep(); 916 | UInt32 posStateNext = (position + lenTest) & _posStateMask; 917 | UInt32 curAndLenCharPrice = 918 | repMatchPrice + GetRepPrice(repIndex, lenTest, state, posState) + 919 | _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice0() + 920 | _literalEncoder.GetSubCoder(position + lenTest, 921 | _matchFinder.GetIndexByte((Int32)lenTest - 1 - 1)).GetPrice(true, 922 | _matchFinder.GetIndexByte((Int32)((Int32)lenTest - 1 - (Int32)(reps[repIndex] + 1))), 923 | _matchFinder.GetIndexByte((Int32)lenTest - 1)); 924 | state2.UpdateChar(); 925 | posStateNext = (position + lenTest + 1) & _posStateMask; 926 | UInt32 nextMatchPrice = curAndLenCharPrice + _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice1(); 927 | UInt32 nextRepMatchPrice = nextMatchPrice + _isRep[state2.Index].GetPrice1(); 928 | 929 | // for(; lenTest2 >= 2; lenTest2--) 930 | { 931 | UInt32 offset = lenTest + 1 + lenTest2; 932 | while(lenEnd < cur + offset) 933 | _optimum[++lenEnd].Price = kIfinityPrice; 934 | UInt32 curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext); 935 | Optimal optimum = _optimum[cur + offset]; 936 | if (curAndLenPrice < optimum.Price) 937 | { 938 | optimum.Price = curAndLenPrice; 939 | optimum.PosPrev = cur + lenTest + 1; 940 | optimum.BackPrev = 0; 941 | optimum.Prev1IsChar = true; 942 | optimum.Prev2 = true; 943 | optimum.PosPrev2 = cur; 944 | optimum.BackPrev2 = repIndex; 945 | } 946 | } 947 | } 948 | } 949 | } 950 | 951 | if (newLen > numAvailableBytes) 952 | { 953 | newLen = numAvailableBytes; 954 | for (numDistancePairs = 0; newLen > _matchDistances[numDistancePairs]; numDistancePairs += 2) ; 955 | _matchDistances[numDistancePairs] = newLen; 956 | numDistancePairs += 2; 957 | } 958 | if (newLen >= startLen) 959 | { 960 | normalMatchPrice = matchPrice + _isRep[state.Index].GetPrice0(); 961 | while (lenEnd < cur + newLen) 962 | _optimum[++lenEnd].Price = kIfinityPrice; 963 | 964 | UInt32 offs = 0; 965 | while (startLen > _matchDistances[offs]) 966 | offs += 2; 967 | 968 | for (UInt32 lenTest = startLen; ; lenTest++) 969 | { 970 | UInt32 curBack = _matchDistances[offs + 1]; 971 | UInt32 curAndLenPrice = normalMatchPrice + GetPosLenPrice(curBack, lenTest, posState); 972 | Optimal optimum = _optimum[cur + lenTest]; 973 | if (curAndLenPrice < optimum.Price) 974 | { 975 | optimum.Price = curAndLenPrice; 976 | optimum.PosPrev = cur; 977 | optimum.BackPrev = curBack + Base.kNumRepDistances; 978 | optimum.Prev1IsChar = false; 979 | } 980 | 981 | if (lenTest == _matchDistances[offs]) 982 | { 983 | if (lenTest < numAvailableBytesFull) 984 | { 985 | UInt32 t = Math.Min(numAvailableBytesFull - 1 - lenTest, _numFastBytes); 986 | UInt32 lenTest2 = _matchFinder.GetMatchLen((Int32)lenTest, curBack, t); 987 | if (lenTest2 >= 2) 988 | { 989 | Base.State state2 = state; 990 | state2.UpdateMatch(); 991 | UInt32 posStateNext = (position + lenTest) & _posStateMask; 992 | UInt32 curAndLenCharPrice = curAndLenPrice + 993 | _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice0() + 994 | _literalEncoder.GetSubCoder(position + lenTest, 995 | _matchFinder.GetIndexByte((Int32)lenTest - 1 - 1)). 996 | GetPrice(true, 997 | _matchFinder.GetIndexByte((Int32)lenTest - (Int32)(curBack + 1) - 1), 998 | _matchFinder.GetIndexByte((Int32)lenTest - 1)); 999 | state2.UpdateChar(); 1000 | posStateNext = (position + lenTest + 1) & _posStateMask; 1001 | UInt32 nextMatchPrice = curAndLenCharPrice + _isMatch[(state2.Index << Base.kNumPosStatesBitsMax) + posStateNext].GetPrice1(); 1002 | UInt32 nextRepMatchPrice = nextMatchPrice + _isRep[state2.Index].GetPrice1(); 1003 | 1004 | UInt32 offset = lenTest + 1 + lenTest2; 1005 | while (lenEnd < cur + offset) 1006 | _optimum[++lenEnd].Price = kIfinityPrice; 1007 | curAndLenPrice = nextRepMatchPrice + GetRepPrice(0, lenTest2, state2, posStateNext); 1008 | optimum = _optimum[cur + offset]; 1009 | if (curAndLenPrice < optimum.Price) 1010 | { 1011 | optimum.Price = curAndLenPrice; 1012 | optimum.PosPrev = cur + lenTest + 1; 1013 | optimum.BackPrev = 0; 1014 | optimum.Prev1IsChar = true; 1015 | optimum.Prev2 = true; 1016 | optimum.PosPrev2 = cur; 1017 | optimum.BackPrev2 = curBack + Base.kNumRepDistances; 1018 | } 1019 | } 1020 | } 1021 | offs += 2; 1022 | if (offs == numDistancePairs) 1023 | break; 1024 | } 1025 | } 1026 | } 1027 | } 1028 | } 1029 | 1030 | bool ChangePair(UInt32 smallDist, UInt32 bigDist) 1031 | { 1032 | const int kDif = 7; 1033 | return (smallDist < ((UInt32)(1) << (32 - kDif)) && bigDist >= (smallDist << kDif)); 1034 | } 1035 | 1036 | void WriteEndMarker(UInt32 posState) 1037 | { 1038 | if (!_writeEndMark) 1039 | return; 1040 | 1041 | _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].Encode(_rangeEncoder, 1); 1042 | _isRep[_state.Index].Encode(_rangeEncoder, 0); 1043 | _state.UpdateMatch(); 1044 | UInt32 len = Base.kMatchMinLen; 1045 | _lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState); 1046 | UInt32 posSlot = (1 << Base.kNumPosSlotBits) - 1; 1047 | UInt32 lenToPosState = Base.GetLenToPosState(len); 1048 | _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot); 1049 | int footerBits = 30; 1050 | UInt32 posReduced = (((UInt32)1) << footerBits) - 1; 1051 | _rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits); 1052 | _posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask); 1053 | } 1054 | 1055 | void Flush(UInt32 nowPos) 1056 | { 1057 | ReleaseMFStream(); 1058 | WriteEndMarker(nowPos & _posStateMask); 1059 | _rangeEncoder.FlushData(); 1060 | _rangeEncoder.FlushStream(); 1061 | } 1062 | 1063 | public void CodeOneBlock(out Int64 inSize, out Int64 outSize, out bool finished) 1064 | { 1065 | inSize = 0; 1066 | outSize = 0; 1067 | finished = true; 1068 | 1069 | if (_inStream != null) 1070 | { 1071 | _matchFinder.SetStream(_inStream); 1072 | _matchFinder.Init(); 1073 | _needReleaseMFStream = true; 1074 | _inStream = null; 1075 | if (_trainSize > 0) 1076 | _matchFinder.Skip(_trainSize); 1077 | } 1078 | 1079 | if (_finished) 1080 | return; 1081 | _finished = true; 1082 | 1083 | 1084 | Int64 progressPosValuePrev = nowPos64; 1085 | if (nowPos64 == 0) 1086 | { 1087 | if (_matchFinder.GetNumAvailableBytes() == 0) 1088 | { 1089 | Flush((UInt32)nowPos64); 1090 | return; 1091 | } 1092 | UInt32 len, numDistancePairs; // it's not used 1093 | ReadMatchDistances(out len, out numDistancePairs); 1094 | UInt32 posState = (UInt32)(nowPos64) & _posStateMask; 1095 | _isMatch[(_state.Index << Base.kNumPosStatesBitsMax) + posState].Encode(_rangeEncoder, 0); 1096 | _state.UpdateChar(); 1097 | Byte curByte = _matchFinder.GetIndexByte((Int32)(0 - _additionalOffset)); 1098 | _literalEncoder.GetSubCoder((UInt32)(nowPos64), _previousByte).Encode(_rangeEncoder, curByte); 1099 | _previousByte = curByte; 1100 | _additionalOffset--; 1101 | nowPos64++; 1102 | } 1103 | if (_matchFinder.GetNumAvailableBytes() == 0) 1104 | { 1105 | Flush((UInt32)nowPos64); 1106 | return; 1107 | } 1108 | while (true) 1109 | { 1110 | UInt32 pos; 1111 | UInt32 len = GetOptimum((UInt32)nowPos64, out pos); 1112 | 1113 | UInt32 posState = ((UInt32)nowPos64) & _posStateMask; 1114 | UInt32 complexState = (_state.Index << Base.kNumPosStatesBitsMax) + posState; 1115 | if (len == 1 && pos == 0xFFFFFFFF) 1116 | { 1117 | _isMatch[complexState].Encode(_rangeEncoder, 0); 1118 | Byte curByte = _matchFinder.GetIndexByte((Int32)(0 - _additionalOffset)); 1119 | LiteralEncoder.Encoder2 subCoder = _literalEncoder.GetSubCoder((UInt32)nowPos64, _previousByte); 1120 | if (!_state.IsCharState()) 1121 | { 1122 | Byte matchByte = _matchFinder.GetIndexByte((Int32)(0 - _repDistances[0] - 1 - _additionalOffset)); 1123 | subCoder.EncodeMatched(_rangeEncoder, matchByte, curByte); 1124 | } 1125 | else 1126 | subCoder.Encode(_rangeEncoder, curByte); 1127 | _previousByte = curByte; 1128 | _state.UpdateChar(); 1129 | } 1130 | else 1131 | { 1132 | _isMatch[complexState].Encode(_rangeEncoder, 1); 1133 | if (pos < Base.kNumRepDistances) 1134 | { 1135 | _isRep[_state.Index].Encode(_rangeEncoder, 1); 1136 | if (pos == 0) 1137 | { 1138 | _isRepG0[_state.Index].Encode(_rangeEncoder, 0); 1139 | if (len == 1) 1140 | _isRep0Long[complexState].Encode(_rangeEncoder, 0); 1141 | else 1142 | _isRep0Long[complexState].Encode(_rangeEncoder, 1); 1143 | } 1144 | else 1145 | { 1146 | _isRepG0[_state.Index].Encode(_rangeEncoder, 1); 1147 | if (pos == 1) 1148 | _isRepG1[_state.Index].Encode(_rangeEncoder, 0); 1149 | else 1150 | { 1151 | _isRepG1[_state.Index].Encode(_rangeEncoder, 1); 1152 | _isRepG2[_state.Index].Encode(_rangeEncoder, pos - 2); 1153 | } 1154 | } 1155 | if (len == 1) 1156 | _state.UpdateShortRep(); 1157 | else 1158 | { 1159 | _repMatchLenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState); 1160 | _state.UpdateRep(); 1161 | } 1162 | UInt32 distance = _repDistances[pos]; 1163 | if (pos != 0) 1164 | { 1165 | for (UInt32 i = pos; i >= 1; i--) 1166 | _repDistances[i] = _repDistances[i - 1]; 1167 | _repDistances[0] = distance; 1168 | } 1169 | } 1170 | else 1171 | { 1172 | _isRep[_state.Index].Encode(_rangeEncoder, 0); 1173 | _state.UpdateMatch(); 1174 | _lenEncoder.Encode(_rangeEncoder, len - Base.kMatchMinLen, posState); 1175 | pos -= Base.kNumRepDistances; 1176 | UInt32 posSlot = GetPosSlot(pos); 1177 | UInt32 lenToPosState = Base.GetLenToPosState(len); 1178 | _posSlotEncoder[lenToPosState].Encode(_rangeEncoder, posSlot); 1179 | 1180 | if (posSlot >= Base.kStartPosModelIndex) 1181 | { 1182 | int footerBits = (int)((posSlot >> 1) - 1); 1183 | UInt32 baseVal = ((2 | (posSlot & 1)) << footerBits); 1184 | UInt32 posReduced = pos - baseVal; 1185 | 1186 | if (posSlot < Base.kEndPosModelIndex) 1187 | RangeCoder.BitTreeEncoder.ReverseEncode(_posEncoders, 1188 | baseVal - posSlot - 1, _rangeEncoder, footerBits, posReduced); 1189 | else 1190 | { 1191 | _rangeEncoder.EncodeDirectBits(posReduced >> Base.kNumAlignBits, footerBits - Base.kNumAlignBits); 1192 | _posAlignEncoder.ReverseEncode(_rangeEncoder, posReduced & Base.kAlignMask); 1193 | _alignPriceCount++; 1194 | } 1195 | } 1196 | UInt32 distance = pos; 1197 | for (UInt32 i = Base.kNumRepDistances - 1; i >= 1; i--) 1198 | _repDistances[i] = _repDistances[i - 1]; 1199 | _repDistances[0] = distance; 1200 | _matchPriceCount++; 1201 | } 1202 | _previousByte = _matchFinder.GetIndexByte((Int32)(len - 1 - _additionalOffset)); 1203 | } 1204 | _additionalOffset -= len; 1205 | nowPos64 += len; 1206 | if (_additionalOffset == 0) 1207 | { 1208 | // if (!_fastMode) 1209 | if (_matchPriceCount >= (1 << 7)) 1210 | FillDistancesPrices(); 1211 | if (_alignPriceCount >= Base.kAlignTableSize) 1212 | FillAlignPrices(); 1213 | inSize = nowPos64; 1214 | outSize = _rangeEncoder.GetProcessedSizeAdd(); 1215 | if (_matchFinder.GetNumAvailableBytes() == 0) 1216 | { 1217 | Flush((UInt32)nowPos64); 1218 | return; 1219 | } 1220 | 1221 | if (nowPos64 - progressPosValuePrev >= (1 << 12)) 1222 | { 1223 | _finished = false; 1224 | finished = false; 1225 | return; 1226 | } 1227 | } 1228 | } 1229 | } 1230 | 1231 | void ReleaseMFStream() 1232 | { 1233 | if (_matchFinder != null && _needReleaseMFStream) 1234 | { 1235 | _matchFinder.ReleaseStream(); 1236 | _needReleaseMFStream = false; 1237 | } 1238 | } 1239 | 1240 | void SetOutStream(System.IO.Stream outStream) { _rangeEncoder.SetStream(outStream); } 1241 | void ReleaseOutStream() { _rangeEncoder.ReleaseStream(); } 1242 | 1243 | void ReleaseStreams() 1244 | { 1245 | ReleaseMFStream(); 1246 | ReleaseOutStream(); 1247 | } 1248 | 1249 | void SetStreams(System.IO.Stream inStream, System.IO.Stream outStream, 1250 | Int64 inSize, Int64 outSize) 1251 | { 1252 | _inStream = inStream; 1253 | _finished = false; 1254 | Create(); 1255 | SetOutStream(outStream); 1256 | Init(); 1257 | 1258 | // if (!_fastMode) 1259 | { 1260 | FillDistancesPrices(); 1261 | FillAlignPrices(); 1262 | } 1263 | 1264 | _lenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen); 1265 | _lenEncoder.UpdateTables((UInt32)1 << _posStateBits); 1266 | _repMatchLenEncoder.SetTableSize(_numFastBytes + 1 - Base.kMatchMinLen); 1267 | _repMatchLenEncoder.UpdateTables((UInt32)1 << _posStateBits); 1268 | 1269 | nowPos64 = 0; 1270 | } 1271 | 1272 | 1273 | public void Code(System.IO.Stream inStream, System.IO.Stream outStream, 1274 | Int64 inSize, Int64 outSize, ICodeProgress progress) 1275 | { 1276 | _needReleaseMFStream = false; 1277 | try 1278 | { 1279 | SetStreams(inStream, outStream, inSize, outSize); 1280 | while (true) 1281 | { 1282 | Int64 processedInSize; 1283 | Int64 processedOutSize; 1284 | bool finished; 1285 | CodeOneBlock(out processedInSize, out processedOutSize, out finished); 1286 | if (finished) 1287 | return; 1288 | if (progress != null) 1289 | { 1290 | progress.SetProgress(processedInSize, processedOutSize); 1291 | } 1292 | } 1293 | } 1294 | finally 1295 | { 1296 | ReleaseStreams(); 1297 | } 1298 | } 1299 | 1300 | const int kPropSize = 5; 1301 | Byte[] properties = new Byte[kPropSize]; 1302 | 1303 | public void WriteCoderProperties(System.IO.Stream outStream) 1304 | { 1305 | properties[0] = (Byte)((_posStateBits * 5 + _numLiteralPosStateBits) * 9 + _numLiteralContextBits); 1306 | for (int i = 0; i < 4; i++) 1307 | properties[1 + i] = (Byte)((_dictionarySize >> (8 * i)) & 0xFF); 1308 | outStream.Write(properties, 0, kPropSize); 1309 | } 1310 | 1311 | UInt32[] tempPrices = new UInt32[Base.kNumFullDistances]; 1312 | UInt32 _matchPriceCount; 1313 | 1314 | void FillDistancesPrices() 1315 | { 1316 | for (UInt32 i = Base.kStartPosModelIndex; i < Base.kNumFullDistances; i++) 1317 | { 1318 | UInt32 posSlot = GetPosSlot(i); 1319 | int footerBits = (int)((posSlot >> 1) - 1); 1320 | UInt32 baseVal = ((2 | (posSlot & 1)) << footerBits); 1321 | tempPrices[i] = BitTreeEncoder.ReverseGetPrice(_posEncoders, 1322 | baseVal - posSlot - 1, footerBits, i - baseVal); 1323 | } 1324 | 1325 | for (UInt32 lenToPosState = 0; lenToPosState < Base.kNumLenToPosStates; lenToPosState++) 1326 | { 1327 | UInt32 posSlot; 1328 | RangeCoder.BitTreeEncoder encoder = _posSlotEncoder[lenToPosState]; 1329 | 1330 | UInt32 st = (lenToPosState << Base.kNumPosSlotBits); 1331 | for (posSlot = 0; posSlot < _distTableSize; posSlot++) 1332 | _posSlotPrices[st + posSlot] = encoder.GetPrice(posSlot); 1333 | for (posSlot = Base.kEndPosModelIndex; posSlot < _distTableSize; posSlot++) 1334 | _posSlotPrices[st + posSlot] += ((((posSlot >> 1) - 1) - Base.kNumAlignBits) << RangeCoder.BitEncoder.kNumBitPriceShiftBits); 1335 | 1336 | UInt32 st2 = lenToPosState * Base.kNumFullDistances; 1337 | UInt32 i; 1338 | for (i = 0; i < Base.kStartPosModelIndex; i++) 1339 | _distancesPrices[st2 + i] = _posSlotPrices[st + i]; 1340 | for (; i < Base.kNumFullDistances; i++) 1341 | _distancesPrices[st2 + i] = _posSlotPrices[st + GetPosSlot(i)] + tempPrices[i]; 1342 | } 1343 | _matchPriceCount = 0; 1344 | } 1345 | 1346 | void FillAlignPrices() 1347 | { 1348 | for (UInt32 i = 0; i < Base.kAlignTableSize; i++) 1349 | _alignPrices[i] = _posAlignEncoder.ReverseGetPrice(i); 1350 | _alignPriceCount = 0; 1351 | } 1352 | 1353 | 1354 | static string[] kMatchFinderIDs = 1355 | { 1356 | "BT2", 1357 | "BT4", 1358 | }; 1359 | 1360 | static int FindMatchFinder(string s) 1361 | { 1362 | for (int m = 0; m < kMatchFinderIDs.Length; m++) 1363 | if (s == kMatchFinderIDs[m]) 1364 | return m; 1365 | return -1; 1366 | } 1367 | 1368 | public void SetCoderProperties(CoderPropID[] propIDs, object[] properties) 1369 | { 1370 | for (UInt32 i = 0; i < properties.Length; i++) 1371 | { 1372 | object prop = properties[i]; 1373 | switch (propIDs[i]) 1374 | { 1375 | case CoderPropID.NumFastBytes: 1376 | { 1377 | if (!(prop is Int32)) 1378 | throw new InvalidParamException(); 1379 | Int32 numFastBytes = (Int32)prop; 1380 | if (numFastBytes < 5 || numFastBytes > Base.kMatchMaxLen) 1381 | throw new InvalidParamException(); 1382 | _numFastBytes = (UInt32)numFastBytes; 1383 | break; 1384 | } 1385 | case CoderPropID.Algorithm: 1386 | { 1387 | /* 1388 | if (!(prop is Int32)) 1389 | throw new InvalidParamException(); 1390 | Int32 maximize = (Int32)prop; 1391 | _fastMode = (maximize == 0); 1392 | _maxMode = (maximize >= 2); 1393 | */ 1394 | break; 1395 | } 1396 | case CoderPropID.MatchFinder: 1397 | { 1398 | if (!(prop is String)) 1399 | throw new InvalidParamException(); 1400 | EMatchFinderType matchFinderIndexPrev = _matchFinderType; 1401 | int m = FindMatchFinder(((string)prop).ToUpper()); 1402 | if (m < 0) 1403 | throw new InvalidParamException(); 1404 | _matchFinderType = (EMatchFinderType)m; 1405 | if (_matchFinder != null && matchFinderIndexPrev != _matchFinderType) 1406 | { 1407 | _dictionarySizePrev = 0xFFFFFFFF; 1408 | _matchFinder = null; 1409 | } 1410 | break; 1411 | } 1412 | case CoderPropID.DictionarySize: 1413 | { 1414 | const int kDicLogSizeMaxCompress = 30; 1415 | if (!(prop is Int32)) 1416 | throw new InvalidParamException(); ; 1417 | Int32 dictionarySize = (Int32)prop; 1418 | if (dictionarySize < (UInt32)(1 << Base.kDicLogSizeMin) || 1419 | dictionarySize > (UInt32)(1 << kDicLogSizeMaxCompress)) 1420 | throw new InvalidParamException(); 1421 | _dictionarySize = (UInt32)dictionarySize; 1422 | int dicLogSize; 1423 | for (dicLogSize = 0; dicLogSize < (UInt32)kDicLogSizeMaxCompress; dicLogSize++) 1424 | if (dictionarySize <= ((UInt32)(1) << dicLogSize)) 1425 | break; 1426 | _distTableSize = (UInt32)dicLogSize * 2; 1427 | break; 1428 | } 1429 | case CoderPropID.PosStateBits: 1430 | { 1431 | if (!(prop is Int32)) 1432 | throw new InvalidParamException(); 1433 | Int32 v = (Int32)prop; 1434 | if (v < 0 || v > (UInt32)Base.kNumPosStatesBitsEncodingMax) 1435 | throw new InvalidParamException(); 1436 | _posStateBits = (int)v; 1437 | _posStateMask = (((UInt32)1) << (int)_posStateBits) - 1; 1438 | break; 1439 | } 1440 | case CoderPropID.LitPosBits: 1441 | { 1442 | if (!(prop is Int32)) 1443 | throw new InvalidParamException(); 1444 | Int32 v = (Int32)prop; 1445 | if (v < 0 || v > (UInt32)Base.kNumLitPosStatesBitsEncodingMax) 1446 | throw new InvalidParamException(); 1447 | _numLiteralPosStateBits = (int)v; 1448 | break; 1449 | } 1450 | case CoderPropID.LitContextBits: 1451 | { 1452 | if (!(prop is Int32)) 1453 | throw new InvalidParamException(); 1454 | Int32 v = (Int32)prop; 1455 | if (v < 0 || v > (UInt32)Base.kNumLitContextBitsMax) 1456 | throw new InvalidParamException(); ; 1457 | _numLiteralContextBits = (int)v; 1458 | break; 1459 | } 1460 | case CoderPropID.EndMarker: 1461 | { 1462 | if (!(prop is Boolean)) 1463 | throw new InvalidParamException(); 1464 | SetWriteEndMarkerMode((Boolean)prop); 1465 | break; 1466 | } 1467 | default: 1468 | throw new InvalidParamException(); 1469 | } 1470 | } 1471 | } 1472 | 1473 | uint _trainSize = 0; 1474 | public void SetTrainSize(uint trainSize) 1475 | { 1476 | _trainSize = trainSize; 1477 | } 1478 | 1479 | } 1480 | } 1481 | --------------------------------------------------------------------------------