├── 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 |
--------------------------------------------------------------------------------